From 9659cfe976a424a20e7b840152a13d266e794226 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Thu, 24 Jan 2019 12:41:06 -0800 Subject: mavenizing bcel-builder - complete --- bcel-builder/.classpath | 10 - bcel-builder/.cvsignore | 2 - bcel-builder/.isJava7 | 1 - bcel-builder/.project | 17 - bcel-builder/.settings/org.eclipse.jdt.core.prefs | 57 - bcel-builder/.settings/org.eclipse.jdt.ui.prefs | 3 - bcel-builder/pom.xml | 19 + .../java/org/aspectj/apache/bcel/Constants.java | 685 +++++++++++ .../aspectj/apache/bcel/ConstantsInitializer.java | 396 ++++++ .../aspectj/apache/bcel/ExceptionConstants.java | 150 +++ .../java/org/aspectj/apache/bcel/Repository.java | 260 ++++ .../apache/bcel/classfile/AnnotationDefault.java | 55 + .../aspectj/apache/bcel/classfile/Attribute.java | 213 ++++ .../apache/bcel/classfile/AttributeUtils.java | 99 ++ .../apache/bcel/classfile/BootstrapMethods.java | 268 ++++ .../bcel/classfile/ClassFormatException.java | 69 ++ .../aspectj/apache/bcel/classfile/ClassParser.java | 249 ++++ .../apache/bcel/classfile/ClassVisitor.java | 180 +++ .../org/aspectj/apache/bcel/classfile/Code.java | 388 ++++++ .../apache/bcel/classfile/CodeException.java | 196 +++ .../aspectj/apache/bcel/classfile/Constant.java | 149 +++ .../aspectj/apache/bcel/classfile/ConstantCP.java | 109 ++ .../apache/bcel/classfile/ConstantClass.java | 112 ++ .../apache/bcel/classfile/ConstantDouble.java | 107 ++ .../apache/bcel/classfile/ConstantDynamic.java | 116 ++ .../apache/bcel/classfile/ConstantFieldref.java | 87 ++ .../apache/bcel/classfile/ConstantFloat.java | 108 ++ .../apache/bcel/classfile/ConstantInteger.java | 111 ++ .../bcel/classfile/ConstantInterfaceMethodref.java | 88 ++ .../bcel/classfile/ConstantInvokeDynamic.java | 132 ++ .../apache/bcel/classfile/ConstantLong.java | 108 ++ .../bcel/classfile/ConstantMethodHandle.java | 132 ++ .../apache/bcel/classfile/ConstantMethodType.java | 121 ++ .../apache/bcel/classfile/ConstantMethodref.java | 87 ++ .../apache/bcel/classfile/ConstantModule.java | 111 ++ .../apache/bcel/classfile/ConstantNameAndType.java | 157 +++ .../apache/bcel/classfile/ConstantObject.java | 66 + .../apache/bcel/classfile/ConstantPackage.java | 111 ++ .../apache/bcel/classfile/ConstantPool.java | 816 +++++++++++++ .../apache/bcel/classfile/ConstantString.java | 120 ++ .../apache/bcel/classfile/ConstantUtf8.java | 109 ++ .../apache/bcel/classfile/ConstantValue.java | 131 ++ .../aspectj/apache/bcel/classfile/Deprecated.java | 171 +++ .../apache/bcel/classfile/EnclosingMethod.java | 87 ++ .../apache/bcel/classfile/ExceptionTable.java | 199 +++ .../org/aspectj/apache/bcel/classfile/Field.java | 136 +++ .../apache/bcel/classfile/FieldOrMethod.java | 201 +++ .../aspectj/apache/bcel/classfile/InnerClass.java | 232 ++++ .../apache/bcel/classfile/InnerClasses.java | 181 +++ .../aspectj/apache/bcel/classfile/JavaClass.java | 837 +++++++++++++ .../aspectj/apache/bcel/classfile/LineNumber.java | 120 ++ .../apache/bcel/classfile/LineNumberTable.java | 276 +++++ .../apache/bcel/classfile/LocalVariable.java | 267 ++++ .../apache/bcel/classfile/LocalVariableTable.java | 230 ++++ .../bcel/classfile/LocalVariableTypeTable.java | 136 +++ .../org/aspectj/apache/bcel/classfile/Method.java | 273 +++++ .../apache/bcel/classfile/MethodParameters.java | 112 ++ .../aspectj/apache/bcel/classfile/Modifiers.java | 140 +++ .../org/aspectj/apache/bcel/classfile/Module.java | 664 ++++++++++ .../apache/bcel/classfile/ModuleMainClass.java | 106 ++ .../apache/bcel/classfile/ModulePackages.java | 126 ++ .../aspectj/apache/bcel/classfile/NestHost.java | 118 ++ .../aspectj/apache/bcel/classfile/NestMembers.java | 131 ++ .../org/aspectj/apache/bcel/classfile/Node.java | 65 + .../aspectj/apache/bcel/classfile/Signature.java | 310 +++++ .../apache/bcel/classfile/SimpleConstant.java | 58 + .../aspectj/apache/bcel/classfile/SourceFile.java | 169 +++ .../aspectj/apache/bcel/classfile/StackMap.java | 190 +++ .../apache/bcel/classfile/StackMapEntry.java | 210 ++++ .../apache/bcel/classfile/StackMapType.java | 172 +++ .../aspectj/apache/bcel/classfile/Synthetic.java | 185 +++ .../org/aspectj/apache/bcel/classfile/Unknown.java | 215 ++++ .../org/aspectj/apache/bcel/classfile/Utility.java | 1094 +++++++++++++++++ .../annotation/AnnotationElementValue.java | 73 ++ .../bcel/classfile/annotation/AnnotationGen.java | 176 +++ .../classfile/annotation/ArrayElementValue.java | 84 ++ .../classfile/annotation/ClassElementValue.java | 79 ++ .../bcel/classfile/annotation/ElementValue.java | 135 ++ .../classfile/annotation/EnumElementValue.java | 116 ++ .../bcel/classfile/annotation/NameValuePair.java | 75 ++ .../bcel/classfile/annotation/RuntimeAnnos.java | 98 ++ .../classfile/annotation/RuntimeInvisAnnos.java | 51 + .../annotation/RuntimeInvisParamAnnos.java | 45 + .../annotation/RuntimeInvisTypeAnnos.java | 36 + .../classfile/annotation/RuntimeParamAnnos.java | 137 +++ .../classfile/annotation/RuntimeTypeAnnos.java | 105 ++ .../bcel/classfile/annotation/RuntimeVisAnnos.java | 51 + .../classfile/annotation/RuntimeVisParamAnnos.java | 45 + .../classfile/annotation/RuntimeVisTypeAnnos.java | 36 + .../classfile/annotation/SimpleElementValue.java | 330 +++++ .../classfile/annotation/TypeAnnotationGen.java | 405 ++++++ .../org/aspectj/apache/bcel/generic/ArrayType.java | 156 +++ .../org/aspectj/apache/bcel/generic/BasicType.java | 111 ++ .../aspectj/apache/bcel/generic/BranchHandle.java | 134 ++ .../org/aspectj/apache/bcel/generic/ClassGen.java | 637 ++++++++++ .../apache/bcel/generic/ClassGenException.java | 68 ++ .../apache/bcel/generic/CodeExceptionGen.java | 202 +++ .../org/aspectj/apache/bcel/generic/FieldGen.java | 245 ++++ .../apache/bcel/generic/FieldGenOrMethodGen.java | 158 +++ .../apache/bcel/generic/FieldInstruction.java | 112 ++ .../aspectj/apache/bcel/generic/FieldOrMethod.java | 133 ++ .../java/org/aspectj/apache/bcel/generic/IINC.java | 121 ++ .../apache/bcel/generic/INVOKEINTERFACE.java | 127 ++ .../aspectj/apache/bcel/generic/InstVisitor.java | 247 ++++ .../aspectj/apache/bcel/generic/Instruction.java | 454 +++++++ .../apache/bcel/generic/InstructionBranch.java | 338 +++++ .../apache/bcel/generic/InstructionByte.java | 108 ++ .../apache/bcel/generic/InstructionCLV.java | 27 + .../aspectj/apache/bcel/generic/InstructionCP.java | 224 ++++ .../apache/bcel/generic/InstructionConstants.java | 379 ++++++ .../apache/bcel/generic/InstructionFactory.java | 771 ++++++++++++ .../apache/bcel/generic/InstructionHandle.java | 189 +++ .../aspectj/apache/bcel/generic/InstructionLV.java | 278 +++++ .../apache/bcel/generic/InstructionList.java | 1287 ++++++++++++++++++++ .../apache/bcel/generic/InstructionSelect.java | 291 +++++ .../apache/bcel/generic/InstructionShort.java | 92 ++ .../apache/bcel/generic/InstructionTargeter.java | 70 ++ .../aspectj/apache/bcel/generic/InvokeDynamic.java | 129 ++ .../apache/bcel/generic/InvokeInstruction.java | 137 +++ .../aspectj/apache/bcel/generic/LOOKUPSWITCH.java | 112 ++ .../aspectj/apache/bcel/generic/LineNumberGen.java | 130 ++ .../aspectj/apache/bcel/generic/LineNumberTag.java | 44 + .../apache/bcel/generic/LocalVariableGen.java | 220 ++++ .../apache/bcel/generic/LocalVariableTag.java | 96 ++ .../apache/bcel/generic/MULTIANEWARRAY.java | 183 +++ .../org/aspectj/apache/bcel/generic/MethodGen.java | 1169 ++++++++++++++++++ .../aspectj/apache/bcel/generic/ObjectType.java | 161 +++ .../java/org/aspectj/apache/bcel/generic/RET.java | 132 ++ .../aspectj/apache/bcel/generic/ReferenceType.java | 365 ++++++ .../apache/bcel/generic/ReturnaddressType.java | 102 ++ .../aspectj/apache/bcel/generic/SwitchBuilder.java | 181 +++ .../aspectj/apache/bcel/generic/TABLESWITCH.java | 138 +++ .../java/org/aspectj/apache/bcel/generic/Tag.java | 45 + .../apache/bcel/generic/TargetLostException.java | 101 ++ .../java/org/aspectj/apache/bcel/generic/Type.java | 508 ++++++++ .../org/aspectj/apache/bcel/util/ByteSequence.java | 82 ++ .../apache/bcel/util/ClassLoaderReference.java | 67 + .../apache/bcel/util/ClassLoaderRepository.java | 394 ++++++ .../org/aspectj/apache/bcel/util/ClassPath.java | 584 +++++++++ .../bcel/util/DefaultClassLoaderReference.java | 75 ++ .../bcel/util/NonCachingClassLoaderRepository.java | 268 ++++ .../org/aspectj/apache/bcel/util/Repository.java | 98 ++ .../apache/bcel/util/SyntheticRepository.java | 195 +++ .../src/org/aspectj/apache/bcel/Constants.java | 685 ----------- .../aspectj/apache/bcel/ConstantsInitializer.java | 396 ------ .../aspectj/apache/bcel/ExceptionConstants.java | 150 --- .../src/org/aspectj/apache/bcel/Repository.java | 260 ---- .../apache/bcel/classfile/AnnotationDefault.java | 55 - .../aspectj/apache/bcel/classfile/Attribute.java | 213 ---- .../apache/bcel/classfile/AttributeUtils.java | 99 -- .../apache/bcel/classfile/BootstrapMethods.java | 268 ---- .../bcel/classfile/ClassFormatException.java | 69 -- .../aspectj/apache/bcel/classfile/ClassParser.java | 249 ---- .../apache/bcel/classfile/ClassVisitor.java | 180 --- .../org/aspectj/apache/bcel/classfile/Code.java | 388 ------ .../apache/bcel/classfile/CodeException.java | 196 --- .../aspectj/apache/bcel/classfile/Constant.java | 149 --- .../aspectj/apache/bcel/classfile/ConstantCP.java | 109 -- .../apache/bcel/classfile/ConstantClass.java | 112 -- .../apache/bcel/classfile/ConstantDouble.java | 107 -- .../apache/bcel/classfile/ConstantDynamic.java | 116 -- .../apache/bcel/classfile/ConstantFieldref.java | 87 -- .../apache/bcel/classfile/ConstantFloat.java | 108 -- .../apache/bcel/classfile/ConstantInteger.java | 111 -- .../bcel/classfile/ConstantInterfaceMethodref.java | 88 -- .../bcel/classfile/ConstantInvokeDynamic.java | 132 -- .../apache/bcel/classfile/ConstantLong.java | 108 -- .../bcel/classfile/ConstantMethodHandle.java | 132 -- .../apache/bcel/classfile/ConstantMethodType.java | 121 -- .../apache/bcel/classfile/ConstantMethodref.java | 87 -- .../apache/bcel/classfile/ConstantModule.java | 111 -- .../apache/bcel/classfile/ConstantNameAndType.java | 157 --- .../apache/bcel/classfile/ConstantObject.java | 66 - .../apache/bcel/classfile/ConstantPackage.java | 111 -- .../apache/bcel/classfile/ConstantPool.java | 816 ------------- .../apache/bcel/classfile/ConstantString.java | 120 -- .../apache/bcel/classfile/ConstantUtf8.java | 109 -- .../apache/bcel/classfile/ConstantValue.java | 131 -- .../aspectj/apache/bcel/classfile/Deprecated.java | 171 --- .../apache/bcel/classfile/EnclosingMethod.java | 87 -- .../apache/bcel/classfile/ExceptionTable.java | 199 --- .../org/aspectj/apache/bcel/classfile/Field.java | 136 --- .../apache/bcel/classfile/FieldOrMethod.java | 201 --- .../aspectj/apache/bcel/classfile/InnerClass.java | 232 ---- .../apache/bcel/classfile/InnerClasses.java | 181 --- .../aspectj/apache/bcel/classfile/JavaClass.java | 837 ------------- .../aspectj/apache/bcel/classfile/LineNumber.java | 120 -- .../apache/bcel/classfile/LineNumberTable.java | 276 ----- .../apache/bcel/classfile/LocalVariable.java | 267 ---- .../apache/bcel/classfile/LocalVariableTable.java | 230 ---- .../bcel/classfile/LocalVariableTypeTable.java | 136 --- .../org/aspectj/apache/bcel/classfile/Method.java | 273 ----- .../apache/bcel/classfile/MethodParameters.java | 112 -- .../aspectj/apache/bcel/classfile/Modifiers.java | 140 --- .../org/aspectj/apache/bcel/classfile/Module.java | 664 ---------- .../apache/bcel/classfile/ModuleMainClass.java | 106 -- .../apache/bcel/classfile/ModulePackages.java | 126 -- .../aspectj/apache/bcel/classfile/NestHost.java | 118 -- .../aspectj/apache/bcel/classfile/NestMembers.java | 131 -- .../org/aspectj/apache/bcel/classfile/Node.java | 65 - .../aspectj/apache/bcel/classfile/Signature.java | 310 ----- .../apache/bcel/classfile/SimpleConstant.java | 58 - .../aspectj/apache/bcel/classfile/SourceFile.java | 169 --- .../aspectj/apache/bcel/classfile/StackMap.java | 190 --- .../apache/bcel/classfile/StackMapEntry.java | 210 ---- .../apache/bcel/classfile/StackMapType.java | 172 --- .../aspectj/apache/bcel/classfile/Synthetic.java | 185 --- .../org/aspectj/apache/bcel/classfile/Unknown.java | 215 ---- .../org/aspectj/apache/bcel/classfile/Utility.java | 1094 ----------------- .../annotation/AnnotationElementValue.java | 73 -- .../bcel/classfile/annotation/AnnotationGen.java | 176 --- .../classfile/annotation/ArrayElementValue.java | 84 -- .../classfile/annotation/ClassElementValue.java | 79 -- .../bcel/classfile/annotation/ElementValue.java | 135 -- .../classfile/annotation/EnumElementValue.java | 116 -- .../bcel/classfile/annotation/NameValuePair.java | 75 -- .../bcel/classfile/annotation/RuntimeAnnos.java | 98 -- .../classfile/annotation/RuntimeInvisAnnos.java | 51 - .../annotation/RuntimeInvisParamAnnos.java | 45 - .../annotation/RuntimeInvisTypeAnnos.java | 36 - .../classfile/annotation/RuntimeParamAnnos.java | 137 --- .../classfile/annotation/RuntimeTypeAnnos.java | 105 -- .../bcel/classfile/annotation/RuntimeVisAnnos.java | 51 - .../classfile/annotation/RuntimeVisParamAnnos.java | 45 - .../classfile/annotation/RuntimeVisTypeAnnos.java | 36 - .../classfile/annotation/SimpleElementValue.java | 330 ----- .../classfile/annotation/TypeAnnotationGen.java | 405 ------ .../org/aspectj/apache/bcel/generic/ArrayType.java | 156 --- .../org/aspectj/apache/bcel/generic/BasicType.java | 111 -- .../aspectj/apache/bcel/generic/BranchHandle.java | 134 -- .../org/aspectj/apache/bcel/generic/ClassGen.java | 637 ---------- .../apache/bcel/generic/ClassGenException.java | 68 -- .../apache/bcel/generic/CodeExceptionGen.java | 202 --- .../org/aspectj/apache/bcel/generic/FieldGen.java | 245 ---- .../apache/bcel/generic/FieldGenOrMethodGen.java | 158 --- .../apache/bcel/generic/FieldInstruction.java | 112 -- .../aspectj/apache/bcel/generic/FieldOrMethod.java | 133 -- .../src/org/aspectj/apache/bcel/generic/IINC.java | 121 -- .../apache/bcel/generic/INVOKEINTERFACE.java | 127 -- .../aspectj/apache/bcel/generic/InstVisitor.java | 247 ---- .../aspectj/apache/bcel/generic/Instruction.java | 454 ------- .../apache/bcel/generic/InstructionBranch.java | 338 ----- .../apache/bcel/generic/InstructionByte.java | 108 -- .../apache/bcel/generic/InstructionCLV.java | 27 - .../aspectj/apache/bcel/generic/InstructionCP.java | 224 ---- .../apache/bcel/generic/InstructionConstants.java | 379 ------ .../apache/bcel/generic/InstructionFactory.java | 771 ------------ .../apache/bcel/generic/InstructionHandle.java | 189 --- .../aspectj/apache/bcel/generic/InstructionLV.java | 278 ----- .../apache/bcel/generic/InstructionList.java | 1287 -------------------- .../apache/bcel/generic/InstructionSelect.java | 291 ----- .../apache/bcel/generic/InstructionShort.java | 92 -- .../apache/bcel/generic/InstructionTargeter.java | 70 -- .../aspectj/apache/bcel/generic/InvokeDynamic.java | 129 -- .../apache/bcel/generic/InvokeInstruction.java | 137 --- .../aspectj/apache/bcel/generic/LOOKUPSWITCH.java | 112 -- .../aspectj/apache/bcel/generic/LineNumberGen.java | 130 -- .../aspectj/apache/bcel/generic/LineNumberTag.java | 44 - .../apache/bcel/generic/LocalVariableGen.java | 220 ---- .../apache/bcel/generic/LocalVariableTag.java | 96 -- .../apache/bcel/generic/MULTIANEWARRAY.java | 183 --- .../org/aspectj/apache/bcel/generic/MethodGen.java | 1169 ------------------ .../aspectj/apache/bcel/generic/ObjectType.java | 161 --- .../src/org/aspectj/apache/bcel/generic/RET.java | 132 -- .../aspectj/apache/bcel/generic/ReferenceType.java | 365 ------ .../apache/bcel/generic/ReturnaddressType.java | 102 -- .../aspectj/apache/bcel/generic/SwitchBuilder.java | 181 --- .../aspectj/apache/bcel/generic/TABLESWITCH.java | 138 --- .../src/org/aspectj/apache/bcel/generic/Tag.java | 45 - .../apache/bcel/generic/TargetLostException.java | 101 -- .../src/org/aspectj/apache/bcel/generic/Type.java | 508 -------- .../org/aspectj/apache/bcel/util/ByteSequence.java | 82 -- .../apache/bcel/util/ClassLoaderReference.java | 67 - .../apache/bcel/util/ClassLoaderRepository.java | 394 ------ .../org/aspectj/apache/bcel/util/ClassPath.java | 584 --------- .../bcel/util/DefaultClassLoaderReference.java | 75 -- .../bcel/util/NonCachingClassLoaderRepository.java | 268 ---- .../org/aspectj/apache/bcel/util/Repository.java | 98 -- .../apache/bcel/util/SyntheticRepository.java | 195 --- .../classfile/tests/AnnotationAccessFlagTest.java | 55 + .../tests/AnnotationDefaultAttributeTest.java | 49 + .../bcel/classfile/tests/AnnotationGenTest.java | 179 +++ .../bcel/classfile/tests/AnonymousClassTest.java | 60 + .../apache/bcel/classfile/tests/BcelTestCase.java | 186 +++ .../classfile/tests/ClassloaderRepositoryTest.java | 89 ++ .../classfile/tests/ConstantPoolToStringTest.java | 54 + .../bcel/classfile/tests/ElementValueGenTest.java | 229 ++++ .../tests/EnclosingMethodAttributeTest.java | 98 ++ .../bcel/classfile/tests/EnumAccessFlagTest.java | 56 + .../bcel/classfile/tests/FieldAnnotationsTest.java | 146 +++ .../apache/bcel/classfile/tests/Fundamentals.java | 319 +++++ .../tests/GeneratingAnnotatedClassesTest.java | 572 +++++++++ .../tests/GenericSignatureParsingTest.java | 472 +++++++ .../classfile/tests/GenericsErasureTesting.java | 50 + .../classfile/tests/GetReflectMembersTest.java | 61 + .../tests/LocalVariableTypeTableTest.java | 72 ++ .../classfile/tests/MethodAnnotationsTest.java | 107 ++ .../bcel/classfile/tests/MethodParametersTest.java | 86 ++ .../apache/bcel/classfile/tests/ModuleTest.java | 136 +++ .../tests/NonCachingClassLoaderRepositoryTest.java | 149 +++ .../classfile/tests/ParameterAnnotationsTest.java | 590 +++++++++ .../RuntimeVisibleAnnotationAttributeTest.java | 395 ++++++ ...imeVisibleParameterAnnotationAttributeTest.java | 143 +++ .../bcel/classfile/tests/TypeAnnotationsTest.java | 374 ++++++ .../apache/bcel/classfile/tests/UtilTests.java | 68 ++ .../apache/bcel/classfile/tests/VarargsTest.java | 97 ++ .../aspectj/apache/bcel/util/ClassPathTests.java | 22 + .../java/org/aspectj/apache/bcel/util/Play.java | 84 ++ .../apache/bcel/classfile/tests/AllTests.java | 52 - .../classfile/tests/AnnotationAccessFlagTest.java | 55 - .../tests/AnnotationDefaultAttributeTest.java | 49 - .../bcel/classfile/tests/AnnotationGenTest.java | 179 --- .../bcel/classfile/tests/AnonymousClassTest.java | 60 - .../apache/bcel/classfile/tests/BcelTestCase.java | 186 --- .../classfile/tests/ClassloaderRepositoryTest.java | 89 -- .../classfile/tests/ConstantPoolToStringTest.java | 54 - .../bcel/classfile/tests/ElementValueGenTest.java | 229 ---- .../tests/EnclosingMethodAttributeTest.java | 98 -- .../bcel/classfile/tests/EnumAccessFlagTest.java | 56 - .../bcel/classfile/tests/FieldAnnotationsTest.java | 146 --- .../apache/bcel/classfile/tests/Fundamentals.java | 319 ----- .../tests/GeneratingAnnotatedClassesTest.java | 572 --------- .../tests/GenericSignatureParsingTest.java | 472 ------- .../classfile/tests/GenericsErasureTesting.java | 50 - .../classfile/tests/GetReflectMembersTest.java | 61 - .../tests/LocalVariableTypeTableTest.java | 72 -- .../classfile/tests/MethodAnnotationsTest.java | 107 -- .../bcel/classfile/tests/MethodParametersTest.java | 86 -- .../apache/bcel/classfile/tests/ModuleTest.java | 136 --- .../tests/NonCachingClassLoaderRepositoryTest.java | 149 --- .../classfile/tests/ParameterAnnotationsTest.java | 590 --------- .../RuntimeVisibleAnnotationAttributeTest.java | 395 ------ ...imeVisibleParameterAnnotationAttributeTest.java | 143 --- .../bcel/classfile/tests/TypeAnnotationsTest.java | 374 ------ .../apache/bcel/classfile/tests/UtilTests.java | 68 -- .../apache/bcel/classfile/tests/VarargsTest.java | 97 -- .../aspectj/apache/bcel/util/ClassPathTests.java | 22 - .../testsrc/org/aspectj/apache/bcel/util/Play.java | 84 -- 338 files changed, 33576 insertions(+), 33699 deletions(-) delete mode 100644 bcel-builder/.classpath delete mode 100644 bcel-builder/.cvsignore delete mode 100644 bcel-builder/.isJava7 delete mode 100644 bcel-builder/.project delete mode 100644 bcel-builder/.settings/org.eclipse.jdt.core.prefs delete mode 100644 bcel-builder/.settings/org.eclipse.jdt.ui.prefs create mode 100644 bcel-builder/pom.xml create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/ConstantsInitializer.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/ExceptionConstants.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/Repository.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AnnotationDefault.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Attribute.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AttributeUtils.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/BootstrapMethods.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassFormatException.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassParser.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassVisitor.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Code.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/CodeException.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Constant.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantCP.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantClass.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDouble.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDynamic.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFieldref.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFloat.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInteger.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantLong.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodType.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodref.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantModule.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantObject.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPackage.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPool.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantString.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantUtf8.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantValue.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Deprecated.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/EnclosingMethod.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ExceptionTable.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Field.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/FieldOrMethod.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClass.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClasses.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/JavaClass.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumber.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumberTable.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariable.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTable.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Method.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/MethodParameters.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Modifiers.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Module.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModuleMainClass.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModulePackages.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestHost.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestMembers.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Node.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Signature.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SimpleConstant.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SourceFile.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMap.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapEntry.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapType.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Synthetic.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Unknown.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Utility.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeTypeAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisTypeAnnos.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/SimpleElementValue.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/TypeAnnotationGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ArrayType.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BasicType.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BranchHandle.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGenException.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/CodeExceptionGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldInstruction.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldOrMethod.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/IINC.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstVisitor.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Instruction.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionBranch.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionByte.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCLV.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCP.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionConstants.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionFactory.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionHandle.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionLV.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionList.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionSelect.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionShort.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionTargeter.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeDynamic.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeInstruction.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberTag.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableTag.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MethodGen.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ObjectType.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/RET.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReferenceType.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReturnaddressType.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/SwitchBuilder.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TABLESWITCH.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Tag.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TargetLostException.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Type.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ByteSequence.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderReference.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderRepository.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassPath.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/util/Repository.java create mode 100644 bcel-builder/src/main/java/org/aspectj/apache/bcel/util/SyntheticRepository.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/Constants.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/ConstantsInitializer.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/ExceptionConstants.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/Repository.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/AnnotationDefault.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/AttributeUtils.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/BootstrapMethods.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassFormatException.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/CodeException.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantCP.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantClass.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantDouble.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantDynamic.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantFieldref.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantFloat.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInteger.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantLong.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodType.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodref.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantObject.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantString.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantUtf8.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantValue.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Deprecated.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/EnclosingMethod.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ExceptionTable.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Field.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/InnerClass.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/InnerClasses.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/JavaClass.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumber.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumberTable.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariable.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariableTable.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Method.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/MethodParameters.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Modifiers.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ModuleMainClass.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/NestHost.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/NestMembers.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Node.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Signature.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/SimpleConstant.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/SourceFile.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMap.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapEntry.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapType.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Synthetic.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Unknown.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/Utility.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeTypeAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisTypeAnnos.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/SimpleElementValue.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/TypeAnnotationGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/ArrayType.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/BasicType.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGenException.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/CodeExceptionGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstVisitor.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCLV.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionConstants.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionTargeter.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeDynamic.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/ObjectType.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/ReferenceType.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/ReturnaddressType.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/SwitchBuilder.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/TABLESWITCH.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/TargetLostException.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/util/ByteSequence.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderReference.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/util/ClassPath.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/util/Repository.java delete mode 100644 bcel-builder/src/org/aspectj/apache/bcel/util/SyntheticRepository.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationAccessFlagTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationDefaultAttributeTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationGenTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnonymousClassTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ClassloaderRepositoryTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ConstantPoolToStringTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ElementValueGenTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/EnclosingMethodAttributeTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/EnumAccessFlagTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/FieldAnnotationsTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/Fundamentals.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GeneratingAnnotatedClassesTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GenericsErasureTesting.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GetReflectMembersTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/LocalVariableTypeTableTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/MethodAnnotationsTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/MethodParametersTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/NonCachingClassLoaderRepositoryTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ParameterAnnotationsTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleAnnotationAttributeTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleParameterAnnotationAttributeTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/UtilTests.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/VarargsTest.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/util/ClassPathTests.java create mode 100644 bcel-builder/src/test/java/org/aspectj/apache/bcel/util/Play.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationAccessFlagTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationDefaultAttributeTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationGenTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnonymousClassTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ClassloaderRepositoryTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ConstantPoolToStringTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ElementValueGenTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/EnclosingMethodAttributeTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/EnumAccessFlagTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/FieldAnnotationsTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/Fundamentals.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GeneratingAnnotatedClassesTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericsErasureTesting.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GetReflectMembersTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/LocalVariableTypeTableTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/MethodAnnotationsTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/MethodParametersTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/NonCachingClassLoaderRepositoryTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ParameterAnnotationsTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleAnnotationAttributeTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleParameterAnnotationAttributeTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/UtilTests.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/VarargsTest.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/util/ClassPathTests.java delete mode 100644 bcel-builder/testsrc/org/aspectj/apache/bcel/util/Play.java diff --git a/bcel-builder/.classpath b/bcel-builder/.classpath deleted file mode 100644 index 5cb8fd272..000000000 --- a/bcel-builder/.classpath +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/bcel-builder/.cvsignore b/bcel-builder/.cvsignore deleted file mode 100644 index 38972d828..000000000 --- a/bcel-builder/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -bintest diff --git a/bcel-builder/.isJava7 b/bcel-builder/.isJava7 deleted file mode 100644 index 136d06384..000000000 --- a/bcel-builder/.isJava7 +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/bcel-builder/.project b/bcel-builder/.project deleted file mode 100644 index 681642c6b..000000000 --- a/bcel-builder/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - bcel-builder - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/bcel-builder/.settings/org.eclipse.jdt.core.prefs b/bcel-builder/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index a7d4334af..000000000 --- a/bcel-builder/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,57 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.7 diff --git a/bcel-builder/.settings/org.eclipse.jdt.ui.prefs b/bcel-builder/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 968f6ad94..000000000 --- a/bcel-builder/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Wed Aug 24 14:55:56 BST 2005 -eclipse.preferences.version=1 -internal.default.compliance=default diff --git a/bcel-builder/pom.xml b/bcel-builder/pom.xml new file mode 100644 index 000000000..58dcd27c5 --- /dev/null +++ b/bcel-builder/pom.xml @@ -0,0 +1,19 @@ + + 4.0.0 + + org.aspectj + bcel-builder + jar + bcel-builder + http://maven.apache.org + + + org.aspectj + aspectj-parent + ${revision} + .. + + + diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java new file mode 100644 index 000000000..c75496527 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java @@ -0,0 +1,685 @@ +package org.aspectj.apache.bcel; + +import org.aspectj.apache.bcel.generic.Type; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Constants for the project, mostly defined in the JVM specification. + * + * @author M. Dahm + * @author Andy Clement + */ +public interface Constants { + // Major and minor version of the code + public final static short MAJOR_1_1 = 45; + public final static short MINOR_1_1 = 3; + public final static short MAJOR_1_2 = 46; + public final static short MINOR_1_2 = 0; + public final static short MAJOR_1_3 = 47; + public final static short MINOR_1_3 = 0; + public final static short MAJOR_1_4 = 48; + public final static short MINOR_1_4 = 0; + public final static short MAJOR_1_5 = 49; + public final static short MINOR_1_5 = 0; + public final static short MAJOR_1_6 = 50; + public final static short MINOR_1_6 = 0; + public final static short MAJOR_1_7 = 51; + public final static short MINOR_1_7 = 0; + public final static short MAJOR_1_8 = 52; + public final static short MINOR_1_8 = 0; + public final static short MAJOR_1_9 = 53; + public final static short MINOR_1_9 = 0; + public final static short MAJOR_10 = 54; + public final static short MINOR_10 = 0; + public final static short MAJOR_11 = 55; + public final static short MINOR_11 = 0; + // Defaults + public final static short MAJOR = MAJOR_1_1; + public final static short MINOR = MINOR_1_1; + + /** Maximum value for an unsigned short */ + public final static int MAX_SHORT = 65535; // 2^16 - 1 + + /** Maximum value for an unsigned byte */ + public final static int MAX_BYTE = 255; // 2^8 - 1 + + /** Access flags for classes, fields and methods */ + public final static short ACC_PUBLIC = 0x0001; + public final static short ACC_PRIVATE = 0x0002; + public final static short ACC_PROTECTED = 0x0004; + public final static short ACC_STATIC = 0x0008; + + public final static short ACC_FINAL = 0x0010; + public final static short ACC_SYNCHRONIZED = 0x0020; + public final static short ACC_VOLATILE = 0x0040; + public final static short ACC_TRANSIENT = 0x0080; + + public final static short ACC_NATIVE = 0x0100; + public final static short ACC_INTERFACE = 0x0200; + public final static short ACC_ABSTRACT = 0x0400; + public final static short ACC_STRICT = 0x0800; + + public final static short ACC_SYNTHETIC = 0x1000; + + public final static short ACC_ANNOTATION = 0x2000; + public final static short ACC_ENUM = 0x4000; + public final static int ACC_MODULE = 0x8000; + public final static short ACC_BRIDGE = 0x0040; + public final static short ACC_VARARGS = 0x0080; + + // Module related + // Indicates that any module which depends on the current module, + // implicitly declares a dependence on the module indicated by this entry. + public final static int MODULE_ACC_TRANSITIVE = 0x0020; + // Indicates that this dependence is mandatory in the static phase, i.e., at + // compile time, but is optional in the dynamic phase, i.e., at run time. + public final static int MODULE_ACC_STATIC_PHASE = 0x0040; + // Indicates that this dependence was not explicitly or implicitly declared + // in the source of the module declaration. + public final static int MODULE_ACC_SYNTHETIC = 0x1000; + // Indicates that this dependence was implicitly declared in the source of + // the module declaration + public final static int MODULE_ACC_MANDATED = 0x8000; + + // Applies to classes compiled by new compilers only + public final static short ACC_SUPER = 0x0020; + + public final static short MAX_ACC_FLAG = ACC_STRICT; + + public final static String[] ACCESS_NAMES = { "public", "private", "protected", "static", "final", "synchronized", "volatile", + "transient", "native", "interface", "abstract", "strictfp" }; + + /** Tags in constant pool to denote type of constant */ + public final static byte CONSTANT_Utf8 = 1; + public final static byte CONSTANT_Integer = 3; + public final static byte CONSTANT_Float = 4; + public final static byte CONSTANT_Long = 5; + public final static byte CONSTANT_Double = 6; + public final static byte CONSTANT_Class = 7; + public final static byte CONSTANT_Fieldref = 9; + public final static byte CONSTANT_String = 8; + public final static byte CONSTANT_Methodref = 10; + public final static byte CONSTANT_InterfaceMethodref = 11; + public final static byte CONSTANT_NameAndType = 12; + + public final static byte CONSTANT_MethodHandle = 15; + public final static byte CONSTANT_MethodType = 16; + public final static byte CONSTANT_Dynamic = 17; + public final static byte CONSTANT_InvokeDynamic = 18; + + public final static byte CONSTANT_Module = 19; + public final static byte CONSTANT_Package = 20; + + + public final static String[] CONSTANT_NAMES = { "", "CONSTANT_Utf8", "", "CONSTANT_Integer", "CONSTANT_Float", "CONSTANT_Long", + "CONSTANT_Double", "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", "CONSTANT_Methodref", + "CONSTANT_InterfaceMethodref", "CONSTANT_NameAndType","","","CONSTANT_MethodHandle","CONSTANT_MethodType","","CONSTANT_InvokeDynamic", + // J9: + "CONSTANT_Module", "CONSTANT_Package"}; + + /** + * The name of the static initializer, also called "class initialization method" or "interface initialization + * method". This is "<clinit>". + */ + public final static String STATIC_INITIALIZER_NAME = ""; + + /** + * The name of every constructor method in a class, also called "instance initialization method". This is + * "<init>". + */ + public final static String CONSTRUCTOR_NAME = ""; + + /** The names of the interfaces implemented by arrays */ + public final static String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = { "java.lang.Cloneable", "java.io.Serializable" }; + + /** + * Limitations of the Java Virtual Machine. See The Java Virtual Machine Specification, Second Edition, page 152, chapter 4.10. + */ + public static final int MAX_CP_ENTRIES = 65535; + public static final int MAX_CODE_SIZE = 65536; // bytes + + /** + * Java VM opcodes. + */ + public static final short NOP = 0; + public static final short ACONST_NULL = 1; + public static final short ICONST_M1 = 2; + public static final short ICONST_0 = 3; + public static final short ICONST_1 = 4; + public static final short ICONST_2 = 5; + public static final short ICONST_3 = 6; + public static final short ICONST_4 = 7; + public static final short ICONST_5 = 8; + public static final short LCONST_0 = 9; + public static final short LCONST_1 = 10; + public static final short FCONST_0 = 11; + public static final short FCONST_1 = 12; + public static final short FCONST_2 = 13; + public static final short DCONST_0 = 14; + public static final short DCONST_1 = 15; + public static final short BIPUSH = 16; + public static final short SIPUSH = 17; + public static final short LDC = 18; + public static final short LDC_W = 19; + public static final short LDC2_W = 20; + public static final short ILOAD = 21; + public static final short LLOAD = 22; + public static final short FLOAD = 23; + public static final short DLOAD = 24; + public static final short ALOAD = 25; + public static final short ILOAD_0 = 26; + public static final short ILOAD_1 = 27; + public static final short ILOAD_2 = 28; + public static final short ILOAD_3 = 29; + public static final short LLOAD_0 = 30; + public static final short LLOAD_1 = 31; + public static final short LLOAD_2 = 32; + public static final short LLOAD_3 = 33; + public static final short FLOAD_0 = 34; + public static final short FLOAD_1 = 35; + public static final short FLOAD_2 = 36; + public static final short FLOAD_3 = 37; + public static final short DLOAD_0 = 38; + public static final short DLOAD_1 = 39; + public static final short DLOAD_2 = 40; + public static final short DLOAD_3 = 41; + public static final short ALOAD_0 = 42; + public static final short ALOAD_1 = 43; + public static final short ALOAD_2 = 44; + public static final short ALOAD_3 = 45; + public static final short IALOAD = 46; + public static final short LALOAD = 47; + public static final short FALOAD = 48; + public static final short DALOAD = 49; + public static final short AALOAD = 50; + public static final short BALOAD = 51; + public static final short CALOAD = 52; + public static final short SALOAD = 53; + public static final short ISTORE = 54; + public static final short LSTORE = 55; + public static final short FSTORE = 56; + public static final short DSTORE = 57; + public static final short ASTORE = 58; + public static final short ISTORE_0 = 59; + public static final short ISTORE_1 = 60; + public static final short ISTORE_2 = 61; + public static final short ISTORE_3 = 62; + public static final short LSTORE_0 = 63; + public static final short LSTORE_1 = 64; + public static final short LSTORE_2 = 65; + public static final short LSTORE_3 = 66; + public static final short FSTORE_0 = 67; + public static final short FSTORE_1 = 68; + public static final short FSTORE_2 = 69; + public static final short FSTORE_3 = 70; + public static final short DSTORE_0 = 71; + public static final short DSTORE_1 = 72; + public static final short DSTORE_2 = 73; + public static final short DSTORE_3 = 74; + public static final short ASTORE_0 = 75; + public static final short ASTORE_1 = 76; + public static final short ASTORE_2 = 77; + public static final short ASTORE_3 = 78; + public static final short IASTORE = 79; + public static final short LASTORE = 80; + public static final short FASTORE = 81; + public static final short DASTORE = 82; + public static final short AASTORE = 83; + public static final short BASTORE = 84; + public static final short CASTORE = 85; + public static final short SASTORE = 86; + public static final short POP = 87; + public static final short POP2 = 88; + public static final short DUP = 89; + public static final short DUP_X1 = 90; + public static final short DUP_X2 = 91; + public static final short DUP2 = 92; + public static final short DUP2_X1 = 93; + public static final short DUP2_X2 = 94; + public static final short SWAP = 95; + public static final short IADD = 96; + public static final short LADD = 97; + public static final short FADD = 98; + public static final short DADD = 99; + public static final short ISUB = 100; + public static final short LSUB = 101; + public static final short FSUB = 102; + public static final short DSUB = 103; + public static final short IMUL = 104; + public static final short LMUL = 105; + public static final short FMUL = 106; + public static final short DMUL = 107; + public static final short IDIV = 108; + public static final short LDIV = 109; + public static final short FDIV = 110; + public static final short DDIV = 111; + public static final short IREM = 112; + public static final short LREM = 113; + public static final short FREM = 114; + public static final short DREM = 115; + public static final short INEG = 116; + public static final short LNEG = 117; + public static final short FNEG = 118; + public static final short DNEG = 119; + public static final short ISHL = 120; + public static final short LSHL = 121; + public static final short ISHR = 122; + public static final short LSHR = 123; + public static final short IUSHR = 124; + public static final short LUSHR = 125; + public static final short IAND = 126; + public static final short LAND = 127; + public static final short IOR = 128; + public static final short LOR = 129; + public static final short IXOR = 130; + public static final short LXOR = 131; + public static final short IINC = 132; + public static final short I2L = 133; + public static final short I2F = 134; + public static final short I2D = 135; + public static final short L2I = 136; + public static final short L2F = 137; + public static final short L2D = 138; + public static final short F2I = 139; + public static final short F2L = 140; + public static final short F2D = 141; + public static final short D2I = 142; + public static final short D2L = 143; + public static final short D2F = 144; + public static final short I2B = 145; + public static final short INT2BYTE = 145; // Old notion + public static final short I2C = 146; + public static final short INT2CHAR = 146; // Old notion + public static final short I2S = 147; + public static final short INT2SHORT = 147; // Old notion + public static final short LCMP = 148; + public static final short FCMPL = 149; + public static final short FCMPG = 150; + public static final short DCMPL = 151; + public static final short DCMPG = 152; + public static final short IFEQ = 153; + public static final short IFNE = 154; + public static final short IFLT = 155; + public static final short IFGE = 156; + public static final short IFGT = 157; + public static final short IFLE = 158; + public static final short IF_ICMPEQ = 159; + public static final short IF_ICMPNE = 160; + public static final short IF_ICMPLT = 161; + public static final short IF_ICMPGE = 162; + public static final short IF_ICMPGT = 163; + public static final short IF_ICMPLE = 164; + public static final short IF_ACMPEQ = 165; + public static final short IF_ACMPNE = 166; + public static final short GOTO = 167; + public static final short JSR = 168; + public static final short RET = 169; + public static final short TABLESWITCH = 170; + public static final short LOOKUPSWITCH = 171; + public static final short IRETURN = 172; + public static final short LRETURN = 173; + public static final short FRETURN = 174; + public static final short DRETURN = 175; + public static final short ARETURN = 176; + public static final short RETURN = 177; + public static final short GETSTATIC = 178; + public static final short PUTSTATIC = 179; + public static final short GETFIELD = 180; + public static final short PUTFIELD = 181; + public static final short INVOKEVIRTUAL = 182; + public static final short INVOKESPECIAL = 183; + public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 + public static final short INVOKESTATIC = 184; + public static final short INVOKEINTERFACE = 185; + public static final short INVOKEDYNAMIC = 186; + public static final short NEW = 187; + public static final short NEWARRAY = 188; + public static final short ANEWARRAY = 189; + public static final short ARRAYLENGTH = 190; + public static final short ATHROW = 191; + public static final short CHECKCAST = 192; + public static final short INSTANCEOF = 193; + public static final short MONITORENTER = 194; + public static final short MONITOREXIT = 195; + public static final short WIDE = 196; + public static final short MULTIANEWARRAY = 197; + public static final short IFNULL = 198; + public static final short IFNONNULL = 199; + public static final short GOTO_W = 200; + public static final short JSR_W = 201; + + /** + * Non-legal opcodes, may be used by JVM internally. + */ + public static final short BREAKPOINT = 202; + public static final short LDC_QUICK = 203; + public static final short LDC_W_QUICK = 204; + public static final short LDC2_W_QUICK = 205; + public static final short GETFIELD_QUICK = 206; + public static final short PUTFIELD_QUICK = 207; + public static final short GETFIELD2_QUICK = 208; + public static final short PUTFIELD2_QUICK = 209; + public static final short GETSTATIC_QUICK = 210; + public static final short PUTSTATIC_QUICK = 211; + public static final short GETSTATIC2_QUICK = 212; + public static final short PUTSTATIC2_QUICK = 213; + public static final short INVOKEVIRTUAL_QUICK = 214; + public static final short INVOKENONVIRTUAL_QUICK = 215; + public static final short INVOKESUPER_QUICK = 216; + public static final short INVOKESTATIC_QUICK = 217; + public static final short INVOKEINTERFACE_QUICK = 218; + public static final short INVOKEVIRTUALOBJECT_QUICK = 219; + public static final short NEW_QUICK = 221; + public static final short ANEWARRAY_QUICK = 222; + public static final short MULTIANEWARRAY_QUICK = 223; + public static final short CHECKCAST_QUICK = 224; + public static final short INSTANCEOF_QUICK = 225; + public static final short INVOKEVIRTUAL_QUICK_W = 226; + public static final short GETFIELD_QUICK_W = 227; + public static final short PUTFIELD_QUICK_W = 228; + public static final short IMPDEP1 = 254; + public static final short IMPDEP2 = 255; + + /** + * For internal purposes only. + */ + public static final short PUSH = 4711; + public static final short SWITCH = 4712; + + /** + * Illegal codes + */ + public static final short UNDEFINED = '/' - '0'; // -1; + public static final short UNPREDICTABLE = '.' - '0';// -2; + public static final short RESERVED = -3; + public static final String ILLEGAL_OPCODE = ""; + public static final String ILLEGAL_TYPE = ""; + + public static final byte T_BOOLEAN = 4; + public static final byte T_CHAR = 5; + public static final byte T_FLOAT = 6; + public static final byte T_DOUBLE = 7; + public static final byte T_BYTE = 8; + public static final byte T_SHORT = 9; + public static final byte T_INT = 10; + public static final byte T_LONG = 11; + + public static final byte T_VOID = 12; // Non-standard + public static final byte T_ARRAY = 13; + public static final byte T_OBJECT = 14; + public static final byte T_REFERENCE = 14; // Deprecated + public static final byte T_UNKNOWN = 15; + public static final byte T_ADDRESS = 16; + + /** + * The primitive type names corresponding to the T_XX constants, e.g., TYPE_NAMES[T_INT] = "int" + */ + public static final String[] TYPE_NAMES = { ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "boolean", "char", "float", + "double", "byte", "short", "int", "long", "void", "array", "object", "unknown" // Non-standard + }; + + /** + * The primitive class names corresponding to the T_XX constants, e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" + */ + public static final String[] CLASS_TYPE_NAMES = { ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "java.lang.Boolean", + "java.lang.Character", "java.lang.Float", "java.lang.Double", "java.lang.Byte", "java.lang.Short", "java.lang.Integer", + "java.lang.Long", "java.lang.Void", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE }; + + /** + * The signature characters corresponding to primitive types, e.g., SHORT_TYPE_NAMES[T_INT] = "I" + */ + public static final String[] SHORT_TYPE_NAMES = { ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "Z", "C", "F", "D", + "B", "S", "I", "J", "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE }; + + public static int PUSH_INST = 0x0001; + public static int CONSTANT_INST = 0x0002; + public static long LOADCLASS_INST = 0x0004; + public static int CP_INST = 0x0008; + public static int INDEXED = 0x0010; + public static int LOAD_INST = 0x0020; // load instruction + public static int LV_INST = 0x0040; // local variable instruction + public static int POP_INST = 0x0080; + public static int STORE_INST = 0x0100; + public static long STACK_INST = 0x0200; + public static long BRANCH_INSTRUCTION = 0x0400; + public static long TARGETER_INSTRUCTION = 0x0800; + public static long NEGATABLE = 0x1000; + public static long IF_INST = 0x2000; + public static long JSR_INSTRUCTION = 0x4000; + public static long RET_INST = 0x8000; + public static long EXCEPTION_THROWER = 0x10000; + + public static final byte[] iLen = new byte[256]; + public static final byte UNDEFINED_LENGTH = 'X' - '0'; + public static final byte VARIABLE_LENGTH = 'V' - '0'; + public static final byte[] stackEntriesProduced = new byte[256]; + public static final Type[] types = new Type[256]; + public static final long[] instFlags = new long[256]; + + public static final Class[][] instExcs = new Class[256][]; + + static final Object _unused = ConstantsInitializer.initialize(); + + /** + * How the byte code operands are to be interpreted. + */ + public static final short[][] TYPE_OF_OPERANDS = { {}/* 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 */, { T_BYTE }/* bipush */, + { T_SHORT }/* sipush */, { T_BYTE }/* ldc */, { T_SHORT }/* ldc_w */, { T_SHORT }/* ldc2_w */, { T_BYTE }/* iload */, + { T_BYTE }/* lload */, { T_BYTE }/* fload */, { T_BYTE }/* dload */, { T_BYTE }/* aload */, {}/* iload_0 */, + {}/* iload_1 */, {}/* iload_2 */, {}/* iload_3 */, {}/* lload_0 */, {}/* lload_1 */, {}/* lload_2 */, {}/* lload_3 */, + {}/* fload_0 */, {}/* fload_1 */, {}/* fload_2 */, {}/* fload_3 */, {}/* dload_0 */, {}/* dload_1 */, {}/* dload_2 */, + {}/* dload_3 */, {}/* aload_0 */, {}/* aload_1 */, {}/* aload_2 */, {}/* aload_3 */, {}/* iaload */, {}/* laload */, + {}/* faload */, {}/* daload */, {}/* aaload */, {}/* baload */, {}/* caload */, {}/* saload */, { T_BYTE }/* istore */, + { T_BYTE }/* lstore */, { T_BYTE }/* fstore */, { T_BYTE }/* dstore */, { T_BYTE }/* astore */, {}/* istore_0 */, + {}/* istore_1 */, {}/* istore_2 */, {}/* istore_3 */, {}/* lstore_0 */, {}/* lstore_1 */, {}/* lstore_2 */, {}/* lstore_3 */, + {}/* fstore_0 */, {}/* fstore_1 */, {}/* fstore_2 */, {}/* fstore_3 */, {}/* dstore_0 */, {}/* dstore_1 */, {}/* dstore_2 */, + {}/* dstore_3 */, {}/* astore_0 */, {}/* astore_1 */, {}/* astore_2 */, {}/* astore_3 */, {}/* 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 */, { T_BYTE, T_BYTE }/* iinc */, {}/* i2l */, + {}/* i2f */, {}/* i2d */, {}/* l2i */, {}/* l2f */, {}/* l2d */, {}/* f2i */, {}/* f2l */, {}/* f2d */, {}/* d2i */, {}/* d2l */, + {}/* d2f */, {}/* i2b */, {}/* i2c */, {}/* i2s */, {}/* lcmp */, {}/* fcmpl */, {}/* fcmpg */, {}/* dcmpl */, + {}/* dcmpg */, { T_SHORT }/* ifeq */, { T_SHORT }/* ifne */, { T_SHORT }/* iflt */, { T_SHORT }/* ifge */, + { T_SHORT }/* ifgt */, { T_SHORT }/* ifle */, { T_SHORT }/* if_icmpeq */, { T_SHORT }/* if_icmpne */, + { T_SHORT }/* if_icmplt */, { T_SHORT }/* if_icmpge */, { T_SHORT }/* if_icmpgt */, { T_SHORT }/* if_icmple */, + { T_SHORT }/* if_acmpeq */, { T_SHORT }/* if_acmpne */, { T_SHORT }/* goto */, { T_SHORT }/* jsr */, + { T_BYTE }/* ret */, {}/* tableswitch */, {}/* lookupswitch */, {}/* ireturn */, {}/* lreturn */, {}/* freturn */, + {}/* dreturn */, {}/* areturn */, {}/* return */, { T_SHORT }/* getstatic */, { T_SHORT }/* putstatic */, + { T_SHORT }/* getfield */, { T_SHORT }/* putfield */, { T_SHORT }/* invokevirtual */, + { T_SHORT }/* invokespecial */, { T_SHORT }/* invokestatic */, { T_SHORT, T_BYTE, T_BYTE }/* invokeinterface */, {}, + { T_SHORT }/* new */, { T_BYTE }/* newarray */, { T_SHORT }/* anewarray */, {}/* arraylength */, {}/* athrow */, + { T_SHORT }/* checkcast */, { T_SHORT }/* instanceof */, {}/* monitorenter */, {}/* monitorexit */, { T_BYTE }/* wide */, + { T_SHORT, T_BYTE }/* multianewarray */, { T_SHORT }/* ifnull */, { T_SHORT }/* ifnonnull */, { T_INT }/* goto_w */, + { T_INT }/* jsr_w */, {}/* breakpoint */, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}/* impdep1 */, {} /* impdep2 */ + }; + + /** + * Names of opcodes. + */ + public static final String[] OPCODE_NAMES = { "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", + "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload", "lload", "fload", "dload", "aload", "iload_0", "iload_1", + "iload_2", "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0", "fload_1", "fload_2", "fload_3", + "dload_0", "dload_1", "dload_2", "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload", "laload", "faload", + "daload", "aaload", "baload", "caload", "saload", "istore", "lstore", "fstore", "dstore", "astore", "istore_0", + "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2", + "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3", "astore_0", "astore_1", "astore_2", "astore_3", "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", "iinc", "i2l", "i2f", "i2d", + "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f", "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg", "dcmpl", + "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", + "if_icmpgt", "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret", "tableswitch", "lookupswitch", "ireturn", + "lreturn", "freturn", "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield", "putfield", + "invokevirtual", "invokespecial", "invokestatic", "invokeinterface", "invokedynamic", "new", "newarray", "anewarray", + "arraylength", "athrow", "checkcast", "instanceof", "monitorenter", "monitorexit", "wide", "multianewarray", "ifnull", + "ifnonnull", "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, "impdep1", "impdep2" }; + + /** + * Number of words consumed on operand stack by instructions. + */ + public static final int[] CONSUME_STACK = { 0/* nop */, 0/* aconst_null */, 0/* iconst_m1 */, 0/* iconst_0 */, 0/* iconst_1 */, + 0/* iconst_2 */, 0/* iconst_3 */, 0/* iconst_4 */, 0/* iconst_5 */, 0/* lconst_0 */, 0/* lconst_1 */, 0/* fconst_0 */, + 0/* fconst_1 */, 0/* fconst_2 */, 0/* dconst_0 */, 0/* dconst_1 */, 0/* bipush */, 0/* sipush */, 0/* ldc */, + 0/* ldc_w */, 0/* ldc2_w */, 0/* iload */, 0/* lload */, 0/* fload */, 0/* dload */, 0/* aload */, 0/* iload_0 */, 0/* iload_1 */, + 0/* iload_2 */, 0/* iload_3 */, 0/* lload_0 */, 0/* lload_1 */, 0/* lload_2 */, 0/* lload_3 */, 0/* fload_0 */, + 0/* fload_1 */, 0/* fload_2 */, 0/* fload_3 */, 0/* dload_0 */, 0/* dload_1 */, 0/* dload_2 */, 0/* dload_3 */, + 0/* aload_0 */, 0/* aload_1 */, 0/* aload_2 */, 0/* aload_3 */, 2/* iaload */, 2/* laload */, 2/* faload */, + 2/* daload */, 2/* aaload */, 2/* baload */, 2/* caload */, 2/* saload */, 1/* istore */, 2/* lstore */, + 1/* fstore */, 2/* dstore */, 1/* astore */, 1/* istore_0 */, 1/* istore_1 */, 1/* istore_2 */, 1/* istore_3 */, + 2/* lstore_0 */, 2/* lstore_1 */, 2/* lstore_2 */, 2/* lstore_3 */, 1/* fstore_0 */, 1/* fstore_1 */, 1/* fstore_2 */, + 1/* fstore_3 */, 2/* dstore_0 */, 2/* dstore_1 */, 2/* dstore_2 */, 2/* dstore_3 */, 1/* astore_0 */, 1/* astore_1 */, + 1/* astore_2 */, 1/* astore_3 */, 3/* iastore */, 4/* lastore */, 3/* fastore */, 4/* dastore */, 3/* aastore */, + 3/* bastore */, 3/* castore */, 3/* sastore */, 1/* pop */, 2/* pop2 */, 1/* dup */, 2/* dup_x1 */, 3/* dup_x2 */, + 2/* dup2 */, 3/* dup2_x1 */, 4/* dup2_x2 */, 2/* swap */, 2/* iadd */, 4/* ladd */, 2/* fadd */, 4/* dadd */, 2/* isub */, + 4/* lsub */, 2/* fsub */, 4/* dsub */, 2/* imul */, 4/* lmul */, 2/* fmul */, 4/* dmul */, 2/* idiv */, 4/* ldiv */, 2/* fdiv */, + 4/* ddiv */, 2/* irem */, 4/* lrem */, 2/* frem */, 4/* drem */, 1/* ineg */, 2/* lneg */, 1/* fneg */, 2/* dneg */, 2/* ishl */, + 3/* lshl */, 2/* ishr */, 3/* lshr */, 2/* iushr */, 3/* lushr */, 2/* iand */, 4/* land */, 2/* ior */, 4/* lor */, 2/* ixor */, + 4/* lxor */, 0/* iinc */, 1/* i2l */, 1/* i2f */, 1/* i2d */, 2/* l2i */, 2/* l2f */, 2/* l2d */, 1/* f2i */, 1/* f2l */, + 1/* f2d */, 2/* d2i */, 2/* d2l */, 2/* d2f */, 1/* i2b */, 1/* i2c */, 1/* i2s */, 4/* lcmp */, 2/* fcmpl */, + 2/* fcmpg */, 4/* dcmpl */, 4/* dcmpg */, 1/* ifeq */, 1/* ifne */, 1/* iflt */, 1/* ifge */, 1/* ifgt */, 1/* ifle */, + 2/* if_icmpeq */, 2/* if_icmpne */, 2/* if_icmplt */, 2 /* if_icmpge */, 2/* if_icmpgt */, 2/* if_icmple */, 2/* if_acmpeq */, + 2/* if_acmpne */, 0/* goto */, 0/* jsr */, 0/* ret */, 1/* tableswitch */, 1/* lookupswitch */, 1/* ireturn */, + 2/* lreturn */, 1/* freturn */, 2/* dreturn */, 1/* areturn */, 0/* return */, 0/* getstatic */, + UNPREDICTABLE/* putstatic */, 1/* getfield */, UNPREDICTABLE/* putfield */, UNPREDICTABLE/* invokevirtual */, + UNPREDICTABLE/* invokespecial */, UNPREDICTABLE/* invokestatic */, UNPREDICTABLE/* invokeinterface */, UNDEFINED, + 0/* new */, 1/* newarray */, 1/* anewarray */, 1/* arraylength */, 1/* athrow */, 1/* checkcast */, 1/* instanceof */, + 1/* monitorenter */, 1/* monitorexit */, 0/* wide */, UNPREDICTABLE/* multianewarray */, 1/* ifnull */, + 1/* ifnonnull */, 0/* goto_w */, 0/* jsr_w */, 0/* breakpoint */, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNPREDICTABLE/* impdep1 */, UNPREDICTABLE /* impdep2 */ + }; + + // Attributes and their corresponding names. + public static final byte ATTR_UNKNOWN = -1; + public static final byte ATTR_SOURCE_FILE = 0; + public static final byte ATTR_CONSTANT_VALUE = 1; + public static final byte ATTR_CODE = 2; + public static final byte ATTR_EXCEPTIONS = 3; + public static final byte ATTR_LINE_NUMBER_TABLE = 4; + public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; + public static final byte ATTR_INNER_CLASSES = 6; + public static final byte ATTR_SYNTHETIC = 7; + public static final byte ATTR_DEPRECATED = 8; + public static final byte ATTR_PMG = 9; + public static final byte ATTR_SIGNATURE = 10; + public static final byte ATTR_STACK_MAP = 11; + public static final byte ATTR_RUNTIME_VISIBLE_ANNOTATIONS = 12; + public static final byte ATTR_RUNTIME_INVISIBLE_ANNOTATIONS = 13; + public static final byte ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = 14; + public static final byte ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = 15; + public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE = 16; + public static final byte ATTR_ENCLOSING_METHOD = 17; + public static final byte ATTR_ANNOTATION_DEFAULT = 18; + public static final byte ATTR_BOOTSTRAPMETHODS = 19; + public static final byte ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = 20; + public static final byte ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = 21; + public static final byte ATTR_METHOD_PARAMETERS = 22; + + // J9: + public static final byte ATTR_MODULE = 23; + public static final byte ATTR_MODULE_PACKAGES = 24; + public static final byte ATTR_MODULE_MAIN_CLASS = 25; + + // J11: + public static final byte ATTR_NEST_HOST = 26; + public static final byte ATTR_NEST_MEMBERS = 27; + + public static final short KNOWN_ATTRIBUTES = 28; + + public static final String[] ATTRIBUTE_NAMES = { + "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", + "InnerClasses", "Synthetic", "Deprecated", "PMGClass", "Signature", "StackMap", + "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations", + "RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod", + "AnnotationDefault","BootstrapMethods", "RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", + "MethodParameters", "Module", "ModulePackages", "ModuleMainClass", "NestHost", "NestMembers" + }; + + /** + * Constants used in the StackMap attribute. + */ + public static final byte ITEM_Bogus = 0; + public static final byte ITEM_Integer = 1; + public static final byte ITEM_Float = 2; + public static final byte ITEM_Double = 3; + public static final byte ITEM_Long = 4; + public static final byte ITEM_Null = 5; + public static final byte ITEM_InitObject = 6; + public static final byte ITEM_Object = 7; + public static final byte ITEM_NewObject = 8; + + public static final String[] ITEM_NAMES = { "Bogus", "Integer", "Float", "Double", "Long", "Null", "InitObject", "Object", + "NewObject" }; +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/ConstantsInitializer.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/ConstantsInitializer.java new file mode 100644 index 000000000..b9bc0d49f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/ConstantsInitializer.java @@ -0,0 +1,396 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel; + +import org.aspectj.apache.bcel.generic.Type; + +public class ConstantsInitializer { + + public static Object initialize() { + Constants.types[Constants.ILOAD] = Type.INT; + Constants.types[Constants.ISTORE] = Type.INT; + Constants.types[Constants.ILOAD_0] = Type.INT; + Constants.types[Constants.ISTORE_0] = Type.INT; + Constants.types[Constants.ILOAD_1] = Type.INT; + Constants.types[Constants.ISTORE_1] = Type.INT; + Constants.types[Constants.ILOAD_2] = Type.INT; + Constants.types[Constants.ISTORE_2] = Type.INT; + Constants.types[Constants.ILOAD_3] = Type.INT; + Constants.types[Constants.ISTORE_3] = Type.INT; + Constants.types[Constants.LLOAD] = Type.LONG; + Constants.types[Constants.LSTORE] = Type.LONG; + Constants.types[Constants.LLOAD_0] = Type.LONG; + Constants.types[Constants.LSTORE_0] = Type.LONG; + Constants.types[Constants.LLOAD_1] = Type.LONG; + Constants.types[Constants.LSTORE_1] = Type.LONG; + Constants.types[Constants.LLOAD_2] = Type.LONG; + Constants.types[Constants.LSTORE_2] = Type.LONG; + Constants.types[Constants.LLOAD_3] = Type.LONG; + Constants.types[Constants.LSTORE_3] = Type.LONG; + Constants.types[Constants.DLOAD] = Type.DOUBLE; + Constants.types[Constants.DSTORE] = Type.DOUBLE; + Constants.types[Constants.DLOAD_0] = Type.DOUBLE; + Constants.types[Constants.DSTORE_0] = Type.DOUBLE; + Constants.types[Constants.DLOAD_1] = Type.DOUBLE; + Constants.types[Constants.DSTORE_1] = Type.DOUBLE; + Constants.types[Constants.DLOAD_2] = Type.DOUBLE; + Constants.types[Constants.DSTORE_2] = Type.DOUBLE; + Constants.types[Constants.DLOAD_3] = Type.DOUBLE; + Constants.types[Constants.DSTORE_3] = Type.DOUBLE; + Constants.types[Constants.FLOAD] = Type.FLOAT; + Constants.types[Constants.FSTORE] = Type.FLOAT; + Constants.types[Constants.FLOAD_0] = Type.FLOAT; + Constants.types[Constants.FSTORE_0] = Type.FLOAT; + Constants.types[Constants.FLOAD_1] = Type.FLOAT; + Constants.types[Constants.FSTORE_1] = Type.FLOAT; + Constants.types[Constants.FLOAD_2] = Type.FLOAT; + Constants.types[Constants.FSTORE_2] = Type.FLOAT; + Constants.types[Constants.FLOAD_3] = Type.FLOAT; + Constants.types[Constants.FSTORE_3] = Type.FLOAT; + Constants.types[Constants.ALOAD] = Type.OBJECT; + Constants.types[Constants.ASTORE] = Type.OBJECT; + Constants.types[Constants.ALOAD_0] = Type.OBJECT; + Constants.types[Constants.ASTORE_0] = Type.OBJECT; + Constants.types[Constants.ALOAD_1] = Type.OBJECT; + Constants.types[Constants.ASTORE_1] = Type.OBJECT; + Constants.types[Constants.ALOAD_2] = Type.OBJECT; + Constants.types[Constants.ASTORE_2] = Type.OBJECT; + Constants.types[Constants.ALOAD_3] = Type.OBJECT; + Constants.types[Constants.ASTORE_3] = Type.OBJECT; + + // INSTRUCTION_FLAGS - set for all + Constants.instFlags[Constants.NOP] = 0; + Constants.instFlags[Constants.ACONST_NULL] = Constants.PUSH_INST; + Constants.instFlags[Constants.ICONST_M1] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.ICONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.ICONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.ICONST_2] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.ICONST_3] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.ICONST_4] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.ICONST_5] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.LCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.LCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.FCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.FCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.FCONST_2] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.DCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.DCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST; + + Constants.instFlags[Constants.BIPUSH] = Constants.PUSH_INST | Constants.CONSTANT_INST; + Constants.instFlags[Constants.SIPUSH] = Constants.PUSH_INST | Constants.CONSTANT_INST; + + Constants.instFlags[Constants.LDC] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST + | Constants.INDEXED; + + Constants.instFlags[Constants.LDC_W] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST + | Constants.INDEXED; + + Constants.instFlags[Constants.LDC2_W] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST + | Constants.INDEXED; + + // the next five could be 'wide' prefixed and so have longer lengths + Constants.instFlags[Constants.ILOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; + Constants.instFlags[Constants.LLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; + Constants.instFlags[Constants.FLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; + Constants.instFlags[Constants.DLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; + Constants.instFlags[Constants.ALOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; + for (int ii = Constants.ILOAD_0; ii <= Constants.ALOAD_3; ii++) { + Constants.instFlags[ii] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; + } + + // the next five could be 'wide' prefixed and so have longer lengths + Constants.instFlags[Constants.ISTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; + Constants.instFlags[Constants.LSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; + Constants.instFlags[Constants.FSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; + Constants.instFlags[Constants.DSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; + Constants.instFlags[Constants.ASTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; + for (int ii = Constants.ISTORE_0; ii <= Constants.ASTORE_3; ii++) { + Constants.instFlags[ii] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; + } + + Constants.instFlags[Constants.IDIV] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.IDIV] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; + Constants.instFlags[Constants.IREM] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.IREM] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; + Constants.instFlags[Constants.LDIV] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.LDIV] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; + Constants.instFlags[Constants.LREM] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.LREM] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; + + Constants.instFlags[Constants.ARRAYLENGTH] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.ARRAYLENGTH] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; + Constants.instFlags[Constants.ATHROW] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.ATHROW] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.THROWABLE }; + + Constants.instFlags[Constants.AALOAD] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.AALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.IALOAD] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.IALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.BALOAD] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.BALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.FALOAD] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.FALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.DALOAD] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.DALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.CALOAD] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.CALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.LALOAD] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.LALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.SALOAD] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.SALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + + Constants.instFlags[Constants.AASTORE] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.AASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.IASTORE] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.IASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.BASTORE] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.BASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.FASTORE] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.FASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.DASTORE] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.DASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.CASTORE] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.CASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.LASTORE] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.LASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + Constants.instFlags[Constants.SASTORE] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.SASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + + // stack instructions + Constants.instFlags[Constants.DUP] = Constants.PUSH_INST | Constants.STACK_INST; + Constants.instFlags[Constants.DUP_X1] = Constants.STACK_INST; // TODO fixme - aren't these two push/stack producers? + // (although peculiar ones...) + Constants.instFlags[Constants.DUP_X2] = Constants.STACK_INST; + Constants.instFlags[Constants.DUP2] = Constants.PUSH_INST | Constants.STACK_INST; + Constants.instFlags[Constants.DUP2_X1] = Constants.STACK_INST; // TODO fixme - aren't these two push/stack producers? + // (although peculiar ones...) + Constants.instFlags[Constants.DUP2_X2] = Constants.STACK_INST; + Constants.instFlags[Constants.POP] = Constants.STACK_INST | Constants.POP_INST; + Constants.instFlags[Constants.POP2] = Constants.STACK_INST | Constants.POP_INST; + Constants.instFlags[Constants.SWAP] = Constants.STACK_INST; + + Constants.instFlags[Constants.MONITORENTER] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.MONITORENTER] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; + Constants.instFlags[Constants.MONITOREXIT] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.MONITOREXIT] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; + + // branching instructions + Constants.instFlags[Constants.GOTO] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION; + Constants.instFlags[Constants.GOTO_W] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION; + Constants.instFlags[Constants.JSR] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.JSR_INSTRUCTION; + Constants.instFlags[Constants.JSR_W] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.JSR_INSTRUCTION; + + Constants.instFlags[Constants.IFGT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE + | Constants.IF_INST; + Constants.instFlags[Constants.IFLE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE + | Constants.IF_INST; + Constants.instFlags[Constants.IFNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE + | Constants.IF_INST; + Constants.instFlags[Constants.IFEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE + | Constants.IF_INST; + Constants.instFlags[Constants.IFGE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE + | Constants.IF_INST; + Constants.instFlags[Constants.IFLT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE + | Constants.IF_INST; + Constants.instFlags[Constants.IFNULL] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE + | Constants.IF_INST; + Constants.instFlags[Constants.IFNONNULL] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + Constants.instFlags[Constants.IF_ACMPEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + Constants.instFlags[Constants.IF_ACMPNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + Constants.instFlags[Constants.IF_ICMPEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + Constants.instFlags[Constants.IF_ICMPGE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + Constants.instFlags[Constants.IF_ICMPGT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + Constants.instFlags[Constants.IF_ICMPLE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + Constants.instFlags[Constants.IF_ICMPLT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + Constants.instFlags[Constants.IF_ICMPNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION + | Constants.NEGATABLE | Constants.IF_INST; + + Constants.instFlags[Constants.LOOKUPSWITCH] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION; + Constants.instFlags[Constants.TABLESWITCH] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION; + + // fixme these class arrays should be constants + Constants.instFlags[Constants.ARETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.ARETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; + Constants.instFlags[Constants.DRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.DRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; + Constants.instFlags[Constants.FRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.FRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; + Constants.instFlags[Constants.IRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.IRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; + Constants.instFlags[Constants.LRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.LRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; + Constants.instFlags[Constants.RETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.RETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; + + Constants.instFlags[Constants.NEW] = Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER | Constants.CP_INST + | Constants.INDEXED; + Constants.instExcs[Constants.NEW] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_FOR_ALLOCATIONS; + Constants.instFlags[Constants.NEWARRAY] = Constants.EXCEPTION_THROWER; + Constants.instExcs[Constants.NEWARRAY] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION }; + + Constants.types[Constants.IINC] = Type.INT; + Constants.instFlags[Constants.IINC] = Constants.LV_INST | Constants.INDEXED; + Constants.instFlags[Constants.RET] = Constants.INDEXED; + + Constants.instFlags[Constants.ANEWARRAY] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER + | Constants.INDEXED; + Constants.instExcs[Constants.ANEWARRAY] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY; + Constants.instFlags[Constants.CHECKCAST] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER + | Constants.INDEXED; + Constants.instExcs[Constants.CHECKCAST] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_CHECKCAST; + Constants.instFlags[Constants.INSTANCEOF] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER + | Constants.INDEXED; + Constants.instExcs[Constants.INSTANCEOF] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION; + Constants.instFlags[Constants.MULTIANEWARRAY] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER + | Constants.INDEXED; + Constants.instExcs[Constants.MULTIANEWARRAY] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY; // fixme i + // think + // this + // is a + // stackproducer, old + // bcel says no... + + Constants.instFlags[Constants.GETFIELD] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST + | Constants.INDEXED; + Constants.instExcs[Constants.GETFIELD] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD; + Constants.instFlags[Constants.GETSTATIC] = Constants.PUSH_INST | Constants.EXCEPTION_THROWER | Constants.LOADCLASS_INST + | Constants.CP_INST | Constants.INDEXED; + Constants.instExcs[Constants.GETSTATIC] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC; + Constants.instFlags[Constants.PUTFIELD] = Constants.POP_INST | Constants.EXCEPTION_THROWER | Constants.LOADCLASS_INST + | Constants.CP_INST | Constants.INDEXED; + Constants.instExcs[Constants.PUTFIELD] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD; + Constants.instFlags[Constants.PUTSTATIC] = Constants.EXCEPTION_THROWER | Constants.POP_INST | Constants.CP_INST + | Constants.LOADCLASS_INST | Constants.INDEXED; + Constants.instExcs[Constants.PUTSTATIC] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC; + + Constants.instFlags[Constants.INVOKEINTERFACE] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST + | Constants.INDEXED; + Constants.instExcs[Constants.INVOKEINTERFACE] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKEINTERFACE; + Constants.instFlags[Constants.INVOKESPECIAL] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST + | Constants.INDEXED; + Constants.instExcs[Constants.INVOKESPECIAL] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL; + Constants.instFlags[Constants.INVOKESTATIC] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST + | Constants.INDEXED; + Constants.instExcs[Constants.INVOKESTATIC] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESTATIC; + Constants.instFlags[Constants.INVOKEVIRTUAL] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST + | Constants.INDEXED; + Constants.instExcs[Constants.INVOKEVIRTUAL] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL; + + Constants.instFlags[Constants.INVOKEDYNAMIC] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST + | Constants.INDEXED; + // TBD + // Constants.instExcs[Constants.INVOKEDYNAMIC] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL; + + //@formatter:off + char[] lengths = // . = varies in length, / = undefined + ("1111111111111111" + // nop > dconst_1 + "2323322222111111" + // bipush > lload_1 + "1111111111111111" + // lload_2 > laload + "1111112222211111" + // faload > lstore_0 + "1111111111111111" + // lstore_1 > iastore + "1111111111111111" + // lastore > swap + "1111111111111111" + // iadd > ddiv + "1111111111111111" + // irem > land + "1111311111111111" + // ior > d2l + "1111111113333333" + // d2f > if_icmpeq + "3333333332..1111" + // if_icmpne > dreturn + "1133333335532311" + // areturn > athrow + "3311.433551/////").toCharArray(); // checkcast > + //@formatter:on + int count = 0; + for (; count < lengths.length; count++) { + Constants.iLen[count] = (byte) (lengths[count] - 48); + } + while (count < 256) { + Constants.iLen[count] = Constants.UNDEFINED; + count++; + } + Constants.iLen[Constants.BREAKPOINT] = 1; + Constants.iLen[Constants.IMPDEP1] = 1; + Constants.iLen[Constants.IMPDEP2] = 1; + + char[] producesOnStack = ("0111111112211122" + // nop > dconst_1 + "1111212121111122" + // bipush > lload_1 + "2211112222111112" + // lload_2 > laload + "1211110000000000" + // faload > lstore_0 + "0000000000000000" + // lstore_1 > iastore + "0000000002344562" + // lastore > swap + "1212121212121212" + // iadd > ddiv + "1212121212121212" + // irem > land + "1212021211212212" + // ior > d2l + "1111111110000000" + // d2f > if_icmpeq + "0000000010000000" + // if_icmpne > dreturn + "00.0.0.....11111" + // areturn > athrow + "11000100010/").toCharArray(); // checkcast > + count = 0; + for (; count < producesOnStack.length; count++) { + Constants.stackEntriesProduced[count] = (byte) (producesOnStack[count] - 48); + } + while (count < 256) { + Constants.iLen[count] = Constants.UNDEFINED; + count++; + } + return null; + } +} \ No newline at end of file diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/ExceptionConstants.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/ExceptionConstants.java new file mode 100644 index 000000000..cf3d81308 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/ExceptionConstants.java @@ -0,0 +1,150 @@ +package org.aspectj.apache.bcel; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Exception constants. + * + * @version $Id: ExceptionConstants.java,v 1.5 2009/09/14 20:29:10 aclement Exp $ + * @author E. Haase + */ +@SuppressWarnings("rawtypes") +public interface ExceptionConstants { + /** + * The mother of all exceptions + */ + public static final Class THROWABLE = Throwable.class; + + /** + * Super class of any run-time exception + */ + public static final Class RUNTIME_EXCEPTION = RuntimeException.class; + + /** + * Super class of any linking exception (aka Linkage Error) + */ + public static final Class LINKING_EXCEPTION = LinkageError.class; + + /** + * Linking Exceptions + */ + public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; + public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; + public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; + public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; + public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; + public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; + public static final Class INSTANTIATION_ERROR = InstantiationError.class; + public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; + public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; + public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; + public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; + public static final Class VERIFY_ERROR = VerifyError.class; + + /* UnsupportedClassVersionError is new in JDK 1.2 */ + // public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; + /** + * Run-Time Exceptions + */ + public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; + public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; + public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; + public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; + public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; + public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; + + /** + * Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual Machine Specification + */ + public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, + ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR }; // Chapter 5.1 + public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_MULTIANEWARRAY = { NO_CLASS_DEF_FOUND_ERROR, + CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, + NEGATIVE_ARRAY_SIZE_EXCEPTION, ILLEGAL_ACCESS_ERROR }; + public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, + VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, + NEGATIVE_ARRAY_SIZE_EXCEPTION }; // Chapter 5.1 + public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_CHECKCAST = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, + VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, CLASS_CAST_EXCEPTION }; // Chapter + // 5.1 + public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_FOR_ALLOCATIONS = { NO_CLASS_DEF_FOUND_ERROR, + CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, + INSTANTIATION_ERROR, ILLEGAL_ACCESS_ERROR }; + + public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, + NO_SUCH_METHOD_ERROR }; // Chapter 5.2 + + public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, + NO_SUCH_METHOD_ERROR, INCOMPATIBLE_CLASS_CHANGE_ERROR, NULL_POINTER_EXCEPTION }; + + public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, + NO_SUCH_METHOD_ERROR, INCOMPATIBLE_CLASS_CHANGE_ERROR }; + + public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKEINTERFACE = { INCOMPATIBLE_CLASS_CHANGE_ERROR, + ILLEGAL_ACCESS_ERROR, ABSTRACT_METHOD_ERROR, UNSATISFIED_LINK_ERROR }; + public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL = { INCOMPATIBLE_CLASS_CHANGE_ERROR, + NULL_POINTER_EXCEPTION, ABSTRACT_METHOD_ERROR, UNSATISFIED_LINK_ERROR }; +// public static final Class[] EXCS_INVOKEDYNAMIC = { BOOTSTRAP_METHOD_ERROR}; + + public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESTATIC = { INCOMPATIBLE_CLASS_CHANGE_ERROR, + UNSATISFIED_LINK_ERROR }; + + public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) + public static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; + // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) + + public static final Class[] EXCS_ARRAY_EXCEPTION = { NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION }; + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/Repository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Repository.java new file mode 100644 index 000000000..073355b5b --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Repository.java @@ -0,0 +1,260 @@ +package org.aspectj.apache.bcel; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.IOException; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.ClassPath; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +/** + * The repository maintains informations about class interdependencies, e.g., whether a class is a sub-class of another. Delegates + * actual class loading to SyntheticRepository with current class path by default. + * + * @see org.aspectj.apache.bcel.util.Repository + * @see org.aspectj.apache.bcel.util.SyntheticRepository + * + * @version $Id: Repository.java,v 1.6 2009/09/09 22:18:20 aclement Exp $ + * @author M. Dahm + */ +public abstract class Repository { + private static org.aspectj.apache.bcel.util.Repository _repository = null; + + /** + * @return currently used repository instance + */ + public static org.aspectj.apache.bcel.util.Repository getRepository() { + if (_repository == null) { + _repository = SyntheticRepository.getInstance(); + } + return _repository; + } + + /** + * Set repository instance to be used for class loading + */ + public static void setRepository(org.aspectj.apache.bcel.util.Repository rep) { + _repository = rep; + } + + /** + * Lookup class somewhere found on your CLASSPATH, or whereever the repository instance looks for it. + * + * @return class object for given fully qualified class name, or null if the class could not be found or parsed correctly + */ + public static JavaClass lookupClass(String class_name) { + try { + JavaClass clazz = getRepository().findClass(class_name); + + if (clazz != null) { + return clazz; + } + + return getRepository().loadClass(class_name); + } catch (ClassNotFoundException ex) { + return null; + } + } + + // /** + // * Try to find class source via getResourceAsStream(). + // * + // * @see Class + // * @return JavaClass object for given runtime class + // */ + // public static JavaClass lookupClass(Class clazz) { + // try { + // return getRepository().loadClass(clazz); + // } catch (ClassNotFoundException ex) { + // return null; + // } + // } + + /** + * @return class file object for given Java class. + */ + public static ClassPath.ClassFile lookupClassFile(String class_name) { + try { + return ClassPath.getSystemClassPath().getClassFile(class_name); + } catch (IOException e) { + return null; + } + } + + /** + * Clear the repository. + */ + public static void clearCache() { + getRepository().clear(); + } + + /** + * Add clazz to repository if there isn't an equally named class already in there. + * + * @return old entry in repository + */ + public static JavaClass addClass(JavaClass clazz) { + JavaClass old = getRepository().findClass(clazz.getClassName()); + getRepository().storeClass(clazz); + return old; + } + + /** + * Remove class with given (fully qualified) name from repository. + */ + public static void removeClass(String clazz) { + getRepository().removeClass(getRepository().findClass(clazz)); + } + + // /** + // * Remove given class from repository. + // */ + // public static void removeClass(JavaClass clazz) { + // getRepository().removeClass(clazz); + // } + + // /** + // * @return list of super classes of clazz in ascending order, i.e., Object is always the last element + // */ + // public static JavaClass[] getSuperClasses(JavaClass clazz) { + // return clazz.getSuperClasses(); + // } + // + // /** + // * @return list of super classes of clazz in ascending order, i.e., Object is always the last element. return "null", if class + // * cannot be found. + // */ + // public static JavaClass[] getSuperClasses(String class_name) { + // JavaClass jc = lookupClass(class_name); + // return jc == null ? null : getSuperClasses(jc); + // } + // + // /** + // * @return all interfaces implemented by class and its super classes and the interfaces that those interfaces extend, and so + // on. + // * (Some people call this a transitive hull). + // */ + // public static JavaClass[] getInterfaces(JavaClass clazz) { + // return clazz.getAllInterfaces(); + // } + + // /** + // * @return all interfaces implemented by class and its super classes and the interfaces that extend those interfaces, and so + // on + // */ + // public static JavaClass[] getInterfaces(String class_name) { + // return getInterfaces(lookupClass(class_name)); + // } + + /** + * Equivalent to runtime "instanceof" operator. + * + * @return true, if clazz is an instance of super_class + */ + public static boolean instanceOf(JavaClass clazz, JavaClass super_class) { + return clazz.instanceOf(super_class); + } + + /** + * @return true, if clazz is an instance of super_class + */ + public static boolean instanceOf(String clazz, String super_class) { + return instanceOf(lookupClass(clazz), lookupClass(super_class)); + } + + // /** + // * @return true, if clazz is an instance of super_class + // */ + // public static boolean instanceOf(JavaClass clazz, String super_class) { + // return instanceOf(clazz, lookupClass(super_class)); + // } + + // /** + // * @return true, if clazz is an instance of super_class + // */ + // public static boolean instanceOf(String clazz, JavaClass super_class) { + // return instanceOf(lookupClass(clazz), super_class); + // } + + /** + * @return true, if clazz is an implementation of interface inter + */ + public static boolean implementationOf(JavaClass clazz, JavaClass inter) { + return clazz.implementationOf(inter); + } + + /** + * @return true, if clazz is an implementation of interface inter + */ + public static boolean implementationOf(String clazz, String inter) { + return implementationOf(lookupClass(clazz), lookupClass(inter)); + } + + // + // /** + // * @return true, if clazz is an implementation of interface inter + // */ + // public static boolean implementationOf(JavaClass clazz, String inter) { + // return implementationOf(clazz, lookupClass(inter)); + // } + + // /** + // * @return true, if clazz is an implementation of interface inter + // */ + // public static boolean implementationOf(String clazz, JavaClass inter) { + // return implementationOf(lookupClass(clazz), inter); + // } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AnnotationDefault.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AnnotationDefault.java new file mode 100644 index 000000000..bd5a7251f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AnnotationDefault.java @@ -0,0 +1,55 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; + +/** + * This attribute is attached to a method and indicates the default + * value for an annotation element. + */ +public class AnnotationDefault extends Attribute { + + private ElementValue value; + + public AnnotationDefault(int nameIndex, int len, DataInputStream dis, ConstantPool cpool) throws IOException { + this(nameIndex, len, ElementValue.readElementValue(dis,cpool), cpool); + } + + private AnnotationDefault(int nameIndex, int len, ElementValue value, ConstantPool cpool) { + super(Constants.ATTR_ANNOTATION_DEFAULT, nameIndex, len, cpool); + this.value = value; + } + + public Attribute copy(ConstantPool constant_pool) { + throw new RuntimeException("Not implemented yet!"); + // is this next line sufficient? + // return (EnclosingMethod)clone(); + } + + public final ElementValue getElementValue() { return value; } + + public final void dump(DataOutputStream dos) throws IOException { + super.dump(dos); + value.dump(dos); + } + + public void accept(ClassVisitor v) { + v.visitAnnotationDefault(this); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Attribute.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Attribute.java new file mode 100644 index 000000000..daeb59a38 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Attribute.java @@ -0,0 +1,213 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.Serializable; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; + +/** + * Abstract super class for Attribute objects. Currently the ConstantValue, SourceFile, Code, + * Exceptiontable, LineNumberTable, LocalVariableTable, InnerClasses and Synthetic + * attributes are supported. The Unknown attribute stands for non-standard-attributes. + * + * @version $Id: Attribute.java,v 1.9 2009/12/09 18:01:31 aclement Exp $ + * @author M. Dahm + * @see ConstantValue + * @see SourceFile + * @see Code + * @see Unknown + * @see ExceptionTable + * @see LineNumberTable + * @see LocalVariableTable + * @see InnerClasses + * @see Synthetic + * @see Deprecated + * @see Signature + */ +public abstract class Attribute implements Cloneable, Node, Serializable { + public final static Attribute[] NoAttributes = new Attribute[0]; + + protected byte tag; // Tag to distinguish subclasses + protected int nameIndex; + protected int length; + protected ConstantPool cpool; + + protected Attribute(byte tag, int nameIndex, int length, ConstantPool cpool) { + this.tag = tag; + this.nameIndex = nameIndex; + this.length = length; + this.cpool = cpool; + } + + public void dump(DataOutputStream file) throws IOException { + file.writeShort(nameIndex); + file.writeInt(length); + } + + // OPTIMIZE how about just reading them in and storing them until we need to decode what they really are? + public static final Attribute readAttribute(DataInputStream file, ConstantPool cpool) throws IOException { + byte tag = Constants.ATTR_UNKNOWN; + int idx = file.readUnsignedShort(); + String name = cpool.getConstantUtf8(idx).getValue(); + int len = file.readInt(); + + // Compare strings to find known attribute + for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++) { + if (name.equals(Constants.ATTRIBUTE_NAMES[i])) { + tag = i; + break; + } + } + switch (tag) { + case Constants.ATTR_UNKNOWN: + return new Unknown(idx, len, file, cpool); + case Constants.ATTR_CONSTANT_VALUE: + return new ConstantValue(idx, len, file, cpool); + case Constants.ATTR_SOURCE_FILE: + return new SourceFile(idx, len, file, cpool); + case Constants.ATTR_CODE: + return new Code(idx, len, file, cpool); + case Constants.ATTR_EXCEPTIONS: + return new ExceptionTable(idx, len, file, cpool); + case Constants.ATTR_LINE_NUMBER_TABLE: + return new LineNumberTable(idx, len, file, cpool); + case Constants.ATTR_LOCAL_VARIABLE_TABLE: + return new LocalVariableTable(idx, len, file, cpool); + case Constants.ATTR_INNER_CLASSES: + return new InnerClasses(idx, len, file, cpool); + case Constants.ATTR_SYNTHETIC: + return new Synthetic(idx, len, file, cpool); + case Constants.ATTR_DEPRECATED: + return new Deprecated(idx, len, file, cpool); + case Constants.ATTR_SIGNATURE: + return new Signature(idx, len, file, cpool); + case Constants.ATTR_STACK_MAP: + return new StackMap(idx, len, file, cpool); + case Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS: + return new RuntimeVisAnnos(idx, len, file, cpool); + case Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS: + return new RuntimeInvisAnnos(idx, len, file, cpool); + case Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: + return new RuntimeVisParamAnnos(idx, len, file, cpool); + case Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: + return new RuntimeInvisParamAnnos(idx, len, file, cpool); + case Constants.ATTR_ANNOTATION_DEFAULT: + return new AnnotationDefault(idx, len, file, cpool); + case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE: + return new LocalVariableTypeTable(idx, len, file, cpool); + case Constants.ATTR_ENCLOSING_METHOD: + return new EnclosingMethod(idx, len, file, cpool); + case Constants.ATTR_BOOTSTRAPMETHODS: + return new BootstrapMethods(idx,len,file,cpool); + case Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS: + return new RuntimeVisTypeAnnos(idx, len, file, cpool); + case Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: + return new RuntimeInvisTypeAnnos(idx, len, file, cpool); + case Constants.ATTR_METHOD_PARAMETERS: + return new MethodParameters(idx, len, file, cpool); + case Constants.ATTR_MODULE: + return new Module(idx, len, file, cpool); + case Constants.ATTR_MODULE_PACKAGES: + return new ModulePackages(idx, len, file, cpool); + case Constants.ATTR_MODULE_MAIN_CLASS: + return new ModuleMainClass(idx, len, file, cpool); + case Constants.ATTR_NEST_HOST: + return new NestHost(idx, len, file, cpool); + case Constants.ATTR_NEST_MEMBERS: + return new NestMembers(idx, len, file, cpool); + default: + throw new IllegalStateException(); + } + } + + public String getName() { + return cpool.getConstantUtf8(nameIndex).getValue(); + } + + public final int getLength() { + return length; + } + + public final int getNameIndex() { + return nameIndex; + } + + public final byte getTag() { + return tag; + } + + public final ConstantPool getConstantPool() { + return cpool; + } + + @Override + public String toString() { + return Constants.ATTRIBUTE_NAMES[tag]; + } + + @Override + public abstract void accept(ClassVisitor v); + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AttributeUtils.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AttributeUtils.java new file mode 100644 index 000000000..45d1597a7 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AttributeUtils.java @@ -0,0 +1,99 @@ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +public class AttributeUtils { + + public static Attribute[] readAttributes(DataInputStream dataInputstream, ConstantPool cpool) { + try { + int length = dataInputstream.readUnsignedShort(); + if (length == 0) { + return Attribute.NoAttributes; + } + Attribute[] attrs = new Attribute[length]; + for (int i = 0; i < length; i++) { + attrs[i] = Attribute.readAttribute(dataInputstream, cpool); + } + return attrs; + } catch (IOException e) { + throw new ClassFormatException("IOException whilst reading set of attributes: " + e.toString()); + } + } + + /** Write (serialize) a set of attributes into a specified output stream */ + public static void writeAttributes(Attribute[] attributes, DataOutputStream file) throws IOException { + if (attributes == null) { + file.writeShort(0); + } else { + file.writeShort(attributes.length); + for (int i = 0; i < attributes.length; i++) { + attributes[i].dump(file); + } + } + } + + public static Signature getSignatureAttribute(Attribute[] attributes) { + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].tag == Constants.ATTR_SIGNATURE) { + return (Signature) attributes[i]; + } + } + return null; + } + + public static Code getCodeAttribute(Attribute[] attributes) { + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].tag == Constants.ATTR_CODE) { + return (Code) attributes[i]; + } + } + return null; + } + + public static ExceptionTable getExceptionTableAttribute(Attribute[] attributes) { + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].tag == Constants.ATTR_EXCEPTIONS) { + return (ExceptionTable) attributes[i]; + } + } + return null; + } + + public static ConstantValue getConstantValueAttribute(Attribute[] attributes) { + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) { + return (ConstantValue) attributes[i]; + } + } + return null; + } + + public static void accept(Attribute[] attributes, ClassVisitor visitor) { + for (int i = 0; i < attributes.length; i++) { + attributes[i].accept(visitor); + } + } + + public static boolean hasSyntheticAttribute(Attribute[] attributes) { + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].tag == Constants.ATTR_SYNTHETIC) { + return true; + } + } + return false; + } + + public static SourceFile getSourceFileAttribute(Attribute[] attributes) { + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].tag == Constants.ATTR_SOURCE_FILE) { + return (SourceFile) attributes[i]; + } + } + return null; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/BootstrapMethods.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/BootstrapMethods.java new file mode 100644 index 000000000..f708c0cab --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/BootstrapMethods.java @@ -0,0 +1,268 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Represents the BootstrapMethods attribute in Java 7 classes. + * + * @author Andy Clement + */ +public final class BootstrapMethods extends Attribute { + + // if 'isInPackedState' then this data needs unpacking + private boolean isInPackedState = false; + private byte[] data; // discarded once unpacked + + private int numBootstrapMethods; + private BootstrapMethod[] bootstrapMethods; + + public BootstrapMethods(BootstrapMethods c) { + this(c.getNameIndex(), c.getLength(), c.getBootstrapMethods(), c.getConstantPool()); + } + + public BootstrapMethods(int nameIndex, int length, BootstrapMethod[] lineNumberTable, ConstantPool constantPool) { + super(Constants.ATTR_BOOTSTRAPMETHODS, nameIndex, length, constantPool); + setBootstrapMethods(lineNumberTable); + isInPackedState = false; + } + + public final void setBootstrapMethods(BootstrapMethod[] bootstrapMethods) { + this.data = null; + this.isInPackedState = false; + this.bootstrapMethods = bootstrapMethods; + this.numBootstrapMethods = bootstrapMethods==null?0:bootstrapMethods.length; + } + + BootstrapMethods(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, (BootstrapMethod[])null, constant_pool); + data = new byte[length]; + file.readFully(data); + isInPackedState = true; + } + + public static class BootstrapMethod { + private int bootstrapMethodRef; + private int[] bootstrapArguments; + + BootstrapMethod(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), readBootstrapArguments(file)); + } + + private static int[] readBootstrapArguments(DataInputStream dis) throws IOException { + int numBootstrapMethods = dis.readUnsignedShort(); + int[] bootstrapArguments = new int[numBootstrapMethods]; + for (int i=0;i 72) { + line.append('\n'); + buf.append(line); + line.setLength(0); + } + } + + buf.append(line); + + return buf.toString(); + } + + + /** + * @return deep copy of this attribute + */ + // @Override + // public Attribute copy(ConstantPool constant_pool) { + // unpack(); + // LineNumberTable newTable = (LineNumberTable) clone(); + // newTable.table = new LineNumber[tableLength]; + // for (int i = 0; i < tableLength; i++) { + // newTable.table[i] = table[i].copy(); + // } + // newTable.cpool = constant_pool; + // return newTable; + // } + public final int getNumBootstrapMethods () { + unpack(); + return bootstrapMethods.length; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassFormatException.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassFormatException.java new file mode 100644 index 000000000..a958329e5 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassFormatException.java @@ -0,0 +1,69 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Thrown when the BCEL attempts to read a class file and determines + * that the file is malformed or otherwise cannot be interpreted as a + * class file. + * + * @version $Id: ClassFormatException.java,v 1.3 2008/05/28 23:53:02 aclement Exp $ + * @author M. Dahm + */ +public class ClassFormatException extends RuntimeException { + public ClassFormatException() { super(); } + public ClassFormatException(String s) { super(s); } +} + diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassParser.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassParser.java new file mode 100644 index 000000000..54882beee --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassParser.java @@ -0,0 +1,249 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.aspectj.apache.bcel.Constants; + +/** + * Wrapper class that parses a given Java .class file. The method parse returns a + * JavaClass object on success. When an I/O error or an + * inconsistency occurs an appropiate exception is propagated back to + * the caller. + * + * The structure and the names comply, except for a few conveniences, + * exactly with the + * JVM specification 1.0. See this paper for + * further details about the structure of a bytecode file. + * + * @version $Id: ClassParser.java,v 1.6 2008/05/30 17:29:14 aclement Exp $ + * @author M. Dahm + */ +public final class ClassParser { + private DataInputStream file; + private String filename; + private int classnameIndex; + private int superclassnameIndex; + private int major, minor; + private int accessflags; + private int[] interfaceIndices; + private ConstantPool cpool; + private Field[] fields; + private Method[] methods; + private Attribute[] attributes; + + private static final int BUFSIZE = 8192; + + /** Parse class from the given stream */ + public ClassParser(InputStream file, String filename) { + this.filename = filename; + if (file instanceof DataInputStream) this.file = (DataInputStream)file; + else this.file = new DataInputStream(new BufferedInputStream(file,BUFSIZE)); + } + + public ClassParser(ByteArrayInputStream baos, String filename) { + this.filename = filename; + this.file = new DataInputStream(baos); + } + + /** Parse class from given .class file */ + public ClassParser(String file_name) throws IOException { + this.filename = file_name; + file = new DataInputStream(new BufferedInputStream(new FileInputStream(file_name),BUFSIZE)); + } + + /** + * Parse the given Java class file and return an object that represents + * the contained data, i.e., constants, methods, fields and commands. + * A ClassFormatException is raised, if the file is not a valid + * .class file. (This does not include verification of the byte code as it + * is performed by the java interpreter). + */ + public JavaClass parse() throws IOException, ClassFormatException { + /****************** Read headers ********************************/ + // Check magic tag of class file + readID(); + + // Get compiler version + readVersion(); + + /****************** Read constant pool and related **************/ + // Read constant pool entries + readConstantPool(); + + // Get class information + readClassInfo(); + + // Get interface information, i.e., implemented interfaces + readInterfaces(); + + /****************** Read class fields and methods ***************/ + // Read class fields, i.e., the variables of the class + readFields(); + + // Read class methods, i.e., the functions in the class + readMethods(); + + // Read class attributes + readAttributes(); + + // Read everything of interest, so close the file + file.close(); + + // Return the information we have gathered in a new object + JavaClass jc= new JavaClass(classnameIndex, superclassnameIndex, + filename, major, minor, accessflags, + cpool, interfaceIndices, fields, + methods, attributes); + return jc; + } + + /** Read information about the attributes of the class */ + private final void readAttributes() { + attributes = AttributeUtils.readAttributes(file,cpool); + } + + /** Read information about the class and its super class */ + private final void readClassInfo() throws IOException { + accessflags = file.readUnsignedShort(); + + /* Interfaces are implicitely abstract, the flag should be set + * according to the JVM specification */ + if((accessflags & Constants.ACC_INTERFACE) != 0) + accessflags |= Constants.ACC_ABSTRACT; + + // don't police it like this... leave higher level verification code to check it. +// if(((access_flags & Constants.ACC_ABSTRACT) != 0) && +// ((access_flags & Constants.ACC_FINAL) != 0 )) +// throw new ClassFormatException("Class can't be both final and abstract"); + + classnameIndex = file.readUnsignedShort(); + superclassnameIndex = file.readUnsignedShort(); + } + + private final void readConstantPool() throws IOException { + try { + cpool = new ConstantPool(file); + } catch (ClassFormatException cfe) { + // add some context if we can + cfe.printStackTrace(); + if (filename!=null) { + String newmessage = "File: '"+filename+"': "+cfe.getMessage(); + throw new ClassFormatException(newmessage); // this loses the old stack trace but I dont think that matters! + } + throw cfe; + } + } + + /** Read information about the fields of the class */ + private final void readFields() throws IOException, ClassFormatException { + int fieldCount = file.readUnsignedShort(); + if (fieldCount == 0) { + fields = Field.NoFields; + } else { + fields = new Field[fieldCount]; + for(int i=0; i < fieldCount; i++) + fields[i] = new Field(file, cpool); + } + } + + /** Check whether the header of the file is ok. Of course, this has + * to be the first action on successive file reads */ + private final void readID() throws IOException { + int magic = 0xCAFEBABE; + if (file.readInt() != magic) + throw new ClassFormatException(filename + " is not a Java .class file"); + } + + private static final int[] NO_INTERFACES = new int[0]; + + /** Read information about the interfaces implemented by this class */ + private final void readInterfaces() throws IOException { + int interfacesCount = file.readUnsignedShort(); + if (interfacesCount==0) { + interfaceIndices = NO_INTERFACES; + } else { + interfaceIndices = new int[interfacesCount]; + for(int i=0; i < interfacesCount; i++) + interfaceIndices[i] = file.readUnsignedShort(); + } + } + + /** Read information about the methods of the class */ + private final void readMethods() throws IOException { + int methodsCount = file.readUnsignedShort(); + if (methodsCount==0) { + methods = Method.NoMethods; + } else { + methods = new Method[methodsCount]; + for(int i=0; i < methodsCount; i++) + methods[i] = new Method(file, cpool); + } + } + + /** Read major and minor version of compiler which created the file */ + private final void readVersion() throws IOException { + minor = file.readUnsignedShort(); + major = file.readUnsignedShort(); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassVisitor.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassVisitor.java new file mode 100644 index 000000000..5c60f818f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassVisitor.java @@ -0,0 +1,180 @@ +package org.aspectj.apache.bcel.classfile; + +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Interface to make use of the Visitor pattern programming style. I.e. a class that implements this interface can traverse the + * contents of a Java class just by calling the `accept' method which all classes have. + * + * Implemented by wish of Boris Bokowski. + * + * @version $Id: ClassVisitor.java,v 1.4 2009/09/15 19:40:13 aclement Exp $ + * @author M. Dahm + */ +public interface ClassVisitor { + public void visitCode(Code obj); + + public void visitCodeException(CodeException obj); + + public void visitConstantClass(ConstantClass obj); + + public void visitConstantDouble(ConstantDouble obj); + + public void visitConstantFieldref(ConstantFieldref obj); + + public void visitConstantFloat(ConstantFloat obj); + + public void visitConstantInteger(ConstantInteger obj); + + public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj); + + public void visitConstantLong(ConstantLong obj); + + public void visitConstantMethodref(ConstantMethodref obj); + + public void visitConstantMethodHandle(ConstantMethodHandle obj); + + public void visitConstantNameAndType(ConstantNameAndType obj); + + public void visitConstantMethodType(ConstantMethodType obj); + + public void visitConstantInvokeDynamic(ConstantInvokeDynamic obj); + + public void visitConstantDynamic(ConstantDynamic obj); + + public void visitConstantPool(ConstantPool obj); + + public void visitConstantString(ConstantString obj); + + public void visitConstantModule(ConstantModule obj); + + public void visitConstantPackage(ConstantPackage obj); + + public void visitConstantUtf8(ConstantUtf8 obj); + + public void visitConstantValue(ConstantValue obj); + + public void visitDeprecated(Deprecated obj); + + public void visitExceptionTable(ExceptionTable obj); + + public void visitField(Field obj); + + public void visitInnerClass(InnerClass obj); + + public void visitInnerClasses(InnerClasses obj); + + public void visitJavaClass(JavaClass obj); + + public void visitLineNumber(LineNumber obj); + + public void visitLineNumberTable(LineNumberTable obj); + + public void visitLocalVariable(LocalVariable obj); + + public void visitLocalVariableTable(LocalVariableTable obj); + + public void visitMethod(Method obj); + + public void visitSignature(Signature obj); + + public void visitSourceFile(SourceFile obj); + + public void visitSynthetic(Synthetic obj); + + public void visitBootstrapMethods(BootstrapMethods obj); + + public void visitUnknown(Unknown obj); + + public void visitStackMap(StackMap obj); + + public void visitStackMapEntry(StackMapEntry obj); + + public void visitEnclosingMethod(EnclosingMethod obj); + + public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos obj); + + public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos obj); + + public void visitRuntimeVisibleParameterAnnotations(RuntimeVisParamAnnos obj); + + public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisParamAnnos obj); + + public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos obj); + + public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos obj); + + public void visitAnnotationDefault(AnnotationDefault obj); + + public void visitLocalVariableTypeTable(LocalVariableTypeTable obj); + + public void visitMethodParameters(MethodParameters methodParameters); + + // J9: + public void visitModule(Module module); + public void visitModulePackages(ModulePackages modulePackage); + public void visitModuleMainClass(ModuleMainClass moduleMainClass); + + // J11: + public void visitNestHost(NestHost nestHost); + public void visitNestMembers(NestMembers nestMembers); +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Code.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Code.java new file mode 100644 index 000000000..b714e6cab --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Code.java @@ -0,0 +1,388 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a chunk of Java byte code contained in a method. It is instantiated by the + * Attribute.readAttribute() method. A Code attribute contains informations about operand stack, local variables, + * byte code and the exceptions handled within this method. + * + * This attribute has attributes itself, namely LineNumberTable which is used for debugging purposes and + * LocalVariableTable which contains information about the local variables. + * + * @version $Id: Code.java,v 1.9 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + * @see Attribute + * @see CodeException + * @see LineNumberTable + * @see LocalVariableTable + */ +public final class Code extends Attribute { + private int maxStack; // Maximum size of stack used by this method + private int maxLocals; // Number of local variables + private byte[] code; // Actual byte code + private CodeException[] exceptionTable; + private Attribute[] attributes; + private static final CodeException[] NO_EXCEPTIONS = new CodeException[] {}; + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical + * copy. + */ + public Code(Code c) { + this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), c.getCode(), c.getExceptionTable(), c + .getAttributes(), c.getConstantPool()); + } + + Code(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + // Initialize with some default values which will be overwritten later + this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), (byte[]) null, (CodeException[]) null, + (Attribute[]) null, constant_pool); + + int len = file.readInt(); + code = new byte[len]; // Read byte code + file.readFully(code); + + /* + * Read exception table that contains all regions where an exception handler is active, i.e., a try { ... } catch() block. + */ + len = file.readUnsignedShort(); + if (len == 0) { + exceptionTable = NO_EXCEPTIONS; + } else { + exceptionTable = new CodeException[len]; + for (int i = 0; i < len; i++) { + exceptionTable[i] = new CodeException(file); + } + } + + // Read all attributes, eg: LineNumberTable, LocalVariableTable + attributes = AttributeUtils.readAttributes(file, constant_pool); + + /* + * Adjust length, because of setAttributes in this(), s.b. length is incorrect, because it didn't take the internal + * attributes into account yet! Very subtle bug, fixed in 3.1.1. + */ + this.length = length; + } + + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param max_stack Maximum size of stack + * @param max_locals Number of local variables + * @param code Actual byte code + * @param exception_table Table of handled exceptions + * @param attributes Attributes of code: LineNumber or LocalVariable + * @param constant_pool Array of constants + */ + public Code(int name_index, int length, int max_stack, int max_locals, byte[] code, CodeException[] exception_table, + Attribute[] attributes, ConstantPool constant_pool) { + super(Constants.ATTR_CODE, name_index, length, constant_pool); + + this.maxStack = max_stack; + this.maxLocals = max_locals; + + setCode(code); + setExceptionTable(exception_table); + setAttributes(attributes); // Overwrites length! + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitCode(this); + } + + /** + * Dump code attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + + file.writeShort(maxStack); + file.writeShort(maxLocals); + file.writeInt(code.length); + file.write(code, 0, code.length); + + file.writeShort(exceptionTable.length); + for (int i = 0; i < exceptionTable.length; i++) { + exceptionTable[i].dump(file); + } + + file.writeShort(attributes.length); + for (int i = 0; i < attributes.length; i++) { + attributes[i].dump(file); + } + } + + /** + * @return Collection of code attributes. + * @see Attribute + */ + public final Attribute[] getAttributes() { + return attributes; + } + + /** + * @return LineNumberTable of Code, if it has one + */ + public LineNumberTable getLineNumberTable() { + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].tag == Constants.ATTR_LINE_NUMBER_TABLE) { + return (LineNumberTable) attributes[i]; + } + } + return null; + } + + /** + * @return LocalVariableTable of Code, if it has one + */ + public LocalVariableTable getLocalVariableTable() { + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].tag == Constants.ATTR_LOCAL_VARIABLE_TABLE) { + return (LocalVariableTable) attributes[i]; + } + } + return null; + } + + /** + * @return Actual byte code of the method. + */ + public final byte[] getCode() { + return code; + } + + /** + * @return Table of handled exceptions. + * @see CodeException + */ + public final CodeException[] getExceptionTable() { + return exceptionTable; + } + + /** + * @return Number of local variables. + */ + public final int getMaxLocals() { + return maxLocals; + } + + /** + * @return Maximum size of stack used by this method. + */ + + public final int getMaxStack() { + return maxStack; + } + + /** + * @return the internal length of this code attribute (minus the first 6 bytes) and excluding all its attributes + */ + private final int getInternalLength() { + return 2 /* max_stack */+ 2 /* max_locals */+ 4 /* code length */ + + (code == null ? 0 : code.length) /* byte-code */ + + 2 /* exception-table length */ + + 8 * (exceptionTable == null ? 0 : exceptionTable.length) /* exception table */ + + 2 /* attributes count */; + } + + /** + * @return the full size of this code attribute, minus its first 6 bytes, including the size of all its contained attributes + */ + private final int calculateLength() { + int len = 0; + if (attributes != null) { + for (int i = 0; i < attributes.length; i++) { + len += attributes[i].length + 6 /* attribute header size */; + } + } + return len + getInternalLength(); + } + + /** + * @param attributes. + */ + public final void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + length = calculateLength(); // Adjust length + } + + /** + * @param code byte code + */ + public final void setCode(byte[] code) { + this.code = code; + } + + /** + * @param exception_table exception table + */ + public final void setExceptionTable(CodeException[] exception_table) { + this.exceptionTable = exception_table; + } + + /** + * @param max_locals maximum number of local variables + */ + public final void setMaxLocals(int max_locals) { + this.maxLocals = max_locals; + } + + /** + * @param max_stack maximum stack size + */ + public final void setMaxStack(int max_stack) { + this.maxStack = max_stack; + } + + /** + * @return String representation of code chunk. + */ + public final String toString(boolean verbose) { + StringBuffer buf; + + buf = new StringBuffer("Code(max_stack = " + maxStack + ", max_locals = " + maxLocals + ", code_length = " + code.length + + ")\n" + Utility.codeToString(code, cpool, 0, -1, verbose)); + + if (exceptionTable.length > 0) { + buf.append("\nException handler(s) = \n" + "From\tTo\tHandler\tType\n"); + + for (int i = 0; i < exceptionTable.length; i++) { + buf.append(exceptionTable[i].toString(cpool, verbose) + "\n"); + } + } + + if (attributes.length > 0) { + buf.append("\nAttribute(s) = \n"); + + for (int i = 0; i < attributes.length; i++) { + buf.append(attributes[i].toString() + "\n"); + } + } + + return buf.toString(); + } + + /** + * @return String representation of code chunk. + */ + @Override + public final String toString() { + return toString(true); + } + + // /** + // * @return deep copy of this attribute + // */ + // public Attribute copy(ConstantPool constant_pool) { + // Code c = (Code)clone(); + // c.code = (byte[])code.clone(); + // c.cpool = constant_pool; + // + // c.exceptionTable = new CodeException[exceptionTable.length]; + // for(int i=0; i < exceptionTable.length; i++) + // c.exceptionTable[i] = exceptionTable[i].copy(); + // + // c.attributes = new Attribute[attributes.length]; + // for(int i=0; i < attributes.length; i++) + // c.attributes[i] = attributes[i].copy(constant_pool); + // + // return c; + // } + + /** + * Returns the same as toString(true) except that the attribute information isn't included (line numbers). Can be used to check + * whether two pieces of code are equivalent. + */ + public String getCodeString() { + StringBuffer codeString = new StringBuffer(); + codeString.append("Code(max_stack = ").append(maxStack); + codeString.append(", max_locals = ").append(maxLocals); + codeString.append(", code_length = ").append(code.length).append(")\n"); + codeString.append(Utility.codeToString(code, cpool, 0, -1, true)); + if (exceptionTable.length > 0) { + codeString.append("\n").append("Exception entries = ").append(exceptionTable.length).append("\n"); + for (int i = 0; i < exceptionTable.length; i++) { + CodeException exc = exceptionTable[i]; + int type = exc.getCatchType(); + String name = "finally"; + if (type != 0) { + name = this.cpool.getConstantString(type, Constants.CONSTANT_Class); + } + codeString.append(name).append("["); + codeString.append(exc.getStartPC()).append(">").append(exc.getEndPC()).append("]\n"); + } + } + return codeString.toString(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/CodeException.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/CodeException.java new file mode 100644 index 000000000..72b4d539e --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/CodeException.java @@ -0,0 +1,196 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.Constants; +import java.io.*; + +/** + * This class represents an entry in the exception table of the Code + * attribute and is used only there. It contains a range in which a + * particular exception handler is active. + * + * @version $Id: CodeException.java,v 1.3 2008/05/28 23:53:02 aclement Exp $ + * @author M. Dahm + * @see Code + */ +public final class CodeException implements Cloneable, Constants, Node, Serializable { + private int start_pc; // Range in the code the exception handler is + private int end_pc; // active. start_pc is inclusive, end_pc exclusive + private int handler_pc; /* Starting address of exception handler, i.e., + * an offset from start of code. + */ + private int catch_type; /* If this is zero the handler catches any + * exception, otherwise it points to the + * exception class which is to be caught. + */ + + public CodeException(CodeException c) { + this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); + } + + CodeException(DataInputStream file) throws IOException { + start_pc = file.readUnsignedShort(); + end_pc = file.readUnsignedShort(); + handler_pc = file.readUnsignedShort(); + catch_type = file.readUnsignedShort(); + } + + public CodeException(int start_pc, int end_pc, int handler_pc, int catch_type) { + this.start_pc = start_pc; + this.end_pc = end_pc; + this.handler_pc = handler_pc; + this.catch_type = catch_type; + } + + public void accept(ClassVisitor v) { + v.visitCodeException(this); + } + + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(start_pc); + file.writeShort(end_pc); + file.writeShort(handler_pc); + file.writeShort(catch_type); + } + + /** + * @return 0, if the handler catches any exception, otherwise it points to + * the exception class which is to be caught. + */ + public final int getCatchType() { return catch_type; } + + /** + * @return Exclusive end index of the region where the handler is active. + */ + public final int getEndPC() { return end_pc; } + + /** + * @return Starting address of exception handler, relative to the code. + */ + public final int getHandlerPC() { return handler_pc; } + + /** + * @return Inclusive start index of the region where the handler is active. + */ + public final int getStartPC() { return start_pc; } + + /** + * @param catch_type. + */ + public final void setCatchType(int catch_type) { + this.catch_type = catch_type; + } + + /** + * @param end_pc end of handled block + */ + public final void setEndPC(int end_pc) { + this.end_pc = end_pc; + } + + /** + * @param handler_pc where the actual code is + */ + public final void setHandlerPC(int handler_pc) { + this.handler_pc = handler_pc; + } + + /** + * @param start_pc start of handled block + */ + public final void setStartPC(int start_pc) { + this.start_pc = start_pc; + } + + /** + * @return String representation. + */ + public final String toString() { + return "CodeException(start_pc = " + start_pc + + ", end_pc = " + end_pc + + ", handler_pc = " + handler_pc + ", catch_type = " + catch_type + ")"; + } + + /** + * @return String representation. + */ + public final String toString(ConstantPool cp, boolean verbose) { + String str; + + if(catch_type == 0) + str = "(0)"; + else + str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false) + + (verbose? "(" + catch_type + ")" : ""); + + return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; + } + + public final String toString(ConstantPool cp) { + return toString(cp, true); + } + + /** + * @return deep copy of this object + */ + public CodeException copy() { + try { + return (CodeException)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Constant.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Constant.java new file mode 100644 index 000000000..d391b75ea --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Constant.java @@ -0,0 +1,149 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Abstract superclass for classes to represent the different constant types in the constant pool of a class file. The classes keep + * closely to the JVM specification. + * + * @version $Id: Constant.java,v 1.5 2009/09/10 15:35:04 aclement Exp $ + * @author M. Dahm + */ +public abstract class Constant implements Cloneable, Node { + + protected byte tag; + + Constant(byte tag) { + this.tag = tag; + } + + public final byte getTag() { + return tag; + } + + @Override + public String toString() { + return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]"; + } + + public abstract void accept(ClassVisitor v); + + public abstract void dump(DataOutputStream dataOutputStream) throws IOException; + + public abstract Object getValue(); + + public Constant copy() { + try { + return (Constant) super.clone(); + } catch (CloneNotSupportedException e) { + } + + return null; + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + static final Constant readConstant(DataInputStream dis) throws IOException, ClassFormatException { + byte b = dis.readByte(); + switch (b) { + case Constants.CONSTANT_Class: + return new ConstantClass(dis); + case Constants.CONSTANT_NameAndType: + return new ConstantNameAndType(dis); + case Constants.CONSTANT_Utf8: + return new ConstantUtf8(dis); + case Constants.CONSTANT_Fieldref: + return new ConstantFieldref(dis); + case Constants.CONSTANT_Methodref: + return new ConstantMethodref(dis); + case Constants.CONSTANT_InterfaceMethodref: + return new ConstantInterfaceMethodref(dis); + case Constants.CONSTANT_String: + return new ConstantString(dis); + case Constants.CONSTANT_Integer: + return new ConstantInteger(dis); + case Constants.CONSTANT_Float: + return new ConstantFloat(dis); + case Constants.CONSTANT_Long: + return new ConstantLong(dis); + case Constants.CONSTANT_Double: + return new ConstantDouble(dis); + case Constants.CONSTANT_MethodHandle: + return new ConstantMethodHandle(dis); + case Constants.CONSTANT_MethodType: + return new ConstantMethodType(dis); + case Constants.CONSTANT_InvokeDynamic: + return new ConstantInvokeDynamic(dis); + case Constants.CONSTANT_Module: + return new ConstantModule(dis); + case Constants.CONSTANT_Package: + return new ConstantPackage(dis); + case Constants.CONSTANT_Dynamic: + return new ConstantDynamic(dis); + default: + throw new ClassFormatException("Invalid byte tag in constant pool: " + b); + } + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantCP.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantCP.java new file mode 100644 index 000000000..a476c4d15 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantCP.java @@ -0,0 +1,109 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Abstract super class for Fieldref and Methodref constants. + * + * @version $Id: ConstantCP.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @see ConstantFieldref + * @see ConstantMethodref + * @see ConstantInterfaceMethodref + */ +public abstract class ConstantCP extends Constant { + + protected int classIndex, nameAndTypeIndex; + + ConstantCP(byte tag, DataInputStream file) throws IOException { + this(tag, file.readUnsignedShort(), file.readUnsignedShort()); + } + + protected ConstantCP(byte tag, int classIndex, int nameAndTypeIndex) { + super(tag); + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(classIndex); + file.writeShort(nameAndTypeIndex); + } + + public final int getClassIndex() { + return classIndex; + } + + public final int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public String getClass(ConstantPool cp) { + return cp.constantToString(classIndex, Constants.CONSTANT_Class); + } + + @Override + public final String toString() { + return super.toString() + "(classIndex = " + classIndex + ", nameAndTypeIndex = " + nameAndTypeIndex + ")"; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantClass.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantClass.java new file mode 100644 index 000000000..883f3b25f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantClass.java @@ -0,0 +1,112 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to a (external) class. + * + * @version $Id: ConstantClass.java,v 1.6 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @author Andy Clement + */ +public final class ConstantClass extends Constant { + private int nameIndex; + + ConstantClass(DataInputStream file) throws IOException { + super(Constants.CONSTANT_Class); + this.nameIndex = file.readUnsignedShort(); + } + + public ConstantClass(int nameIndex) { + super(Constants.CONSTANT_Class); + this.nameIndex = nameIndex; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantClass(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(nameIndex); + } + + public final int getNameIndex() { + return nameIndex; + } + + @Override + public Integer getValue() { + return nameIndex; + } + + public String getClassname(ConstantPool cpool) { + return cpool.getConstantUtf8(nameIndex).getValue(); + } + + @Override + public final String toString() { + return super.toString() + "(name_index = " + nameIndex + ")"; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDouble.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDouble.java new file mode 100644 index 000000000..813aec72a --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDouble.java @@ -0,0 +1,107 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to a Double object. + * + * @version $Id: ConstantDouble.java,v 1.6 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @author Andy Clement + */ +public final class ConstantDouble extends Constant implements SimpleConstant { + private double value; + + public ConstantDouble(double value) { + super(Constants.CONSTANT_Double); + this.value = value; + } + + ConstantDouble(DataInputStream file) throws IOException { + this(file.readDouble()); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantDouble(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeDouble(value); + } + + @Override + public final String toString() { + return super.toString() + "(bytes = " + value + ")"; + } + + @Override + public Double getValue() { + return value; + } + + public String getStringValue() { + return Double.toString(value); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDynamic.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDynamic.java new file mode 100644 index 000000000..40100f83b --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDynamic.java @@ -0,0 +1,116 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to the name and signature of a field or method. + * + * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.10 + * + * @author Andy Clement + * @see Constant + */ +public final class ConstantDynamic extends Constant { + private final int bootstrapMethodAttrIndex; + private final int nameAndTypeIndex; + + ConstantDynamic(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } + + public ConstantDynamic(int readUnsignedShort, int nameAndTypeIndex) { + super(Constants.CONSTANT_InvokeDynamic); + this.bootstrapMethodAttrIndex = readUnsignedShort; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(bootstrapMethodAttrIndex); + file.writeShort(nameAndTypeIndex); + } + + public final int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public final int getBootstrapMethodAttrIndex() { + return bootstrapMethodAttrIndex; + } + + @Override + public final String toString() { + return super.toString() + "(bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex + ",nameAndTypeIndex=" + nameAndTypeIndex + ")"; + } + + @Override + public String getValue() { + return toString(); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantDynamic(this); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFieldref.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFieldref.java new file mode 100644 index 000000000..056f3e3fd --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFieldref.java @@ -0,0 +1,87 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a constant pool reference to a field. + * + * @version $Id: ConstantFieldref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + */ +public final class ConstantFieldref extends ConstantCP { + + ConstantFieldref(DataInputStream file) throws IOException { + super(Constants.CONSTANT_Fieldref, file); + } + + public ConstantFieldref(int class_index, int name_and_type_index) { + super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantFieldref(this); + } + + @Override + public String getValue() { + return toString(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFloat.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFloat.java new file mode 100644 index 000000000..985c28125 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFloat.java @@ -0,0 +1,108 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to a float object. + * + * @version $Id: ConstantFloat.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @see Constant + */ +public final class ConstantFloat extends Constant implements SimpleConstant { + private float floatValue; + + public ConstantFloat(float floatValue) { + super(Constants.CONSTANT_Float); + this.floatValue = floatValue; + } + + ConstantFloat(DataInputStream file) throws IOException { + this(file.readFloat()); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantFloat(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeFloat(floatValue); + } + + @Override + public final Float getValue() { + return floatValue; + } + + public final String getStringValue() { + return Float.toString(floatValue); + } + + @Override + public final String toString() { + return super.toString() + "(bytes = " + floatValue + ")"; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInteger.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInteger.java new file mode 100644 index 000000000..415706eed --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInteger.java @@ -0,0 +1,111 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to an int object. + * + * @version $Id: ConstantInteger.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @see Constant + */ +public final class ConstantInteger extends Constant implements SimpleConstant { + private int intValue; + + public ConstantInteger(int intValue) { + super(Constants.CONSTANT_Integer); + this.intValue = intValue; + } + + ConstantInteger(DataInputStream file) throws IOException { + this(file.readInt()); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantInteger(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeInt(intValue); + } + + @Override + public final String toString() { + return super.toString() + "(bytes = " + intValue + ")"; + } + + @Override + public Integer getValue() { + return intValue; + } + + public int getIntValue() { + return intValue; + } + + public String getStringValue() { + return Integer.toString(intValue); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java new file mode 100644 index 000000000..b973c726e --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java @@ -0,0 +1,88 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a constant pool reference to an interface method. + * + * @version $Id: ConstantInterfaceMethodref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + */ +public final class ConstantInterfaceMethodref extends ConstantCP { + + ConstantInterfaceMethodref(DataInputStream file) throws IOException { + super(Constants.CONSTANT_InterfaceMethodref, file); + } + + public ConstantInterfaceMethodref(int classIndex, int nameAndTypeIndex) { + super(Constants.CONSTANT_InterfaceMethodref, classIndex, nameAndTypeIndex); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantInterfaceMethodref(this); + } + + @Override + public String getValue() { + return toString(); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java new file mode 100644 index 000000000..0d263aa65 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java @@ -0,0 +1,132 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to the name and signature of a field or method. + * + * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.10 + * + * @author Andy Clement + * @see Constant + */ +public final class ConstantInvokeDynamic extends Constant { + private final int bootstrapMethodAttrIndex; + private final int nameAndTypeIndex; + + ConstantInvokeDynamic(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } + + public ConstantInvokeDynamic(int readUnsignedShort, int nameAndTypeIndex) { + super(Constants.CONSTANT_InvokeDynamic); + this.bootstrapMethodAttrIndex = readUnsignedShort; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(bootstrapMethodAttrIndex); + file.writeShort(nameAndTypeIndex); + } +// +// public final byte getReferenceKind() { +// return bootstrapMethodAttrIndex; +// } +// +// public final String getName(ConstantPool cp) { +// return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); +// } +// +// public final int getSignatureIndex() { +// return referenceIndex; +// } +// +// public final String getSignature(ConstantPool cp) { +// return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); +// } + + public final int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + public final int getBootstrapMethodAttrIndex() { + return bootstrapMethodAttrIndex; + } + + @Override + public final String toString() { + return super.toString() + "(bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex + ",nameAndTypeIndex=" + nameAndTypeIndex + ")"; + } + + @Override + public String getValue() { + return toString(); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantInvokeDynamic(this); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantLong.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantLong.java new file mode 100644 index 000000000..1d56b98a3 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantLong.java @@ -0,0 +1,108 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to a long object. + * + * @version $Id: ConstantLong.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @see Constant + */ +public final class ConstantLong extends Constant implements SimpleConstant { + private long longValue; + + public ConstantLong(long longValue) { + super(Constants.CONSTANT_Long); + this.longValue = longValue; + } + + ConstantLong(DataInputStream file) throws IOException { + this(file.readLong()); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantLong(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeLong(longValue); + } + + @Override + public final Long getValue() { + return longValue; + } + + public final String getStringValue() { + return Long.toString(longValue); + } + + @Override + public final String toString() { + return super.toString() + "(longValue = " + longValue + ")"; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java new file mode 100644 index 000000000..712a13f4c --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java @@ -0,0 +1,132 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to the name and signature of a field or method. + * + * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.8 + * + * @author Andy Clement + * @see Constant + */ +public final class ConstantMethodHandle extends Constant { + private byte referenceKind; + private int referenceIndex; + + ConstantMethodHandle(DataInputStream file) throws IOException { + this(file.readByte(), file.readUnsignedShort()); + } + + public ConstantMethodHandle(byte referenceKind, int referenceIndex) { + super(Constants.CONSTANT_MethodHandle); + this.referenceKind = referenceKind; + this.referenceIndex = referenceIndex; + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeByte(referenceKind); + file.writeShort(referenceIndex); + } + + public final byte getReferenceKind() { + return referenceKind; + } + + public final int getReferenceIndex() { + return referenceIndex; + } + + @Override + public final String toString() { + return super.toString() + "(referenceKind=" + referenceKind + ",referenceIndex=" + referenceIndex + ")"; + } + + @Override + public String getValue() { + return toString(); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantMethodHandle(this); + } + + public static String kindToString(byte kind) { + switch (kind) { + case 1: return "getfield"; + case 2: return "getstatic"; + case 3: return "putfield"; + case 4: return "putstatic"; + case 5: return "invokevirtual"; + case 6: return "invokestatic"; + case 7: return "invokespecial"; + case 8: return "newinvokespecial"; + case 9: return "invokeinterface"; + default: + return "nyi"; + } + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodType.java new file mode 100644 index 000000000..867e7eb0a --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodType.java @@ -0,0 +1,121 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to the name and signature of a field or method. + * + * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.9 + * + * @author Andy Clement + * @see Constant + */ +public final class ConstantMethodType extends Constant { + private int descriptorIndex; + + ConstantMethodType(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + + public ConstantMethodType(int descriptorIndex) { + super(Constants.CONSTANT_MethodType); + this.descriptorIndex = descriptorIndex; + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(descriptorIndex); + } + + public final int getDescriptorIndex() { + return descriptorIndex; + } + +// public final String getName(ConstantPool cp) { +// return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); +// } +// +// public final int getSignatureIndex() { +// return referenceIndex; +// } +// +// public final String getSignature(ConstantPool cp) { +// return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); +// } + + @Override + public final String toString() { + return super.toString() + "(descriptorIndex=" + descriptorIndex + ")"; + } + + @Override + public String getValue() { + return toString(); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantMethodType(this); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodref.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodref.java new file mode 100644 index 000000000..29b37c5d7 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodref.java @@ -0,0 +1,87 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a constant pool reference to a method. + * + * @version $Id: ConstantMethodref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + */ +public final class ConstantMethodref extends ConstantCP { + + ConstantMethodref(DataInputStream file) throws IOException { + super(Constants.CONSTANT_Methodref, file); + } + + public ConstantMethodref(int class_index, int name_and_type_index) { + super(Constants.CONSTANT_Methodref, class_index, name_and_type_index); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantMethodref(this); + } + + @Override + public String getValue() { + return toString(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantModule.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantModule.java new file mode 100644 index 000000000..efe4d3a1b --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantModule.java @@ -0,0 +1,111 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Represents a module. + * + * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.11 + * + * @author Andy Clement + */ +public final class ConstantModule extends Constant { + + private int nameIndex; + + ConstantModule(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + + public ConstantModule(int nameIndex) { + super(Constants.CONSTANT_Module); + this.nameIndex = nameIndex; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantModule(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(nameIndex); + } + + @Override + public Integer getValue() { + return nameIndex; + } + + public final int getNameIndex() { + return nameIndex; + } + + @Override + public final String toString() { + return super.toString() + "(name_index = " + nameIndex + ")"; + } + + public String getModuleName(ConstantPool cpool) { + Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getValue(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java new file mode 100644 index 000000000..8af80fab2 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java @@ -0,0 +1,157 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to the name and signature of a field or method. + * + * @version $Id: ConstantNameAndType.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @see Constant + */ +public final class ConstantNameAndType extends Constant { + private int name_index; // Name of field/method + private int signature_index; // and its signature. + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantNameAndType(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } + + /** + * @param name_index Name of field/method + * @param signature_index and its signature + */ + public ConstantNameAndType(int name_index, int signature_index) { + super(Constants.CONSTANT_NameAndType); + this.name_index = name_index; + this.signature_index = signature_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitConstantNameAndType(this); + } + + /** + * Dump name and signature index to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(name_index); + file.writeShort(signature_index); + } + + /** + * @return Name index in constant pool of field/method name. + */ + public final int getNameIndex() { + return name_index; + } + + /** + * @return name + */ + public final String getName(ConstantPool cp) { + return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); + } + + /** + * @return Index in constant pool of field/method signature. + */ + public final int getSignatureIndex() { + return signature_index; + } + + /** + * @return signature + */ + public final String getSignature(ConstantPool cp) { + return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); + } + + @Override + public final String toString() { + return super.toString() + "(name_index = " + name_index + ", signature_index = " + signature_index + ")"; + } + + @Override + public String getValue() { + return toString(); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantObject.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantObject.java new file mode 100644 index 000000000..70e9b1d0d --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantObject.java @@ -0,0 +1,66 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * This interface denotes those constants that have a "natural" value, such as ConstantLong, ConstantString, etc.. + * + * @version $Id: ConstantObject.java,v 1.4 2009/09/10 03:59:33 aclement Exp $ + * @author M. Dahm + * @see Constant + */ +public interface ConstantObject { + public abstract Object getConstantValue(ConstantPool cp); +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPackage.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPackage.java new file mode 100644 index 000000000..70f22c749 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPackage.java @@ -0,0 +1,111 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Represents a module. + * + * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.12 + * + * @author Andy Clement + */ +public final class ConstantPackage extends Constant { + + private int nameIndex; + + ConstantPackage(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + + public ConstantPackage(int nameIndex) { + super(Constants.CONSTANT_Package); + this.nameIndex = nameIndex; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantPackage(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(nameIndex); + } + + @Override + public Integer getValue() { + return nameIndex; + } + + public final int getNameIndex() { + return nameIndex; + } + + @Override + public final String toString() { + return super.toString() + "(name_index = " + nameIndex + ")"; + } + + public String getPackageName(ConstantPool cpool) { + Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getValue(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPool.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPool.java new file mode 100644 index 000000000..0430e28ba --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPool.java @@ -0,0 +1,816 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.generic.ArrayType; +import org.aspectj.apache.bcel.generic.ObjectType; + +/** + * This class represents the constant pool, i.e., a table of constants, of a parsed classfile. It may contain null references, due + * to the JVM specification that skips an entry after an 8-byte constant (double, long) entry. + */ +public class ConstantPool implements Node { + private Constant[] pool; + private int poolSize; // number of entries in the pool (could be < pool.length as the array is resized in 'chunks') + + private Map utf8Cache = new HashMap(); + private Map methodCache = new HashMap(); + private Map fieldCache = new HashMap(); + + public int getSize() { + return poolSize; + } + + public ConstantPool() { + pool = new Constant[10]; + poolSize = 0; + } + + public ConstantPool(Constant[] constants) { + pool = constants; + poolSize = (constants == null ? 0 : constants.length); + } + + ConstantPool(DataInputStream file) throws IOException { + byte tag; + poolSize = file.readUnsignedShort(); + pool = new Constant[poolSize]; + // pool[0] is unused by the compiler and may be used freely by the implementation + for (int i = 1; i < poolSize; i++) { + pool[i] = Constant.readConstant(file); + tag = pool[i].getTag(); + if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) { + i++; + } + } + } + + public Constant getConstant(int index, byte tag) { + Constant c = getConstant(index); + // if (c == null) throw new ClassFormatException("Constant pool at index " + index + " is null."); + if (c.tag == tag) + return c; + throw new ClassFormatException("Expected class '" + Constants.CONSTANT_NAMES[tag] + "' at index " + index + " and found " + + c); + } + + public Constant getConstant(int index) { + try { + return pool[index]; + } catch (ArrayIndexOutOfBoundsException aioobe) { + throw new ClassFormatException("Index " + index + " into constant pool (size:" + poolSize + ") is invalid"); + } + } + + /** + * @return deep copy of this constant pool + */ + public ConstantPool copy() { + Constant[] newConstants = new Constant[poolSize]; // use the correct size + for (int i = 1; i < poolSize; i++) { + if (pool[i] != null) { + newConstants[i] = pool[i].copy(); + } + } + return new ConstantPool(newConstants); + } + + /** + * Get string from constant pool and bypass the indirection of `ConstantClass' and `ConstantString' objects. I.e. these classes + * have an index field that points to another entry of the constant pool of type `ConstantUtf8' which contains the real data. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, either ConstantClass or ConstantString + * @return Contents of string reference + * @see ConstantClass + * @see ConstantString + * @throws ClassFormatException + */ + public String getConstantString(int index, byte tag) throws ClassFormatException { + Constant c = getConstant(index, tag); + int i; + /* + * This switch() is not that elegant, since the two classes have the same contents, they just differ in the name of the + * index field variable. But we want to stick to the JVM naming conventions closely though we could have solved these more + * elegantly by using the same variable name or by subclassing. + */ + // OPTIMIZE remove the difference - use the an interface and same index methods for string ref id + switch (tag) { + case Constants.CONSTANT_Class: + i = ((ConstantClass) c).getNameIndex(); + break; + case Constants.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + break; + default: + throw new RuntimeException("getConstantString called with illegal tag " + tag); + } + // Finally get the string from the constant pool + c = getConstant(i, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getValue(); + } + + /** + * Resolve constant to a string representation. + */ + public String constantToString(Constant c) { + String str; + int i; + + switch (c.tag) { + case Constants.CONSTANT_Class: + i = ((ConstantClass) c).getNameIndex(); + c = getConstant(i, Constants.CONSTANT_Utf8); + str = Utility.compactClassName(((ConstantUtf8) c).getValue(), false); + break; + + case Constants.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + c = getConstant(i, Constants.CONSTANT_Utf8); + str = "\"" + escape(((ConstantUtf8) c).getValue()) + "\""; + break; + + case Constants.CONSTANT_Utf8: + case Constants.CONSTANT_Double: + case Constants.CONSTANT_Float: + case Constants.CONSTANT_Long: + case Constants.CONSTANT_Integer: + str = ((SimpleConstant) c).getStringValue(); + break; + + case Constants.CONSTANT_NameAndType: + str = (constantToString(((ConstantNameAndType) c).getNameIndex(), Constants.CONSTANT_Utf8) + " " + constantToString( + ((ConstantNameAndType) c).getSignatureIndex(), Constants.CONSTANT_Utf8)); + break; + + case Constants.CONSTANT_InterfaceMethodref: + case Constants.CONSTANT_Methodref: + case Constants.CONSTANT_Fieldref: + str = (constantToString(((ConstantCP) c).getClassIndex(), Constants.CONSTANT_Class) + "." + constantToString( + ((ConstantCP) c).getNameAndTypeIndex(), Constants.CONSTANT_NameAndType)); + break; + + case Constants.CONSTANT_InvokeDynamic: + ConstantInvokeDynamic cID = ((ConstantInvokeDynamic)c); + return "#"+cID.getBootstrapMethodAttrIndex()+"."+constantToString(cID.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType); + + case Constants.CONSTANT_MethodHandle: + ConstantMethodHandle cMH = ((ConstantMethodHandle)c); + return cMH.getReferenceKind()+":"+constantToString(cMH.getReferenceIndex(),Constants.CONSTANT_Methodref); + + case Constants.CONSTANT_MethodType: + ConstantMethodType cMT = (ConstantMethodType)c; + return constantToString(cMT.getDescriptorIndex(),Constants.CONSTANT_Utf8); + + case Constants.CONSTANT_Module: + ConstantModule cM = (ConstantModule)c; + return "Module:"+constantToString(cM.getNameIndex(),Constants.CONSTANT_Utf8); + + case Constants.CONSTANT_Package: + ConstantPackage cP = (ConstantPackage)c; + return "Package:"+constantToString(cP.getNameIndex(),Constants.CONSTANT_Utf8); + + default: // Never reached + throw new RuntimeException("Unknown constant type " + c.tag); + } + + return str; + } + + private static final String escape(String str) { + int len = str.length(); + StringBuffer buf = new StringBuffer(len + 5); + char[] ch = str.toCharArray(); + + for (int i = 0; i < len; i++) { + switch (ch[i]) { + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + case '\t': + buf.append("\\t"); + break; + case '\b': + buf.append("\\b"); + break; + case '"': + buf.append("\\\""); + break; + default: + buf.append(ch[i]); + } + } + + return buf.toString(); + } + + public String constantToString(int index, byte tag) { + Constant c = getConstant(index, tag); + return constantToString(c); + } + + public String constantToString(int index) { + return constantToString(getConstant(index)); + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantPool(this); + } + + public Constant[] getConstantPool() { + return pool; + } // TEMPORARY, DONT LIKE PASSING THIS DATA OUT! + + public void dump(DataOutputStream file) throws IOException { + file.writeShort(poolSize); + for (int i = 1; i < poolSize; i++) + if (pool[i] != null) + pool[i].dump(file); + } + + public ConstantUtf8 getConstantUtf8(int index) { + Constant c = getConstant(index); + assert c != null; + assert c.tag == Constants.CONSTANT_Utf8; + return (ConstantUtf8) c; + } + + public ConstantModule getConstantModule(int index) { + Constant c = getConstant(index); + assert c != null; + assert c.tag == Constants.CONSTANT_Module; + return (ConstantModule)c; + } + + public ConstantPackage getConstantPackage(int index) { + Constant c = getConstant(index); + assert c != null; + assert c.tag == Constants.CONSTANT_Package; + return (ConstantPackage)c; + } + + public String getConstantString_CONSTANTClass(int index) { + ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class); + index = c.getNameIndex(); + return ((ConstantUtf8) getConstant(index, Constants.CONSTANT_Utf8)).getValue(); + } + + public int getLength() { + return poolSize; + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + + for (int i = 1; i < poolSize; i++) + buf.append(i + ")" + pool[i] + "\n"); + + return buf.toString(); + } + + public int lookupInteger(int n) { + for (int i = 1; i < poolSize; i++) { + if (pool[i] instanceof ConstantInteger) { + ConstantInteger c = (ConstantInteger) pool[i]; + if (c.getValue() == n) + return i; + } + } + return -1; + } + + public int lookupUtf8(String string) { + Integer pos = utf8Cache.get(string); + if (pos != null) { + return pos; + } + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_Utf8) { + if (((ConstantUtf8) c).getValue().equals(string)) { + utf8Cache.put(string, i); + return i; + } + } + } + return -1; + } + + public int lookupClass(String classname) { + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_Class) { + int cIndex = ((ConstantClass) c).getNameIndex(); + String cName = ((ConstantUtf8) pool[cIndex]).getValue(); + if (cName.equals(classname)) + return i; + } + } + return -1; + } + + public int addUtf8(String n) { + int ret = lookupUtf8(n); + if (ret != -1) + return ret; + adjustSize(); + ret = poolSize; + pool[poolSize++] = new ConstantUtf8(n); + return ret; + } + + public int addInteger(int n) { + int ret = lookupInteger(n); + if (ret != -1) + return ret; + adjustSize(); + ret = poolSize; + pool[poolSize++] = new ConstantInteger(n); + return ret; + } + + public int addArrayClass(ArrayType type) { + return addClass(type.getSignature()); + } + + public int addClass(ObjectType type) { + return addClass(type.getClassName()); + } + + public int addClass(String classname) { + String toAdd = classname.replace('.', '/'); + int ret = lookupClass(toAdd); + if (ret != -1) + return ret; + adjustSize(); + ConstantClass c = new ConstantClass(addUtf8(toAdd)); + ret = poolSize; + pool[poolSize++] = c; + return ret; + } + + private void adjustSize() { + if (poolSize + 3 >= pool.length) { + Constant[] cs = pool; + pool = new Constant[cs.length + 8]; + System.arraycopy(cs, 0, pool, 0, cs.length); + } + if (poolSize == 0) + poolSize = 1; // someone about to do something in here! + } + + public int addFieldref(String class_name, String field_name, String signature) { + int ret = lookupFieldref(class_name, field_name, signature); + int class_index, name_and_type_index; + + if (ret != -1) + return ret; + + adjustSize(); + + class_index = addClass(class_name); + name_and_type_index = addNameAndType(field_name, signature); + ret = poolSize; + pool[poolSize++] = new ConstantFieldref(class_index, name_and_type_index); + + return ret; + } + + public int lookupFieldref(String searchClassname, String searchFieldname, String searchSignature) { + searchClassname = searchClassname.replace('.', '/'); + String k = new StringBuffer().append(searchClassname).append(searchFieldname).append(searchSignature).toString(); + Integer pos = fieldCache.get(k); + if (pos != null) + return pos.intValue(); + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_Fieldref) { + ConstantFieldref cfr = (ConstantFieldref) c; + ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; + + // check the class + int cIndex = cfr.getClassIndex(); + ConstantClass cc = (ConstantClass) pool[cIndex]; + String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); + if (!cName.equals(searchClassname)) + continue; + + // check the name and type + String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); + if (!name.equals(searchFieldname)) + continue; // not this one + String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); + if (!typeSignature.equals(searchSignature)) + continue; + fieldCache.put(k, new Integer(i)); + return i; + } + } + return -1; + } + + public int addNameAndType(String name, String signature) { + int ret = lookupNameAndType(name, signature); + if (ret != -1) + return ret; + adjustSize(); + int name_index = addUtf8(name); + int signature_index = addUtf8(signature); + ret = poolSize; + pool[poolSize++] = new ConstantNameAndType(name_index, signature_index); + return ret; + } + + public int lookupNameAndType(String searchName, String searchTypeSignature) { + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_NameAndType) { + ConstantNameAndType cnat = (ConstantNameAndType) c; + String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); + if (!name.equals(searchName)) + continue; // not this one + String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); + if (!typeSignature.equals(searchTypeSignature)) + continue; + return i; + } + } + return -1; + } + + public int addFloat(float f) { + int ret = lookupFloat(f); + if (ret != -1) + return ret; + adjustSize(); + ret = poolSize; + pool[poolSize++] = new ConstantFloat(f); + return ret; + } + + public int lookupFloat(float f) { + int bits = Float.floatToIntBits(f); + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_Float) { + ConstantFloat cf = (ConstantFloat) c; + if (Float.floatToIntBits(cf.getValue()) == bits) + return i; + } + } + return -1; + } + + public int addDouble(double d) { + int ret = lookupDouble(d); + if (ret != -1) + return ret; + adjustSize(); + ret = poolSize; + pool[poolSize] = new ConstantDouble(d); + poolSize += 2; + return ret; + } + + public int lookupDouble(double d) { + long bits = Double.doubleToLongBits(d); + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_Double) { + ConstantDouble cf = (ConstantDouble) c; + if (Double.doubleToLongBits(cf.getValue()) == bits) + return i; + } + } + return -1; + } + + public int addLong(long l) { + int ret = lookupLong(l); + if (ret != -1) + return ret; + adjustSize(); + ret = poolSize; + pool[poolSize] = new ConstantLong(l); + poolSize += 2; + return ret; + } + + public int lookupString(String s) { + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_String) { + ConstantString cs = (ConstantString) c; + ConstantUtf8 cu8 = (ConstantUtf8) pool[cs.getStringIndex()]; + if (cu8.getValue().equals(s)) + return i; + } + } + return -1; + } + + public int addString(String str) { + int ret = lookupString(str); + if (ret != -1) + return ret; + int utf8 = addUtf8(str); + adjustSize(); + ConstantString s = new ConstantString(utf8); + ret = poolSize; + pool[poolSize++] = s; + return ret; + } + + public int lookupLong(long l) { + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_Long) { + ConstantLong cf = (ConstantLong) c; + if (cf.getValue() == l) + return i; + } + } + return -1; + } + + public int addConstant(Constant c, ConstantPool cp) { + Constant[] constants = cp.getConstantPool(); + switch (c.getTag()) { + + case Constants.CONSTANT_String: { + ConstantString s = (ConstantString) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; + + return addString(u8.getValue()); + } + + case Constants.CONSTANT_Class: { + ConstantClass s = (ConstantClass) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; + + return addClass(u8.getValue()); + } + + case Constants.CONSTANT_NameAndType: { + ConstantNameAndType n = (ConstantNameAndType) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; + ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; + + return addNameAndType(u8.getValue(), u8_2.getValue()); + } + + case Constants.CONSTANT_InvokeDynamic: { + ConstantInvokeDynamic cid = (ConstantInvokeDynamic)c; + int index1 = cid.getBootstrapMethodAttrIndex(); + ConstantNameAndType cnat = (ConstantNameAndType)constants[cid.getNameAndTypeIndex()]; + ConstantUtf8 name = (ConstantUtf8) constants[cnat.getNameIndex()]; + ConstantUtf8 signature = (ConstantUtf8) constants[cnat.getSignatureIndex()]; + int index2 = addNameAndType(name.getValue(), signature.getValue()); + return addInvokeDynamic(index1,index2); + } + + case Constants.CONSTANT_MethodHandle: + ConstantMethodHandle cmh = (ConstantMethodHandle)c; + return addMethodHandle(cmh.getReferenceKind(),addConstant(constants[cmh.getReferenceIndex()],cp)); + + case Constants.CONSTANT_Utf8: + return addUtf8(((ConstantUtf8) c).getValue()); + + case Constants.CONSTANT_Double: + return addDouble(((ConstantDouble) c).getValue()); + + case Constants.CONSTANT_Float: + return addFloat(((ConstantFloat) c).getValue()); + + case Constants.CONSTANT_Long: + return addLong(((ConstantLong) c).getValue()); + + case Constants.CONSTANT_Integer: + return addInteger(((ConstantInteger) c).getValue()); + + case Constants.CONSTANT_MethodType: + ConstantMethodType cmt = (ConstantMethodType)c; + return addMethodType(addConstant(constants[cmt.getDescriptorIndex()],cp)); + + case Constants.CONSTANT_InterfaceMethodref: + case Constants.CONSTANT_Methodref: + case Constants.CONSTANT_Fieldref: { + ConstantCP m = (ConstantCP) c; + ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; + ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + String class_name = u8.getValue().replace('/', '.'); + + u8 = (ConstantUtf8) constants[n.getNameIndex()]; + String name = u8.getValue(); + + u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; + String signature = u8.getValue(); + + switch (c.getTag()) { + case Constants.CONSTANT_InterfaceMethodref: + return addInterfaceMethodref(class_name, name, signature); + + case Constants.CONSTANT_Methodref: + return addMethodref(class_name, name, signature); // OPTIMIZE indicate it should be cached! + + case Constants.CONSTANT_Fieldref: + return addFieldref(class_name, name, signature); + + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } + } + + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } + } + + public int addMethodHandle(byte referenceKind, int referenceIndex) { + adjustSize(); + int ret = poolSize; + pool[poolSize++] = new ConstantMethodHandle(referenceKind, referenceIndex); + return ret; + } + + public int addMethodType(int descriptorIndex) { + adjustSize(); + int ret = poolSize; + pool[poolSize++] = new ConstantMethodType(descriptorIndex); + return ret; + } + + // OPTIMIZE should put it in the cache now + public int addMethodref(String class_name, String method_name, String signature) { + int ret, class_index, name_and_type_index; + if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) + return ret; // Already in CP + + adjustSize(); + + name_and_type_index = addNameAndType(method_name, signature); + class_index = addClass(class_name); + ret = poolSize; + pool[poolSize++] = new ConstantMethodref(class_index, name_and_type_index); + return ret; + } + + public int addInvokeDynamic(int bootstrapMethodIndex, int constantNameAndTypeIndex) { + adjustSize(); + int ret = poolSize; + pool[poolSize++] = new ConstantInvokeDynamic(bootstrapMethodIndex, constantNameAndTypeIndex); + return ret; + } + + public int addInterfaceMethodref(String class_name, String method_name, String signature) { + int ret = lookupInterfaceMethodref(class_name, method_name, signature); + int class_index, name_and_type_index; + + if (ret != -1) + return ret; + adjustSize(); + + class_index = addClass(class_name); + name_and_type_index = addNameAndType(method_name, signature); + ret = poolSize; + pool[poolSize++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); + return ret; + } + + public int lookupInterfaceMethodref(String searchClassname, String searchMethodName, String searchSignature) { + searchClassname = searchClassname.replace('.', '/'); + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_InterfaceMethodref) { + ConstantInterfaceMethodref cfr = (ConstantInterfaceMethodref) c; + + ConstantClass cc = (ConstantClass) pool[cfr.getClassIndex()]; + String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); + if (!cName.equals(searchClassname)) + continue; + + // check the name and type + ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; + String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); + if (!name.equals(searchMethodName)) + continue; // not this one + String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); + if (!typeSignature.equals(searchSignature)) + continue; + return i; + } + } + return -1; + } + + public int lookupMethodref(String searchClassname, String searchMethodName, String searchSignature) { + String key = new StringBuffer().append(searchClassname).append(searchMethodName).append(searchSignature).toString(); + Integer cached = methodCache.get(key); + if (cached != null) + return cached.intValue(); + searchClassname = searchClassname.replace('.', '/'); + for (int i = 1; i < poolSize; i++) { + Constant c = pool[i]; + if (c != null && c.tag == Constants.CONSTANT_Methodref) { + ConstantMethodref cfr = (ConstantMethodref) c; + ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; + + // check the class + int cIndex = cfr.getClassIndex(); + ConstantClass cc = (ConstantClass) pool[cIndex]; + String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); + if (!cName.equals(searchClassname)) + continue; + + // check the name and type + String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); + if (!name.equals(searchMethodName)) + continue; // not this one + String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); + if (!typeSignature.equals(searchSignature)) + continue; + methodCache.put(key, new Integer(i)); + return i; + } + } + return -1; + } + + public ConstantPool getFinalConstantPool() { + Constant[] cs = new Constant[poolSize]; // create it the exact size we need + System.arraycopy(pool, 0, cs, 0, poolSize); + return new ConstantPool(cs); + } + + public String getModuleName(int moduleIndex) { + return getConstantModule(moduleIndex).getModuleName(this); + } + + public String getPackageName(int packageIndex) { + return getConstantPackage(packageIndex).getPackageName(this); + } +} \ No newline at end of file diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantString.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantString.java new file mode 100644 index 000000000..ef9da55db --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantString.java @@ -0,0 +1,120 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to a String object. + * + * @version $Id: ConstantString.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @see Constant + */ +public final class ConstantString extends Constant { + + private int stringIndex; + + ConstantString(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + + public ConstantString(int stringIndex) { + super(Constants.CONSTANT_String); + this.stringIndex = stringIndex; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantString(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(stringIndex); + } + + // OPTIMIZE fix duplication in these next two methods + /** + * @return the index of the string in the constant pool + */ + @Override + public Integer getValue() { + return stringIndex; + } + + public final int getStringIndex() { + return stringIndex; + } + + @Override + public final String toString() { + return super.toString() + "(string_index = " + stringIndex + ")"; + } + + /** + * @return the string, as dereferenced using the internal index into the supplied constant pool + */ + public String getString(ConstantPool cpool) { + Constant c = cpool.getConstant(stringIndex, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getValue(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantUtf8.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantUtf8.java new file mode 100644 index 000000000..f8200db47 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantUtf8.java @@ -0,0 +1,109 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from the abstract Constant class and + * represents a reference to a Utf8 encoded string. + * + * @version $Id: ConstantUtf8.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @see Constant + */ +public final class ConstantUtf8 extends Constant implements SimpleConstant { + private String string; + + ConstantUtf8(DataInputStream file) throws IOException { + super(Constants.CONSTANT_Utf8); + string = file.readUTF(); + } + + public ConstantUtf8(String string) { + super(Constants.CONSTANT_Utf8); + assert string != null; + this.string = string; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantUtf8(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeUTF(string); + } + + @Override + public final String toString() { + return super.toString() + "(\"" + Utility.replace(string, "\n", "\\n") + "\")"; + } + + @Override + public String getValue() { + return string; + } + + public String getStringValue() { + return string; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantValue.java new file mode 100644 index 000000000..730e8aff0 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantValue.java @@ -0,0 +1,131 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from Attribute and represents a constant value, i.e., a default value for initializing a class + * field. This class is instantiated by the Attribute.readAttribute() method. + * + * @version $Id: ConstantValue.java,v 1.6 2009/09/16 00:43:49 aclement Exp $ + * @author M. Dahm + * @see Attribute + */ +public final class ConstantValue extends Attribute { + private int constantvalue_index; + + ConstantValue(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, file.readUnsignedShort(), constant_pool); + } + + public ConstantValue(int name_index, int length, int constantvalue_index, ConstantPool constant_pool) { + super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); + this.constantvalue_index = constantvalue_index; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantValue(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(constantvalue_index); + } + + public final int getConstantValueIndex() { + return constantvalue_index; + } + + @Override + public final String toString() { + Constant c = cpool.getConstant(constantvalue_index); + + String buf; + int i; + + // Print constant to string depending on its type + switch (c.getTag()) { + case Constants.CONSTANT_Long: + buf = "" + ((ConstantLong) c).getValue(); + break; + case Constants.CONSTANT_Float: + buf = "" + ((ConstantFloat) c).getValue(); + break; + case Constants.CONSTANT_Double: + buf = "" + ((ConstantDouble) c).getValue(); + break; + case Constants.CONSTANT_Integer: + buf = "" + ((ConstantInteger) c).getValue(); + break; + case Constants.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + c = cpool.getConstant(i, Constants.CONSTANT_Utf8); + buf = "\"" + Utility.convertString(((ConstantUtf8) c).getValue()) + "\""; + break; + + default: + throw new IllegalStateException("Type of ConstValue invalid: " + c); + } + + return buf; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Deprecated.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Deprecated.java new file mode 100644 index 000000000..21bbbcb46 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Deprecated.java @@ -0,0 +1,171 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from Attribute and denotes that this is a deprecated method. It is instantiated from the + * Attribute.readAttribute() method. + * + * @version $Id: Deprecated.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Attribute + */ +public final class Deprecated extends Attribute { + private byte[] bytes; + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical + * copy. + */ + public Deprecated(Deprecated c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param bytes Attribute contents + * @param constant_pool Array of constants + */ + public Deprecated(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { + super(Constants.ATTR_DEPRECATED, name_index, length, constant_pool); + this.bytes = bytes; + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Deprecated(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + + if (length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + System.err.println("Deprecated attribute with length > 0"); + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitDeprecated(this); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + + if (length > 0) + file.write(bytes, 0, length); + } + + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } + + /** + * @param bytes. + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + /** + * @return attribute name + */ + @Override + public final String toString() { + return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED]; + } + + // /** + // * @return deep copy of this attribute + // */ + // public Attribute copy(ConstantPool constant_pool) { + // Deprecated c = (Deprecated)clone(); + // + // if(bytes != null) + // c.bytes = (byte[])bytes.clone(); + // + // c.cpool = constant_pool; + // return c; + // } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/EnclosingMethod.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/EnclosingMethod.java new file mode 100644 index 000000000..9e1554ec5 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/EnclosingMethod.java @@ -0,0 +1,87 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This attribute exists for local or + * anonymous classes and ... there can be only one. + */ +public class EnclosingMethod extends Attribute { + + // Pointer to the CONSTANT_Class_info structure representing the + // innermost class that encloses the declaration of the current class. + private int classIndex; + + // If the current class is not immediately enclosed by a method or + // constructor, then the value of the method_index item must be zero. + // Otherwise, the value of the method_index item must point to a + // CONSTANT_NameAndType_info structure representing the name and the + // type of a method in the class referenced by the class we point + // to in the class_index. *It is the compiler responsibility* to + // ensure that the method identified by this index is the closest + // lexically enclosing method that includes the local/anonymous class. + private int methodIndex; + + // Ctors - and code to read an attribute in. + public EnclosingMethod(int nameIndex, int len, DataInputStream dis, ConstantPool cpool) throws IOException { + this(nameIndex, len, dis.readUnsignedShort(), dis.readUnsignedShort(), cpool); + } + + private EnclosingMethod(int nameIndex, int len, int classIdx,int methodIdx, ConstantPool cpool) { + super(Constants.ATTR_ENCLOSING_METHOD, nameIndex, len, cpool); + classIndex = classIdx; + methodIndex = methodIdx; + } + + public void accept(ClassVisitor v) { + v.visitEnclosingMethod(this); + } + + public Attribute copy(ConstantPool constant_pool) { + throw new RuntimeException("Not implemented yet!"); + // is this next line sufficient? + // return (EnclosingMethod)clone(); + } + + // Accessors + public final int getEnclosingClassIndex() { return classIndex; } + public final int getEnclosingMethodIndex(){ return methodIndex;} + + public final void setEnclosingClassIndex(int idx) {classIndex = idx;} + public final void setEnclosingMethodIndex(int idx){methodIndex= idx;} + + public final ConstantClass getEnclosingClass() { + ConstantClass c = + (ConstantClass)cpool.getConstant(classIndex,Constants.CONSTANT_Class); + return c; + } + + public final ConstantNameAndType getEnclosingMethod() { + if (methodIndex == 0) return null; + ConstantNameAndType nat = + (ConstantNameAndType)cpool.getConstant(methodIndex,Constants.CONSTANT_NameAndType); + return nat; + } + + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(classIndex); + file.writeShort(methodIndex); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ExceptionTable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ExceptionTable.java new file mode 100644 index 000000000..ad7d43f2e --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ExceptionTable.java @@ -0,0 +1,199 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents the table of exceptions that are thrown by a method. This attribute may be used once per method. The name + * of this class is ExceptionTable for historical reasons; The Java Virtual Machine Specification, Second Edition defines + * this attribute using the name Exceptions (which is inconsistent with the other classes). + * + * @version $Id: ExceptionTable.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Code + */ +public final class ExceptionTable extends Attribute { + private int number_of_exceptions; // Table of indices into + private int[] exception_index_table; // constant pool + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical + * copy. + */ + public ExceptionTable(ExceptionTable c) { + this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param exception_index_table Table of indices in constant pool + * @param constant_pool Array of constants + */ + public ExceptionTable(int name_index, int length, int[] exception_index_table, ConstantPool constant_pool) { + super(Constants.ATTR_EXCEPTIONS, name_index, length, constant_pool); + setExceptionIndexTable(exception_index_table); + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + ExceptionTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, (int[]) null, constant_pool); + + number_of_exceptions = file.readUnsignedShort(); + exception_index_table = new int[number_of_exceptions]; + + for (int i = 0; i < number_of_exceptions; i++) + exception_index_table[i] = file.readUnsignedShort(); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitExceptionTable(this); + } + + /** + * Dump exceptions attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(number_of_exceptions); + for (int i = 0; i < number_of_exceptions; i++) + file.writeShort(exception_index_table[i]); + } + + /** + * @return Array of indices into constant pool of thrown exceptions. + */ + public final int[] getExceptionIndexTable() { + return exception_index_table; + } + + /** + * @return Length of exception table. + */ + public final int getNumberOfExceptions() { + return number_of_exceptions; + } + + /** + * @return class names of thrown exceptions + */ + public final String[] getExceptionNames() { + String[] names = new String[number_of_exceptions]; + for (int i = 0; i < number_of_exceptions; i++) + names[i] = cpool.getConstantString(exception_index_table[i], Constants.CONSTANT_Class).replace('/', '.'); + return names; + } + + /** + * @param exception_index_table. Also redefines number_of_exceptions according to table length. + */ + public final void setExceptionIndexTable(int[] exception_index_table) { + this.exception_index_table = exception_index_table; + number_of_exceptions = (exception_index_table == null) ? 0 : exception_index_table.length; + } + + /** + * @return String representation, i.e., a list of thrown exceptions. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(""); + String str; + + for (int i = 0; i < number_of_exceptions; i++) { + str = cpool.getConstantString(exception_index_table[i], Constants.CONSTANT_Class); + buf.append(Utility.compactClassName(str, false)); + + if (i < number_of_exceptions - 1) + buf.append(", "); + } + + return buf.toString(); + } + + // /** + // * @return deep copy of this attribute + // */ + // public Attribute copy(ConstantPool constant_pool) { + // ExceptionTable c = (ExceptionTable)clone(); + // c.exception_index_table = (int[])exception_index_table.clone(); + // c.cpool = constant_pool; + // return c; + // } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Field.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Field.java new file mode 100644 index 000000000..f34464375 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Field.java @@ -0,0 +1,136 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataInputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.generic.Type; + +/** + * This class represents the field info structure, i.e., the representation for a variable in the class. See JVM specification for + * details. + * + * @version $Id: Field.java,v 1.6 2009/09/15 03:33:52 aclement Exp $ + * @author M. Dahm + */ +public final class Field extends FieldOrMethod { + + public static final Field[] NoFields = new Field[0]; + + private Type fieldType = null; // lazily initialized + + private Field() { + } + + public Field(Field c) { + super(c); + } + + Field(DataInputStream dis, ConstantPool cpool) throws IOException { + super(dis, cpool); + } + + public Field(int modifiers, int nameIndex, int signatureIndex, Attribute[] attributes, ConstantPool cpool) { + super(modifiers, nameIndex, signatureIndex, attributes, cpool); + } + + public void accept(ClassVisitor v) { + v.visitField(this); + } + + /** + * @return constant value associated with this field (may be null) + */ + public final ConstantValue getConstantValue() { + return AttributeUtils.getConstantValueAttribute(attributes); + } + + /** + * Return string representation close to declaration format, eg: 'public static final short MAX = 100' + */ + @Override + public final String toString() { + // Get names from constant pool + StringBuffer buf = new StringBuffer(Utility.accessToString(modifiers)); + if (buf.length() > 0) { + buf.append(" "); + } + String signature = Utility.signatureToString(getSignature()); + + buf.append(signature).append(" ").append(getName()); + + ConstantValue cv = getConstantValue(); + if (cv != null) { + buf.append(" = ").append(cv); + } + + // append all attributes that are *not* "ConstantValue" + for (Attribute a : attributes) { + if (!(a instanceof ConstantValue)) { + buf.append(" [").append(a.toString()).append("]"); + } + } + + return buf.toString(); + } + + /** return the type of the field */ + public Type getType() { + if (fieldType == null) { + fieldType = Type.getReturnType(getSignature()); + } + return fieldType; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/FieldOrMethod.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/FieldOrMethod.java new file mode 100644 index 000000000..a152b616f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/FieldOrMethod.java @@ -0,0 +1,201 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; + +/** + * Abstract super class for fields and methods. + * + * @version $Id: FieldOrMethod.java,v 1.12 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + */ +public abstract class FieldOrMethod extends Modifiers implements Node { + protected int nameIndex; + protected int signatureIndex; + protected Attribute[] attributes; + + protected ConstantPool cpool; + private String name; // lazily initialized + private String signature; // lazily initialized + private AnnotationGen[] annotations; // lazily initialized + private String signatureAttributeString = null; + private boolean searchedForSignatureAttribute = false; + + protected FieldOrMethod() { + } + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical + * copy. + */ + protected FieldOrMethod(FieldOrMethod c) { + this(c.getModifiers(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c.getConstantPool()); + } + + protected FieldOrMethod(DataInputStream file, ConstantPool cpool) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, cpool); + attributes = AttributeUtils.readAttributes(file, cpool); + } + + protected FieldOrMethod(int accessFlags, int nameIndex, int signatureIndex, Attribute[] attributes, ConstantPool cpool) { + this.modifiers = accessFlags; + this.nameIndex = nameIndex; + this.signatureIndex = signatureIndex; + this.cpool = cpool; + this.attributes = attributes; + } + + /** + * @param attributes Collection of object attributes. + */ + public void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + } + + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(modifiers); + file.writeShort(nameIndex); + file.writeShort(signatureIndex); + AttributeUtils.writeAttributes(attributes, file); + } + + public final Attribute[] getAttributes() { + return attributes; + } + + public final ConstantPool getConstantPool() { + return cpool; + } + + public final int getNameIndex() { + return nameIndex; + } + + public final int getSignatureIndex() { + return signatureIndex; + } + + public final String getName() { + if (name == null) { + ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); + name = c.getValue(); + } + return name; + } + + public final String getSignature() { + if (signature == null) { + ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(signatureIndex, Constants.CONSTANT_Utf8); + signature = c.getValue(); + } + return signature; + } + + /** + * This will return the contents of a signature attribute attached to a member, or if there is none it will return the same as + * 'getSignature()'. Signature attributes are attached to members that were declared generic. + */ + public final String getDeclaredSignature() { + if (getGenericSignature() != null) + return getGenericSignature(); + return getSignature(); + } + + public AnnotationGen[] getAnnotations() { + // Ensure we have unpacked any attributes that contain annotations. + // We don't remove these annotation attributes from the attributes list, they + // remain there. + if (annotations == null) { + // Find attributes that contain annotation data + List accumulatedAnnotations = new ArrayList(); + for (int i = 0; i < attributes.length; i++) { + Attribute attribute = attributes[i]; + if (attribute instanceof RuntimeAnnos) { + RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attribute; + accumulatedAnnotations.addAll(runtimeAnnotations.getAnnotations()); + } + } + if (accumulatedAnnotations.size() == 0) { + annotations = AnnotationGen.NO_ANNOTATIONS; + } else { + annotations = accumulatedAnnotations.toArray(new AnnotationGen[] {}); + } + } + return annotations; + } + + /** + * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature may be + * (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector;' Coded for performance - + * searches for the attribute only when requested - only searches for it once. + */ + public final String getGenericSignature() { + if (!searchedForSignatureAttribute) { + Signature sig = AttributeUtils.getSignatureAttribute(attributes); + signatureAttributeString = (sig == null ? null : sig.getSignature()); + searchedForSignatureAttribute = true; + } + return signatureAttributeString; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClass.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClass.java new file mode 100644 index 000000000..d3b1eb0a8 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClass.java @@ -0,0 +1,232 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a inner class attribute, i.e., the class indices of the inner and outer classes, the name and the + * attributes of the inner class. + * + * @version $Id: InnerClass.java,v 1.4 2009/09/10 15:35:05 aclement Exp $ + * @author M. Dahm + * @see InnerClasses + */ +public final class InnerClass implements Cloneable, Node { + private int inner_class_index; + private int outer_class_index; + private int inner_name_index; + private int inner_access_flags; + + /** + * Initialize from another object. + */ + public InnerClass(InnerClass c) { + this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c.getInnerAccessFlags()); + } + + /** + * Construct object from file stream. + * + * @param file Input stream + * @throws IOException + */ + InnerClass(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort()); + } + + /** + * @param inner_class_index Class index in constant pool of inner class + * @param outer_class_index Class index in constant pool of outer class + * @param inner_name_index Name index in constant pool of inner class + * @param inner_access_flags Access flags of inner class + */ + public InnerClass(int inner_class_index, int outer_class_index, int inner_name_index, int inner_access_flags) { + this.inner_class_index = inner_class_index; + this.outer_class_index = outer_class_index; + this.inner_name_index = inner_name_index; + this.inner_access_flags = inner_access_flags; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(ClassVisitor v) { + v.visitInnerClass(this); + } + + /** + * Dump inner class attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(inner_class_index); + file.writeShort(outer_class_index); + file.writeShort(inner_name_index); + file.writeShort(inner_access_flags); + } + + /** + * @return access flags of inner class. + */ + public final int getInnerAccessFlags() { + return inner_access_flags; + } + + /** + * @return class index of inner class. + */ + public final int getInnerClassIndex() { + return inner_class_index; + } + + /** + * @return name index of inner class. + */ + public final int getInnerNameIndex() { + return inner_name_index; + } + + /** + * @return class index of outer class. + */ + public final int getOuterClassIndex() { + return outer_class_index; + } + + /** + * @param inner_access_flags. + */ + public final void setInnerAccessFlags(int inner_access_flags) { + this.inner_access_flags = inner_access_flags; + } + + /** + * @param inner_class_index. + */ + public final void setInnerClassIndex(int inner_class_index) { + this.inner_class_index = inner_class_index; + } + + /** + * @param inner_name_index. + */ + public final void setInnerNameIndex(int inner_name_index) { + this.inner_name_index = inner_name_index; + } + + /** + * @param outer_class_index. + */ + public final void setOuterClassIndex(int outer_class_index) { + this.outer_class_index = outer_class_index; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + return "InnerClass(" + inner_class_index + ", " + outer_class_index + ", " + inner_name_index + ", " + inner_access_flags + + ")"; + } + + /** + * @return Resolved string representation + */ + public final String toString(ConstantPool constant_pool) { + String inner_class_name, outer_class_name, inner_name, access; + + inner_class_name = constant_pool.getConstantString(inner_class_index, Constants.CONSTANT_Class); + inner_class_name = Utility.compactClassName(inner_class_name); + + if (outer_class_index != 0) { + outer_class_name = constant_pool.getConstantString(outer_class_index, Constants.CONSTANT_Class); + outer_class_name = Utility.compactClassName(outer_class_name); + } else + outer_class_name = ""; + + if (inner_name_index != 0) + inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index, Constants.CONSTANT_Utf8)).getValue(); + else + inner_name = ""; + + access = Utility.accessToString(inner_access_flags, true); + access = access.equals("") ? "" : (access + " "); + + return "InnerClass:" + access + inner_class_name + "(\"" + outer_class_name + "\", \"" + inner_name + "\")"; + } + + /** + * @return deep copy of this object + */ + public InnerClass copy() { + try { + return (InnerClass) clone(); + } catch (CloneNotSupportedException e) { + } + + return null; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClasses.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClasses.java new file mode 100644 index 000000000..0078156ed --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClasses.java @@ -0,0 +1,181 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from Attribute and denotes that this class is an Inner class of another. to the source file of + * this class. It is instantiated from the Attribute.readAttribute() method. + * + * @version $Id: InnerClasses.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Attribute + */ +public final class InnerClasses extends Attribute { + private InnerClass[] inner_classes; + private int number_of_classes; + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical + * copy. + */ + public InnerClasses(InnerClasses c) { + this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param inner_classes array of inner classes attributes + * @param constant_pool Array of constants + * @param sourcefile_index Index in constant pool to CONSTANT_Utf8 + */ + public InnerClasses(int name_index, int length, InnerClass[] inner_classes, ConstantPool constant_pool) { + super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool); + setInnerClasses(inner_classes); + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + InnerClasses(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, (InnerClass[]) null, constant_pool); + + number_of_classes = file.readUnsignedShort(); + inner_classes = new InnerClass[number_of_classes]; + + for (int i = 0; i < number_of_classes; i++) + inner_classes[i] = new InnerClass(file); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitInnerClasses(this); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(number_of_classes); + + for (int i = 0; i < number_of_classes; i++) + inner_classes[i].dump(file); + } + + /** + * @return array of inner class "records" + */ + public final InnerClass[] getInnerClasses() { + return inner_classes; + } + + /** + * @param inner_classes. + */ + public final void setInnerClasses(InnerClass[] inner_classes) { + this.inner_classes = inner_classes; + number_of_classes = (inner_classes == null) ? 0 : inner_classes.length; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(); + + for (int i = 0; i < number_of_classes; i++) + buf.append(inner_classes[i].toString(cpool) + "\n"); + + return buf.toString(); + } + + // /** + // * @return deep copy of this attribute + // */ + // public Attribute copy(ConstantPool constant_pool) { + // InnerClasses c = (InnerClasses)clone(); + // + // c.inner_classes = new InnerClass[number_of_classes]; + // for(int i=0; i < number_of_classes; i++) + // c.inner_classes[i] = inner_classes[i].copy(); + // + // c.cpool = constant_pool; + // return c; + // } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/JavaClass.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/JavaClass.java new file mode 100644 index 000000000..25c415295 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/JavaClass.java @@ -0,0 +1,837 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.StringTokenizer; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; +import org.aspectj.apache.bcel.generic.Type; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +/** + * Represents a Java class, i.e., the data structures, constant pool, fields, methods and commands contained in a Java .class file. + * See JVM specification for details. + * + * The intent of this class is to represent a parsed or otherwise existing class file. Those interested in programatically + * generating classes should see the ClassGen class. + * + * @version $Id: JavaClass.java,v 1.22 2009/09/15 19:40:14 aclement Exp $ + * @see org.aspectj.apache.bcel.generic.ClassGen + * @author M. Dahm + */ +public class JavaClass extends Modifiers implements Cloneable, Node { + + private static final String[] NoInterfaceNames = new String[0]; + private static final Field[] NoFields = new Field[0]; + private static final Method[] NoMethod = new Method[0]; + private static final int[] NoInterfaceIndices = new int[0]; + private static final Attribute[] NoAttributes = new Attribute[0]; + + private String fileName; + private String packageName; + private String sourcefileName; + private int classnameIdx; + private int superclassnameIdx; + private String classname; + private String superclassname; + private int major, minor; + private ConstantPool cpool; + private int[] interfaces; + private String[] interfacenames; + private Field[] fields; + private Method[] methods; + private Attribute[] attributes; + private AnnotationGen[] annotations; + + private boolean isGeneric = false; + private boolean isAnonymous = false; + private boolean isNested = false; + private boolean computedNestedTypeStatus = false; + + // Annotations are collected from certain attributes, don't do it more than necessary! + private boolean annotationsOutOfDate = true; + + // state for dealing with generic signature string + private String signatureAttributeString = null; + private Signature signatureAttribute = null; + private boolean searchedForSignatureAttribute = false; + + /** + * In cases where we go ahead and create something, use the default SyntheticRepository, because we don't know any better. + */ + private transient org.aspectj.apache.bcel.util.Repository repository = null; + + public JavaClass(int classnameIndex, int superclassnameIndex, String filename, int major, int minor, int access_flags, + ConstantPool cpool, int[] interfaces, Field[] fields, Method[] methods, Attribute[] attributes) { + if (interfaces == null) { + interfaces = NoInterfaceIndices; + } + + this.classnameIdx = classnameIndex; + this.superclassnameIdx = superclassnameIndex; + this.fileName = filename; + this.major = major; + this.minor = minor; + this.modifiers = access_flags; + this.cpool = cpool; + this.interfaces = interfaces; + this.fields = (fields == null ? NoFields : fields); + this.methods = (methods == null ? NoMethod : methods); + this.attributes = (attributes == null ? NoAttributes : attributes); + annotationsOutOfDate = true; + + // Get source file name if available + SourceFile sfAttribute = AttributeUtils.getSourceFileAttribute(attributes); + sourcefileName = sfAttribute == null ? "" : sfAttribute.getSourceFileName(); + + /* + * According to the specification the following entries must be of type `ConstantClass' but we check that anyway via the + * `ConstPool.getConstant' method. + */ + classname = cpool.getConstantString(classnameIndex, Constants.CONSTANT_Class); + classname = Utility.compactClassName(classname, false); + + int index = classname.lastIndexOf('.'); + if (index < 0) { + packageName = ""; + } else { + packageName = classname.substring(0, index); + } + + if (superclassnameIndex > 0) { // May be zero -> class is java.lang.Object + superclassname = cpool.getConstantString(superclassnameIndex, Constants.CONSTANT_Class); + superclassname = Utility.compactClassName(superclassname, false); + } else { + superclassname = "java.lang.Object"; + } + + if (interfaces.length == 0) { + interfacenames = NoInterfaceNames; + } else { + interfacenames = new String[interfaces.length]; + for (int i = 0; i < interfaces.length; i++) { + String str = cpool.getConstantString(interfaces[i], Constants.CONSTANT_Class); + interfacenames[i] = Utility.compactClassName(str, false); + } + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(ClassVisitor v) { + v.visitJavaClass(this); + } + + /** + * Dump class to a file. + * + * @param file Output file + * @throws IOException + */ + public void dump(File file) throws IOException { + String parent = file.getParent(); + if (parent != null) { + File dir = new File(parent); + dir.mkdirs(); + } + dump(new DataOutputStream(new FileOutputStream(file))); + } + + /** + * Dump class to a file named file_name. + * + * @param file_name Output file name + * @exception IOException + */ + public void dump(String file_name) throws IOException { + dump(new File(file_name)); + } + + /** + * @return class in binary format + */ + public byte[] getBytes() { + ByteArrayOutputStream s = new ByteArrayOutputStream(); + DataOutputStream ds = new DataOutputStream(s); + + try { + dump(ds); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + ds.close(); + } catch (IOException e2) { + e2.printStackTrace(); + } + } + + return s.toByteArray(); + } + + /** + * Dump Java class to output stream in binary format. + */ + public void dump(OutputStream file) throws IOException { + dump(new DataOutputStream(file)); + } + + /** + * Dump Java class to output stream in binary format. + */ + public void dump(DataOutputStream file) throws IOException { + file.writeInt(0xcafebabe); + file.writeShort(minor); + file.writeShort(major); + + cpool.dump(file); + + file.writeShort(modifiers); + file.writeShort(classnameIdx); + file.writeShort(superclassnameIdx); + + file.writeShort(interfaces.length); + for (int i = 0; i < interfaces.length; i++) { + file.writeShort(interfaces[i]); + } + + file.writeShort(fields.length); + for (int i = 0; i < fields.length; i++) { + fields[i].dump(file); + } + + file.writeShort(methods.length); + for (int i = 0; i < methods.length; i++) { + methods[i].dump(file); + } + + AttributeUtils.writeAttributes(attributes, file); + + file.close(); + } + + public Attribute[] getAttributes() { + return attributes; + } + + public AnnotationGen[] getAnnotations() { + if (annotationsOutOfDate) { + // Find attributes that contain annotation data + List accumulatedAnnotations = new ArrayList(); + for (int i = 0; i < attributes.length; i++) { + Attribute attribute = attributes[i]; + if (attribute instanceof RuntimeAnnos) { + RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attribute; + accumulatedAnnotations.addAll(runtimeAnnotations.getAnnotations()); + } + } + annotations = accumulatedAnnotations.toArray(new AnnotationGen[] {}); + annotationsOutOfDate = false; + } + return annotations; + } + + /** + * @return Class name. + */ + public String getClassName() { + return classname; + } + + /** + * @return Package name. + */ + public String getPackageName() { + return packageName; + } + + public int getClassNameIndex() { + return classnameIdx; + } + + public ConstantPool getConstantPool() { + return cpool; + } + + /** + * @return Fields, i.e., variables of the class. Like the JVM spec mandates for the classfile format, these fields are those + * specific to this class, and not those of the superclass or superinterfaces. + */ + public Field[] getFields() { + return fields; + } + + /** + * @return File name of class, aka SourceFile attribute value + */ + public String getFileName() { + return fileName; + } + + /** + * @return Names of implemented interfaces. + */ + public String[] getInterfaceNames() { + return interfacenames; + } + + /** + * @return Indices in constant pool of implemented interfaces. + */ + public int[] getInterfaceIndices() { + return interfaces; + } + + public int getMajor() { + return major; + } + + /** + * @return Methods of the class. + */ + public Method[] getMethods() { + return methods; + } + + /** + * @return A org.aspectj.apache.bcel.classfile.Method corresponding to java.lang.reflect.Method if any + */ + public Method getMethod(java.lang.reflect.Method m) { + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + + if (m.getName().equals(method.getName()) && m.getModifiers() == method.getModifiers() + && Type.getSignature(m).equals(method.getSignature())) { + return method; + } + } + + return null; + } + + public Method getMethod(java.lang.reflect.Constructor c) { + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + if (method.getName().equals("") && c.getModifiers() == method.getModifiers() + && Type.getSignature(c).equals(method.getSignature())) { + return method; + } + } + + return null; + } + + public Field getField(java.lang.reflect.Field field) { + String fieldName = field.getName(); + for (Field f : fields) { + if (f.getName().equals(fieldName)) { + return f; + } + } + return null; + } + + /** + * @return Minor number of class file version. + */ + public int getMinor() { + return minor; + } + + /** + * @return sbsolute path to file where this class was read from + */ + public String getSourceFileName() { + return sourcefileName; + } + + /** + * @return Superclass name. + */ + public String getSuperclassName() { + return superclassname; + } + + /** + * @return Class name index. + */ + public int getSuperclassNameIndex() { + return superclassnameIdx; + } + + /** + * @param attributes . + */ + public void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + annotationsOutOfDate = true; + } + + /** + * @param class_name . + */ + public void setClassName(String class_name) { + this.classname = class_name; + } + + /** + * @param class_name_index . + */ + public void setClassNameIndex(int class_name_index) { + this.classnameIdx = class_name_index; + } + + /** + * @param constant_pool . + */ + public void setConstantPool(ConstantPool constant_pool) { + this.cpool = constant_pool; + } + + /** + * @param fields . + */ + public void setFields(Field[] fields) { + this.fields = fields; + } + + /** + * Set File name of class, aka SourceFile attribute value + */ + public void setFileName(String file_name) { + this.fileName = file_name; + } + + /** + * @param interface_names . + */ + public void setInterfaceNames(String[] interface_names) { + this.interfacenames = interface_names; + } + + /** + * @param interfaces . + */ + public void setInterfaces(int[] interfaces) { + this.interfaces = interfaces; + } + + public void setMajor(int major) { + this.major = major; + } + + public void setMethods(Method[] methods) { + this.methods = methods; + } + + public void setMinor(int minor) { + this.minor = minor; + } + + /** + * Set absolute path to file this class was read from. + */ + public void setSourceFileName(String source_file_name) { + this.sourcefileName = source_file_name; + } + + /** + * @param superclass_name . + */ + public void setSuperclassName(String superclass_name) { + this.superclassname = superclass_name; + } + + /** + * @param superclass_name_index . + */ + public void setSuperclassNameIndex(int superclass_name_index) { + this.superclassnameIdx = superclass_name_index; + } + + /** + * @return String representing class contents. + */ + @Override + public String toString() { + String access = Utility.accessToString(modifiers, true); + access = access.equals("") ? "" : access + " "; + + StringBuffer buf = new StringBuffer(access + Utility.classOrInterface(modifiers) + " " + classname + " extends " + + Utility.compactClassName(superclassname, false) + '\n'); + int size = interfaces.length; + + if (size > 0) { + buf.append("implements\t\t"); + + for (int i = 0; i < size; i++) { + buf.append(interfacenames[i]); + if (i < size - 1) { + buf.append(", "); + } + } + + buf.append('\n'); + } + + buf.append("filename\t\t" + fileName + '\n'); + buf.append("compiled from\t\t" + sourcefileName + '\n'); + buf.append("compiler version\t" + major + "." + minor + '\n'); + buf.append("access flags\t\t" + modifiers + '\n'); + buf.append("constant pool\t\t" + cpool.getLength() + " entries\n"); + buf.append("ACC_SUPER flag\t\t" + isSuper() + "\n"); + + if (attributes.length > 0) { + buf.append("\nAttribute(s):\n"); + for (int i = 0; i < attributes.length; i++) { + buf.append(indent(attributes[i])); + } + } + + if (annotations != null && annotations.length > 0) { + buf.append("\nAnnotation(s):\n"); + for (int i = 0; i < annotations.length; i++) { + buf.append(indent(annotations[i])); + } + } + + if (fields.length > 0) { + buf.append("\n" + fields.length + " fields:\n"); + for (int i = 0; i < fields.length; i++) { + buf.append("\t" + fields[i] + '\n'); + } + } + + if (methods.length > 0) { + buf.append("\n" + methods.length + " methods:\n"); + for (int i = 0; i < methods.length; i++) { + buf.append("\t" + methods[i] + '\n'); + } + } + + return buf.toString(); + } + + private static final String indent(Object obj) { + StringTokenizer tok = new StringTokenizer(obj.toString(), "\n"); + StringBuffer buf = new StringBuffer(); + + while (tok.hasMoreTokens()) { + buf.append("\t" + tok.nextToken() + "\n"); + } + + return buf.toString(); + } + + public final boolean isSuper() { + return (modifiers & Constants.ACC_SUPER) != 0; + } + + public final boolean isClass() { + return (modifiers & Constants.ACC_INTERFACE) == 0; + } + + public final boolean isAnonymous() { + computeNestedTypeStatus(); + return this.isAnonymous; + } + + public final boolean isNested() { + computeNestedTypeStatus(); + return this.isNested; + } + + private final void computeNestedTypeStatus() { + if (computedNestedTypeStatus) { + return; + } + // Attribute[] attrs = attributes.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + if (attributes[i] instanceof InnerClasses) { + InnerClass[] innerClasses = ((InnerClasses) attributes[i]).getInnerClasses(); + for (int j = 0; j < innerClasses.length; j++) { + boolean innerClassAttributeRefersToMe = false; + String inner_class_name = cpool.getConstantString(innerClasses[j].getInnerClassIndex(), + Constants.CONSTANT_Class); + inner_class_name = Utility.compactClassName(inner_class_name); + if (inner_class_name.equals(getClassName())) { + innerClassAttributeRefersToMe = true; + } + if (innerClassAttributeRefersToMe) { + this.isNested = true; + if (innerClasses[j].getInnerNameIndex() == 0) { + this.isAnonymous = true; + } + } + } + } + } + this.computedNestedTypeStatus = true; + } + + // J5SUPPORT: + /** + * Returns true if this class represents an annotation, i.e. it was a 'public @interface blahblah' declaration + */ + public final boolean isAnnotation() { + return (modifiers & Constants.ACC_ANNOTATION) != 0; + } + + /** + * Returns true if this class represents an enum type + */ + public final boolean isEnum() { + return (modifiers & Constants.ACC_ENUM) != 0; + } + + /********************* New repository functionality *********************/ + + /** + * Gets the ClassRepository which holds its definition. By default this is the same as SyntheticRepository.getInstance(); + */ + public org.aspectj.apache.bcel.util.Repository getRepository() { + if (repository == null) { + repository = SyntheticRepository.getInstance(); + } + return repository; + } + + /** + * Sets the ClassRepository which loaded the JavaClass. Should be called immediately after parsing is done. + */ + public void setRepository(org.aspectj.apache.bcel.util.Repository repository) { + this.repository = repository; + } + + /** + * Equivalent to runtime "instanceof" operator. + * + * @return true if this JavaClass is derived from teh super class + */ + public final boolean instanceOf(JavaClass super_class) { + if (this.equals(super_class)) { + return true; + } + + JavaClass[] super_classes = getSuperClasses(); + + for (int i = 0; i < super_classes.length; i++) { + if (super_classes[i].equals(super_class)) { + return true; + } + } + + if (super_class.isInterface()) { + return implementationOf(super_class); + } + + return false; + } + + /** + * @return true, if clazz is an implementation of interface inter + */ + public boolean implementationOf(JavaClass inter) { + if (!inter.isInterface()) { + throw new IllegalArgumentException(inter.getClassName() + " is no interface"); + } + + if (this.equals(inter)) { + return true; + } + + Collection superInterfaces = getAllInterfaces(); + + for (JavaClass superInterface : superInterfaces) { + if (superInterface.equals(inter)) { + return true; + } + } + // for (int i = 0; i < super_interfaces.length; i++) { + // if (super_interfaces[i].equals(inter)) { + // return true; + // } + // } + + return false; + } + + /** + * @return the superclass for this JavaClass object, or null if this is java.lang.Object + */ + public JavaClass getSuperClass() { + if ("java.lang.Object".equals(getClassName())) { + return null; + } + + try { + return getRepository().loadClass(getSuperclassName()); + } catch (ClassNotFoundException e) { + System.err.println(e); + return null; + } + } + + /** + * @return list of super classes of this class in ascending order, i.e., java.lang.Object is always the last element + */ + public JavaClass[] getSuperClasses() { + JavaClass clazz = this; + List vec = new ArrayList(); + for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) { + vec.add(clazz); + } + return vec.toArray(new JavaClass[vec.size()]); + } + + /** + * Get interfaces directly implemented by this JavaClass. + */ + public JavaClass[] getInterfaces() { + String[] interfaces = getInterfaceNames(); + JavaClass[] classes = new JavaClass[interfaces.length]; + + try { + for (int i = 0; i < interfaces.length; i++) { + classes[i] = getRepository().loadClass(interfaces[i]); + } + } catch (ClassNotFoundException e) { + System.err.println(e); + return null; + } + + return classes; + } + + /** + * Get all interfaces implemented by this JavaClass (transitively). + */ + public Collection getAllInterfaces() { + Queue queue = new LinkedList(); + List interfaceList = new ArrayList(); + + queue.add(this); + + while (!queue.isEmpty()) { + JavaClass clazz = queue.remove(); + + JavaClass souper = clazz.getSuperClass(); + JavaClass[] interfaces = clazz.getInterfaces(); + + if (clazz.isInterface()) { + interfaceList.add(clazz); + } else { + if (souper != null) { + queue.add(souper); + } + } + + for (int i = 0; i < interfaces.length; i++) { + queue.add(interfaces[i]); + } + } + + return interfaceList; + // return interfaceList.toArray(new JavaClass[interfaceList.size()]); + } + + /** + * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature may be + * Ljava/util/Vector; the signature attribute will tell us e.g. "Ljava/lang/Object". We can learn the type variable names, + * their bounds, and the true superclass and superinterface types (including any parameterizations) Coded for performance - + * searches for the attribute only when requested - only searches for it once. + */ + public final String getGenericSignature() { + loadGenericSignatureInfoIfNecessary(); + return signatureAttributeString; + } + + public boolean isGeneric() { + loadGenericSignatureInfoIfNecessary(); + return isGeneric; + } + + private void loadGenericSignatureInfoIfNecessary() { + if (!searchedForSignatureAttribute) { + signatureAttribute = AttributeUtils.getSignatureAttribute(attributes); + signatureAttributeString = signatureAttribute == null ? null : signatureAttribute.getSignature(); + isGeneric = signatureAttribute != null && signatureAttributeString.charAt(0) == '<'; + searchedForSignatureAttribute = true; + } + } + + public final Signature getSignatureAttribute() { + loadGenericSignatureInfoIfNecessary(); + return signatureAttribute; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumber.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumber.java new file mode 100644 index 000000000..6b2a64877 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumber.java @@ -0,0 +1,120 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * This class represents a (PC offset, line number) pair, i.e., a line number in the source that corresponds to a relative address + * in the byte code. This is used for debugging purposes. + * + * @version $Id: LineNumber.java,v 1.6 2009/09/09 21:26:54 aclement Exp $ + * @author M. Dahm + * @author Andy Clement + * @see LineNumberTable + */ +public final class LineNumber implements Node { + private int startPC; + private int lineNumber; + + public LineNumber(LineNumber c) { + this(c.getStartPC(), c.getLineNumber()); + } + + LineNumber(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } + + public LineNumber(int startPC, int lineNumber) { + this.startPC = startPC; + this.lineNumber = lineNumber; + } + + public void accept(ClassVisitor v) { + v.visitLineNumber(this); + } + + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(startPC); + file.writeShort(lineNumber); + } + + public final int getLineNumber() { + return lineNumber; + } + + public final int getStartPC() { + return startPC; + } + + // public final void setLineNumber(int line_number) { + // this.lineNumber = line_number; + // } + // + // public final void setStartPC(int start_pc) { + // this.startPC = start_pc; + // } + + @Override + public final String toString() { + return "LineNumber(" + startPC + ", " + lineNumber + ")"; + } + + public LineNumber copy() { + return new LineNumber(this); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumberTable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumberTable.java new file mode 100644 index 000000000..871bfe6bf --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumberTable.java @@ -0,0 +1,276 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a table of line numbers for debugging purposes. This attribute is used by the Code attribute. It + * contains pairs of PCs and line numbers. + * + * @version $Id: LineNumberTable.java,v 1.8 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Code changes: asc Feb06 Made unpacking lazy + */ +public final class LineNumberTable extends Attribute { + + // if 'isInPackedState' then this data needs unpacking + private boolean isInPackedState = false; + private byte[] data; // discarded once unpacked + + private int tableLength; + private LineNumber[] table; + + /* + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical + * copy. + */ + public LineNumberTable(LineNumberTable c) { + this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool()); + } + + public LineNumberTable(int nameIndex, int length, LineNumber[] lineNumberTable, ConstantPool constantPool) { + super(Constants.ATTR_LINE_NUMBER_TABLE, nameIndex, length, constantPool); + setLineNumberTable(lineNumberTable); + isInPackedState = false; + } + + /** + * Construct object from file stream. + * + * @param name_index Index of name + * @param length Content length in bytes + * @param file Input stream + * @throws IOException + * @param constant_pool Array of constants + */ + LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, (LineNumber[]) null, constant_pool); + data = new byte[length]; + file.readFully(data); + isInPackedState = true; + // assert(bytesRead==length) + } + + // Unpacks the byte array into the table + private void unpack() { + if (isInPackedState) { + try { + ByteArrayInputStream bs = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bs); + tableLength = (dis.readUnsignedShort()); + table = new LineNumber[tableLength]; + for (int i = 0; i < tableLength; i++) { + table[i] = new LineNumber(dis); + } + dis.close(); + data = null; // throw it away now + } catch (IOException e) { + throw new RuntimeException("Unpacking of LineNumberTable attribute failed"); + } + isInPackedState = false; + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + unpack(); + v.visitLineNumberTable(this); + } + + /** + * Dump line number table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (isInPackedState) { + file.write(data); + } else { + file.writeShort(tableLength); + for (int i = 0; i < tableLength; i++) { + table[i].dump(file); + } + } + } + + /** + * @return Array of (pc offset, line number) pairs. + */ + public final LineNumber[] getLineNumberTable() { + unpack(); + return table; + } + + /** + * @param line_number_table. + */ + public final void setLineNumberTable(LineNumber[] line_number_table) { + this.data = null; + this.isInPackedState = false; + this.table = line_number_table; + this.tableLength = (line_number_table == null) ? 0 : line_number_table.length; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + unpack(); + StringBuffer buf = new StringBuffer(); + StringBuffer line = new StringBuffer(); + + for (int i = 0; i < tableLength; i++) { + line.append(table[i].toString()); + + if (i < tableLength - 1) { + line.append(", "); + } + + if (line.length() > 72) { + line.append('\n'); + buf.append(line); + line.setLength(0); + } + } + + buf.append(line); + + return buf.toString(); + } + + /** + * Map byte code positions to source code lines. + * + * @param pos byte code offset + * @return corresponding line in source code + */ + public int getSourceLine(int pos) { + unpack(); + int l = 0, r = tableLength - 1; + + if (r < 0) // array is empty + return -1; + + int min_index = -1, min = -1; + + /* + * Do a binary search since the array is ordered. + */ + do { + int i = (l + r) / 2; + int j = table[i].getStartPC(); + + if (j == pos) + return table[i].getLineNumber(); + else if (pos < j) // else constrain search area + r = i - 1; + else + // pos > j + l = i + 1; + + /* + * If exact match can't be found (which is the most common case) return the line number that corresponds to the greatest + * index less than pos. + */ + if (j < pos && j > min) { + min = j; + min_index = i; + } + } while (l <= r); + + /* + * It's possible that we did not find any valid entry for the bytecode offset we were looking for. + */ + if (min_index < 0) + return -1; + + return table[min_index].getLineNumber(); + } + + /** + * @return deep copy of this attribute + */ + // @Override + // public Attribute copy(ConstantPool constant_pool) { + // unpack(); + // LineNumberTable newTable = (LineNumberTable) clone(); + // newTable.table = new LineNumber[tableLength]; + // for (int i = 0; i < tableLength; i++) { + // newTable.table[i] = table[i].copy(); + // } + // newTable.cpool = constant_pool; + // return newTable; + // } + public final int getTableLength() { + unpack(); + return tableLength; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariable.java new file mode 100644 index 000000000..c8d5cd87f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariable.java @@ -0,0 +1,267 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a local variable within a method. It contains its scope, name, signature and index on the method's frame. + * + * @version $Id: LocalVariable.java,v 1.5 2009/09/10 15:35:05 aclement Exp $ + * @author M. Dahm + * @see LocalVariableTable + */ +public final class LocalVariable implements Constants, Cloneable, Node { + + private int start_pc; // Range in which the variable is valid + private int length; + private int name_index; // Index in constant pool of variable name + private int signature_index; // Index of variable signature + private int index; /* + * Variable is `index'th local variable on this method's frame. + */ + + private ConstantPool constant_pool; + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical + * copy. + */ + public LocalVariable(LocalVariable c) { + this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(), c.getConstantPool()); + } + + /** + * Construct object from file stream. + * + * @param file Input stream + * @throws IOException + */ + LocalVariable(DataInputStream file, ConstantPool constant_pool) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort(), constant_pool); + } + + /** + * @param start_pc Range in which the variable + * @param length ... is valid + * @param name_index Index in constant pool of variable name + * @param signature_index Index of variable's signature + * @param index Variable is `index'th local variable on the method's frame + * @param constant_pool Array of constants + */ + public LocalVariable(int start_pc, int length, int name_index, int signature_index, int index, ConstantPool constant_pool) { + this.start_pc = start_pc; + this.length = length; + this.name_index = name_index; + this.signature_index = signature_index; + this.index = index; + this.constant_pool = constant_pool; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(ClassVisitor v) { + v.visitLocalVariable(this); + } + + /** + * Dump local variable to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(start_pc); + file.writeShort(length); + file.writeShort(name_index); + file.writeShort(signature_index); + file.writeShort(index); + } + + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } + + /** + * @return Variable is valid within getStartPC() .. getStartPC()+getLength() + */ + public final int getLength() { + return length; + } + + /** + * @return Variable name. + */ + public final String getName() { + ConstantUtf8 c; + + c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8); + return c.getValue(); + } + + /** + * @return Index in constant pool of variable name. + */ + public final int getNameIndex() { + return name_index; + } + + /** + * @return Signature. + */ + public final String getSignature() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(signature_index, CONSTANT_Utf8); + return c.getValue(); + } + + /** + * @return Index in constant pool of variable signature. + */ + public final int getSignatureIndex() { + return signature_index; + } + + /** + * @return index of register where variable is stored + */ + public final int getIndex() { + return index; + } + + /** + * @return Start of range where he variable is valid + */ + public final int getStartPC() { + return start_pc; + } + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * @param length. + */ + public final void setLength(int length) { + this.length = length; + } + + /** + * @param name_index. + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } + + /** + * @param signature_index. + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } + + /** + * @param index. + */ + public final void setIndex(int index) { + this.index = index; + } + + /** + * @param start_pc Specify range where the local variable is valid. + */ + public final void setStartPC(int start_pc) { + this.start_pc = start_pc; + } + + /** + * @return string representation. + */ + @Override + public final String toString() { + String name = getName(), signature = Utility.signatureToString(getSignature()); + + return "LocalVariable(start_pc = " + start_pc + ", length = " + length + ", index = " + index + ":" + signature + " " + + name + ")"; + } + + /** + * @return deep copy of this object + */ + public LocalVariable copy() { + try { + return (LocalVariable) clone(); + } catch (CloneNotSupportedException e) { + } + + return null; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTable.java new file mode 100644 index 000000000..e6415dae6 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTable.java @@ -0,0 +1,230 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents collection of local variables in a method. This attribute is contained in the Code attribute. + * + * @version $Id: LocalVariableTable.java,v 1.8 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Code + * @see LocalVariable Updates: Andy 14Feb06 - Made unpacking of the data lazy, depending on someone actually asking for it. + */ +public class LocalVariableTable extends Attribute { + + // if 'isInPackedState' then this data needs unpacking + private boolean isInPackedState = false; + private byte[] data; + + private int localVariableTableLength; + private LocalVariable[] localVariableTable; + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical + * copy. + */ + public LocalVariableTable(LocalVariableTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool to `LocalVariableTable' + * @param length Content length in bytes + * @param local_variable_table Table of local variables + * @param constant_pool Array of constants + */ + public LocalVariableTable(int name_index, int length, LocalVariable[] local_variable_table, ConstantPool constant_pool) { + super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); + setLocalVariableTable(local_variable_table); + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + LocalVariableTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); + data = new byte[length]; + file.readFully(data); + isInPackedState = true; + // assert(bytesRead==length) + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + unpack(); + v.visitLocalVariableTable(this); + } + + /** + * Dump local variable table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (isInPackedState) { + file.write(data); + } else { + file.writeShort(localVariableTableLength); + for (int i = 0; i < localVariableTableLength; i++) + localVariableTable[i].dump(file); + } + } + + /** + * @return Array of local variables of method. + */ + public final LocalVariable[] getLocalVariableTable() { + unpack(); + return localVariableTable; + } + + /** + * @return first matching variable using index + */ + public final LocalVariable getLocalVariable(int index) { + unpack(); + for (int i = 0; i < localVariableTableLength; i++) { + if (localVariableTable[i] != null && localVariableTable[i].getIndex() == index) { + return localVariableTable[i]; + } + } + return null; + } + + public final void setLocalVariableTable(LocalVariable[] local_variable_table) { + data = null; + isInPackedState = false; + this.localVariableTable = local_variable_table; + localVariableTableLength = (local_variable_table == null) ? 0 : local_variable_table.length; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(""); + unpack(); + for (int i = 0; i < localVariableTableLength; i++) { + buf.append(localVariableTable[i].toString()); + + if (i < localVariableTableLength - 1) + buf.append('\n'); + } + + return buf.toString(); + } + + /** + * @return deep copy of this attribute + */ + // public Attribute copy(ConstantPool constant_pool) { + // unpack(); + // LocalVariableTable c = (LocalVariableTable) clone(); + // + // c.localVariableTable = new LocalVariable[localVariableTableLength]; + // for (int i = 0; i < localVariableTableLength; i++) + // c.localVariableTable[i] = localVariableTable[i].copy(); + // + // c.cpool = constant_pool; + // return c; + // } + public final int getTableLength() { + unpack(); + return localVariableTableLength; + } + + // --- + // Unpacks the byte array into the table + private void unpack() { + if (!isInPackedState) + return; + try { + ByteArrayInputStream bs = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bs); + localVariableTableLength = (dis.readUnsignedShort()); + localVariableTable = new LocalVariable[localVariableTableLength]; + for (int i = 0; i < localVariableTableLength; i++) + localVariableTable[i] = new LocalVariable(dis, cpool); + dis.close(); + data = null; // throw it away now + } catch (IOException e) { + throw new RuntimeException("Unpacking of LocalVariableTable attribute failed"); + } + isInPackedState = false; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java new file mode 100644 index 000000000..ecd7e4383 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java @@ -0,0 +1,136 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * Heavily based on LocalVariableTable + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +// The new table is used when generic types are about... + +//LocalVariableTable_attribute { +// u2 attribute_name_index; +// u4 attribute_length; +// u2 local_variable_table_length; +// { u2 start_pc; +// u2 length; +// u2 name_index; +// u2 descriptor_index; +// u2 index; +// } local_variable_table[local_variable_table_length]; +// } + +//LocalVariableTypeTable_attribute { +// u2 attribute_name_index; +// u4 attribute_length; +// u2 local_variable_type_table_length; +// { +// u2 start_pc; +// u2 length; +// u2 name_index; +// u2 signature_index; +// u2 index; +// } local_variable_type_table[local_variable_type_table_length]; +// } +// J5TODO: Needs some testing ! +public class LocalVariableTypeTable extends Attribute { + private int local_variable_type_table_length; // Table of local + private LocalVariable[] local_variable_type_table; // variables + + public LocalVariableTypeTable(LocalVariableTypeTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool()); + } + + public LocalVariableTypeTable(int name_index, int length, LocalVariable[] local_variable_table, ConstantPool constant_pool) { + super(Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool); + setLocalVariableTable(local_variable_table); + } + + LocalVariableTypeTable(int nameIdx, int len, DataInputStream dis, ConstantPool cpool) throws IOException { + this(nameIdx, len, (LocalVariable[]) null, cpool); + + local_variable_type_table_length = (dis.readUnsignedShort()); + local_variable_type_table = new LocalVariable[local_variable_type_table_length]; + + for (int i = 0; i < local_variable_type_table_length; i++) + local_variable_type_table[i] = new LocalVariable(dis, cpool); + } + + @Override + public void accept(ClassVisitor v) { + v.visitLocalVariableTypeTable(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(local_variable_type_table_length); + for (int i = 0; i < local_variable_type_table_length; i++) + local_variable_type_table[i].dump(file); + } + + public final LocalVariable[] getLocalVariableTypeTable() { + return local_variable_type_table; + } + + public final LocalVariable getLocalVariable(int index) { + for (int i = 0; i < local_variable_type_table_length; i++) + if (local_variable_type_table[i].getIndex() == index) + return local_variable_type_table[i]; + + return null; + } + + public final void setLocalVariableTable(LocalVariable[] local_variable_table) { + this.local_variable_type_table = local_variable_table; + local_variable_type_table_length = (local_variable_table == null) ? 0 : local_variable_table.length; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(""); + + for (int i = 0; i < local_variable_type_table_length; i++) { + buf.append(local_variable_type_table[i].toString()); + + if (i < local_variable_type_table_length - 1) + buf.append('\n'); + } + + return buf.toString(); + } + + // /** + // * @return deep copy of this attribute + // */ + // public Attribute copy(ConstantPool constant_pool) { + // LocalVariableTypeTable c = (LocalVariableTypeTable)clone(); + // + // c.local_variable_type_table = new LocalVariable[local_variable_type_table_length]; + // for(int i=0; i < local_variable_type_table_length; i++) + // c.local_variable_type_table[i] = local_variable_type_table[i].copy(); + // + // c.cpool = constant_pool; + // return c; + // } + + public final int getTableLength() { + return local_variable_type_table_length; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Method.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Method.java new file mode 100644 index 000000000..46aeac845 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Method.java @@ -0,0 +1,273 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; +import org.aspectj.apache.bcel.generic.Type; + +/** + * This class represents the method info structure, i.e., the representation for a method in the class. See JVM specification for + * details. A method has access flags, a name, a signature and a number of attributes. + * + * @version $Id: Method.java,v 1.11 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + */ +public final class Method extends FieldOrMethod { + + public static final AnnotationGen[][] NO_PARAMETER_ANNOTATIONS = new AnnotationGen[][] {}; + + public static final Method[] NoMethods = new Method[0]; + + private boolean parameterAnnotationsOutOfDate = true; + private AnnotationGen[][] unpackedParameterAnnotations; + + private Method() { + parameterAnnotationsOutOfDate = true; + } + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical + * copy. + */ + public Method(Method c) { + super(c); + parameterAnnotationsOutOfDate = true; + } + + Method(DataInputStream file, ConstantPool constant_pool) throws IOException { + super(file, constant_pool); + } + + public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes, ConstantPool constant_pool) { + super(access_flags, name_index, signature_index, attributes, constant_pool); + parameterAnnotationsOutOfDate = true; + } + + public void accept(ClassVisitor v) { + v.visitMethod(this); + } + + // CUSTARD mutable or not? + @Override + public void setAttributes(Attribute[] attributes) { + parameterAnnotationsOutOfDate = true; + super.setAttributes(attributes); + } + + /** + * @return Code attribute of method, if any + */ + public final Code getCode() { + return AttributeUtils.getCodeAttribute(attributes); + } + + public final ExceptionTable getExceptionTable() { + return AttributeUtils.getExceptionTableAttribute(attributes); + } + + /** + * Return LocalVariableTable of code attribute if any (the call is forwarded to the Code attribute) + */ + public final LocalVariableTable getLocalVariableTable() { + Code code = getCode(); + if (code != null) + return code.getLocalVariableTable(); + return null; + } + + /** + * Return LineNumberTable of code attribute if any (the call is forwarded to the Code attribute) + */ + public final LineNumberTable getLineNumberTable() { + Code code = getCode(); + if (code != null) + return code.getLineNumberTable(); + return null; + } + + /** + * Return string representation close to declaration format, eg: 'public static void main(String[] args) throws IOException' + */ + @Override + public final String toString() { + ConstantUtf8 c; + String name, signature, access; // Short cuts to constant pool + StringBuffer buf; + + access = Utility.accessToString(modifiers); + + // Get name and signature from constant pool + c = (ConstantUtf8) cpool.getConstant(signatureIndex, Constants.CONSTANT_Utf8); + signature = c.getValue(); + + c = (ConstantUtf8) cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); + name = c.getValue(); + + signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable()); + buf = new StringBuffer(signature); + + for (int i = 0; i < attributes.length; i++) { + Attribute a = attributes[i]; + if (!((a instanceof Code) || (a instanceof ExceptionTable))) + buf.append(" [" + a.toString() + "]"); + } + + ExceptionTable e = getExceptionTable(); + if (e != null) { + String str = e.toString(); + if (!str.equals("")) + buf.append("\n\t\tthrows " + str); + } + + return buf.toString(); + } + + /** + * @return return type of method + */ + public Type getReturnType() { + return Type.getReturnType(getSignature()); + } + + /** + * @return array of method argument types + */ + public Type[] getArgumentTypes() { + return Type.getArgumentTypes(getSignature()); + } + + private void ensureParameterAnnotationsUnpacked() { + if (!parameterAnnotationsOutOfDate) + return; + parameterAnnotationsOutOfDate = false; + + int parameterCount = getArgumentTypes().length; + if (parameterCount == 0) { + unpackedParameterAnnotations = NO_PARAMETER_ANNOTATIONS; + return; + } + + RuntimeVisParamAnnos parameterAnnotationsVis = null; + RuntimeInvisParamAnnos parameterAnnotationsInvis = null; + + // Find attributes that contain annotation data + Attribute[] attrs = getAttributes(); + + for (int i = 0; i < attrs.length; i++) { + Attribute attribute = attrs[i]; + if (attribute instanceof RuntimeVisParamAnnos) { + parameterAnnotationsVis = (RuntimeVisParamAnnos) attribute; + } else if (attribute instanceof RuntimeInvisParamAnnos) { + parameterAnnotationsInvis = (RuntimeInvisParamAnnos) attribute; + } + } + + boolean foundSome = false; + // Build a list of annotation arrays, one per argument + if (parameterAnnotationsInvis != null || parameterAnnotationsVis != null) { + List annotationsForEachParameter = new ArrayList(); + AnnotationGen[] visibleOnes = null; + AnnotationGen[] invisibleOnes = null; + for (int i = 0; i < parameterCount; i++) { + int count = 0; + visibleOnes = new AnnotationGen[0]; + invisibleOnes = new AnnotationGen[0]; + if (parameterAnnotationsVis != null) { + visibleOnes = parameterAnnotationsVis.getAnnotationsOnParameter(i); + count += visibleOnes.length; + } + if (parameterAnnotationsInvis != null) { + invisibleOnes = parameterAnnotationsInvis.getAnnotationsOnParameter(i); + count += invisibleOnes.length; + } + + AnnotationGen[] complete = AnnotationGen.NO_ANNOTATIONS; + if (count != 0) { + complete = new AnnotationGen[visibleOnes.length + invisibleOnes.length]; + System.arraycopy(visibleOnes, 0, complete, 0, visibleOnes.length); + System.arraycopy(invisibleOnes, 0, complete, visibleOnes.length, invisibleOnes.length); + foundSome = true; + } + annotationsForEachParameter.add(complete); + } + if (foundSome) { + unpackedParameterAnnotations = annotationsForEachParameter.toArray(new AnnotationGen[][] {}); + return; + } + } + unpackedParameterAnnotations = NO_PARAMETER_ANNOTATIONS; + } + + public AnnotationGen[] getAnnotationsOnParameter(int i) { + ensureParameterAnnotationsUnpacked(); + if (unpackedParameterAnnotations == NO_PARAMETER_ANNOTATIONS) { + return AnnotationGen.NO_ANNOTATIONS; + } + return unpackedParameterAnnotations[i]; + } + + public AnnotationGen[][] getParameterAnnotations() { + ensureParameterAnnotationsUnpacked(); + return unpackedParameterAnnotations; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/MethodParameters.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/MethodParameters.java new file mode 100644 index 000000000..547041584 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/MethodParameters.java @@ -0,0 +1,112 @@ +/* ******************************************************************* + * Copyright (c) 2013 VMware + * + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +// see http://cr.openjdk.java.net/~abuckley/8misc.pdf +public class MethodParameters extends Attribute { + + public final static int[] NO_PARAMETER_NAME_INDEXES = new int[0]; + public final static int[] NO_PARAMETER_ACCESS_FLAGS = new int[0]; + + public final static int ACCESS_FLAGS_FINAL = 0x0010; + public final static int ACCESS_FLAGS_SYNTHETIC = 0x1000; + public final static int ACCESS_FLAGS_MANDATED = 0x8000; + + // if 'isInPackedState' then this data needs unpacking + private boolean isInPackedState = false; + private byte[] data; + private int[] names; + private int[] accessFlags; + + public MethodParameters(int index, int length, DataInputStream dis, ConstantPool cpool) throws IOException { + super(Constants.ATTR_METHOD_PARAMETERS,index,length,cpool); + data = new byte[length]; + dis.readFully(data,0,length); + isInPackedState = true; + } + + private void ensureInflated() { + if (names!=null) return; + try { + DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data)); + int parametersCount = dis.readUnsignedByte(); + if (parametersCount == 0) { + names = NO_PARAMETER_NAME_INDEXES; + accessFlags = NO_PARAMETER_ACCESS_FLAGS; + } else { + names = new int[parametersCount]; + accessFlags = new int[parametersCount]; + for (int i=0;i. + */ + +import org.aspectj.apache.bcel.Constants; + +/** + * Super class for all objects that have modifiers like private, final, ... I.e. + * classes, fields, and methods. + * was AccessFlags + * + * @version $Id: Modifiers.java,v 1.2 2008/05/28 23:53:01 aclement Exp $ + * @author M. Dahm + */ +public abstract class Modifiers { + + protected int modifiers; + + public Modifiers() { } + + public Modifiers(int a) { + modifiers = a; + } + + public final int getModifiers() { + return modifiers; + } + + public final void setModifiers(int modifiers) { + this.modifiers = modifiers; + } + + public final boolean isPublic() { + return (modifiers & Constants.ACC_PUBLIC) != 0; + } + + public final boolean isPrivate() { + return (modifiers & Constants.ACC_PRIVATE) != 0; + } + + public final boolean isProtected() { + return (modifiers & Constants.ACC_PROTECTED) != 0; + } + + public final boolean isStatic() { + return (modifiers & Constants.ACC_STATIC) != 0; + } + + public final boolean isFinal() { + return (modifiers & Constants.ACC_FINAL) != 0; + } + + public final boolean isSynchronized() { + return (modifiers & Constants.ACC_SYNCHRONIZED) != 0; + } + + public final boolean isVolatile() { + return (modifiers & Constants.ACC_VOLATILE) != 0; + } + + public final boolean isTransient() { + return (modifiers & Constants.ACC_TRANSIENT) != 0; + } + + public final boolean isNative() { + return (modifiers & Constants.ACC_NATIVE) != 0; + } + + public final boolean isInterface() { + return (modifiers & Constants.ACC_INTERFACE) != 0; + } + + public final boolean isAbstract() { + return (modifiers & Constants.ACC_ABSTRACT) != 0; + } + + public final boolean isStrictfp() { + return (modifiers & Constants.ACC_STRICT) != 0; + } + + public final boolean isVarargs() { + return (modifiers & Constants.ACC_VARARGS) != 0; + } + + public final boolean isBridge() { + return (modifiers & Constants.ACC_BRIDGE) != 0; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Module.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Module.java new file mode 100644 index 000000000..5eef18cde --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Module.java @@ -0,0 +1,664 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2016-17 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from Attribute and represents the module + * information captured in a class file. + * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 + * + * @author Andy Clement + */ +public final class Module extends Attribute { + + private static final String[] NO_MODULE_NAMES = {}; + + private int moduleNameIndex; // u2 module_name_index + private int moduleFlags; // u2 module_flags + private int moduleVersionIndex; // u2 module_version_index + private Require[] requires; + private Export[] exports; + private Open[] opens; + private Uses[] uses; + private Provide[] provides; + + private byte[] moduleInfo; + private int ptr; + private boolean unpacked = false; + + public Module(Module module) { + super(module.getTag(), module.getNameIndex(), module.getLength(), module.getConstantPool()); + moduleInfo = module.getBytes(); + } + + public Module(int nameIndex, int length, byte[] data, ConstantPool cp) { + super(Constants.ATTR_MODULE, nameIndex, length, cp); + } + + Module(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, (byte[])null, cp); + moduleInfo = new byte[length]; + stream.read(moduleInfo); + unpacked = false; + } + + public class Require { + + private final int moduleIndex; + private final int flags; + private final int versionIndex; + + public Require(int moduleIndex, int flags, int versionIndex) { + this.moduleIndex = moduleIndex; + this.flags = flags; + this.versionIndex = versionIndex; + } + + public String getModuleName() { + return cpool.getModuleName(moduleIndex); + } + + public int getFlags() { + return flags; + } + + public int getVersionIndex() { + return versionIndex; + } + + public String getVersionString() { + if (versionIndex == 0) { + return null; + } else { + return cpool.getConstantUtf8(versionIndex).getValue(); + } + } + + public String getFlagsAsString() { + StringBuilder s = new StringBuilder(); + if ((flags & Constants.MODULE_ACC_TRANSITIVE)!=0) { + s.append(" transitive"); + } + if ((flags & Constants.MODULE_ACC_STATIC_PHASE)!=0) { + s.append(" static"); + } + if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { + s.append(" synthetic"); + } + if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { + s.append(" mandated"); + } + return s.toString(); + } + + public String toString() { + return "requires"+getFlagsAsString()+" "+getModuleName()+(versionIndex==0?"":" "+getVersionString()); + } + } + + + public class Export { + + private final int packageIndex; + private final int flags; + private final int[] toModuleIndices; + + public Export(int packageIndex, int flags, int[] toModuleIndices) { + this.packageIndex = packageIndex; + this.flags = flags; + this.toModuleIndices = toModuleIndices; + } + + public int getPackageIndex() { + return packageIndex; + } + + public int getFlags() { + return flags; + } + + public int[] getToModuleIndices() { + return toModuleIndices; + } + + public String getPackage() { + return cpool.getPackageName(packageIndex); + } + + public String getFlagsAsString() { + StringBuilder s = new StringBuilder(); + if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { + s.append(" synthetic"); + } + if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { + s.append(" synthetic"); + } + return s.toString(); + } + + public String[] getToModuleNames() { + if (toModuleIndices==null) { + return NO_MODULE_NAMES; + } + String[] toModuleNames = new String[toModuleIndices.length]; + for (int i=0;i0) { + s.append(", "); + } + s.append(toModules[i]); + } + } + return s.toString().trim(); + } + } + + + public class Open { + + private final int packageIndex; + private final int flags; + private final int[] toModuleIndices; + + public Open(int packageIndex, int flags, int[] toModuleIndices) { + this.packageIndex = packageIndex; + this.flags = flags; + this.toModuleIndices = toModuleIndices; + } + + public int getPackageIndex() { + return packageIndex; + } + + public int getFlags() { + return flags; + } + + public int[] getToModuleIndices() { + return toModuleIndices; + } + + public String getPackage() { + return cpool.getPackageName(packageIndex); + } + + public String getFlagsAsString() { + StringBuilder s = new StringBuilder(); + if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { + s.append(" synthetic"); + } + if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { + s.append(" synthetic"); + } + return s.toString(); + } + + public String[] getToModuleNames() { + if (toModuleIndices==null) { + return NO_MODULE_NAMES; + } + String[] toModuleNames = new String[toModuleIndices.length]; + for (int i=0;i0) { + s.append(", "); + } + s.append(toModules[i]); + } + } + return s.toString().trim(); + } + } + + public class Provide { + private final int providedTypeIndex; + private final int[] withTypeIndices; + + public Provide(int providedTypeIndex, int[] withTypeIndices) { + this.providedTypeIndex = providedTypeIndex; + this.withTypeIndices = withTypeIndices; + } + + public String getProvidedType() { + return cpool.getConstantString_CONSTANTClass(providedTypeIndex); + } + + public int getProvidedTypeIndex() { + return providedTypeIndex; + } + + public String[] getWithTypeStrings() { + String[] result = new String[withTypeIndices.length]; + for (int i=0;i0) s.append(","); + s.append(withtypes[i].replace('/','.')); + } + return s.toString(); + } + } + + public class Uses { + private final int typeNameIndex; + + public Uses(int typeNameIndex) { + this.typeNameIndex = typeNameIndex; + } + + public String getTypeName() { + return cpool.getConstantString_CONSTANTClass(typeNameIndex); + } + + public int getTypeNameIndex() { + return typeNameIndex; + } + + public String toString() { + StringBuilder s =new StringBuilder(); + s.append("uses ").append(getTypeName().replace('/', '.')); + return s.toString().trim(); + } + } + + private final int readInt() { + return ((moduleInfo[ptr++] & 0xFF) << 24) + ((moduleInfo[ptr++] & 0xFF) << 16) + + ((moduleInfo[ptr++] & 0xFF) << 8) + (moduleInfo[ptr++] & 0xFF); + } + + private final int readUnsignedShort() { + return ((moduleInfo[ptr++] & 0xff) << 8) + (moduleInfo[ptr++] & 0xff); + } + + private final int readUnsignedShort(int offset) { + return ((moduleInfo[offset++] & 0xff) << 8) + (moduleInfo[offset] & 0xff); + } + + // Format: http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 + private void ensureUnpacked() { + if (!unpacked) { + ptr = 0; + moduleNameIndex = readUnsignedShort(); + moduleFlags = readUnsignedShort(); + moduleVersionIndex = readUnsignedShort(); + + int count = readUnsignedShort(); + requires = new Require[count]; + for (int i = 0; i < count; i++) { + requires[i] = new Require(readUnsignedShort(), readUnsignedShort(), readUnsignedShort()); + } + + count = readUnsignedShort(); + exports = new Export[count]; + for (int i = 0; i < count; i++) { + int index = readUnsignedShort(); + int flags = readUnsignedShort(); + int toCount = readUnsignedShort(); + int[] to = new int[toCount]; + for (int j = 0; j < toCount; j++) { + to[j] = readUnsignedShort(); + } + exports[i] = new Export(index, flags, to); + } + + count = readUnsignedShort(); + opens = new Open[count]; + for (int i = 0; i < count; i++) { + int index = readUnsignedShort(); + int flags = readUnsignedShort(); + int toCount = readUnsignedShort(); + int[] to = new int[toCount]; + for (int j = 0; j < toCount; j++) { + to[j] = readUnsignedShort(); + } + opens[i] = new Open(index, flags, to); + } + count = readUnsignedShort(); + uses = new Uses[count]; + for (int i = 0; i < count; i++) { + uses[i] = new Uses(readUnsignedShort()); + } + count = readUnsignedShort(); + provides = new Provide[count]; + for (int i = 0; i < count; i++) { + int index = readUnsignedShort(); + int toCount = readUnsignedShort(); + int[] to = new int[toCount]; + for (int j = 0; j < toCount; j++) { + to[j] = readUnsignedShort(); + } + provides[i] = new Provide(index, to); + } + unpacked = true; + } + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (!unpacked) { + file.write(moduleInfo); + } else { + + file.writeShort(moduleNameIndex); + file.writeShort(moduleFlags); + file.writeShort(moduleVersionIndex); + + file.writeShort(requires.length); + for (int i = 0; i < requires.length; i++) { + file.writeShort(requires[i].moduleIndex); + file.writeShort(requires[i].flags); + file.writeShort(requires[i].versionIndex); + } + file.writeShort(exports.length); + for (Export export : exports) { + file.writeShort(export.packageIndex); + int[] toIndices = export.toModuleIndices; + file.writeShort(toIndices.length); + for (int index : toIndices) { + file.writeShort(index); + } + } + file.writeShort(opens.length); + for (Open open : opens) { + file.writeShort(open.packageIndex); + int[] toIndices = open.toModuleIndices; + file.writeShort(toIndices.length); + for (int index : toIndices) { + file.writeShort(index); + } + } + file.writeShort(uses.length); + for (Uses use : uses) { + file.writeShort(use.getTypeNameIndex()); + } + file.writeShort(provides.length); + for (Provide provide : provides) { + file.writeShort(provide.providedTypeIndex); + int[] toIndices = provide.withTypeIndices; + file.writeShort(toIndices.length); + for (int index : toIndices) { + file.writeShort(index); + } + } + } + } + + public String toStringRequires() { + StringBuilder s = new StringBuilder(); + s.append('#').append(requires.length); + if (requires.length > 0) { + for (Require require : requires) { + s.append(' '); + s.append(require.moduleIndex).append(':').append(require.flags); + } + } + return s.toString(); + } + + public String toStringExports() { + StringBuilder s = new StringBuilder(); + s.append('#').append(exports.length); + if (exports.length > 0) { + for (Export export : exports) { + s.append(' '); + s.append(export.packageIndex).append(":["); + int[] toIndices = export.toModuleIndices; + for (int i = 0; i < toIndices.length; i++) { + if (i > 0) + s.append(','); + s.append(toIndices[i]); + } + s.append("]"); + } + } + return s.toString(); + } + + public String toStringOpens() { + StringBuilder s = new StringBuilder(); + s.append('#').append(opens.length); + if (opens.length > 0) { + for (Open open : opens) { + s.append(' '); + s.append(open.packageIndex).append(":["); + int[] toIndices = open.toModuleIndices; + for (int i = 0; i < toIndices.length; i++) { + if (i > 0) + s.append(','); + s.append(toIndices[i]); + } + s.append("]"); + } + } + return s.toString(); + } + + public String toStringUses() { + StringBuilder s = new StringBuilder(); + s.append('#').append(uses.length); + if (uses.length > 0) { + for (Uses use : uses) { + s.append(' '); + s.append(use.getTypeName()); + } + } + return s.toString(); + } + + public String toStringProvides() { + StringBuilder s = new StringBuilder(); + s.append('#').append(provides.length); + if (provides.length > 0) { + for (Provide provide : provides) { + s.append(' '); + s.append(provide.providedTypeIndex).append(":["); + int[] indices = provide.withTypeIndices; + for (int i = 0; i < indices.length; i++) { + if (i > 0) + s.append(','); + s.append(indices[i]); + } + s.append("]"); + } + } + return s.toString(); + } + + @Override + public final String toString() { + StringBuilder s = new StringBuilder(); + ensureUnpacked(); + s.append("Module("); + if (requires.length != 0) { + s.append("requires="); + s.append(toStringRequires()); + s.append(" "); + } + if (exports.length != 0) { + s.append("exports="); + s.append(toStringExports()); + s.append(" "); + } + if (opens.length != 0) { + s.append("opens="); + s.append(toStringOpens()); + s.append(" "); + } + if (uses.length != 0) { + s.append("uses="); + s.append(toStringUses()); + s.append(" "); + } + if (provides.length != 0) { + s.append("provides="); + s.append(toStringProvides()); + s.append(" "); + } + return s.toString().trim()+")"; + } + + /** + * @return deep copy of this attribute // + */ +// @Override +// public Attribute copy(ConstantPool constant_pool) { +// return (Module) clone(); +// } + + @Override + public void accept(ClassVisitor v) { + v.visitModule(this); + } + + public Require[] getRequires() { + ensureUnpacked(); + return requires; + } + + public String[] getRequiredModuleNames() { + ensureUnpacked(); + String[] results = new String[requires.length]; + for (int i=0;i. + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Indicates the main class of a module. + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26 + * + * @author Andy Clement + */ +public final class ModuleMainClass extends Attribute { + + private int mainClassIndex; + + public ModuleMainClass(ModuleMainClass c) { + this(c.getNameIndex(), c.getLength(), c.getMainClassIndex(), c.getConstantPool()); + } + + public ModuleMainClass(int nameIndex, int length, int mainClassIndex, ConstantPool cp) { + super(Constants.ATTR_MODULE_MAIN_CLASS, nameIndex, length, cp); + this.mainClassIndex = mainClassIndex; + } + + ModuleMainClass(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, 0, cp); + this.mainClassIndex = stream.readUnsignedShort(); + } + + @Override + public void accept(ClassVisitor v) { + v.visitModuleMainClass(this); + } + + @Override + public final void dump(DataOutputStream stream) throws IOException { + super.dump(stream); + stream.writeShort(mainClassIndex); + } + + public final int getMainClassIndex() { + return mainClassIndex; + } + + @Override + public final String toString() { + return cpool.getConstantString_CONSTANTClass(mainClassIndex); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModulePackages.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModulePackages.java new file mode 100644 index 000000000..37da4bc47 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModulePackages.java @@ -0,0 +1,126 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Indicates all the packages of a module that are exported or opened by the module attribute. + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26 + * + * @author Andy Clement + */ +public final class ModulePackages extends Attribute { + + private static int[] NO_PACKAGES = new int[0]; + private int[] packageIndices; + + public ModulePackages(ModulePackages c) { + this(c.getNameIndex(), c.getLength(), c.getPackageIndices(), c.getConstantPool()); + } + + public ModulePackages(int nameIndex, int length, int[] packageIndices, ConstantPool cp) { + super(Constants.ATTR_MODULE_PACKAGES, nameIndex, length, cp); + setPackageIndices(packageIndices); + } + + ModulePackages(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, (int[]) null, cp); + int packageIndicesCount = stream.readUnsignedShort(); + packageIndices = new int[packageIndicesCount]; + for (int i = 0; i < packageIndicesCount; i++) { + packageIndices[i] = stream.readUnsignedShort(); + } + } + + @Override + public void accept(ClassVisitor v) { + v.visitModulePackages(this); + } + + @Override + public final void dump(DataOutputStream stream) throws IOException { + super.dump(stream); + stream.writeShort(packageIndices.length); + for (int i = 0; i < packageIndices.length; i++) { + stream.writeShort(packageIndices[i]); + } + } + + public final int[] getPackageIndices() { + return packageIndices; + } + + public final void setPackageIndices(int[] packageIndices) { + if (packageIndices == null) { + this.packageIndices = NO_PACKAGES; + } else { + this.packageIndices = packageIndices; + } + } + + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < packageIndices.length; i++) { + buf.append(cpool.getPackageName(packageIndices[i]) + "\n"); + } + return buf.toString(); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestHost.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestHost.java new file mode 100644 index 000000000..52d312659 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestHost.java @@ -0,0 +1,118 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.28 + * + * @see Attribute + */ +public final class NestHost extends Attribute { + private int hostClassIndex; + + public NestHost(NestHost c) { + this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool()); + } + + public NestHost(int nameIndex, int length, int hostClassIndex, ConstantPool cp) { + super(Constants.ATTR_NEST_MEMBERS, nameIndex, length, cp); + this.hostClassIndex = hostClassIndex; + } + + NestHost(int nameIndex, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(nameIndex, length, 0, constant_pool); + hostClassIndex = file.readUnsignedShort(); + } + + @Override + public void accept(ClassVisitor v) { + v.visitNestHost(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(hostClassIndex); + } + + public final int getHostClassIndex() { + return hostClassIndex; + } + + public final void setHostClassIndex(int hostClassIndex) { + this.hostClassIndex = hostClassIndex; + } + + public final String getHostClassName() { + ConstantClass constantClass = (ConstantClass)cpool.getConstant(hostClassIndex,Constants.CONSTANT_Class); + return constantClass.getClassname(cpool); + } + + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("NestHost("); + ConstantClass constantClass = (ConstantClass)cpool.getConstant(hostClassIndex,Constants.CONSTANT_Class); + buf.append(constantClass.getClassname(cpool)); + buf.append(")"); + return buf.toString(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestMembers.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestMembers.java new file mode 100644 index 000000000..9d273966f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestMembers.java @@ -0,0 +1,131 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.29 + * + * @see Attribute + */ +public final class NestMembers extends Attribute { + private int numberOfClasses; + private int[] classes; // CONSTANT_Class_info references + + public NestMembers(NestMembers c) { + this(c.getNameIndex(), c.getLength(), c.getClasses(), c.getConstantPool()); + } + + public NestMembers(int nameIndex, int length, int[] classes, ConstantPool cp) { + super(Constants.ATTR_NEST_MEMBERS, nameIndex, length, cp); + setClasses(classes); + } + + NestMembers(int nameIndex, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(nameIndex, length, (int[]) null, constant_pool); + numberOfClasses = file.readUnsignedShort(); + classes = new int[numberOfClasses]; + for (int i = 0; i < numberOfClasses; i++) { + classes[i] = file.readUnsignedShort(); + } + } + + @Override + public void accept(ClassVisitor v) { + v.visitNestMembers(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(numberOfClasses); + for (int i = 0; i < numberOfClasses; i++) { + file.writeShort(classes[i]); + } + } + + public final int[] getClasses() { + return classes; + } + + public final void setClasses(int[] inner_classes) { + this.classes = inner_classes; + numberOfClasses = (inner_classes == null) ? 0 : inner_classes.length; + } + + public final String[] getClassesNames() { + String[] result = new String[numberOfClasses]; + for (int i = 0; i < numberOfClasses; i++) { + ConstantClass constantClass = (ConstantClass)cpool.getConstant(classes[i],Constants.CONSTANT_Class); + result[i] = constantClass.getClassname(cpool); + } + return result; + } + + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < numberOfClasses; i++) { + ConstantClass constantClass = (ConstantClass)cpool.getConstant(classes[i],Constants.CONSTANT_Class); + buf.append(constantClass.getClassname(cpool)).append(" "); + } + return "NestMembers("+buf.toString().trim()+")"; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Node.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Node.java new file mode 100644 index 000000000..5bef82979 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Node.java @@ -0,0 +1,65 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Denote class to have an accept method(); + * + * @version $Id: Node.java,v 1.3 2008/05/28 23:53:01 aclement Exp $ + * @author M. Dahm + */ +public interface Node { + public void accept(ClassVisitor obj); +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Signature.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Signature.java new file mode 100644 index 000000000..b7488e9a4 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Signature.java @@ -0,0 +1,310 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + * Extended by Adrian Colyer, June 2005 to support unpacking of Signature + * attribute + */ + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from Attribute and represents a reference to a GJ + * attribute. + * + * @version $Id: Signature.java,v 1.11 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Attribute + */ +public final class Signature extends Attribute { + private int signature_index; + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical + * copy. + */ + public Signature(Signature c) { + this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool()); + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Signature(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, file.readUnsignedShort(), constant_pool); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param constant_pool Array of constants + * @param Signature_index Index in constant pool to CONSTANT_Utf8 + */ + public Signature(int name_index, int length, int signature_index, ConstantPool constant_pool) { + super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool); + this.signature_index = signature_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + System.err.println("Visiting non-standard Signature object"); + v.visitSignature(this); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(signature_index); + } + + /** + * @return Index in constant pool of source file name. + */ + public final int getSignatureIndex() { + return signature_index; + } + + /** + * @param Signature_index. + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } + + /** + * @return GJ signature. + */ + public final String getSignature() { + ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(signature_index, Constants.CONSTANT_Utf8); + return c.getValue(); + } + + /** + * Extends ByteArrayInputStream to make 'unreading' chars possible. + */ + private static final class MyByteArrayInputStream extends ByteArrayInputStream { + MyByteArrayInputStream(String data) { + super(data.getBytes()); + } + + final int mark() { + return pos; + } + + final String getData() { + return new String(buf); + } + + final void reset(int p) { + pos = p; + } + + final void unread() { + if (pos > 0) + pos--; + } + } + + private static boolean identStart(int ch) { + return ch == 'T' || ch == 'L'; + } + + private static final void matchIdent(MyByteArrayInputStream in, StringBuffer buf) { + int ch; + + if ((ch = in.read()) == -1) + throw new RuntimeException("Illegal signature: " + in.getData() + " no ident, reaching EOF"); + + // System.out.println("return from ident:" + (char)ch); + + if (!identStart(ch)) { + StringBuffer buf2 = new StringBuffer(); + + int count = 1; + while (Character.isJavaIdentifierPart((char) ch)) { + buf2.append((char) ch); + count++; + ch = in.read(); + } + + if (ch == ':') { // Ok, formal parameter + in.skip("Ljava/lang/Object".length()); + buf.append(buf2); + + ch = in.read(); + in.unread(); + // System.out.println("so far:" + buf2 + ":next:" +(char)ch); + } else { + for (int i = 0; i < count; i++) + in.unread(); + } + + return; + } + + StringBuffer buf2 = new StringBuffer(); + ch = in.read(); + + do { + buf2.append((char) ch); + ch = in.read(); + // System.out.println("within ident:"+ (char)ch); + + } while ((ch != -1) && (Character.isJavaIdentifierPart((char) ch) || (ch == '/'))); + + buf.append(buf2.toString().replace('/', '.')); + + // System.out.println("regular return ident:"+ (char)ch + ":" + buf2); + + if (ch != -1) + in.unread(); + } + + private static final void matchGJIdent(MyByteArrayInputStream in, StringBuffer buf) { + int ch; + + matchIdent(in, buf); + + ch = in.read(); + if ((ch == '<') || ch == '(') { // Parameterized or method + // System.out.println("Enter <"); + buf.append((char) ch); + matchGJIdent(in, buf); + + while (((ch = in.read()) != '>') && (ch != ')')) { // List of parameters + if (ch == -1) + throw new RuntimeException("Illegal signature: " + in.getData() + " reaching EOF"); + + // System.out.println("Still no >"); + buf.append(", "); + in.unread(); + matchGJIdent(in, buf); // Recursive call + } + + // System.out.println("Exit >"); + + buf.append((char) ch); + } else + in.unread(); + + ch = in.read(); + if (identStart(ch)) { + in.unread(); + matchGJIdent(in, buf); + } else if (ch == ')') { + in.unread(); + return; + } else if (ch != ';') + throw new RuntimeException("Illegal signature: " + in.getData() + " read " + (char) ch); + } + + public static String translate(String s) { + // System.out.println("Sig:" + s); + StringBuffer buf = new StringBuffer(); + + matchGJIdent(new MyByteArrayInputStream(s), buf); + + return buf.toString(); + } + + public static final boolean isFormalParameterList(String s) { + return s.startsWith("<") && (s.indexOf(':') > 0); + } + + public static final boolean isActualParameterList(String s) { + return s.startsWith("L") && s.endsWith(">;"); + } + + /** + * @return String representation + */ + @Override + public final String toString() { + String s = getSignature(); + + return "Signature(" + s + ")"; + } + + // /** + // * @return deep copy of this attribute + // */ + // @Override + // public Attribute copy(ConstantPool constant_pool) { + // return (Signature) clone(); + // } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SimpleConstant.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SimpleConstant.java new file mode 100644 index 000000000..84ff40cf9 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SimpleConstant.java @@ -0,0 +1,58 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +public interface SimpleConstant { + public String getStringValue(); +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SourceFile.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SourceFile.java new file mode 100644 index 000000000..9fd840fc0 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SourceFile.java @@ -0,0 +1,169 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from Attribute and represents a reference to the source file of this class. At most one SourceFile + * attribute should appear per classfile. The intention of this class is that it is instantiated from the + * Attribute.readAttribute() method. + * + * @version $Id: SourceFile.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Attribute + */ +public final class SourceFile extends Attribute { + private int sourcefile_index; + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical + * copy. + */ + public SourceFile(SourceFile c) { + this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c.getConstantPool()); + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + SourceFile(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, file.readUnsignedShort(), constant_pool); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8, which should represent the string "SourceFile". + * @param length Content length in bytes, the value should be 2. + * @param constant_pool The constant pool that this attribute is associated with. + * @param sourcefile_index Index in constant pool to CONSTANT_Utf8. This string will be interpreted as the name of the file from + * which this class was compiled. It will not be interpreted as indicating the name of the directory contqining the file + * or an absolute path; this information has to be supplied the consumer of this attribute - in many cases, the JVM. + */ + public SourceFile(int name_index, int length, int sourcefile_index, ConstantPool constant_pool) { + super(Constants.ATTR_SOURCE_FILE, name_index, length, constant_pool); + this.sourcefile_index = sourcefile_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitSourceFile(this); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(sourcefile_index); + } + + /** + * @return Index in constant pool of source file name. + */ + public final int getSourceFileIndex() { + return sourcefile_index; + } + + /** + * @param sourcefile_index. + */ + public final void setSourceFileIndex(int sourcefile_index) { + this.sourcefile_index = sourcefile_index; + } + + /** + * @return Source file name. + */ + public final String getSourceFileName() { + ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(sourcefile_index, Constants.CONSTANT_Utf8); + return c.getValue(); + } + + /** + * @return String representation + */ + @Override + public final String toString() { + return "SourceFile(" + getSourceFileName() + ")"; + } + + /** + * @return deep copy of this attribute // + */ + // @Override + // public Attribute copy(ConstantPool constant_pool) { + // return (SourceFile) clone(); + // } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMap.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMap.java new file mode 100644 index 000000000..29f9c1535 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMap.java @@ -0,0 +1,190 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a stack map attribute used for preverification of Java classes for the + * Java 2 Micro Edition (J2ME). This attribute is used by the KVM and contained + * within the Code attribute of a method. See CLDC specification 5.3.1.2 + * + * @version $Id: StackMap.java,v 1.6 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Code + * @see StackMapEntry + * @see StackMapType + */ +public final class StackMap extends Attribute { + private int map_length; + private StackMapEntry[] map; // Table of stack map entries + + /* + * @param name_index Index of name + * + * @param length Content length in bytes + * + * @param map Table of stack map entries + * + * @param constant_pool Array of constants + */ + public StackMap(int name_index, int length, StackMapEntry[] map, ConstantPool constant_pool) { + super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool); + + setStackMap(map); + } + + /** + * Construct object from file stream. + * + * @param name_index Index of name + * @param length Content length in bytes + * @param file Input stream + * @throws IOException + * @param constant_pool Array of constants + */ + StackMap(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, (StackMapEntry[]) null, constant_pool); + + map_length = file.readUnsignedShort(); + map = new StackMapEntry[map_length]; + + for (int i = 0; i < map_length; i++) + map[i] = new StackMapEntry(file, constant_pool); + } + + /** + * Dump line number table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(map_length); + for (int i = 0; i < map_length; i++) + map[i].dump(file); + } + + /** + * @return Array of stack map entries + */ + public final StackMapEntry[] getStackMap() { + return map; + } + + /** + * @param map Array of stack map entries + */ + public final void setStackMap(StackMapEntry[] map) { + this.map = map; + + map_length = (map == null) ? 0 : map.length; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer("StackMap("); + + for (int i = 0; i < map_length; i++) { + buf.append(map[i].toString()); + + if (i < map_length - 1) + buf.append(", "); + } + + buf.append(')'); + + return buf.toString(); + } + + // + // /** + // * @return deep copy of this attribute + // */ + // public Attribute copy(ConstantPool constant_pool) { + // StackMap c = (StackMap)clone(); + // + // c.map = new StackMapEntry[map_length]; + // for(int i=0; i < map_length; i++) + // c.map[i] = map[i].copy(); + // + // c.cpool = constant_pool; + // return c; + // } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitStackMap(this); + } + + public final int getMapLength() { + return map_length; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapEntry.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapEntry.java new file mode 100644 index 000000000..76bb2ab79 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapEntry.java @@ -0,0 +1,210 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * This class represents a stack map entry recording the types of + * local variables and the the of stack items at a given byte code offset. + * See CLDC specification 5.3.1.2 + * + * @version $Id: StackMapEntry.java,v 1.5 2008/05/28 23:53:02 aclement Exp $ + * @author M. Dahm + * @see StackMap + * @see StackMapType + */ +public final class StackMapEntry implements Cloneable { + private int byte_code_offset; + private int number_of_locals; + private StackMapType[] types_of_locals; + private int number_of_stack_items; + private StackMapType[] types_of_stack_items; + private ConstantPool constant_pool; + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + StackMapEntry(DataInputStream file, ConstantPool constant_pool) throws IOException + { + this(file.readShort(), file.readShort(), null, -1, null, constant_pool); + + types_of_locals = new StackMapType[number_of_locals]; + for(int i=0; i < number_of_locals; i++) + types_of_locals[i] = new StackMapType(file, constant_pool); + + number_of_stack_items = file.readShort(); + types_of_stack_items = new StackMapType[number_of_stack_items]; + for(int i=0; i < number_of_stack_items; i++) + types_of_stack_items[i] = new StackMapType(file, constant_pool); + } + + public StackMapEntry(int byte_code_offset, int number_of_locals, + StackMapType[] types_of_locals, + int number_of_stack_items, + StackMapType[] types_of_stack_items, + ConstantPool constant_pool) { + this.byte_code_offset = byte_code_offset; + this.number_of_locals = number_of_locals; + this.types_of_locals = types_of_locals; + this.number_of_stack_items = number_of_stack_items; + this.types_of_stack_items = types_of_stack_items; + this.constant_pool = constant_pool; + } + + /** + * Dump stack map entry + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeShort(byte_code_offset); + + file.writeShort(number_of_locals); + for(int i=0; i < number_of_locals; i++) + types_of_locals[i].dump(file); + + file.writeShort(number_of_stack_items); + for(int i=0; i < number_of_stack_items; i++) + types_of_stack_items[i].dump(file); + } + + /** + * @return String representation. + */ + public final String toString() { + StringBuffer buf = new StringBuffer("(offset=" + byte_code_offset); + + if(number_of_locals > 0) { + buf.append(", locals={"); + + for(int i=0; i < number_of_locals; i++) { + buf.append(types_of_locals[i]); + if(i < number_of_locals - 1) + buf.append(", "); + } + + buf.append("}"); + } + + if(number_of_stack_items > 0) { + buf.append(", stack items={"); + + for(int i=0; i < number_of_stack_items; i++) { + buf.append(types_of_stack_items[i]); + if(i < number_of_stack_items - 1) + buf.append(", "); + } + + buf.append("}"); + } + + buf.append(")"); + + return buf.toString(); + } + + + public void setByteCodeOffset(int b) { byte_code_offset = b; } + public int getByteCodeOffset() { return byte_code_offset; } + public void setNumberOfLocals(int n) { number_of_locals = n; } + public int getNumberOfLocals() { return number_of_locals; } + public void setTypesOfLocals(StackMapType[] t) { types_of_locals = t; } + public StackMapType[] getTypesOfLocals() { return types_of_locals; } + public void setNumberOfStackItems(int n) { number_of_stack_items = n; } + public int getNumberOfStackItems() { return number_of_stack_items; } + public void setTypesOfStackItems(StackMapType[] t) { types_of_stack_items = t; } + public StackMapType[] getTypesOfStackItems() { return types_of_stack_items; } + + /** + * @return deep copy of this object + */ + public StackMapEntry copy() { + try { + return (StackMapEntry)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(ClassVisitor v) { + v.visitStackMapEntry(this); + } + + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { return constant_pool; } + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapType.java new file mode 100644 index 000000000..b1116abbe --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapType.java @@ -0,0 +1,172 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.Constants; +import java.io.*; + +/** + * This class represents the type of a local variable or item on stack + * used in the StackMap entries. + * + * @version $Id: StackMapType.java,v 1.3 2008/05/28 23:53:02 aclement Exp $ + * @author M. Dahm + * @see StackMapEntry + * @see StackMap + * @see Constants + */ +public final class StackMapType implements Cloneable { + private byte type; + private int index = -1; // Index to CONSTANT_Class or offset + private ConstantPool constant_pool; + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + StackMapType(DataInputStream file, ConstantPool constant_pool) throws IOException + { + this(file.readByte(), -1, constant_pool); + + if(hasIndex()) + setIndex(file.readShort()); + + setConstantPool(constant_pool); + } + + /** + * @param type type tag as defined in the Constants interface + * @param index index to constant pool, or byte code offset + */ + public StackMapType(byte type, int index, ConstantPool constant_pool) { + setType(type); + setIndex(index); + setConstantPool(constant_pool); + } + + public void setType(byte t) { + if((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) + throw new RuntimeException("Illegal type for StackMapType: " + t); + type = t; + } + + public byte getType() { return type; } + public void setIndex(int t) { index = t; } + + /** @return index to constant pool if type == ITEM_Object, or offset + * in byte code, if type == ITEM_NewObject, and -1 otherwise + */ + public int getIndex() { return index; } + + /** + * Dump type entries to file. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(type); + if(hasIndex()) + file.writeShort(getIndex()); + } + + /** @return true, if type is either ITEM_Object or ITEM_NewObject + */ + public final boolean hasIndex() { + return ((type == Constants.ITEM_Object) || + (type == Constants.ITEM_NewObject)); + } + + private String printIndex() { + if(type == Constants.ITEM_Object) + return ", class=" + constant_pool.constantToString(index, Constants.CONSTANT_Class); + else if(type == Constants.ITEM_NewObject) + return ", offset=" + index; + else + return ""; + } + + /** + * @return String representation + */ + public final String toString() { + return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")"; + } + + /** + * @return deep copy of this object + */ + public StackMapType copy() { + try { + return (StackMapType)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } + + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { return constant_pool; } + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Synthetic.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Synthetic.java new file mode 100644 index 000000000..57fe97468 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Synthetic.java @@ -0,0 +1,185 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from Attribute and declares this class as `synthetic', i.e., it needs special handling. The JVM + * specification states "A class member that does not appear in the source code must be marked using a Synthetic attribute." It may + * appear in the ClassFile attribute table, a field_info table or a method_info table. This class is intended to be instantiated + * from the Attribute.readAttribute() method. + * + * @version $Id: Synthetic.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ + * @author M. Dahm + * @see Attribute + */ +public final class Synthetic extends Attribute { + private byte[] bytes; + + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical + * copy. + */ + public Synthetic(Synthetic c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } + + // + // public Synthetic(ConstantPoolGen cpool) { + // super(Constants.ATTR_SYNTHETIC, cpool.addUtf8("Synthetic"), 0, cpool); + // ConstantPoolGen cpg = myGen.getConstantPool(); + // int index = ; + // Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg.getConstantPool()); + // } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8, which should represent the string "Synthetic". + * @param length Content length in bytes - should be zero. + * @param bytes Attribute contents + * @param constant_pool The constant pool this attribute is associated with. + */ + public Synthetic(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { + super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool); + this.bytes = bytes; + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Synthetic(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + + if (length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + System.err.println("Synthetic attribute with length > 0"); + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitSynthetic(this); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (length > 0) + file.write(bytes, 0, length); + } + + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } + + /** + * @param bytes. + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer("Synthetic"); + + if (length > 0) + buf.append(" " + Utility.toHexString(bytes)); + + return buf.toString(); + } + + // /** + // * @return deep copy of this attribute + // */ + // public Attribute copy(ConstantPool constant_pool) { + // Synthetic c = (Synthetic)clone(); + // + // if(bytes != null) + // c.bytes = (byte[])bytes.clone(); + // + // c.cpool = constant_pool; + // return c; + // } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Unknown.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Unknown.java new file mode 100644 index 000000000..416d105b1 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Unknown.java @@ -0,0 +1,215 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class represents a reference to an unknown (i.e., application-specific) attribute of a class. It is instantiated from the + * Attribute.readAttribute() method. Applications that need to read in application-specific attributes should create an AttributeReader implementation and attach it via Attribute.addAttributeReader. + * + * + * @version $Id: Unknown.java,v 1.6 2009/09/15 19:40:12 aclement Exp $ + * @see org.aspectj.apache.bcel.classfile.Attribute + * @author M. Dahm + */ +public final class Unknown extends Attribute { + private byte[] bytes; + private String name; + + // evil static - removed by Andy C - no apparent users (4 Mar 06) + // private static HashMap unknown_attributes = new HashMap(); + + /** + * @return array of unknown attributes, but just one for each kind. + */ + // static Unknown[] getUnknownAttributes() { + // Unknown[] unknowns = new Unknown[unknown_attributes.size()]; + // Iterator entries = unknown_attributes.values().iterator(); + // + // for(int i=0; entries.hasNext(); i++) + // unknowns[i] = (Unknown)entries.next(); + // + // unknown_attributes.clear(); + // return unknowns; + // } + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical + * copy. + */ + public Unknown(Unknown c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } + + /** + * Create a non-standard attribute. + * + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param bytes Attribute contents + * @param constant_pool Array of constants + */ + public Unknown(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { + super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool); + this.bytes = bytes; + + name = ((ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8)).getValue(); + // unknown_attributes.put(name, this); + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Unknown(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + + if (length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the + * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(ClassVisitor v) { + v.visitUnknown(this); + } + + /** + * Dump unknown bytes to file stream. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (length > 0) + file.write(bytes, 0, length); + } + + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } + + /** + * @return name of attribute. + */ + @Override + public String getName() { + return name; + } + + /** + * @param bytes. + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + if (length == 0 || bytes == null) + return "(Unknown attribute " + name + ")"; + + String hex; + if (length > 10) { + byte[] tmp = new byte[10]; + System.arraycopy(bytes, 0, tmp, 0, 10); + hex = Utility.toHexString(tmp) + "... (truncated)"; + } else + hex = Utility.toHexString(bytes); + + return "(Unknown attribute " + name + ": " + hex + ")"; + } + + /** + * @return deep copy of this attribute + */ + // @Override + // public Attribute copy(ConstantPool constant_pool) { + // Unknown c = (Unknown) clone(); + // + // if (bytes != null) + // c.bytes = bytes.clone(); + // + // c.cpool = constant_pool; + // return c; + // } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Utility.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Utility.java new file mode 100644 index 000000000..98f5952ae --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Utility.java @@ -0,0 +1,1094 @@ +package org.aspectj.apache.bcel.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; +import org.aspectj.apache.bcel.generic.Type; +import org.aspectj.apache.bcel.util.ByteSequence; + +/** + * Utility functions that do not really belong to any class in particular. + * + * @version $Id: Utility.java,v 1.14 2009/09/28 16:39:46 aclement Exp $ + * @author M. Dahm + * + * modified: Andy Clement 2-mar-05 Removed unnecessary static and optimized + */ +public abstract class Utility { + + /* + * The 'WIDE' instruction is used in the byte code to allow 16-bit wide indices for local variables. This opcode precedes an + * 'ILOAD', e.g.. The opcode immediately following takes an extra byte which is combined with the following byte to form a + * 16-bit value. + */ + private static boolean wide = false; + + /** + * Convert bit field of flags into string such as 'static final'. + * + * @param access_flags Access flags + * @return String representation of flags + */ + public static final String accessToString(int access_flags) { + return accessToString(access_flags, false); + } + + /** + * Convert bit field of flags into string such as 'static final'. + * + * Special case: Classes compiled with new compilers and with the 'ACC_SUPER' flag would be said to be "synchronized". This is + * because SUN used the same value for the flags 'ACC_SUPER' and 'ACC_SYNCHRONIZED'. + * + * @param access_flags Access flags + * @param for_class access flags are for class qualifiers ? + * @return String representation of flags + */ + public static final String accessToString(int access_flags, boolean for_class) { + StringBuffer buf = new StringBuffer(); + + int p = 0; + for (int i = 0; p < Constants.MAX_ACC_FLAG; i++) { // Loop through known flags + p = pow2(i); + if ((access_flags & p) != 0) { + // Special case: see comment at top of class... + if (for_class && ((p == Constants.ACC_SUPER) || (p == Constants.ACC_INTERFACE))) { + continue; + } + buf.append(Constants.ACCESS_NAMES[i]).append(" "); + } + } + return buf.toString().trim(); + } + + /** + * @return "class" or "interface", depending on the ACC_INTERFACE flag + */ + public static final String classOrInterface(int access_flags) { + return ((access_flags & Constants.ACC_INTERFACE) != 0) ? "interface" : "class"; + } + + /** + * Disassemble a byte array of JVM byte codes starting from code line 'index' and return the disassembled string representation. + * Decode only 'num' opcodes (including their operands), use -1 if you want to decompile everything. + * + * @param code byte code array + * @param constant_pool Array of constants + * @param index offset in `code' array (number of opcodes, not bytes!) + * @param length number of opcodes to decompile, -1 for all + * @param verbose be verbose, e.g. print constant pool index + * @return String representation of byte codes + */ + public static final String codeToString(byte[] code, ConstantPool constant_pool, int index, int length, boolean verbose) { + StringBuffer buf = new StringBuffer(code.length * 20); // Should be sufficient + ByteSequence stream = new ByteSequence(code); + + try { + for (int i = 0; i < index; i++) { + // Skip `index' lines of code + codeToString(stream, constant_pool, verbose); + } + + for (int i = 0; stream.available() > 0; i++) { + if ((length < 0) || (i < length)) { + String indices = fillup(stream.getIndex() + ":", 6, true, ' '); + buf.append(indices + codeToString(stream, constant_pool, verbose) + '\n'); + } + } + } catch (IOException e) { + System.out.println(buf.toString()); + e.printStackTrace(); + throw new ClassFormatException("Byte code error: " + e); + } + + return buf.toString(); + } + + /** + * Disassemble a stream of byte codes and return the string representation. + */ + public static final String codeToString(byte[] code, ConstantPool constant_pool, int index, int length) { + return codeToString(code, constant_pool, index, length, true); + } + + public static final String codeToString(ByteSequence bytes, ConstantPool constant_pool) throws IOException { + return codeToString(bytes, constant_pool, true); + } + + /** + * Shorten long class names, java/lang/String becomes String. + * + * @param str The long class name + * @return Compacted class name + */ + public static final String compactClassName(String str) { + return compactClassName(str, true); + } + + /** + * Shorten long class name str, i.e., chop off the prefix, if the class name starts with this string and the + * flag chopit is true. Slashes / are converted to dots .. + * + * @param str The long class name + * @param prefix The prefix the get rid off + * @param chopit Flag that determines whether chopping is executed or not + * @return Compacted class name + */ + public static final String compactClassName(String str, String prefix, boolean chopit) { + str = str.replace('/', '.'); + if (chopit) { + int len = prefix.length(); + // If string starts with 'prefix' and contains no further dots + if (str.startsWith(prefix)) { + String result = str.substring(len); + if (result.indexOf('.') == -1) { + str = result; + } + } + } + return str; + } + + /** + * Shorten long class names, java/lang/String becomes java.lang.String, e.g.. If chopit is + * true the prefix java.lang is also removed. + * + * @param str The long class name + * @param chopit Flag that determines whether chopping is executed or not + * @return Compacted class name + */ + public static final String compactClassName(String str, boolean chopit) { + return compactClassName(str, "java.lang.", chopit); + } + + public static final String methodSignatureToString(String signature, String name, String access) { + return methodSignatureToString(signature, name, access, true); + } + + public static final String methodSignatureToString(String signature, String name, String access, boolean chopit) { + return methodSignatureToString(signature, name, access, chopit, null); + } + + /** + * This method converts such a string into a Java type declaration like 'void main(String[])' and throws a + * 'ClassFormatException' when the parsed type is invalid. + */ + public static final String methodSignatureToString(String signature, String name, String access, boolean chopit, + LocalVariableTable vars) throws ClassFormatException { + StringBuffer buf = new StringBuffer("("); + String type; + int index; + int var_index = (access.indexOf("static") >= 0) ? 0 : 1; + + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + + index = 1; // current string position + + while (signature.charAt(index) != ')') { + ResultHolder rh = signatureToStringInternal(signature.substring(index), chopit); + String param_type = rh.getResult(); + buf.append(param_type); + + if (vars != null) { + LocalVariable l = vars.getLocalVariable(var_index); + + if (l != null) { + buf.append(" " + l.getName()); + } + } else { + buf.append(" arg" + var_index); + } + + if ("double".equals(param_type) || "long".equals(param_type)) { + var_index += 2; + } else { + var_index++; + } + + buf.append(", "); + index += rh.getConsumedChars(); + } + + index++; + + // Read return type after `)' + type = signatureToString(signature.substring(index), chopit); + + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature); + } + + if (buf.length() > 1) { + buf.setLength(buf.length() - 2); + } + + buf.append(")"); + + return access + ((access.length() > 0) ? " " : "") + // May be an empty string + type + " " + name + buf.toString(); + } + + /** + * Replace all occurences of old in str with new. + * + * @param str String to permute + * @param old String to be replaced + * @param new Replacement string + * @return new String object + */ + public static final String replace(String str, String old, String new_) { + int index, old_index; + StringBuffer buf = new StringBuffer(); + + try { + index = str.indexOf(old); + if (index != -1) { + old_index = 0; + + // While we have something to replace + while ((index = str.indexOf(old, old_index)) != -1) { + buf.append(str.substring(old_index, index)); // append prefix + buf.append(new_); // append replacement + old_index = index + old.length(); // Skip 'old'.length chars + } + + buf.append(str.substring(old_index)); // append rest of string + str = buf.toString(); + } + } catch (StringIndexOutOfBoundsException e) { + System.err.println(e); + } + + return str; + } + + /** + * Converts signature to string with all class names compacted. + * + * @param signature to convert + * @return Human readable signature + */ + public static final String signatureToString(String signature) { + return signatureToString(signature, true); + } + + public static final String signatureToString(String signature, boolean chopit) { + ResultHolder rh = signatureToStringInternal(signature, chopit); + return rh.getResult(); + } + + /** + * This method converts this string into a Java type declaration such as 'String[]' and throws a `ClassFormatException' when the + * parsed type is invalid. + */ + public static final ResultHolder signatureToStringInternal(String signature, boolean chopit) { + int processedChars = 1; // This is the default, read just one char + try { + switch (signature.charAt(0)) { + case 'B': + return ResultHolder.BYTE; + case 'C': + return ResultHolder.CHAR; + case 'D': + return ResultHolder.DOUBLE; + case 'F': + return ResultHolder.FLOAT; + case 'I': + return ResultHolder.INT; + case 'J': + return ResultHolder.LONG; + case 'L': { // Full class name + int index = signature.indexOf(';'); // Look for closing ';' + + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + + if (signature.length() > index + 1 && signature.charAt(index + 1) == '>') { + index = index + 2; + } + + int genericStart = signature.indexOf('<'); + if (genericStart != -1) { + int genericEnd = signature.indexOf('>'); + // FIXME asc going to need a lot more work in here for generics + ResultHolder rh = signatureToStringInternal(signature.substring(genericStart + 1, genericEnd), chopit); + StringBuffer sb = new StringBuffer(); + sb.append(signature.substring(1, genericStart)); + sb.append("<").append(rh.getResult()).append(">"); + ResultHolder retval = new ResultHolder(compactClassName(sb.toString(), chopit), genericEnd + 1); + return retval; + } else { + processedChars = index + 1; // "Lblabla;" `L' and `;' are removed + ResultHolder retval = new ResultHolder(compactClassName(signature.substring(1, index), chopit), processedChars); + return retval; + } + } + + case 'S': + return ResultHolder.SHORT; + case 'Z': + return ResultHolder.BOOLEAN; + + case '[': { // Array declaration + StringBuffer brackets; + int consumedChars, n; + + brackets = new StringBuffer(); // Accumulate []'s + // Count opening brackets and look for optional size argument + for (n = 0; signature.charAt(n) == '['; n++) { + brackets.append("[]"); + } + consumedChars = n; + ResultHolder restOfIt = signatureToStringInternal(signature.substring(n), chopit); + consumedChars += restOfIt.getConsumedChars(); + brackets.insert(0, restOfIt.getResult()); + return new ResultHolder(brackets.toString(), consumedChars); + } + case 'V': + return ResultHolder.VOID; + + default: + throw new ClassFormatException("Invalid signature: `" + signature + "'"); + } + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid signature: " + e + ":" + signature); + } + } + + /** + * Return type of method signature as a byte value as defined in Constants + * + * @param signature in format described above + * @return type of method signature + * @see Constants + */ + public static final byte typeOfMethodSignature(String signature) throws ClassFormatException { + int index; + try { + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + index = signature.lastIndexOf(')') + 1; + return typeOfSignature(signature.substring(index)); + } catch (StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature); + } + } + + /** + * Convert (signed) byte to (unsigned) short value, i.e., all negative values become positive. + */ + private static final short byteToShort(byte b) { + return (b < 0) ? (short) (256 + b) : (short) b; + } + + /** + * Convert bytes into hexidecimal string + * + * @return bytes as hexidecimal string, e.g. 00 FA 12 ... + */ + public static final String toHexString(byte[] bytes) { + StringBuffer buf = new StringBuffer(); + + for (int i = 0; i < bytes.length; i++) { + short b = byteToShort(bytes[i]); + String hex = Integer.toString(b, 0x10); + + // Just one digit, so prepend 0 + if (b < 0x10) { + buf.append('0'); + } + + buf.append(hex); + + if (i < bytes.length - 1) { + buf.append(' '); + } + } + + return buf.toString(); + } + + /** + * Return a string for an integer justified left or right and filled up with 'fill' characters if necessary. + * + * @param i integer to format + * @param length length of desired string + * @param left_justify format left or right + * @param fill fill character + * @return formatted int + */ + public static final String format(int i, int length, boolean left_justify, char fill) { + return fillup(Integer.toString(i), length, left_justify, fill); + } + + /** + * Fillup char with up to length characters with char `fill' and justify it left or right. + * + * @param str string to format + * @param length length of desired string + * @param left_justify format left or right + * @param fill fill character + * @return formatted string + */ + public static final String fillup(String str, int length, boolean left_justify, char fill) { + int len = length - str.length(); + char[] buf = new char[(len < 0) ? 0 : len]; + + for (int j = 0; j < buf.length; j++) { + buf[j] = fill; + } + + if (left_justify) { + return str + new String(buf); + } else { + return new String(buf) + str; + } + } + + /** + * Escape all occurences of newline chars '\n', quotes \", etc. + */ + public static final String convertString(String label) { + char[] ch = label.toCharArray(); + StringBuffer buf = new StringBuffer(); + + for (int i = 0; i < ch.length; i++) { + switch (ch[i]) { + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + case '\"': + buf.append("\\\""); + break; + case '\'': + buf.append("\\'"); + break; + case '\\': + buf.append("\\\\"); + break; + default: + buf.append(ch[i]); + break; + } + } + + return buf.toString(); + } + + /** + * Converts a list of AnnotationGen objects into a set of attributes that can be attached to the class file. + * + * @param cp The constant pool gen where we can create the necessary name refs + * @param annotations A list of AnnotationGen objects + */ + public static Collection getAnnotationAttributes(ConstantPool cp, List annotations) { + + if (annotations.size() == 0) { + return null; + } + + try { + int countVisible = 0; + int countInvisible = 0; + + // put the annotations in the right output stream + for (AnnotationGen a : annotations) { + if (a.isRuntimeVisible()) { + countVisible++; + } else { + countInvisible++; + } + } + + ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); + ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); + DataOutputStream rvaDos = new DataOutputStream(rvaBytes); + DataOutputStream riaDos = new DataOutputStream(riaBytes); + + rvaDos.writeShort(countVisible); + riaDos.writeShort(countInvisible); + + // put the annotations in the right output stream + for (AnnotationGen a : annotations) { + if (a.isRuntimeVisible()) { + a.dump(rvaDos); + } else { + a.dump(riaDos); + } + } + + rvaDos.close(); + riaDos.close(); + + byte[] rvaData = rvaBytes.toByteArray(); + byte[] riaData = riaBytes.toByteArray(); + + int rvaIndex = -1; + int riaIndex = -1; + + if (rvaData.length > 2) { + rvaIndex = cp.addUtf8("RuntimeVisibleAnnotations"); + } + if (riaData.length > 2) { + riaIndex = cp.addUtf8("RuntimeInvisibleAnnotations"); + } + + List newAttributes = new ArrayList(); + if (rvaData.length > 2) { + newAttributes.add(new RuntimeVisAnnos(rvaIndex, rvaData.length, rvaData, cp)); + } + if (riaData.length > 2) { + newAttributes.add(new RuntimeInvisAnnos(riaIndex, riaData.length, riaData, cp)); + } + + return newAttributes; + } catch (IOException e) { + System.err.println("IOException whilst processing annotations"); + e.printStackTrace(); + } + return null; + } + + /** + * Annotations against a class are stored in one of four attribute kinds: - RuntimeVisibleParameterAnnotations - + * RuntimeInvisibleParameterAnnotations + */ + // OPTIMIZE looks heavyweight? + public static Attribute[] getParameterAnnotationAttributes(ConstantPool cp, List[] vec) { + + int visCount[] = new int[vec.length]; + int totalVisCount = 0; + int invisCount[] = new int[vec.length]; + int totalInvisCount = 0; + try { + + for (int i = 0; i < vec.length; i++) { + List l = vec[i]; + if (l != null) { + for (AnnotationGen element : l) { + if (element.isRuntimeVisible()) { + visCount[i]++; + totalVisCount++; + } else { + invisCount[i]++; + totalInvisCount++; + } + } + } + } + + // Lets do the visible ones + ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); + DataOutputStream rvaDos = new DataOutputStream(rvaBytes); + rvaDos.writeByte(vec.length); // First goes number of parameters + + for (int i = 0; i < vec.length; i++) { + rvaDos.writeShort(visCount[i]); + if (visCount[i] > 0) { + List l = vec[i]; + for (AnnotationGen element : l) { + if (element.isRuntimeVisible()) { + element.dump(rvaDos); + } + } + } + } + rvaDos.close(); + + // Lets do the invisible ones + ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); + DataOutputStream riaDos = new DataOutputStream(riaBytes); + riaDos.writeByte(vec.length); // First goes number of parameters + + for (int i = 0; i < vec.length; i++) { + riaDos.writeShort(invisCount[i]); + if (invisCount[i] > 0) { + List l = vec[i]; + for (AnnotationGen element : l) { + if (!element.isRuntimeVisible()) { + element.dump(riaDos); + } + } + } + } + riaDos.close(); + + byte[] rvaData = rvaBytes.toByteArray(); + byte[] riaData = riaBytes.toByteArray(); + + int rvaIndex = -1; + int riaIndex = -1; + + if (totalVisCount > 0) { + rvaIndex = cp.addUtf8("RuntimeVisibleParameterAnnotations"); + } + if (totalInvisCount > 0) { + riaIndex = cp.addUtf8("RuntimeInvisibleParameterAnnotations"); + } + + List newAttributes = new ArrayList(); + + if (totalVisCount > 0) { + newAttributes.add(new RuntimeVisParamAnnos(rvaIndex, rvaData.length, rvaData, cp)); + } + + if (totalInvisCount > 0) { + newAttributes.add(new RuntimeInvisParamAnnos(riaIndex, riaData.length, riaData, cp)); + } + + return newAttributes.toArray(new Attribute[] {}); + } catch (IOException e) { + System.err.println("IOException whilst processing parameter annotations"); + e.printStackTrace(); + } + return null; + } + + public static class ResultHolder { + private String result; + private int consumed; + + public static final ResultHolder BYTE = new ResultHolder("byte", 1); + public static final ResultHolder CHAR = new ResultHolder("char", 1); + public static final ResultHolder DOUBLE = new ResultHolder("double", 1); + public static final ResultHolder FLOAT = new ResultHolder("float", 1); + public static final ResultHolder INT = new ResultHolder("int", 1); + public static final ResultHolder LONG = new ResultHolder("long", 1); + public static final ResultHolder SHORT = new ResultHolder("short", 1); + public static final ResultHolder BOOLEAN = new ResultHolder("boolean", 1); + public static final ResultHolder VOID = new ResultHolder("void", 1); + + public ResultHolder(String s, int c) { + result = s; + consumed = c; + } + + public String getResult() { + return result; + } + + public int getConsumedChars() { + return consumed; + } + } + + /** + * Return type of signature as a byte value as defined in Constants + * + * @param signature in format described above + * @return type of signature + * @see Constants + */ + public static final byte typeOfSignature(String signature) throws ClassFormatException { + try { + switch (signature.charAt(0)) { + case 'B': + return Constants.T_BYTE; + case 'C': + return Constants.T_CHAR; + case 'D': + return Constants.T_DOUBLE; + case 'F': + return Constants.T_FLOAT; + case 'I': + return Constants.T_INT; + case 'J': + return Constants.T_LONG; + case 'L': + return Constants.T_REFERENCE; + case '[': + return Constants.T_ARRAY; + case 'V': + return Constants.T_VOID; + case 'Z': + return Constants.T_BOOLEAN; + case 'S': + return Constants.T_SHORT; + default: + throw new ClassFormatException("Invalid method signature: " + signature); + } + } catch (StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature); + } + } + + public static final byte typeOfSignature(char c) throws ClassFormatException { + switch (c) { + case 'B': + return Constants.T_BYTE; + case 'C': + return Constants.T_CHAR; + case 'D': + return Constants.T_DOUBLE; + case 'F': + return Constants.T_FLOAT; + case 'I': + return Constants.T_INT; + case 'J': + return Constants.T_LONG; + case 'L': + return Constants.T_REFERENCE; + case '[': + return Constants.T_ARRAY; + case 'V': + return Constants.T_VOID; + case 'Z': + return Constants.T_BOOLEAN; + case 'S': + return Constants.T_SHORT; + default: + throw new ClassFormatException("Invalid type of signature: " + c); + } + } + + /** + * Disassemble a stream of byte codes and return the string representation. + * + * @param bytes stream of bytes + * @param constant_pool Array of constants + * @param verbose be verbose, e.g. print constant pool index + * @return String representation of byte code + */ + public static final String codeToString(ByteSequence bytes, ConstantPool constant_pool, boolean verbose) throws IOException { + short opcode = (short) bytes.readUnsignedByte(); + int default_offset = 0, low, high, npairs; + int index, vindex, constant; + int[] match, jump_table; + int no_pad_bytes = 0, offset; + StringBuffer buf = new StringBuffer(Constants.OPCODE_NAMES[opcode]); + + /* + * Special case: Skip (0-3) padding bytes, i.e., the following bytes are 4-byte-aligned + */ + if ((opcode == Constants.TABLESWITCH) || (opcode == Constants.LOOKUPSWITCH)) { + int remainder = bytes.getIndex() % 4; + no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; + + for (int i = 0; i < no_pad_bytes; i++) { + byte b = bytes.readByte(); + if (b != 0) { + System.err.println("Warning: Padding byte != 0 in " + Constants.OPCODE_NAMES[opcode] + ":" + b); + } + } + + // Both cases have a field default_offset in common + default_offset = bytes.readInt(); + } + + switch (opcode) { + /* + * Table switch has variable length arguments. + */ + case Constants.TABLESWITCH: + low = bytes.readInt(); + high = bytes.readInt(); + + offset = bytes.getIndex() - 12 - no_pad_bytes - 1; + default_offset += offset; + + buf.append("\tdefault = " + default_offset + ", low = " + low + ", high = " + high + "("); + + jump_table = new int[high - low + 1]; + for (int i = 0; i < jump_table.length; i++) { + jump_table[i] = offset + bytes.readInt(); + buf.append(jump_table[i]); + if (i < jump_table.length - 1) { + buf.append(", "); + } + } + buf.append(")"); + break; + + /* + * Lookup switch has variable length arguments. + */ + case Constants.LOOKUPSWITCH: { + + npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - no_pad_bytes - 1; + + match = new int[npairs]; + jump_table = new int[npairs]; + default_offset += offset; + + buf.append("\tdefault = " + default_offset + ", npairs = " + npairs + " ("); + + for (int i = 0; i < npairs; i++) { + match[i] = bytes.readInt(); + jump_table[i] = offset + bytes.readInt(); + buf.append("(" + match[i] + ", " + jump_table[i] + ")"); + if (i < npairs - 1) { + buf.append(", "); + } + } + buf.append(")"); + } + break; + + // Two address bytes + offset from start of byte stream form the jump target + case Constants.GOTO: + case Constants.IFEQ: + case Constants.IFGE: + case Constants.IFGT: + case Constants.IFLE: + case Constants.IFLT: + case Constants.JSR: + case Constants.IFNE: + case Constants.IFNONNULL: + case Constants.IFNULL: + case Constants.IF_ACMPEQ: + case Constants.IF_ACMPNE: + case Constants.IF_ICMPEQ: + case Constants.IF_ICMPGE: + case Constants.IF_ICMPGT: + case Constants.IF_ICMPLE: + case Constants.IF_ICMPLT: + case Constants.IF_ICMPNE: + buf.append("\t\t#" + ((bytes.getIndex() - 1) + bytes.readShort())); + break; + + // 32-bit wide jumps + case Constants.GOTO_W: + case Constants.JSR_W: + buf.append("\t\t#" + ((bytes.getIndex() - 1) + bytes.readInt())); + break; + + // Index byte references local variable (register) + case Constants.ALOAD: + case Constants.ASTORE: + case Constants.DLOAD: + case Constants.DSTORE: + case Constants.FLOAD: + case Constants.FSTORE: + case Constants.ILOAD: + case Constants.ISTORE: + case Constants.LLOAD: + case Constants.LSTORE: + case Constants.RET: + if (wide) { + vindex = bytes.readUnsignedShort(); + wide = false; // Clear flag + } else { + vindex = bytes.readUnsignedByte(); + } + buf.append("\t\t%" + vindex); + break; + + /* + * Remember wide byte which is used to form a 16-bit address in the following instruction. Relies on that the method is + * called again with the following opcode. + */ + case Constants.WIDE: + wide = true; + buf.append("\t(wide)"); + break; + + // Array of basic type + case Constants.NEWARRAY: + buf.append("\t\t<" + Constants.TYPE_NAMES[bytes.readByte()] + ">"); + break; + + // Access object/class fields + case Constants.GETFIELD: + case Constants.GETSTATIC: + case Constants.PUTFIELD: + case Constants.PUTSTATIC: + index = bytes.readUnsignedShort(); + buf.append("\t\t" + constant_pool.constantToString(index, Constants.CONSTANT_Fieldref) + + (verbose ? " (" + index + ")" : "")); + break; + + // Operands are references to classes in constant pool + case Constants.NEW: + case Constants.CHECKCAST: + buf.append("\t"); + case Constants.INSTANCEOF: + index = bytes.readUnsignedShort(); + buf.append("\t<" + constant_pool.constantToString(index) + ">" + (verbose ? " (" + index + ")" : "")); + break; + + // Operands are references to methods in constant pool + case Constants.INVOKESPECIAL: + case Constants.INVOKESTATIC: + case Constants.INVOKEVIRTUAL: + index = bytes.readUnsignedShort(); + buf.append("\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : "")); + break; + + case Constants.INVOKEINTERFACE: + index = bytes.readUnsignedShort(); + int nargs = bytes.readUnsignedByte(); // historical, redundant + buf.append("\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")\t" : "") + nargs + "\t" + + bytes.readUnsignedByte()); // Last byte is a reserved + // space + break; + + case Constants.INVOKEDYNAMIC://http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokedynamic + index = bytes.readUnsignedShort(); + bytes.readUnsignedShort(); // zeroes + buf.append("\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : "")); + break; + + // Operands are references to items in constant pool + case Constants.LDC_W: + case Constants.LDC2_W: + index = bytes.readUnsignedShort(); + buf.append("\t\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : "")); + break; + + case Constants.LDC: + index = bytes.readUnsignedByte(); + buf.append("\t\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : "")); + break; + + // Array of references + case Constants.ANEWARRAY: + index = bytes.readUnsignedShort(); + buf.append("\t\t<" + compactClassName(constant_pool.getConstantString(index, Constants.CONSTANT_Class), false) + ">" + + (verbose ? " (" + index + ")" : "")); + break; + + // Multidimensional array of references + case Constants.MULTIANEWARRAY: { + index = bytes.readUnsignedShort(); + int dimensions = bytes.readUnsignedByte(); + + buf.append("\t<" + compactClassName(constant_pool.getConstantString(index, Constants.CONSTANT_Class), false) + ">\t" + + dimensions + (verbose ? " (" + index + ")" : "")); + } + break; + + // Increment local variable + case Constants.IINC: + if (wide) { + vindex = bytes.readUnsignedShort(); + constant = bytes.readShort(); + wide = false; + } else { + vindex = bytes.readUnsignedByte(); + constant = bytes.readByte(); + } + buf.append("\t\t%" + vindex + "\t" + constant); + break; + + default: + if ((Constants.iLen[opcode] - 1) > 0) { + for (int i = 0; i < Constants.TYPE_OF_OPERANDS[opcode].length; i++) { + buf.append("\t\t"); + switch (Constants.TYPE_OF_OPERANDS[opcode][i]) { + case Constants.T_BYTE: + buf.append(bytes.readByte()); + break; + case Constants.T_SHORT: + buf.append(bytes.readShort()); + break; + case Constants.T_INT: + buf.append(bytes.readInt()); + break; + + default: // Never reached + System.err.println("Unreachable default case reached!"); + System.exit(-1); + } + } + } + } + return buf.toString(); + } + + // private helpers + private static final int pow2(int n) { + return 1 << n; + } + + /** + * Convert type to Java method signature, e.g. int[] f(java.lang.String x) becomes (Ljava/lang/String;)[I + * + * @param returnType what the method returns + * @param argTypes what are the argument types + * @return method signature for given type(s). + */ + public static String toMethodSignature(Type returnType, Type[] argTypes) { + StringBuffer buf = new StringBuffer("("); + int length = (argTypes == null) ? 0 : argTypes.length; + for (int i = 0; i < length; i++) { + buf.append(argTypes[i].getSignature()); + } + buf.append(')'); + buf.append(returnType.getSignature()); + return buf.toString(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java new file mode 100644 index 000000000..2e6024580 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java @@ -0,0 +1,73 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ConstantUtf8; + +public class AnnotationElementValue extends ElementValue { + + private AnnotationGen a; + + public AnnotationElementValue(AnnotationGen a, ConstantPool cpool) { + super(ANNOTATION, cpool); + this.a = a; + } + + public AnnotationElementValue(int type, AnnotationGen annotation, ConstantPool cpool) { + super(type, cpool); + assert type == ANNOTATION; + this.a = annotation; + } + + public AnnotationElementValue(AnnotationElementValue value, ConstantPool cpool, boolean copyPoolEntries) { + super(ANNOTATION, cpool); + a = new AnnotationGen(value.getAnnotation(), cpool, copyPoolEntries); + } + + @Override + public void dump(DataOutputStream dos) throws IOException { + dos.writeByte(type); // u1 type of value (ANNOTATION == '@') + a.dump(dos); + } + + @Override + public String stringifyValue() { + StringBuffer sb = new StringBuffer(); + ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(a.getTypeIndex(), Constants.CONSTANT_Utf8); + sb.append(cu8.getValue()); + // haven't really tested this values section: + List pairs = a.getValues(); + if (pairs != null && pairs.size() > 0) { + sb.append("("); + for (int p = 0; p < pairs.size(); p++) { + if (p > 0) { + sb.append(","); + } + sb.append(pairs.get(p).getNameString()).append("=").append(pairs.get(p).getValue().stringifyValue()); + } + sb.append(")"); + } + return sb.toString(); + } + + public AnnotationGen getAnnotation() { + return a; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java new file mode 100644 index 000000000..9a0a42909 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java @@ -0,0 +1,176 @@ +/* ******************************************************************* + * Copyright (c) 2004, 2013 IBM Corporation + * + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ConstantUtf8; +import org.aspectj.apache.bcel.classfile.Utility; +import org.aspectj.apache.bcel.generic.ObjectType; + +public class AnnotationGen { + public static final AnnotationGen[] NO_ANNOTATIONS = new AnnotationGen[0]; + + private int typeIndex; + private List pairs = Collections.emptyList(); + private ConstantPool cpool; + private boolean isRuntimeVisible = false; + + public AnnotationGen(AnnotationGen a, ConstantPool cpool, boolean copyPoolEntries) { + this.cpool = cpool; + if (copyPoolEntries) { + typeIndex = cpool.addUtf8(a.getTypeSignature()); + } else { + typeIndex = a.getTypeIndex(); + } + isRuntimeVisible = a.isRuntimeVisible(); + pairs = copyValues(a.getValues(), cpool, copyPoolEntries); + } + + private List copyValues(List in, ConstantPool cpool, boolean copyPoolEntries) { + List out = new ArrayList(); + for (NameValuePair nvp : in) { + out.add(new NameValuePair(nvp, cpool, copyPoolEntries)); + } + return out; + } + + private AnnotationGen(ConstantPool cpool) { + this.cpool = cpool; + } + + /** + * Retrieve an immutable version of this AnnotationGen + */ + public AnnotationGen(ObjectType type, List pairs, boolean runtimeVisible, ConstantPool cpool) { + this.cpool = cpool; + if (type != null) { + this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects + } + this.pairs = pairs; + isRuntimeVisible = runtimeVisible; + } + + public static AnnotationGen read(DataInputStream dis, ConstantPool cpool, boolean b) throws IOException { + AnnotationGen a = new AnnotationGen(cpool); + a.typeIndex = dis.readUnsignedShort(); + int elemValuePairCount = dis.readUnsignedShort(); + for (int i = 0; i < elemValuePairCount; i++) { + int nidx = dis.readUnsignedShort(); + a.addElementNameValuePair(new NameValuePair(nidx, ElementValue.readElementValue(dis, cpool), cpool)); + } + a.isRuntimeVisible(b); + return a; + } + + public void dump(DataOutputStream dos) throws IOException { + dos.writeShort(typeIndex); // u2 index of type name in cpool + dos.writeShort(pairs.size()); // u2 element_value pair count + for (int i = 0; i < pairs.size(); i++) { + NameValuePair envp = pairs.get(i); + envp.dump(dos); + } + } + + public void addElementNameValuePair(NameValuePair evp) { + if (pairs == Collections.EMPTY_LIST) { + pairs = new ArrayList(); + } + pairs.add(evp); + } + + public int getTypeIndex() { + return typeIndex; + } + + public String getTypeSignature() { + ConstantUtf8 utf8 = (ConstantUtf8) cpool.getConstant(typeIndex); + return utf8.getValue(); + } + + public String getTypeName() { + return Utility.signatureToString(getTypeSignature()); + } + + public List getValues() { + return pairs; + } + + @Override + public String toString() { + StringBuffer s = new StringBuffer(); + s.append("AnnotationGen:[" + getTypeName() + " #" + pairs.size() + " {"); + for (int i = 0; i < pairs.size(); i++) { + s.append(pairs.get(i)); + if (i + 1 < pairs.size()) + s.append(","); + } + s.append("}]"); + return s.toString(); + } + + public String toShortString() { + StringBuffer s = new StringBuffer(); + s.append("@").append(getTypeName()); + if (pairs.size()!=0) { + s.append("("); + for (int i = 0; i < pairs.size(); i++) { + s.append(pairs.get(i)); + if (i + 1 < pairs.size()) + s.append(","); + } + s.append(")"); + } + return s.toString(); + } + + private void isRuntimeVisible(boolean b) { + isRuntimeVisible = b; + } + + public boolean isRuntimeVisible() { + return isRuntimeVisible; + } + + /** + * @return true if the annotation has a value with the specified name and (toString'd) value + */ + public boolean hasNameValuePair(String name, String value) { + for (NameValuePair pair : pairs) { + if (pair.getNameString().equals(name)) { + if (pair.getValue().stringifyValue().equals(value)) { + return true; + } + } + } + return false; + } + + /** + * @return true if the annotation has a value with the specified name + */ + public boolean hasNamedValue(String name) { + for (NameValuePair pair : pairs) { + if (pair.getNameString().equals(name)) { + return true; + } + } + return false; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java new file mode 100644 index 000000000..3dd19af71 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java @@ -0,0 +1,84 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.classfile.ConstantPool; + +public class ArrayElementValue extends ElementValue { + private static final ElementValue[] NO_VALUES = new ElementValue[0]; + + // J5TODO: Should we make this an array or a list? A list would be easier to modify ... + private ElementValue[] evalues = NO_VALUES; + + public ElementValue[] getElementValuesArray() { + return evalues; + } + + public int getElementValuesArraySize() { + return evalues.length; + } + + public ArrayElementValue(ConstantPool cp) { + super(ARRAY, cp); + } + + public ArrayElementValue(int type, ElementValue[] datums, ConstantPool cpool) { + super(type, cpool); + if (type != ARRAY) + throw new RuntimeException("Only element values of type array can be built with this ctor"); + this.evalues = datums; + } + + public ArrayElementValue(ArrayElementValue value, ConstantPool cpool, boolean copyPoolEntries) { + super(ARRAY, cpool); + evalues = new ElementValue[value.getElementValuesArraySize()]; + ElementValue[] in = value.getElementValuesArray(); + for (int i = 0; i < in.length; i++) { + evalues[i] = ElementValue.copy(in[i], cpool, copyPoolEntries); + } + } + + @Override + public void dump(DataOutputStream dos) throws IOException { + dos.writeByte(type); // u1 type of value (ARRAY == '[') + dos.writeShort(evalues.length); + for (int i = 0; i < evalues.length; i++) { + evalues[i].dump(dos); + } + } + + @Override + public String stringifyValue() { + StringBuffer sb = new StringBuffer(); + sb.append("["); + for (int i = 0; i < evalues.length; i++) { + ElementValue element = evalues[i]; + sb.append(element.stringifyValue()); + if ((i + 1) < evalues.length) + sb.append(","); + } + sb.append("]"); + return sb.toString(); + } + + public void addElement(ElementValue gen) { + ElementValue[] old = evalues; + evalues = new ElementValue[evalues.length + 1]; + System.arraycopy(old, 0, evalues, 0, old.length); + evalues[old.length] = gen; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java new file mode 100644 index 000000000..a4e18b6d4 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java @@ -0,0 +1,79 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ConstantUtf8; +import org.aspectj.apache.bcel.generic.ObjectType; + +public class ClassElementValue extends ElementValue { + + // For primitive types and string type, this points to the value entry in the cpool + // For 'class' this points to the class entry in the cpool + private int idx; + + protected ClassElementValue(int typeIdx, ConstantPool cpool) { + super(ElementValue.CLASS, cpool); + this.idx = typeIdx; + } + + public ClassElementValue(ObjectType t, ConstantPool cpool) { + super(ElementValue.CLASS, cpool); + // this.idx = cpool.addClass(t); + idx = cpool.addUtf8(t.getSignature()); + } + + /** + * Return immutable variant of this ClassElementValueGen + */ + // public ElementValueGen getElementValue() { + // return new ClassElementValueGen(type,idx,cpGen); + // } + public ClassElementValue(ClassElementValue value, ConstantPool cpool, boolean copyPoolEntries) { + super(CLASS, cpool); + if (copyPoolEntries) { + // idx = cpool.addClass(value.getClassString()); + idx = cpool.addUtf8(value.getClassString()); + } else { + idx = value.getIndex(); + + } + } + + public int getIndex() { + return idx; + } + + public String getClassString() { + ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); + return cu8.getValue(); + // ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx); + // ConstantUtf8 utf8 = (ConstantUtf8)getConstantPool().getConstant(c.getNameIndex()); + // return utf8.getBytes(); + } + + @Override + public String stringifyValue() { + return getClassString(); + } + + @Override + public void dump(DataOutputStream dos) throws IOException { + dos.writeByte(type); // u1 kind of value + dos.writeShort(idx); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java new file mode 100644 index 000000000..06f7c7273 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java @@ -0,0 +1,135 @@ +/* ******************************************************************* + * Copyright (c) 2004, 2013 IBM, VMware + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.classfile.ConstantPool; + +public abstract class ElementValue { + + public static final int STRING = 's'; + public static final int ENUM_CONSTANT = 'e'; + public static final int CLASS = 'c'; + public static final int ANNOTATION = '@'; + public static final int ARRAY = '['; + + public static final int PRIMITIVE_INT = 'I'; + public static final int PRIMITIVE_BYTE = 'B'; + public static final int PRIMITIVE_CHAR = 'C'; + public static final int PRIMITIVE_DOUBLE = 'D'; + public static final int PRIMITIVE_FLOAT = 'F'; + public static final int PRIMITIVE_LONG = 'J'; + public static final int PRIMITIVE_SHORT = 'S'; + public static final int PRIMITIVE_BOOLEAN = 'Z'; + + protected int type; + protected ConstantPool cpool; + + protected ElementValue(int type, ConstantPool cpool) { + this.type = type; + this.cpool = cpool; + } + + public int getElementValueType() { + return type; + } + + public abstract String stringifyValue(); + + public abstract void dump(DataOutputStream dos) throws IOException; + + public static ElementValue readElementValue(DataInputStream dis, ConstantPool cpGen) throws IOException { + int type = dis.readUnsignedByte(); + switch (type) { + case 'B': // byte + return new SimpleElementValue(PRIMITIVE_BYTE, dis.readUnsignedShort(), cpGen); + case 'C': // char + return new SimpleElementValue(PRIMITIVE_CHAR, dis.readUnsignedShort(), cpGen); + case 'D': // double + return new SimpleElementValue(PRIMITIVE_DOUBLE, dis.readUnsignedShort(), cpGen); + case 'F': // float + return new SimpleElementValue(PRIMITIVE_FLOAT, dis.readUnsignedShort(), cpGen); + case 'I': // int + return new SimpleElementValue(PRIMITIVE_INT, dis.readUnsignedShort(), cpGen); + case 'J': // long + return new SimpleElementValue(PRIMITIVE_LONG, dis.readUnsignedShort(), cpGen); + case 'S': // short + return new SimpleElementValue(PRIMITIVE_SHORT, dis.readUnsignedShort(), cpGen); + case 'Z': // boolean + return new SimpleElementValue(PRIMITIVE_BOOLEAN, dis.readUnsignedShort(), cpGen); + case 's': // String + return new SimpleElementValue(STRING, dis.readUnsignedShort(), cpGen); + + case 'e': // Enum constant + return new EnumElementValue(dis.readUnsignedShort(), dis.readUnsignedShort(), cpGen); + + case 'c': // Class + return new ClassElementValue(dis.readUnsignedShort(), cpGen); + + // FIXME should this be true here? or should it be the value for the containing annotation? + case '@': // Annotation + return new AnnotationElementValue(ANNOTATION, AnnotationGen.read(dis, cpGen, true), cpGen); + + case '[': // Array + int numArrayVals = dis.readUnsignedShort(); + ElementValue[] evalues = new ElementValue[numArrayVals]; + for (int j = 0; j < numArrayVals; j++) { + evalues[j] = ElementValue.readElementValue(dis, cpGen); + } + return new ArrayElementValue(ARRAY, evalues, cpGen); + + default: + throw new RuntimeException("Unexpected element value kind in annotation: " + type); + } + } + + protected ConstantPool getConstantPool() { + return cpool; + } + + /** + * Creates an (modifiable) ElementValueGen copy of an (immutable) ElementValue - constant pool is assumed correct. + */ + public static ElementValue copy(ElementValue value, ConstantPool cpool, boolean copyPoolEntries) { + switch (value.getElementValueType()) { + case 'B': // byte + case 'C': // char + case 'D': // double + case 'F': // float + case 'I': // int + case 'J': // long + case 'S': // short + case 'Z': // boolean + case 's': // String + return new SimpleElementValue((SimpleElementValue) value, cpool, copyPoolEntries); + + case 'e': // Enum constant + return new EnumElementValue((EnumElementValue) value, cpool, copyPoolEntries); + + case '@': // Annotation + return new AnnotationElementValue((AnnotationElementValue) value, cpool, copyPoolEntries); + + case '[': // Array + return new ArrayElementValue((ArrayElementValue) value, cpool, copyPoolEntries); + + case 'c': // Class + return new ClassElementValue((ClassElementValue) value, cpool, copyPoolEntries); + + default: + throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")"); + } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java new file mode 100644 index 000000000..a8b219774 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java @@ -0,0 +1,116 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ConstantUtf8; +import org.aspectj.apache.bcel.generic.ObjectType; + +public class EnumElementValue extends ElementValue { + + // For enum types, these two indices point to the type and value + private int typeIdx; + private int valueIdx; + + /** + * This ctor assumes the constant pool already contains the right type and value - as indicated by typeIdx and valueIdx. This + * ctor is used for deserialization + */ + protected EnumElementValue(int typeIdx, int valueIdx, ConstantPool cpool) { + super(ElementValue.ENUM_CONSTANT, cpool); + if (type != ENUM_CONSTANT) { + throw new RuntimeException("Only element values of type enum can be built with this ctor"); + } + this.typeIdx = typeIdx; + this.valueIdx = valueIdx; + } + + // /** + // * Return immutable variant of this EnumElementValue + // */ + // public ElementValueGen getElementValue() { + // System.err.println("Duplicating value: "+getEnumTypeString()+":"+getEnumValueString()); + // return new EnumElementValueGen(type,typeIdx,valueIdx,cpGen); + // } + + public EnumElementValue(ObjectType t, String value, ConstantPool cpool) { + super(ElementValue.ENUM_CONSTANT, cpool); + typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t); + valueIdx = cpool.addUtf8(value);// was addString(value); + } + + public EnumElementValue(EnumElementValue value, ConstantPool cpool, boolean copyPoolEntries) { + super(ENUM_CONSTANT, cpool); + if (copyPoolEntries) { + typeIdx = cpool.addUtf8(value.getEnumTypeString());// was addClass(value.getEnumTypeString()); + valueIdx = cpool.addUtf8(value.getEnumValueString()); // was addString(value.getEnumValueString()); + } else { + typeIdx = value.getTypeIndex(); + valueIdx = value.getValueIndex(); + } + } + + @Override + public void dump(DataOutputStream dos) throws IOException { + dos.writeByte(type); // u1 type of value (ENUM_CONSTANT == 'e') + dos.writeShort(typeIdx); // u2 + dos.writeShort(valueIdx); // u2 + } + + /** + * return signature and value, something like Lp/Color;RED + */ + @Override + public String stringifyValue() { + StringBuffer sb = new StringBuffer(); + ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(typeIdx, Constants.CONSTANT_Utf8); + sb.append(cu8.getValue()); + cu8 = (ConstantUtf8) cpool.getConstant(valueIdx, Constants.CONSTANT_Utf8); + sb.append(cu8.getValue()); + return sb.toString(); + } + + public String toString() { + StringBuilder s = new StringBuilder("E("); + s.append(getEnumTypeString()).append(" ").append(getEnumValueString()).append(")"); + return s.toString(); + } + + // BCELBUG: Should we need to call utility.signatureToString() on the output here? + public String getEnumTypeString() { + // Constant cc = getConstantPool().getConstant(typeIdx); + // ConstantClass cu8 = (ConstantClass)getConstantPool().getConstant(typeIdx); + // return ((ConstantUtf8)getConstantPool().getConstant(cu8.getNameIndex())).getBytes(); + return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)).getValue(); + // return Utility.signatureToString(cu8.getBytes()); + } + + public String getEnumValueString() { + return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getValue(); + // ConstantString cu8 = (ConstantString)getConstantPool().getConstant(valueIdx); + // return ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); + } + + public int getValueIndex() { + return valueIdx; + } + + public int getTypeIndex() { + return typeIdx; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java new file mode 100644 index 000000000..99b4211ec --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java @@ -0,0 +1,75 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.classfile.ConstantPool; + +public class NameValuePair { + private int nameIdx; + private ElementValue value; + private ConstantPool cpool; + + public NameValuePair(NameValuePair pair, ConstantPool cpool, boolean copyPoolEntries) { + this.cpool = cpool; + // J5ASSERT: + // Could assert nvp.getNameString() points to the same thing as cpool.getConstant(nvp.getNameIndex()) + // if (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes())) { + // throw new RuntimeException("envp buggered"); + // } + if (copyPoolEntries) { + nameIdx = cpool.addUtf8(pair.getNameString()); + } else { + nameIdx = pair.getNameIndex(); + } + value = ElementValue.copy(pair.getValue(), cpool, copyPoolEntries); + } + + protected NameValuePair(int idx, ElementValue value, ConstantPool cpool) { + this.nameIdx = idx; + this.value = value; + this.cpool = cpool; + } + + public NameValuePair(String name, ElementValue value, ConstantPool cpool) { + this.nameIdx = cpool.addUtf8(name); + this.value = value; + this.cpool = cpool; + } + + protected void dump(DataOutputStream dos) throws IOException { + dos.writeShort(nameIdx); // u2 name of the element + value.dump(dos); + } + + public int getNameIndex() { + return nameIdx; + } + + public final String getNameString() { + return cpool.getConstantUtf8(nameIdx).getValue(); + } + + public final ElementValue getValue() { + return value; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(getNameString()).append("=").append(value.stringifyValue()); + return sb.toString(); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java new file mode 100644 index 000000000..ac145087b --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java @@ -0,0 +1,98 @@ +/* ******************************************************************* + * Copyright (c) 2004, 2013 IBM, VMware + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +public abstract class RuntimeAnnos extends Attribute { + + private List annotations; + private boolean visible; + + // Keep just a byte stream of the data until someone actually asks for it + private boolean inflated = false; + private byte[] annotation_data; + + public RuntimeAnnos(byte attrid, boolean visible, int nameIdx, int len, ConstantPool cpool) { + super(attrid, nameIdx, len, cpool); + this.visible = visible; + annotations = new ArrayList(); + } + + public RuntimeAnnos(byte attrid, boolean visible, int nameIdx, int len, byte[] data, ConstantPool cpool) { + super(attrid, nameIdx, len, cpool); + this.visible = visible; + annotations = new ArrayList(); + annotation_data = data; + } + + public List getAnnotations() { + if (!inflated) + inflate(); + return annotations; + } + + public boolean areVisible() { + return visible; + } + + protected void readAnnotations(DataInputStream dis, ConstantPool cpool) throws IOException { + annotation_data = new byte[length]; + dis.readFully(annotation_data, 0, length); + } + + protected void writeAnnotations(DataOutputStream dos) throws IOException { + if (!inflated) { + dos.write(annotation_data, 0, length); + } else { + dos.writeShort(annotations.size()); + for (Iterator i = annotations.iterator(); i.hasNext();) { + AnnotationGen ann = i.next(); + ann.dump(dos); + } + } + } + + + private void inflate() { + try { + DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data)); + int numberOfAnnotations = dis.readUnsignedShort(); + if (numberOfAnnotations > 0) { + List inflatedAnnotations = new ArrayList(); + for (int i = 0; i < numberOfAnnotations; i++) { + inflatedAnnotations.add(AnnotationGen.read(dis, getConstantPool(), visible)); + } + annotations = inflatedAnnotations; + } + dis.close(); + inflated = true; + } catch (IOException ioe) { + throw new RuntimeException("Unabled to inflate annotation data, badly formed? "); + } + } + + /** FOR TESTING ONLY: Tells you if the annotations have been inflated to an object graph */ + public boolean isInflated() { + return inflated; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java new file mode 100644 index 000000000..a6b2e529f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java @@ -0,0 +1,51 @@ +/* ******************************************************************* + * Copyright (c) 2004, 2013 IBM, VMware + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ClassVisitor; + +public class RuntimeInvisAnnos extends RuntimeAnnos { + + public RuntimeInvisAnnos(int nameIdx, int len, ConstantPool cpool) { + super(Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS, false, nameIdx, len, cpool); + } + + public RuntimeInvisAnnos(int nameIdx, int len, + DataInputStream dis,ConstantPool cpool) throws IOException { + this(nameIdx, len, cpool); + readAnnotations(dis,cpool); + } + + public RuntimeInvisAnnos(int nameIndex, int len, byte[] rvaData,ConstantPool cpool) { + super(Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS,false,nameIndex,len,rvaData,cpool); + } + + public void accept(ClassVisitor v) { + v.visitRuntimeInvisibleAnnotations(this); + } + + public final void dump(DataOutputStream dos) throws IOException { + super.dump(dos); + writeAnnotations(dos); + } + + public Attribute copy(ConstantPool constant_pool) { + throw new RuntimeException("Not implemented yet!"); + } +} \ No newline at end of file diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java new file mode 100644 index 000000000..cb2eb8d7a --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java @@ -0,0 +1,45 @@ +/* ******************************************************************* + * Copyright (c) 2004, 2013 IBM, VMware + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataInputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ClassVisitor; + +public class RuntimeInvisParamAnnos extends RuntimeParamAnnos { + + public RuntimeInvisParamAnnos(int nameIdx, int len, ConstantPool cpool) { + super(Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, false, nameIdx, len, cpool); + } + + public RuntimeInvisParamAnnos(int nameIdx, int len, + DataInputStream dis,ConstantPool cpool) throws IOException { + this(nameIdx, len, cpool); + readParameterAnnotations(dis,cpool); + } + + public RuntimeInvisParamAnnos(int nameIndex, int len, byte[] rvaData,ConstantPool cpool) { + super(Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,false,nameIndex,len,rvaData,cpool); + } + + public void accept(ClassVisitor v) { + v.visitRuntimeInvisibleParameterAnnotations(this); + } + + public Attribute copy(ConstantPool constant_pool) { + throw new RuntimeException("Not implemented yet!"); + } +} \ No newline at end of file diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java new file mode 100644 index 000000000..333ccbddd --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java @@ -0,0 +1,36 @@ +/* ******************************************************************* + * Copyright (c) 2013 VMware + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.DataInputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ClassVisitor; + +public class RuntimeInvisTypeAnnos extends RuntimeTypeAnnos { + + public RuntimeInvisTypeAnnos(int nameIdx, int len, DataInputStream dis, + ConstantPool cpool) throws IOException { + this(nameIdx, len, cpool); + readTypeAnnotations(dis, cpool); + } + + public RuntimeInvisTypeAnnos(int nameIdx, int len, ConstantPool cpool) { + super(Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, false, nameIdx, len, cpool); + } + + public void accept(ClassVisitor v) { + v.visitRuntimeInvisibleTypeAnnotations(this); + } +} \ No newline at end of file diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java new file mode 100644 index 000000000..517ebee62 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java @@ -0,0 +1,137 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.annotation; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +public abstract class RuntimeParamAnnos extends Attribute { + + private List parameterAnnotations; + private boolean visible; + + + // Keep just a byte stream of the data until someone actually asks for it + private boolean inflated = false; + private byte[] annotation_data; + + + public RuntimeParamAnnos(byte attrid, boolean visible, + int nameIdx, int len, ConstantPool cpool) { + super(attrid,nameIdx,len,cpool); + this.visible = visible; + parameterAnnotations = new ArrayList(); + } + + public RuntimeParamAnnos(byte attrid,boolean visible,int nameIdx,int len,byte[] data,ConstantPool cpool) { + super(attrid,nameIdx,len,cpool); + this.visible = visible; + parameterAnnotations = new ArrayList(); + annotation_data = data; + } + + public final void dump(DataOutputStream dos) throws IOException { + super.dump(dos); + writeAnnotations(dos); + } + + public Attribute copy(ConstantPool constant_pool) { + throw new RuntimeException("Not implemented yet!"); + } + + /** Return a list of Annotation[] - each list entry contains the annotations for one parameter */ + public List /*Annotation[]*/ getParameterAnnotations() { + if (!inflated) inflate(); + return parameterAnnotations; + } + + public AnnotationGen[] getAnnotationsOnParameter(int parameterIndex) { + if (!inflated) inflate(); + // This may happen. In a ctor for a non static inner type the compiler + // may have added an extra parameter to the generated ctor (the parameter + // contains the instance of the outer class) - in this case + // it may appear that there are more parameters than there are entries + // in the parameter annotations array + if (parameterIndex>=parameterAnnotations.size()) { + return AnnotationGen.NO_ANNOTATIONS; + } + return parameterAnnotations.get(parameterIndex); + } + + public boolean areVisible() { + return visible; + } + + protected void readParameterAnnotations(DataInputStream dis,ConstantPool cpool) throws IOException { + annotation_data = new byte[length]; + dis.readFully(annotation_data,0,length); + } + + private void inflate() { + try { + DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data)); + int numParameters = dis.readUnsignedByte(); + if (numParameters > 0) { + List inflatedParameterAnnotations = new ArrayList(); + for (int i=0; i(); +// annotation_data = data; +// } + + public Attribute copy(ConstantPool constant_pool) { + throw new RuntimeException("Not implemented yet!"); + } + + public TypeAnnotationGen[] getTypeAnnotations() { + ensureInflated(); + return typeAnnotations; + } + + + public boolean areVisible() { + return visible; + } + + private void ensureInflated() { + if (typeAnnotations !=null) { + return; + } + try { + DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data)); + int numTypeAnnotations = dis.readUnsignedShort(); + if (numTypeAnnotations == 0) { + typeAnnotations = TypeAnnotationGen.NO_TYPE_ANNOTATIONS; + } else { + typeAnnotations = new TypeAnnotationGen[numTypeAnnotations]; + for (int i=0; i copyValues(List in, ConstantPool cpool, boolean copyPoolEntries) { +// List out = new ArrayList(); +// for (NameValuePair nvp : in) { +// out.add(new NameValuePair(nvp, cpool, copyPoolEntries)); +// } +// return out; +// } +// +// +// /** +// * Retrieve an immutable version of this AnnotationGen +// */ +// public TypeAnnotationGen(ObjectType type, List pairs, boolean runtimeVisible, ConstantPool cpool) { +// this.cpool = cpool; +// if (type != null) { +// this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects +// } +// this.pairs = pairs; +// isRuntimeVisible = runtimeVisible; +// } +// + + public int[] getTypePath() { + return typePath; + } + + public String getTypePathString() { + return toTypePathString(typePath); + } + + public static String toTypePathString(int[] typepath) { + StringBuilder sb = new StringBuilder(); + int count = 0; + sb.append("["); + while (count < typepath.length) { + if (count>0) sb.append(","); + switch (typepath[count++]) { + case TYPE_PATH_ENTRY_KIND_ARRAY: + sb.append("ARRAY"); + count++; + break; + case TYPE_PATH_ENTRY_KIND_INNER_TYPE: + sb.append("INNER_TYPE"); + count++; + break; + case TYPE_PATH_ENTRY_KIND_WILDCARD: + sb.append("WILDCARD"); + count++; + break; + case TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT: + sb.append("TYPE_ARGUMENT(").append(typepath[count++]).append(")"); + break; + } + } + sb.append("]"); + return sb.toString(); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ArrayType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ArrayType.java new file mode 100644 index 000000000..d9599289b --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ArrayType.java @@ -0,0 +1,156 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import org.aspectj.apache.bcel.Constants; + +/** + * Denotes array type, such as int[][] + * + * @version $Id: ArrayType.java,v 1.4 2008/08/26 15:02:04 aclement Exp $ + * @author M. Dahm + */ +public final class ArrayType extends ReferenceType { + private int dimensions; + private Type basic_type; + + /** + * Convenience constructor for array type, e.g. int[] + * + * @param type array type, e.g. T_INT + */ + public ArrayType(byte type, int dimensions) { + this(BasicType.getType(type), dimensions); + } + + /** + * Convenience constructor for reference array type, e.g. Object[] + * + * @param class_name complete name of class (java.lang.String, e.g.) + */ + public ArrayType(String class_name, int dimensions) { + this(new ObjectType(class_name), dimensions); + } + + /** + * Constructor for array of given type + * + * @param type type of array (may be an array itself) + */ + public ArrayType(Type type, int dimensions) { + super(Constants.T_ARRAY, ""); + + if((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) + throw new ClassGenException("Invalid number of dimensions: " + dimensions); + + switch(type.getType()) { + case Constants.T_ARRAY: + ArrayType array = (ArrayType)type; + this.dimensions = dimensions + array.dimensions; + basic_type = array.basic_type; + break; + + case Constants.T_VOID: + throw new ClassGenException("Invalid type: void[]"); + + default: // Basic type or reference + this.dimensions = dimensions; + basic_type = type; + break; + } + + StringBuffer buf = new StringBuffer(); + for(int i=0; i < this.dimensions; i++) + buf.append('['); + + buf.append(basic_type.getSignature()); + + signature = buf.toString(); + } + + /** + * @return basic type of array, i.e., for int[][][] the basic type is int + */ + public Type getBasicType() { + return basic_type; + } + + /** + * @return element type of array, i.e., for int[][][] the element type is int[][] + */ + public Type getElementType() { + if(dimensions == 1) + return basic_type; + else + return new ArrayType(basic_type, dimensions - 1); + } + + /** @return number of dimensions of array + */ + public int getDimensions() { return dimensions; } + + /** @return a hash code value for the object. + */ + public int hashCode() { return basic_type.hashCode() ^ dimensions; } + + /** @return true if both type objects refer to the same array type. + */ + public boolean equals(Object type) { + if(type instanceof ArrayType) { + ArrayType array = (ArrayType)type; + return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); + } else + return false; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BasicType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BasicType.java new file mode 100644 index 000000000..477fb1dff --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BasicType.java @@ -0,0 +1,111 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import org.aspectj.apache.bcel.Constants; + +/** + * Denotes basic type such as int. + * + * @version $Id: BasicType.java,v 1.4 2008/08/28 00:05:57 aclement Exp $ + * @author M. Dahm + */ +public final class BasicType extends Type { + /** + * Constructor for basic types such as int, long, `void' + * + * @param type one of T_INT, T_BOOLEAN, ..., T_VOID + * @see org.aspectj.apache.bcel.Constants + */ + BasicType(byte type) { + super(type, Constants.SHORT_TYPE_NAMES[type]); + + if (type < Constants.T_BOOLEAN || type > Constants.T_VOID) { + throw new ClassGenException("Invalid type: " + type); + } + } + + public static final BasicType getType(byte type) { + switch (type) { + case Constants.T_VOID: + return VOID; + case Constants.T_BOOLEAN: + return BOOLEAN; + case Constants.T_BYTE: + return BYTE; + case Constants.T_SHORT: + return SHORT; + case Constants.T_CHAR: + return CHAR; + case Constants.T_INT: + return INT; + case Constants.T_LONG: + return LONG; + case Constants.T_DOUBLE: + return DOUBLE; + case Constants.T_FLOAT: + return FLOAT; + + default: + throw new ClassGenException("Invalid type: " + type); + } + } + + /** + * @return true if both type objects refer to the same type + */ + public boolean equals(Object type) { + return type instanceof BasicType ? ((BasicType) type).type == this.type : false; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BranchHandle.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BranchHandle.java new file mode 100644 index 000000000..35d9528b8 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BranchHandle.java @@ -0,0 +1,134 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * BranchHandle is returned by specialized InstructionList.append() whenever a BranchInstruction is appended. This is useful when + * the target of this instruction is not known at time of creation and must be set later via setTarget(). + * + * @see InstructionHandle + * @see Instruction + * @see InstructionList + * @version $Id: BranchHandle.java,v 1.5 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public final class BranchHandle extends InstructionHandle { + private InstructionBranch bi; // An alias in fact, but saves lots of casts + + private BranchHandle(InstructionBranch i) { + super(i); + bi = i; + } + + static final BranchHandle getBranchHandle(InstructionBranch i) { + return new BranchHandle(i); + } + + /* + * Override InstructionHandle methods: delegate to branch instruction. Through this overriding all access to the private + * i_position field should be prevented. + */ + public int getPosition() { + return bi.positionOfThisInstruction; + } + + void setPosition(int pos) { + this.pos = bi.positionOfThisInstruction = pos; + } + + /** + * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length + * instructions 'setPositions()' performs multiple passes over the instruction list to calculate the correct (byte) positions + * and offsets by calling this function. + * + * @param offset additional offset caused by preceding (variable length) instructions + * @param max_offset the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's length + */ + protected int updatePosition(int offset, int max_offset) { + int x = bi.updatePosition(offset, max_offset); + pos = bi.positionOfThisInstruction; + return x; + } + + /** + * Pass new target to instruction. + */ + public void setTarget(InstructionHandle ih) { + bi.setTarget(ih); + } + + /** + * Update target of instruction. + */ + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + bi.updateTarget(old_ih, new_ih); + } + + /** + * @return target of instruction. + */ + public InstructionHandle getTarget() { + return bi.getTarget(); + } + + /** + * Set new contents. Old instruction is disposed and may not be used anymore. + */ + public void setInstruction(Instruction i) { + super.setInstruction(i); + bi = (InstructionBranch) i; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGen.java new file mode 100644 index 000000000..4ba767d97 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGen.java @@ -0,0 +1,637 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.lang.reflect.Modifier; +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.Field; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.Modifiers; +import org.aspectj.apache.bcel.classfile.SourceFile; +import org.aspectj.apache.bcel.classfile.Utility; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; + +/** + * Template class for building up a java class. May be initialized with an existing java class. + * + * @see JavaClass + * @version $Id: ClassGen.java,v 1.15 2009/09/15 19:40:14 aclement Exp $ + * @author M. Dahm + * + * Upgraded, Andy Clement 9th Mar 06 - calculates SUID + */ +public class ClassGen extends Modifiers implements Cloneable { + + private String classname; + private String superclassname; + private String filename; + private int classnameIndex = -1; + private int superclassnameIndex = -1; + private int major = Constants.MAJOR_1_1; + private int minor = Constants.MINOR_1_1; + private ConstantPool cpool; + private List fieldsList = new ArrayList(); + private List methodsList = new ArrayList(); + private List attributesList = new ArrayList(); + private List interfaceList = new ArrayList(); + private List annotationsList = new ArrayList(); + + public ClassGen(String classname, String superclassname, String filename, int modifiers, String[] interfacenames, + ConstantPool cpool) { + this.classname = classname; + this.superclassname = superclassname; + this.filename = filename; + this.modifiers = modifiers; + this.cpool = cpool; + if (filename != null) { + addAttribute(new SourceFile(cpool.addUtf8("SourceFile"), 2, cpool.addUtf8(filename), cpool)); + } + this.classnameIndex = cpool.addClass(classname); + this.superclassnameIndex = cpool.addClass(superclassname); + if (interfacenames != null) { + for (String interfacename : interfacenames) { + addInterface(interfacename); + } + } + } + + public ClassGen(String classname, String superclassname, String filename, int modifiers, String[] interfacenames) { + this(classname, superclassname, filename, modifiers, interfacenames, new ConstantPool()); + } + + public ClassGen(JavaClass clazz) { + classnameIndex = clazz.getClassNameIndex(); + superclassnameIndex = clazz.getSuperclassNameIndex(); + classname = clazz.getClassName(); + superclassname = clazz.getSuperclassName(); + filename = clazz.getSourceFileName(); + modifiers = clazz.getModifiers(); + cpool = clazz.getConstantPool().copy(); + major = clazz.getMajor(); + minor = clazz.getMinor(); + + Method[] methods = clazz.getMethods(); + Field[] fields = clazz.getFields(); + String[] interfaces = clazz.getInterfaceNames(); + + for (int i = 0; i < interfaces.length; i++) { + addInterface(interfaces[i]); + } + + // OPTIMIZE Could make unpacking lazy, done on first reference + Attribute[] attributes = clazz.getAttributes(); + for (Attribute attr : attributes) { + if (attr instanceof RuntimeVisAnnos) { + RuntimeVisAnnos rva = (RuntimeVisAnnos) attr; + List annos = rva.getAnnotations(); + for (AnnotationGen a : annos) { + annotationsList.add(new AnnotationGen(a, cpool, false)); + } + } else if (attr instanceof RuntimeInvisAnnos) { + RuntimeInvisAnnos ria = (RuntimeInvisAnnos) attr; + List annos = ria.getAnnotations(); + for (AnnotationGen anno : annos) { + annotationsList.add(new AnnotationGen(anno, cpool, false)); + } + } else { + attributesList.add(attr); + } + } + + for (int i = 0; i < methods.length; i++) { + addMethod(methods[i]); + } + + for (int i = 0; i < fields.length; i++) { + addField(fields[i]); + } + } + + /** + * @return build and return a JavaClass + */ + public JavaClass getJavaClass() { + int[] interfaces = getInterfaces(); + Field[] fields = getFields(); + Method[] methods = getMethods(); + + Collection attributes = null; + if (annotationsList.size() == 0) { + attributes = attributesList; + } else { + // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations' + attributes = new ArrayList(); + attributes.addAll(Utility.getAnnotationAttributes(cpool, annotationsList)); + attributes.addAll(attributesList); + } + + // Must be last since the above calls may still add something to it + ConstantPool cp = this.cpool.getFinalConstantPool(); + + return new JavaClass(classnameIndex, superclassnameIndex, filename, major, minor, modifiers, cp, interfaces, fields, + methods, attributes.toArray(new Attribute[attributes.size()]));// OPTIMIZE avoid toArray()? + } + + public void addInterface(String name) { + interfaceList.add(name); + } + + public void removeInterface(String name) { + interfaceList.remove(name); + } + + public int getMajor() { + return major; + } + + public void setMajor(int major) { + this.major = major; + } + + public void setMinor(int minor) { + this.minor = minor; + } + + public int getMinor() { + return minor; + } + + public void addAttribute(Attribute a) { + attributesList.add(a); + } + + public void addAnnotation(AnnotationGen a) { + annotationsList.add(a); + } + + public void addMethod(Method m) { + methodsList.add(m); + } + + /** + * Convenience method. + * + * Add an empty constructor to this class that does nothing but calling super(). + * + * @param access rights for constructor + */ + public void addEmptyConstructor(int access_flags) { + InstructionList il = new InstructionList(); + il.append(InstructionConstants.THIS); // Push `this' + il.append(new InvokeInstruction(Constants.INVOKESPECIAL, cpool.addMethodref(superclassname, "", "()V"))); + il.append(InstructionConstants.RETURN); + + MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "", classname, il, cpool); + mg.setMaxStack(1); + mg.setMaxLocals(); + addMethod(mg.getMethod()); + } + + /** + * Add a field to this class. + * + * @param f field to add + */ + public void addField(Field f) { + fieldsList.add(f); + } + + public boolean containsField(Field f) { + return fieldsList.contains(f); + } + + /** + * @return field object with given name, or null if not found + */ + public Field findsField(String name) { + for (Field field : fieldsList) { + if (field.getName().equals(name)) { + return field; + } + } + return null; + } + + /** + * @return method object with given name and signature, or null if not found + */ + public Method containsMethod(String name, String signature) { + for (Method method : methodsList) { + if (method.getName().equals(name) && method.getSignature().equals(signature)) { + return method; + } + } + return null; + } + + public void removeAttribute(Attribute a) { + attributesList.remove(a); + } + + public void removeAnnotation(AnnotationGen a) { + annotationsList.remove(a); + } + + public void removeMethod(Method m) { + methodsList.remove(m); + } + + /** + * Replace given method with new one. If the old one does not exist add the new_ method to the class anyway. + */ + public void replaceMethod(Method old, Method new_) { + if (new_ == null) + throw new ClassGenException("Replacement method must not be null"); + + int i = methodsList.indexOf(old); + + if (i < 0) + methodsList.add(new_); + else + methodsList.set(i, new_); + } + + /** + * Replace given field with new one. If the old one does not exist add the new_ field to the class anyway. + */ + public void replaceField(Field old, Field new_) { + if (new_ == null) + throw new ClassGenException("Replacement method must not be null"); + + int i = fieldsList.indexOf(old); + + if (i < 0) + fieldsList.add(new_); + else + fieldsList.set(i, new_); + } + + public void removeField(Field f) { + fieldsList.remove(f); + } + + public String getClassName() { + return classname; + } + + public String getSuperclassName() { + return superclassname; + } + + public String getFileName() { + return filename; + } + + public void setClassName(String name) { + classname = name.replace('/', '.'); + classnameIndex = cpool.addClass(name); + } + + public void setSuperclassName(String name) { + superclassname = name.replace('/', '.'); + superclassnameIndex = cpool.addClass(name); + } + + public Method[] getMethods() { + Method[] methods = new Method[methodsList.size()]; + methodsList.toArray(methods); + return methods; + } + + public void setMethods(Method[] methods) { + methodsList.clear(); + for (int m = 0; m < methods.length; m++) + addMethod(methods[m]); + } + + public void setFields(Field[] fs) { + fieldsList.clear(); + for (int m = 0; m < fs.length; m++) + addField(fs[m]); + } + + public void setMethodAt(Method method, int pos) { + methodsList.set(pos, method); + } + + public Method getMethodAt(int pos) { + return methodsList.get(pos); + } + + public String[] getInterfaceNames() { + int size = interfaceList.size(); + String[] interfaces = new String[size]; + + interfaceList.toArray(interfaces); + return interfaces; + } + + public int[] getInterfaces() { + int size = interfaceList.size(); + int[] interfaces = new int[size]; + + for (int i = 0; i < size; i++) + interfaces[i] = cpool.addClass(interfaceList.get(i)); + + return interfaces; + } + + public Field[] getFields() { + Field[] fields = new Field[fieldsList.size()]; + fieldsList.toArray(fields); + return fields; + } + + public Collection getAttributes() { + return attributesList; + } + + // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here? + public AnnotationGen[] getAnnotations() { + AnnotationGen[] annotations = new AnnotationGen[annotationsList.size()]; + annotationsList.toArray(annotations); + return annotations; + } + + public ConstantPool getConstantPool() { + return cpool; + } + + public void setConstantPool(ConstantPool constant_pool) { + cpool = constant_pool; + } + + public void setClassNameIndex(int class_name_index) { + this.classnameIndex = class_name_index; + classname = cpool.getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.'); + } + + public void setSuperclassNameIndex(int superclass_name_index) { + this.superclassnameIndex = superclass_name_index; + superclassname = cpool.getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.'); + } + + public int getSuperclassNameIndex() { + return superclassnameIndex; + } + + public int getClassNameIndex() { + return classnameIndex; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } + + public final boolean isAnnotation() { + return (modifiers & Constants.ACC_ANNOTATION) != 0; + } + + public final boolean isEnum() { + return (modifiers & Constants.ACC_ENUM) != 0; + } + + /** + * Calculate the SerialVersionUID for a class. + */ + public long getSUID() { + try { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + + // 1. classname + dos.writeUTF(getClassName()); + + // 2. classmodifiers: ACC_PUBLIC, ACC_FINAL, ACC_INTERFACE, and ACC_ABSTRACT + int classmods = 0; + classmods |= (isPublic() ? Constants.ACC_PUBLIC : 0); + classmods |= (isFinal() ? Constants.ACC_FINAL : 0); + classmods |= (isInterface() ? Constants.ACC_INTERFACE : 0); + + if (isAbstract()) { + // if an interface then abstract is only set if it has methods + if (isInterface()) { + if (methodsList.size() > 0) + classmods |= Constants.ACC_ABSTRACT; + } else { + classmods |= Constants.ACC_ABSTRACT; + } + } + + dos.writeInt(classmods); + + // 3. ordered list of interfaces + String[] names = getInterfaceNames(); + if (names != null) { + Arrays.sort(names); + for (int i = 0; i < names.length; i++) + dos.writeUTF(names[i]); + } + + // 4. ordered list of fields (ignoring private static and private transient fields): + // (relevant modifiers are ACC_PUBLIC, ACC_PRIVATE, + // ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, + // ACC_TRANSIENT) + List relevantFields = new ArrayList(); + for (Field field : fieldsList) { + if (!(field.isPrivate() && field.isStatic()) && !(field.isPrivate() && field.isTransient())) { + relevantFields.add(field); + } + } + Collections.sort(relevantFields, new FieldComparator()); + int relevantFlags = Constants.ACC_PUBLIC | Constants.ACC_PRIVATE | Constants.ACC_PROTECTED | Constants.ACC_STATIC + | Constants.ACC_FINAL | Constants.ACC_VOLATILE | Constants.ACC_TRANSIENT; + for (Field f : relevantFields) { + dos.writeUTF(f.getName()); + dos.writeInt(relevantFlags & f.getModifiers()); + dos.writeUTF(f.getType().getSignature()); + } + + // some up front method processing: discover clinit, init and ordinary methods of interest: + List relevantMethods = new ArrayList(); + List relevantCtors = new ArrayList(); + boolean hasClinit = false; + for (Method m : methodsList) { + boolean couldBeInitializer = m.getName().charAt(0) == '<'; + if (couldBeInitializer && m.getName().equals("")) { + hasClinit = true; + } else if (couldBeInitializer && m.getName().equals("")) { + if (!m.isPrivate()) + relevantCtors.add(m); + } else { + if (!m.isPrivate()) + relevantMethods.add(m); + } + } + Collections.sort(relevantCtors, new ConstructorComparator()); + Collections.sort(relevantMethods, new MethodComparator()); + + // 5. If a class initializer exists, write out the following: + // 1. The name of the method, . + // 2. The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer. + // 3. The descriptor of the method, ()V. + if (hasClinit) { + dos.writeUTF(""); + dos.writeInt(Modifier.STATIC); + dos.writeUTF("()V"); + } + + // for methods and constructors: + // ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, + // ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT + relevantFlags = Constants.ACC_PUBLIC | Constants.ACC_PRIVATE | Constants.ACC_PROTECTED | Constants.ACC_STATIC + | Constants.ACC_FINAL | Constants.ACC_SYNCHRONIZED | Constants.ACC_NATIVE | Constants.ACC_ABSTRACT + | Constants.ACC_STRICT; + + // 6. sorted non-private constructors + for (Method ctor : relevantCtors) { + dos.writeUTF(ctor.getName()); // + dos.writeInt(relevantFlags & ctor.getModifiers()); + dos.writeUTF(ctor.getSignature().replace('/', '.')); + } + + // 7. sorted non-private methods + for (Method m : relevantMethods) { + dos.writeUTF(m.getName()); + dos.writeInt(relevantFlags & m.getModifiers()); + dos.writeUTF(m.getSignature().replace('/', '.')); + } + dos.flush(); + dos.close(); + byte[] bs = baos.toByteArray(); + MessageDigest md = MessageDigest.getInstance("SHA"); + byte[] result = md.digest(bs); + + long suid = 0L; + int pos = result.length > 8 ? 7 : result.length - 1; // use the bytes we have + while (pos >= 0) { + suid = suid << 8 | ((long) result[pos--] & 0xff); + } + + // if it was definetly 8 everytime... + // long suid = ((long)(sha[0]&0xff) | (long)(sha[1]&0xff) << 8 | + // (long)(sha[2]&0xff) << 16 | (long)(sha[3]&0xff) << 24 | + // (long)(sha[4]&0xff) << 32 | (long)(sha[5]&0xff) << 40 | + // (long)(sha[6]&0xff) << 48 | (long)(sha[7]&0xff) << 56); + return suid; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Unable to calculate suid for " + getClassName() + ": " + e.toString()); + } + } + + private static class FieldComparator implements Comparator { + public int compare(Field f0, Field f1) { + return f0.getName().compareTo(f1.getName()); + } + } + + private static class ConstructorComparator implements Comparator { + public int compare(Method m0, Method m1) { + // can ignore the name... + return (m0).getSignature().compareTo(m1.getSignature()); + } + } + + private static class MethodComparator implements Comparator { + public int compare(Method m0, Method m1) { + int result = m0.getName().compareTo(m1.getName()); + if (result == 0) { + result = m0.getSignature().compareTo(m1.getSignature()); + } + return result; + } + } + + public boolean hasAttribute(String attributeName) { + for (Attribute attr : attributesList) { + if (attr.getName().equals(attributeName)) { + return true; + } + } + return false; + } + + public Attribute getAttribute(String attributeName) { + for (Attribute attr : attributesList) { + if (attr.getName().equals(attributeName)) { + return attr; + } + } + return null; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGenException.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGenException.java new file mode 100644 index 000000000..b981dc8dc --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGenException.java @@ -0,0 +1,68 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared + * in the throws clause every time. + * + * @version $Id: ClassGenException.java,v 1.3 2008/05/28 23:52:57 aclement Exp $ + * @author M. Dahm + */ +public class ClassGenException extends RuntimeException { + public ClassGenException() { super(); } + public ClassGenException(String s) { super(s); } +} + diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/CodeExceptionGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/CodeExceptionGen.java new file mode 100644 index 000000000..01b839207 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/CodeExceptionGen.java @@ -0,0 +1,202 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.classfile.CodeException; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +/** + * This class represents an exception handler, i.e., specifies the region where + * a handler is active and an instruction where the actual handling is done. + * pool as parameters. Opposed to the JVM specification the end of the handled + * region is set to be inclusive, i.e. all instructions between start and end + * are protected including the start and end instructions (handles) themselves. + * The end of the region is automatically mapped to be exclusive when calling + * getCodeException(), i.e., there is no difference semantically. + * + * @version $Id: CodeExceptionGen.java,v 1.5 2008/05/28 23:52:56 aclement Exp $ + * @author M. Dahm + * @see MethodGen + * @see CodeException + * @see InstructionHandle + */ +public final class CodeExceptionGen + implements InstructionTargeter, Cloneable, java.io.Serializable { + private InstructionHandle start_pc; + private InstructionHandle end_pc; + private InstructionHandle handler_pc; + private ObjectType catch_type; + + /** + * Add an exception handler, i.e., specify region where a handler is active and an + * instruction where the actual handling is done. + * + * @param start_pc Start of handled region (inclusive) + * @param end_pc End of handled region (inclusive) + * @param handler_pc Where handling is done + * @param catch_type which exception is handled, null for ANY + */ + public CodeExceptionGen(InstructionHandle start_pc, InstructionHandle end_pc, + InstructionHandle handler_pc, ObjectType catch_type) { + setStartPC(start_pc); + setEndPC(end_pc); + setHandlerPC(handler_pc); + this.catch_type = catch_type; + } + + /** + * Get CodeException object.
+ * + * This relies on that the instruction list has already been dumped + * to byte code or or that the `setPositions' methods has been + * called for the instruction list. + * + * @param cp constant pool + */ + public CodeException getCodeException(ConstantPool cp) { + return new CodeException(start_pc.getPosition(), + end_pc.getPosition() + end_pc.getInstruction().getLength(), + handler_pc.getPosition(), + (catch_type == null)? 0 : cp.addClass(catch_type)); + } + + /* Set start of handler + * @param start_pc Start of handled region (inclusive) + */ + public void setStartPC(InstructionHandle start_pc) { + InstructionBranch.notifyTarget(this.start_pc, start_pc, this); + this.start_pc = start_pc; + } + + /* Set end of handler + * @param end_pc End of handled region (inclusive) + */ + public void setEndPC(InstructionHandle end_pc) { + InstructionBranch.notifyTarget(this.end_pc, end_pc, this); + this.end_pc = end_pc; + } + + /* Set handler code + * @param handler_pc Start of handler + */ + public void setHandlerPC(InstructionHandle handler_pc) { + InstructionBranch.notifyTarget(this.handler_pc, handler_pc, this); + this.handler_pc = handler_pc; + } + + /** + * @param old_ih old target, either start or end + * @param new_ih new target + */ + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + boolean targeted = false; + + if(start_pc == old_ih) { + targeted = true; + setStartPC(new_ih); + } + + if(end_pc == old_ih) { + targeted = true; + setEndPC(new_ih); + } + + if(handler_pc == old_ih) { + targeted = true; + setHandlerPC(new_ih); + } + + if(!targeted) + throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", " + + end_pc + ", " + handler_pc + "}"); + } + + /** + * @return true, if ih is target of this handler + */ + public boolean containsTarget(InstructionHandle ih) { + return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); + } + + /** Sets the type of the Exception to catch. Set 'null' for ANY. */ + public void setCatchType(ObjectType catch_type) { this.catch_type = catch_type; } + /** Gets the type of the Exception to catch, 'null' for ANY. */ + public ObjectType getCatchType() { return catch_type; } + + /** @return start of handled region (inclusive) + */ + public InstructionHandle getStartPC() { return start_pc; } + + /** @return end of handled region (inclusive) + */ + public InstructionHandle getEndPC() { return end_pc; } + + /** @return start of handler + */ + public InstructionHandle getHandlerPC() { return handler_pc; } + + public String toString() { + return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; + } + + public Object clone() { + try { + return super.clone(); + } catch(CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGen.java new file mode 100644 index 000000000..6a12a8c80 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGen.java @@ -0,0 +1,245 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.util.Iterator; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.Constant; +import org.aspectj.apache.bcel.classfile.ConstantDouble; +import org.aspectj.apache.bcel.classfile.ConstantFloat; +import org.aspectj.apache.bcel.classfile.ConstantInteger; +import org.aspectj.apache.bcel.classfile.ConstantLong; +import org.aspectj.apache.bcel.classfile.ConstantObject; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ConstantString; +import org.aspectj.apache.bcel.classfile.ConstantValue; +import org.aspectj.apache.bcel.classfile.Field; +import org.aspectj.apache.bcel.classfile.Utility; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; + +/** + * Template class for building up a field. The only extraordinary thing one can do is to add a constant value attribute to a field + * (which must of course be compatible with the declared type). + * + * @version $Id: FieldGen.java,v 1.11 2011/10/03 22:41:24 aclement Exp $ + * @author M. Dahm + * @see Field + */ +public class FieldGen extends FieldGenOrMethodGen { + private Object value = null; + + /** + * Declare a field. If it is static (isStatic() == true) and has a basic type like int or String it may have an initial value + * associated with it as defined by setInitValue(). + * + * @param modifiers access qualifiers + * @param type field type + * @param name field name + * @param cpool constant pool + */ + public FieldGen(int modifiers, Type type, String name, ConstantPool cpool) { + setModifiers(modifiers); + setType(type); + setName(name); + setConstantPool(cpool); + } + + /** + * Instantiate from existing field. + * + * @param field Field object + * @param cp constant pool (must contain the same entries as the field's constant pool) + */ + public FieldGen(Field field, ConstantPool cp) { + this(field.getModifiers(), Type.getType(field.getSignature()), field.getName(), cp); + + Attribute[] attrs = field.getAttributes(); + + for (int i = 0; i < attrs.length; i++) { + if (attrs[i] instanceof ConstantValue) { + setValue(((ConstantValue) attrs[i]).getConstantValueIndex()); + } else if (attrs[i] instanceof RuntimeAnnos) { + RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attrs[i]; + List l = runtimeAnnotations.getAnnotations(); + for (Iterator it = l.iterator(); it.hasNext();) { + AnnotationGen element = it.next(); + addAnnotation(new AnnotationGen(element, cp, false)); + } + } else { + addAttribute(attrs[i]); + } + } + } + + public void setValue(int index) { + ConstantPool cp = this.cp; + Constant c = cp.getConstant(index); + if (c instanceof ConstantInteger) { + value = ((ConstantInteger) c).getIntValue(); + } else if (c instanceof ConstantFloat) { + value = ((ConstantFloat) c).getValue(); + } else if (c instanceof ConstantDouble) { + value = ((ConstantDouble) c).getValue(); + } else if (c instanceof ConstantLong) { + value = ((ConstantLong) c).getValue(); + } else if (c instanceof ConstantString) { + value = ((ConstantString)c).getString(cp); + } else { + value = ((ConstantObject) c).getConstantValue(cp); + } + } + + public void setValue(String constantString) { + value = constantString; + } + + public void wipeValue() { + value = null; + } + + private void checkType(Type atype) { + if (type == null) + throw new ClassGenException("You haven't defined the type of the field yet"); + + if (!isFinal()) + throw new ClassGenException("Only final fields may have an initial value!"); + + if (!type.equals(atype)) + throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype); + } + + /** + * Get field object after having set up all necessary values. + */ + public Field getField() { + String signature = getSignature(); + int nameIndex = cp.addUtf8(name); + int signatureIndex = cp.addUtf8(signature); + + if (value != null) { + checkType(type); + int index = addConstant(); + addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), 2, index, cp)); + } + + addAnnotationsAsAttribute(cp); + + return new Field(modifiers, nameIndex, signatureIndex, getAttributesImmutable(), cp); + } + + private int addConstant() { + switch (type.getType()) { + case Constants.T_INT: + case Constants.T_CHAR: + case Constants.T_BYTE: + case Constants.T_BOOLEAN: + case Constants.T_SHORT: + return cp.addInteger(((Integer) value).intValue()); + + case Constants.T_FLOAT: + return cp.addFloat(((Float) value).floatValue()); + + case Constants.T_DOUBLE: + return cp.addDouble(((Double) value).doubleValue()); + + case Constants.T_LONG: + return cp.addLong(((Long) value).longValue()); + + case Constants.T_REFERENCE: + return cp.addString(((String) value)); + + default: + throw new RuntimeException("Oops: Unhandled : " + type.getType()); + } + } + + @Override + public String getSignature() { + return type.getSignature(); + } + + public String getInitialValue() { + return (value == null ? null : value.toString()); + } + + public void setInitialStringValue(String value) { + this.value = value; + } + + /** + * Return string representation close to declaration format, `public static final short MAX = 100', e.g.. + */ + @Override + public final String toString() { + String access = Utility.accessToString(modifiers); + access = access.equals("") ? "" : (access + " "); + String signature = type.toString(); + String name = getName(); + + StringBuffer buf = new StringBuffer(access).append(signature).append(" ").append(name); + String value = getInitialValue(); + + if (value != null) { + buf.append(" = ").append(value); + } + // TODO: Add attributes and annotations to the string + return buf.toString(); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java new file mode 100644 index 000000000..ff8b6f42c --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java @@ -0,0 +1,158 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.Modifiers; +import org.aspectj.apache.bcel.classfile.Utility; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; + +/** + * Super class for FieldGen and MethodGen objects, since they have some methods in common! + * + * @version $Id: FieldGenOrMethodGen.java,v 1.8 2009/09/15 19:40:14 aclement Exp $ + * @author M. Dahm + */ +public abstract class FieldGenOrMethodGen extends Modifiers { + + protected String name; + protected Type type; + protected ConstantPool cp; + private ArrayList attributeList = new ArrayList(); + protected ArrayList annotationList = new ArrayList(); + + protected FieldGenOrMethodGen() { + } + + public void setType(Type type) { + this.type = type; + } + + public Type getType() { + return type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ConstantPool getConstantPool() { + return cp; + } + + public void setConstantPool(ConstantPool cp) { + this.cp = cp; + } + + public void addAttribute(Attribute a) { + attributeList.add(a); + } + + public void removeAttribute(Attribute a) { + attributeList.remove(a); + } + + public void removeAttributes() { + attributeList.clear(); + } + + public List getAnnotations() { + return annotationList; + } + + public void addAnnotation(AnnotationGen ag) { + annotationList.add(ag); + } + + public void removeAnnotation(AnnotationGen ag) { + annotationList.remove(ag); + } + + public void removeAnnotations() { + annotationList.clear(); + } + + public List getAttributes() { + return attributeList; + } + + public Attribute[] getAttributesImmutable() { + Attribute[] attributes = new Attribute[attributeList.size()]; + attributeList.toArray(attributes); + return attributes; + } + + protected void addAnnotationsAsAttribute(ConstantPool cp) { + Collection attrs = Utility.getAnnotationAttributes(cp, annotationList); + if (attrs != null) { + for (Attribute attr : attrs) { + addAttribute(attr); + } + } + } + + public abstract String getSignature(); + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldInstruction.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldInstruction.java new file mode 100644 index 000000000..54983e7c9 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldInstruction.java @@ -0,0 +1,112 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.classfile.ConstantPool; + +/** + * Super class for the GET/PUTxxx family of instructions. + * + * @version $Id: FieldInstruction.java,v 1.7 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public class FieldInstruction extends FieldOrMethod { + + public FieldInstruction(short opcode, int index) { + super(opcode, index); + } + + public String toString(ConstantPool cp) { + return org.aspectj.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + + cp.constantToString(index, org.aspectj.apache.bcel.Constants.CONSTANT_Fieldref); + } + + /** + * @return size of field (1 or 2) + */ + protected int getFieldSize(ConstantPool cpg) { + return Type.getTypeSize(getSignature(cpg)); + } + + public Type getType(ConstantPool cpg) { + return getFieldType(cpg); + } + + public Type getFieldType(ConstantPool cpg) { + return Type.getType(getSignature(cpg)); + } + + public String getFieldName(ConstantPool cpg) { + return getName(cpg); + } + + public int produceStack(ConstantPool cpg) { + if (!isStackProducer()) { + return 0; + } + + return getFieldSize(cpg); // SAME FOR GETFIELD/GETSTATIC + } + + public int consumeStack(ConstantPool cpg) { + if (!isStackConsumer()) { + return 0; + } + if (opcode == GETFIELD) { + return 1; + } + return getFieldSize(cpg) + (opcode == PUTFIELD ? 1 : 0); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldOrMethod.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldOrMethod.java new file mode 100644 index 000000000..44b263ffb --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldOrMethod.java @@ -0,0 +1,133 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import org.aspectj.apache.bcel.classfile.Constant; +import org.aspectj.apache.bcel.classfile.ConstantCP; +import org.aspectj.apache.bcel.classfile.ConstantNameAndType; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ConstantUtf8; + +/** + * Super class for InvokeInstruction and FieldInstruction, since they have some methods in common! + * + * @version $Id: FieldOrMethod.java,v 1.8 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public abstract class FieldOrMethod extends InstructionCP { + + protected String signature; + protected String name; + private String classname; + + protected FieldOrMethod(short opcode, int index) { + super(opcode, index); + } + + /** + * @return signature of referenced method/field. + */ + public String getSignature(ConstantPool cp) { + if (signature == null) { + Constant c = cp.getConstant(index); + ConstantCP cmr = (ConstantCP) c; + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + signature = ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getValue(); + } + return signature; + } + + /** + * @return name of referenced method/field. + */ + public String getName(ConstantPool cp) { + if (name == null) { + ConstantCP cmr = (ConstantCP) cp.getConstant(index); + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + name = ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getValue(); + } + return name; + } + + /** + * @return name of the referenced class/interface + */ + public String getClassName(ConstantPool cp) { + if (classname == null) { + ConstantCP cmr = (ConstantCP) cp.getConstant(index); + String str = cp.getConstantString(cmr.getClassIndex(), CONSTANT_Class); + if (str.charAt(0) == '[') { + classname = str; + } else { + classname = str.replace('/', '.'); + } + } + return classname; + } + + /** + * @return type of the referenced class/interface + */ + public ObjectType getClassType(ConstantPool cpg) { + return new ObjectType(getClassName(cpg)); + } + + /** + * @return type of the referenced class/interface + */ + @Override + public ObjectType getLoadClassType(ConstantPool cpg) { + return getClassType(cpg); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/IINC.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/IINC.java new file mode 100644 index 000000000..d70e20308 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/IINC.java @@ -0,0 +1,121 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * IINC - Increment local variable by constant + * + * @version $Id: IINC.java,v 1.5 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public class IINC extends InstructionLV { + private int c; + + public IINC(int n, int c, boolean w) { + super(Constants.IINC, n); + this.c = c; + // this.wide = w;//((n > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE)); + } + + private boolean wide() { + return ((lvar > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE)); + } + + public void dump(DataOutputStream out) throws IOException { + if (wide()) { + out.writeByte(WIDE); + out.writeByte(opcode); + out.writeShort(lvar); + out.writeShort(c); + } else { + out.writeByte(opcode); + out.writeByte(lvar); + out.writeByte(c); + } + } + + public int getLength() { + if (wide()) { + return 6; + } else { + return 3; // includes wide byte + } + } + + public String toString(boolean verbose) { + return super.toString(verbose) + " " + c; + } + + public final int getIncrement() { + return c; + } + + public boolean equals(Object other) { + if (!(other instanceof IINC)) { + return false; + } + IINC o = (IINC) other; + return /* o.opcode == opcode && */o.lvar == lvar && o.c == c; + } + + public int hashCode() { + return opcode * 37 + lvar * (c + 17); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java new file mode 100644 index 000000000..b545f4d37 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java @@ -0,0 +1,127 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +/** + * INVOKEINTERFACE - Invoke interface method + * + *
+ * Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
+ * 
+ * + * @version $Id: INVOKEINTERFACE.java,v 1.4 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public final class INVOKEINTERFACE extends InvokeInstruction { + private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2 + + public INVOKEINTERFACE(int index, int nargs, int zerobyte) { + super(Constants.INVOKEINTERFACE, index); + + if (nargs < 1) { + throw new ClassGenException("Number of arguments must be > 0 " + nargs); + } + + this.nargs = nargs; + } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeShort(index); + out.writeByte(nargs); + out.writeByte(0); + } + + /** + * The count argument according to the Java Language Specification, Second Edition. + */ + public int getCount() { + return nargs; + } + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + public String toString(ConstantPool cp) { + return super.toString(cp) + " " + nargs; + } + + public int consumeStack(ConstantPool cpg) { // nargs is given in byte-code + return nargs; // nargs includes this reference + } + + public boolean equals(Object other) { + if (!(other instanceof INVOKEINTERFACE)) { + return false; + } + INVOKEINTERFACE o = (INVOKEINTERFACE) other; + return o.opcode == opcode && o.index == index && o.nargs == nargs; + } + + public int hashCode() { + return opcode * 37 + index * (nargs + 17); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstVisitor.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstVisitor.java new file mode 100644 index 000000000..424ff4a66 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstVisitor.java @@ -0,0 +1,247 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Interface implementing the Visitor pattern programming style. + * I.e., a class that implements this interface can handle all types of + * instructions with the properly typed methods just by calling the accept() + * method. + * + * @version $Id: InstVisitor.java,v 1.2 2008/05/28 23:52:59 aclement Exp $ + * @author M. Dahm + */ +public interface InstVisitor { + public void visitStackInstruction(Instruction obj); + public void visitLocalVariableInstruction(InstructionLV obj); + public void visitBranchInstruction(InstructionBranch obj); + public void visitLoadClass(Instruction obj); + public void visitFieldInstruction(Instruction obj); + public void visitIfInstruction(Instruction obj); + public void visitConversionInstruction(Instruction obj); + public void visitPopInstruction(Instruction obj); + public void visitStoreInstruction(Instruction obj); + public void visitTypedInstruction(Instruction obj); + public void visitSelect(InstructionSelect obj); + public void visitJsrInstruction(InstructionBranch obj); + public void visitGotoInstruction(Instruction obj); + public void visitUnconditionalBranch(Instruction obj); + public void visitPushInstruction(Instruction obj); + public void visitArithmeticInstruction(Instruction obj); + public void visitCPInstruction(Instruction obj); + public void visitInvokeInstruction(InvokeInstruction obj); + public void visitArrayInstruction(Instruction obj); + public void visitAllocationInstruction(Instruction obj); + public void visitReturnInstruction(Instruction obj); + public void visitFieldOrMethod(Instruction obj); + public void visitConstantPushInstruction(Instruction obj); + public void visitExceptionThrower(Instruction obj); + public void visitLoadInstruction(Instruction obj); + public void visitVariableLengthInstruction(Instruction obj); + public void visitStackProducer(Instruction obj); + public void visitStackConsumer(Instruction obj); + public void visitACONST_NULL(Instruction obj); + public void visitGETSTATIC(FieldInstruction obj); + public void visitIF_ICMPLT(Instruction obj); + public void visitMONITOREXIT(Instruction obj); + public void visitIFLT(Instruction obj); + public void visitLSTORE(Instruction obj); + public void visitPOP2(Instruction obj); + public void visitBASTORE(Instruction obj); + public void visitISTORE(Instruction obj); + public void visitCHECKCAST(Instruction obj); + public void visitFCMPG(Instruction obj); + public void visitI2F(Instruction obj); + public void visitATHROW(Instruction obj); + public void visitDCMPL(Instruction obj); + public void visitARRAYLENGTH(Instruction obj); + public void visitDUP(Instruction obj); + public void visitINVOKESTATIC(InvokeInstruction obj); + public void visitLCONST(Instruction obj); + public void visitDREM(Instruction obj); + public void visitIFGE(Instruction obj); + public void visitCALOAD(Instruction obj); + public void visitLASTORE(Instruction obj); + public void visitI2D(Instruction obj); + public void visitDADD(Instruction obj); + public void visitINVOKESPECIAL(InvokeInstruction obj); + public void visitIAND(Instruction obj); + public void visitPUTFIELD(FieldInstruction obj); + public void visitILOAD(Instruction obj); + public void visitDLOAD(Instruction obj); + public void visitDCONST(Instruction obj); + public void visitNEW(Instruction obj); + public void visitIFNULL(Instruction obj); + public void visitLSUB(Instruction obj); + public void visitL2I(Instruction obj); + public void visitISHR(Instruction obj); + public void visitTABLESWITCH(TABLESWITCH obj); + public void visitIINC(IINC obj); + public void visitDRETURN(Instruction obj); + public void visitFSTORE(Instruction obj); + public void visitDASTORE(Instruction obj); + public void visitIALOAD(Instruction obj); + public void visitDDIV(Instruction obj); + public void visitIF_ICMPGE(Instruction obj); + public void visitLAND(Instruction obj); + public void visitIDIV(Instruction obj); + public void visitLOR(Instruction obj); + public void visitCASTORE(Instruction obj); + public void visitFREM(Instruction obj); + public void visitLDC(Instruction obj); + public void visitBIPUSH(Instruction obj); + public void visitDSTORE(Instruction obj); + public void visitF2L(Instruction obj); + public void visitFMUL(Instruction obj); + public void visitLLOAD(Instruction obj); + public void visitJSR(InstructionBranch obj); + public void visitFSUB(Instruction obj); + public void visitSASTORE(Instruction obj); + public void visitALOAD(Instruction obj); + public void visitDUP2_X2(Instruction obj); + public void visitRETURN(Instruction obj); + public void visitDALOAD(Instruction obj); + public void visitSIPUSH(Instruction obj); + public void visitDSUB(Instruction obj); + public void visitL2F(Instruction obj); + public void visitIF_ICMPGT(Instruction obj); + public void visitF2D(Instruction obj); + public void visitI2L(Instruction obj); + public void visitIF_ACMPNE(Instruction obj); + public void visitPOP(Instruction obj); + public void visitI2S(Instruction obj); + public void visitIFEQ(Instruction obj); + public void visitSWAP(Instruction obj); + public void visitIOR(Instruction obj); + public void visitIREM(Instruction obj); + public void visitIASTORE(Instruction obj); + public void visitNEWARRAY(Instruction obj); + public void visitINVOKEINTERFACE(INVOKEINTERFACE obj); + public void visitINEG(Instruction obj); + public void visitLCMP(Instruction obj); + public void visitJSR_W(InstructionBranch obj); + public void visitMULTIANEWARRAY(MULTIANEWARRAY obj); + public void visitDUP_X2(Instruction obj); + public void visitSALOAD(Instruction obj); + public void visitIFNONNULL(Instruction obj); + public void visitDMUL(Instruction obj); + public void visitIFNE(Instruction obj); + public void visitIF_ICMPLE(Instruction obj); + public void visitLDC2_W(Instruction obj); + public void visitGETFIELD(FieldInstruction obj); + public void visitLADD(Instruction obj); + public void visitNOP(Instruction obj); + public void visitFALOAD(Instruction obj); + public void visitINSTANCEOF(Instruction obj); + public void visitIFLE(Instruction obj); + public void visitLXOR(Instruction obj); + public void visitLRETURN(Instruction obj); + public void visitFCONST(Instruction obj); + public void visitIUSHR(Instruction obj); + public void visitBALOAD(Instruction obj); + public void visitDUP2(Instruction obj); + public void visitIF_ACMPEQ(Instruction obj); + public void visitIMPDEP1(Instruction obj); + public void visitMONITORENTER(Instruction obj); + public void visitLSHL(Instruction obj); + public void visitDCMPG(Instruction obj); + public void visitD2L(Instruction obj); + public void visitIMPDEP2(Instruction obj); + public void visitL2D(Instruction obj); + public void visitRET(RET obj); + public void visitIFGT(Instruction obj); + public void visitIXOR(Instruction obj); + public void visitINVOKEVIRTUAL(InvokeInstruction obj); + public void visitFASTORE(Instruction obj); + public void visitIRETURN(Instruction obj); + public void visitIF_ICMPNE(Instruction obj); + public void visitFLOAD(Instruction obj); + public void visitLDIV(Instruction obj); + public void visitPUTSTATIC(FieldInstruction obj); + public void visitAALOAD(Instruction obj); + public void visitD2I(Instruction obj); + public void visitIF_ICMPEQ(Instruction obj); + public void visitAASTORE(Instruction obj); + public void visitARETURN(Instruction obj); + public void visitDUP2_X1(Instruction obj); + public void visitFNEG(Instruction obj); + public void visitGOTO_W(Instruction obj); + public void visitD2F(Instruction obj); + public void visitGOTO(Instruction obj); + public void visitISUB(Instruction obj); + public void visitF2I(Instruction obj); + public void visitDNEG(Instruction obj); + public void visitICONST(Instruction obj); + public void visitFDIV(Instruction obj); + public void visitI2B(Instruction obj); + public void visitLNEG(Instruction obj); + public void visitLREM(Instruction obj); + public void visitIMUL(Instruction obj); + public void visitIADD(Instruction obj); + public void visitLSHR(Instruction obj); + public void visitLOOKUPSWITCH(LOOKUPSWITCH obj); + public void visitDUP_X1(Instruction obj); + public void visitFCMPL(Instruction obj); + public void visitI2C(Instruction obj); + public void visitLMUL(Instruction obj); + public void visitLUSHR(Instruction obj); + public void visitISHL(Instruction obj); + public void visitLALOAD(Instruction obj); + public void visitASTORE(Instruction obj); + public void visitANEWARRAY(Instruction obj); + public void visitFRETURN(Instruction obj); + public void visitFADD(Instruction obj); + public void visitBREAKPOINT(Instruction obj); +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Instruction.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Instruction.java new file mode 100644 index 000000000..113be06ee --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Instruction.java @@ -0,0 +1,454 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.Serializable; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.util.ByteSequence; + +/** + * Abstract super class for all Java byte codes. + * + * @version $Id: Instruction.java,v 1.10 2011/04/05 15:15:33 aclement Exp $ + * @author M. Dahm + */ +public class Instruction implements Cloneable, Serializable, Constants { + public short opcode = -1; + + public Instruction(short opcode) { + this.opcode = opcode; + } + + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + } + + public String getName() { + return Constants.OPCODE_NAMES[opcode]; + } + + /** + * Use with caution, since 'BranchInstruction's have a 'target' reference which is not copied correctly (only basic types are). + * This also applies for 'Select' instructions with their multiple branch targets. + * + * @return (shallow) copy of an instruction + */ + // GET RID OF THIS - make it throw an exception and track the callers + final public Instruction copy() { + // if overridden correctly can just return 'this' here + if (InstructionConstants.INSTRUCTIONS[opcode] != null) { // immutable instructions do not need copying + return this; + } else { + Instruction i = null; + try {// OPTIMIZE is clone the right thing to do here? it is horrible + i = (Instruction) clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + } + return i; + } + } + + /** + * Read an instruction bytecode from an input stream and return the appropriate object. + * + * @param file file to read from + * @return instruction object being read + */ + public static final Instruction readInstruction(ByteSequence bytes) throws IOException { + boolean wide = false; + short opcode = (short) bytes.readUnsignedByte(); + + if (opcode == Constants.WIDE) { + wide = true; + opcode = (short) bytes.readUnsignedByte(); + } + + Instruction constantInstruction = InstructionConstants.INSTRUCTIONS[opcode]; + + if (constantInstruction != null) { + return constantInstruction; + } + + Instruction obj = null; + try { + switch (opcode) { + case Constants.BIPUSH: + obj = new InstructionByte(Constants.BIPUSH, bytes.readByte()); + break; + case Constants.SIPUSH: + obj = new InstructionShort(Constants.SIPUSH, bytes.readShort()); + break; + case Constants.LDC: + obj = new InstructionCP(Constants.LDC, bytes.readUnsignedByte()); + break; + case Constants.LDC_W: + case Constants.LDC2_W: + obj = new InstructionCP(opcode, bytes.readUnsignedShort()); + break; + case Constants.ILOAD: + case Constants.LLOAD: + case Constants.FLOAD: + case Constants.DLOAD: + case Constants.ALOAD: + case Constants.ISTORE: + case Constants.LSTORE: + case Constants.FSTORE: + case Constants.DSTORE: + case Constants.ASTORE: + obj = new InstructionLV(opcode, wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte()); + break; + case Constants.IINC: + obj = new IINC(wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte(), wide ? bytes.readShort() + : bytes.readByte(), wide); + break; + case Constants.IFNULL: + case Constants.IFNONNULL: + case Constants.IFEQ: + case Constants.IFNE: + case Constants.IFLT: + case Constants.IFGE: + case Constants.IFGT: + case Constants.IFLE: + case Constants.IF_ICMPEQ: + case Constants.IF_ICMPNE: + case Constants.IF_ICMPLT: + case Constants.IF_ICMPGE: + case Constants.IF_ICMPGT: + case Constants.IF_ICMPLE: + case Constants.IF_ACMPEQ: + case Constants.IF_ACMPNE: + case Constants.GOTO: + case Constants.JSR: + obj = new InstructionBranch(opcode, bytes.readShort()); + break; + case Constants.GOTO_W: + case Constants.JSR_W: + obj = new InstructionBranch(opcode, bytes.readInt()); + break; + case Constants.TABLESWITCH: + obj = new TABLESWITCH(bytes); + break; + case Constants.LOOKUPSWITCH: + obj = new LOOKUPSWITCH(bytes); + break; + case Constants.RET: + obj = new RET(wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte(), wide); + break; + case Constants.NEW: + obj = new InstructionCP(Constants.NEW, bytes.readUnsignedShort()); + break; + case Constants.GETSTATIC: + case Constants.PUTSTATIC: + case Constants.GETFIELD: + case Constants.PUTFIELD: + obj = new FieldInstruction(opcode, bytes.readUnsignedShort()); + break; + case Constants.INVOKEVIRTUAL: + case Constants.INVOKESPECIAL: + case Constants.INVOKESTATIC: + obj = new InvokeInstruction(opcode, bytes.readUnsignedShort()); + break; + case Constants.INVOKEINTERFACE: + obj = new INVOKEINTERFACE(bytes.readUnsignedShort(), bytes.readUnsignedByte(), bytes.readByte()); + break; + case Constants.INVOKEDYNAMIC: + obj = new InvokeDynamic(bytes.readUnsignedShort(),bytes.readUnsignedShort()); + break; + case Constants.NEWARRAY: + obj = new InstructionByte(Constants.NEWARRAY, bytes.readByte()); + break; + case Constants.ANEWARRAY: + case Constants.CHECKCAST: + obj = new InstructionCP(opcode, bytes.readUnsignedShort()); + break; + case Constants.INSTANCEOF: + obj = new InstructionCP(Constants.INSTANCEOF, bytes.readUnsignedShort()); + break; + case Constants.MULTIANEWARRAY: + obj = new MULTIANEWARRAY(bytes.readUnsignedShort(), bytes.readByte()); + break; + default: + throw new ClassGenException("Illegal opcode detected"); + } + } catch (ClassGenException e) { + throw e; + } catch (Exception e) { + throw new ClassGenException(e.toString()); + } + + return obj; + } + + /** + * @return Number of words consumed from stack by this instruction, or Constants.UNPREDICTABLE, if this can not be computed + * statically + */ + public int consumeStack(ConstantPool cpg) { + return Constants.CONSUME_STACK[opcode]; + } + + /** + * @return Number of words produced onto stack by this instruction, or Constants.UNPREDICTABLE, if this can not be computed + * statically + */ + public int produceStack(ConstantPool cpg) { + return Constants.stackEntriesProduced[opcode]; + } + + public short getOpcode() { + return opcode; + } + + public int getLength() { + // if it is zero, it should have been provided by an overriding implementation of getLength() + int len = Constants.iLen[opcode]; + assert len != 0; + // if (len == 0) { + // throw new IllegalStateException("Length not right for " + getName().toUpperCase()); + // } + return len; + } + + /** Some instructions may be reused, so don't do anything by default */ + void dispose() { + } + + @Override + public boolean equals(Object other) { + if (this.getClass() != Instruction.class) { + throw new RuntimeException("NO WAY " + this.getClass()); + } + if (!(other instanceof Instruction)) { + return false; + } + return ((Instruction) other).opcode == opcode; + + // IMPLEMENT EQUALS AND HASHCODE IN THE SUBTYPES! + + // Instruction i1 = this; + // Instruction i2 = (Instruction) that; + // if (i1.opcode == i2.opcode) { + // if (i1.isConstantInstruction()) { + // return i1.getValue().equals(i2.getValue()); + // } else if (i1.isIndexedInstruction()) { + // return i1.getIndex() == i2.getIndex(); + // } else if (i1.opcode == Constants.NEWARRAY) { + // return ((InstructionByte) i1).getTypecode() == ((InstructionByte) i2).getTypecode(); + // } else { + // return true; + // } + // } + // + // return false; + } + + @Override + public int hashCode() { + if (this.getClass() != Instruction.class) { + throw new RuntimeException("NO WAY " + this.getClass()); + } + return opcode * 37; + // int result = 17 + opcode * 37; + // if (isConstantInstruction()) { + // result = 37 * getValue().hashCode() + result; + // } else if (isIndexedInstruction()) { + // result = 37 * getIndex() + result; + // } else if (opcode == Constants.NEWARRAY) { + // result = 37 * ((InstructionByte) this).getTypecode() + result; + // } + // return result; + } + + public Type getType() { + return getType(null); + } + + public Type getType(ConstantPool cp) { + // if (types[opcode]==null) throw new RuntimeException(getName()+" is not a typed instruction"); + Type t = Constants.types[opcode]; + if (t != null) { + return t; + } + throw new RuntimeException("Do not know type for instruction " + getName() + "(" + opcode + ")"); + } + + public Number getValue() { + assert (instFlags[opcode] & CONSTANT_INST) == 0; + // if ((instFlags[opcode] & CONSTANT_INST) == 0) { + // throw new RuntimeException(getName() + " is not a constant instruction"); + // } + switch (opcode) { + case ICONST_M1: + case ICONST_0: + case ICONST_1: + case ICONST_2: + case ICONST_3: + case ICONST_4: + case ICONST_5: + return new Integer(opcode - ICONST_0); + default: + throw new IllegalStateException("Not implemented yet for " + getName()); + } + } + + public int getIndex() { + return -1; + } + + public void setIndex(int i) { + throw new IllegalStateException("Shouldnt be asking " + getName().toUpperCase()); + } + + public Object getValue(ConstantPool cpg) { + throw new IllegalStateException("Shouldnt be asking " + getName().toUpperCase()); + } + + public boolean isLoadInstruction() { + return (Constants.instFlags[opcode] & LOAD_INST) != 0; + } + + // remove these from here, leave them in the InstructionLV + public boolean isASTORE() { + return false; + } + + public boolean isALOAD() { + return false; + } + + public boolean isStoreInstruction() { + return (Constants.instFlags[opcode] & STORE_INST) != 0; + } + + // public boolean containsTarget(InstructionHandle ih) { + // throw new IllegalStateException("Dont ask!!"); + // } + + public boolean isJsrInstruction() { + return (Constants.instFlags[opcode] & JSR_INSTRUCTION) != 0; + } + + public boolean isConstantInstruction() { + return (Constants.instFlags[opcode] & CONSTANT_INST) != 0; + } + + public boolean isConstantPoolInstruction() { + return (Constants.instFlags[opcode] & CP_INST) != 0; + } + + public boolean isStackProducer() { + return Constants.stackEntriesProduced[opcode] != 0; + } + + public boolean isStackConsumer() { + return Constants.CONSUME_STACK[opcode] != 0; + } + + public boolean isIndexedInstruction() { + return (Constants.instFlags[opcode] & INDEXED) != 0; + } + + public boolean isArrayCreationInstruction() { + return opcode == NEWARRAY || opcode == ANEWARRAY || opcode == MULTIANEWARRAY; + } + + public ObjectType getLoadClassType(ConstantPool cpg) { + assert (Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0; + // if ((Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0) { + // throw new IllegalStateException("This opcode " + opcode + " does not have the property " + // + Long.toHexString(Constants.LOADCLASS_INST)); + // } + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return t instanceof ObjectType ? (ObjectType) t : null; + } + + public boolean isReturnInstruction() { + return (Constants.instFlags[opcode] & RET_INST) != 0; + } + + // public boolean isGoto() { + // return opcode == GOTO || opcode == GOTO_W; + // } + + public boolean isLocalVariableInstruction() { + return (Constants.instFlags[opcode] & LV_INST) != 0; + } + + /** + * Long output format: 'name of opcode' "[" 'opcode number' "]" "(" 'length of instruction' ")" + */ + public String toString(boolean verbose) { + if (verbose) { + StringBuffer sb = new StringBuffer(); + sb.append(getName()).append("[").append(opcode).append("](size").append(Constants.iLen[opcode]).append(")"); + return sb.toString(); + } else { + return getName(); + } + } + + @Override + public String toString() { + return toString(true); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionBranch.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionBranch.java new file mode 100644 index 000000000..53fed8e52 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionBranch.java @@ -0,0 +1,338 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +/** + * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch instructions may have a variable length, namely + * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH. A branch instruction may be talking in terms of absolute destination (targetIndex) or + * about an instruction it doesnt yet know the position if (targetInstruction). targetInstruction (if set) overrides targetIndex + * + * @see InstructionList + * @version $Id: InstructionBranch.java,v 1.6 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public class InstructionBranch extends Instruction implements InstructionTargeter { + private static final int UNSET = -1; + + protected int targetIndex = UNSET; // Branch target relative to this + // instruction + protected InstructionHandle targetInstruction; // Target object in + // instruction list + protected int positionOfThisInstruction; // for calculating relative branch + + // destinations! + + public InstructionBranch(short opcode, InstructionHandle target) { + super(opcode); + setTarget(target); + } + + public InstructionBranch(short opcode, int index) { + super(opcode); + this.targetIndex = index; + } + + public InstructionBranch(short opcode) { + super(opcode); + } + + public void dump(DataOutputStream out) throws IOException { + int target = getTargetOffset(); + + if (Math.abs(target) >= 32767 && opcode != GOTO_W && opcode != JSR_W) { + throw new ClassGenException("Branch target offset too large for short. Instruction: " + getName().toUpperCase() + "(" + + opcode + ")"); + } + + out.writeByte(opcode); + + switch (opcode) { + + case GOTO_W: + case JSR_W: + out.writeInt(target); + break; + + case IF_ACMPEQ: + case IF_ACMPNE: + case IF_ICMPEQ: + case IF_ICMPGE: + case IF_ICMPGT: + case IF_ICMPLE: + case IF_ICMPLT: + case IF_ICMPNE: + case IFEQ: + case IFLE: + case IFLT: + case IFGT: + case IFNE: + case IFGE: + case IFNULL: + case IFNONNULL: + case GOTO: + case JSR: + out.writeShort(target); + break; + + default: + throw new IllegalStateException("Don't know how to write out " + getName().toUpperCase()); + } + + } + + protected int getTargetOffset() { + if (targetInstruction == null && targetIndex == UNSET) { + throw new ClassGenException("Target of " + super.toString(true) + " is unknown"); + } + + if (targetInstruction == null) { + return targetIndex; + } else { + return targetInstruction.getPosition() - positionOfThisInstruction; + } + } + + /** + * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length + * instructions `setPositions' performs multiple passes over the instruction list to calculate the correct (byte) positions and + * offsets by calling this function. + * + * @param offset additional offset caused by preceding (variable length) instructions + * @param max_offset the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's length + */ + protected int updatePosition(int offset, int max_offset) { + int i = getTargetOffset(); + + positionOfThisInstruction += offset; + + if (Math.abs(i) >= 32767 - max_offset && opcode != JSR_W && opcode != GOTO_W) { + // Try and promote it to wide if we can + if (opcode == JSR || opcode == GOTO) { + if (opcode == JSR) { + opcode = JSR_W; + } else { + opcode = GOTO_W; + } + return 2; // instruction jump destination grows from a short to a long + } else { + throw new IllegalStateException("Unable to pack method, jump (with opcode=" + opcode + ") is too far: " + + Math.abs(i)); + } + } + + return 0; + } + + /** + * Long output format: + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + public String toString(boolean verbose) { + String s = super.toString(verbose); + String t = "null"; + + if (verbose) { + if (targetInstruction != null) { + if (targetInstruction.getInstruction() == this) { + t = ""; + } else if (targetInstruction.getInstruction() == null) { + t = ""; + } else { + t = targetInstruction.getInstruction().toString(false); + } + } + } else { + if (targetInstruction != null) { + targetIndex = getTargetOffset(); + t = "" + (targetIndex + positionOfThisInstruction); + } + } + + return s + " -> " + t; + } + + /** + * @return target offset in byte code + */ + public final int getIndex() { + return targetIndex; + } + + /** + * @return target of branch instruction + */ + public InstructionHandle getTarget() { + return targetInstruction; + } + + /** + * Set branch target + * + * @param target branch target + */ + public void setTarget(InstructionHandle target) { + notifyTarget(this.targetInstruction, target, this); + this.targetInstruction = target; + } + + /** + * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen + */ + static final void notifyTarget(InstructionHandle oldHandle, InstructionHandle newHandle, InstructionTargeter t) { + if (oldHandle != null) { + oldHandle.removeTargeter(t); + } + if (newHandle != null) { + newHandle.addTargeter(t); + } + } + + /** + * Update the target destination for this instruction. If an oldHandle is provided it is checked to verify that is where the + * target currently points to before changing it. + * + * @param oldHandle old target + * @param newHandle new target + */ + public void updateTarget(InstructionHandle oldHandle, InstructionHandle newHandle) { + if (targetInstruction == oldHandle) { + setTarget(newHandle); + } else { + throw new ClassGenException("Not targeting " + oldHandle + ", but " + targetInstruction); + } + } + + /** + * @return true, if ih is target of this instruction + */ + public boolean containsTarget(InstructionHandle ih) { + return targetInstruction == ih; + } + + /** + * Inform target that it's not targeted anymore. + */ + void dispose() { + setTarget(null); + targetIndex = -1; + positionOfThisInstruction = -1; + } + + public Type getType(ConstantPool cp) { + if ((Constants.instFlags[opcode] & Constants.JSR_INSTRUCTION) != 0) { + return new ReturnaddressType(physicalSuccessor()); + } + return super.getType(cp); + } + + /** + * Returns an InstructionHandle to the physical successor of this JsrInstruction. For this method to work, this + * JsrInstruction object must not be shared between multiple InstructionHandle objects! Formally, there must not be + * InstructionHandle objects i, j where i != j and i.getInstruction() == this == j.getInstruction(). + * + * @return an InstructionHandle to the "next" instruction that will be executed when RETurned from a subroutine. + */ + public InstructionHandle physicalSuccessor() { + InstructionHandle ih = this.targetInstruction; + + // Rewind! + while (ih.getPrev() != null) { + ih = ih.getPrev(); + } + + // Find the handle for "this" JsrInstruction object. + while (ih.getInstruction() != this) { + ih = ih.getNext(); + } + + InstructionHandle toThis = ih; + + while (ih != null) { + ih = ih.getNext(); + if (ih != null && ih.getInstruction() == this) { + throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction."); + } + } + + // Return the physical successor + return toThis.getNext(); + } + + public boolean isIfInstruction() { + return (Constants.instFlags[opcode] & Constants.IF_INST) != 0; + } + + /** + * Only equal if they are the same branch instruction - otherwise too risky as the targets may only temporarily be pointing at + * the same destination. + */ + public boolean equals(Object other) { + return this == other; + } + + public int hashCode() { + int result = 17; + result = opcode * 37 + result; + return result; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionByte.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionByte.java new file mode 100644 index 000000000..5ba8a9abe --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionByte.java @@ -0,0 +1,108 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Instruction that needs one byte + */ +public class InstructionByte extends Instruction { + private final byte theByte; + + public InstructionByte(short opcode, byte b) { + super(opcode); + this.theByte = b; + } + + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeByte(theByte); + } + + public String toString(boolean verbose) { + return super.toString(verbose) + " " + theByte; + } + + /** + * For supporting NEWARRAY + * + * @return typecode of the array + */ + public final byte getTypecode() { + return theByte; + } + + /** + * For supporting NEWARRAY + * + * @return type of the array + */ + public final Type getType() { + return new ArrayType(BasicType.getType(theByte), 1); + } + + public boolean equals(Object other) { + if (!(other instanceof InstructionByte)) { + return false; + } + InstructionByte o = (InstructionByte) other; + return o.opcode == opcode && o.theByte == theByte; + } + + public int hashCode() { + return opcode * 37 + theByte; + } +} \ No newline at end of file diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCLV.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCLV.java new file mode 100644 index 000000000..85ae588e5 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCLV.java @@ -0,0 +1,27 @@ +package org.aspectj.apache.bcel.generic; + +/** + * A small subclass of the local variable accessing instruction class InstructionLV - this subclass does + * not allow the index to be altered. + */ +public class InstructionCLV extends InstructionLV { + + public InstructionCLV(short opcode) { + super(opcode); + } + + public InstructionCLV(short opcode,int localVariableIndex) { + super(opcode,localVariableIndex); + } + + public void setIndex(int localVariableIndex) { + if (localVariableIndex!=getIndex()) { + throw new ClassGenException("Do not attempt to modify the index to '"+localVariableIndex+"' for this constant instruction: "+this); + } + } + + public boolean canSetIndex() { + return false; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCP.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCP.java new file mode 100644 index 000000000..09222d6a4 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCP.java @@ -0,0 +1,224 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Constant; +import org.aspectj.apache.bcel.classfile.ConstantClass; +import org.aspectj.apache.bcel.classfile.ConstantDouble; +import org.aspectj.apache.bcel.classfile.ConstantFloat; +import org.aspectj.apache.bcel.classfile.ConstantInteger; +import org.aspectj.apache.bcel.classfile.ConstantLong; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ConstantString; +import org.aspectj.apache.bcel.classfile.ConstantUtf8; + +/** + * Class for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc. + * + * @version $Id: InstructionCP.java,v 1.6 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public class InstructionCP extends Instruction { + protected int index; + + public InstructionCP(short opcode, int index) { + super(opcode); + this.index = index; + } + + @Override + public void dump(DataOutputStream out) throws IOException { + if (opcode == LDC_W && index < 256) { + out.writeByte(LDC); + out.writeByte(index); + } else { + out.writeByte(opcode); + if (Constants.iLen[opcode] == 2) { + if (index > 255) { + throw new IllegalStateException(); + } + out.writeByte(index); + } else { + out.writeShort(index); + } + } + } + + @Override + public int getLength() { + if (opcode == LDC_W && index < 256) { + return 2; + } else { + return super.getLength(); + } + } + + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of instruction>")" "<"< constant pool + * index>">" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + return super.toString(verbose) + " " + index; + } + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + public String toString(ConstantPool cp) { + Constant c = cp.getConstant(index); + String str = cp.constantToString(c); + + if (c instanceof ConstantClass) { + str = str.replace('.', '/'); + } + + return org.aspectj.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + str; + } + + /** + * @return index in constant pool referred by this instruction. + */ + @Override + public final int getIndex() { + return index; + } + + @Override + public void setIndex(int index) { + this.index = index; + if (this.index > 255 && opcode == LDC) { + // promote it + opcode = LDC_W; + } + } + + @Override + public Type getType(ConstantPool cpg) { + switch (cpg.getConstant(index).getTag()) { + case CONSTANT_String: + return Type.STRING; + case CONSTANT_Float: + return Type.FLOAT; + case CONSTANT_Integer: + return Type.INT; + case CONSTANT_Long: + return Type.LONG; + case CONSTANT_Double: + return Type.DOUBLE; + case CONSTANT_Class: + String name = cpg.getConstantString_CONSTANTClass(index); + // ConstantPool cp = cpg.getConstantPool(); + // String name = cp.getConstantString(index, CONSTANT_Class); + if (!name.startsWith("[")) { + StringBuffer sb = new StringBuffer(); + sb.append("L").append(name).append(";"); + return Type.getType(sb.toString()); + } else { + return Type.getType(name); + } + default: + throw new RuntimeException("Unknown or invalid constant type at " + index); + } + } + + @Override + public Object getValue(ConstantPool constantPool) { + Constant constant = constantPool.getConstant(index); + + switch (constant.getTag()) { + case Constants.CONSTANT_String: + int i = ((ConstantString) constant).getStringIndex(); + constant = constantPool.getConstant(i); + return ((ConstantUtf8) constant).getValue(); + + case Constants.CONSTANT_Float: + return ((ConstantFloat) constant).getValue(); + + case Constants.CONSTANT_Integer: + return ((ConstantInteger) constant).getValue(); + + case Constants.CONSTANT_Long: + return ((ConstantLong) constant).getValue(); + + case Constants.CONSTANT_Double: + return ((ConstantDouble) constant).getValue(); + default: + throw new RuntimeException("Unknown or invalid constant type at " + index); + } + } + + public boolean equals(Object other) { + if (!(other instanceof InstructionCP)) { + return false; + } + InstructionCP o = (InstructionCP) other; + return o.opcode == opcode && o.index == index; + } + + public int hashCode() { + return opcode * 37 + index; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionConstants.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionConstants.java new file mode 100644 index 000000000..e6f884793 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionConstants.java @@ -0,0 +1,379 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.Constants; + +/** + * This interface contains shareable instruction objects. + * + * In order to save memory you can use some instructions multiply, + * since they have an immutable state and are directly derived from + * Instruction. I.e. they have no instance fields that could be + * changed. Since some of these instructions like ICONST_0 occur + * very frequently this can save a lot of time and space. This + * feature is an adaptation of the FlyWeight design pattern, we + * just use an array instead of a factory. + * + * The Instructions can also accessed directly under their names, so + * it's possible to write il.append(Instruction.ICONST_0); + * + * @version $Id: InstructionConstants.java,v 1.4 2008/08/13 18:18:22 aclement Exp $ + * @author M. Dahm + */ +public interface InstructionConstants { + /** Predefined instruction objects + */ + public static final Instruction NOP = new Instruction(Constants.NOP); + public static final Instruction ACONST_NULL = new Instruction(Constants.ACONST_NULL); + public static final Instruction ICONST_M1 = new Instruction(Constants.ICONST_M1); + public static final Instruction ICONST_0 = new Instruction(Constants.ICONST_0); + public static final Instruction ICONST_1 = new Instruction(Constants.ICONST_1); + public static final Instruction ICONST_2 = new Instruction(Constants.ICONST_2); + public static final Instruction ICONST_3 = new Instruction(Constants.ICONST_3); + public static final Instruction ICONST_4 = new Instruction(Constants.ICONST_4); + public static final Instruction ICONST_5 = new Instruction(Constants.ICONST_5); + public static final Instruction LCONST_0 = new Instruction(Constants.LCONST_0); + public static final Instruction LCONST_1 = new Instruction(Constants.LCONST_1); + public static final Instruction FCONST_0 = new Instruction(Constants.FCONST_0); + public static final Instruction FCONST_1 = new Instruction(Constants.FCONST_1); + public static final Instruction FCONST_2 = new Instruction(Constants.FCONST_2); + public static final Instruction DCONST_0 = new Instruction(Constants.DCONST_0); + public static final Instruction DCONST_1 = new Instruction(Constants.DCONST_1); + public static final Instruction IALOAD = new Instruction(Constants.IALOAD); + public static final Instruction LALOAD = new Instruction(Constants.LALOAD); + public static final Instruction FALOAD = new Instruction(Constants.FALOAD); + public static final Instruction DALOAD = new Instruction(Constants.DALOAD); + public static final Instruction AALOAD = new Instruction(Constants.AALOAD); + public static final Instruction BALOAD = new Instruction(Constants.BALOAD); + public static final Instruction CALOAD = new Instruction(Constants.CALOAD); + public static final Instruction SALOAD = new Instruction(Constants.SALOAD); + public static final Instruction IASTORE = new Instruction(Constants.IASTORE); + public static final Instruction LASTORE = new Instruction(Constants.LASTORE); + public static final Instruction FASTORE = new Instruction(Constants.FASTORE); + public static final Instruction DASTORE = new Instruction(Constants.DASTORE); + public static final Instruction AASTORE = new Instruction(Constants.AASTORE); + public static final Instruction BASTORE = new Instruction(Constants.BASTORE); + public static final Instruction CASTORE = new Instruction(Constants.CASTORE); + public static final Instruction SASTORE = new Instruction(Constants.SASTORE); + public static final Instruction POP = new Instruction(Constants.POP); + public static final Instruction POP2 = new Instruction(Constants.POP2); + public static final Instruction DUP = new Instruction(Constants.DUP); + public static final Instruction DUP_X1 = new Instruction(Constants.DUP_X1); + public static final Instruction DUP_X2 = new Instruction(Constants.DUP_X2); + public static final Instruction DUP2 = new Instruction(Constants.DUP2); + public static final Instruction DUP2_X1 = new Instruction(Constants.DUP2_X1); + public static final Instruction DUP2_X2 = new Instruction(Constants.DUP2_X2); + public static final Instruction SWAP = new Instruction(Constants.SWAP); + public static final Instruction IADD = new Instruction(Constants.IADD); + public static final Instruction LADD = new Instruction(Constants.LADD); + public static final Instruction FADD = new Instruction(Constants.FADD); + public static final Instruction DADD = new Instruction(Constants.DADD); + public static final Instruction ISUB = new Instruction(Constants.ISUB); + public static final Instruction LSUB = new Instruction(Constants.LSUB); + public static final Instruction FSUB = new Instruction(Constants.FSUB); + public static final Instruction DSUB = new Instruction(Constants.DSUB); + public static final Instruction IMUL = new Instruction(Constants.IMUL); + public static final Instruction LMUL = new Instruction(Constants.LMUL); + public static final Instruction FMUL = new Instruction(Constants.FMUL); + public static final Instruction DMUL = new Instruction(Constants.DMUL); + public static final Instruction IDIV = new Instruction(Constants.IDIV); + public static final Instruction LDIV = new Instruction(Constants.LDIV); + public static final Instruction FDIV = new Instruction(Constants.FDIV); + public static final Instruction DDIV = new Instruction(Constants.DDIV); + public static final Instruction IREM = new Instruction(Constants.IREM); + public static final Instruction LREM = new Instruction(Constants.LREM); + public static final Instruction FREM = new Instruction(Constants.FREM); + public static final Instruction DREM = new Instruction(Constants.DREM); + public static final Instruction INEG = new Instruction(Constants.INEG); + public static final Instruction LNEG = new Instruction(Constants.LNEG); + public static final Instruction FNEG = new Instruction(Constants.FNEG); + public static final Instruction DNEG = new Instruction(Constants.DNEG); + public static final Instruction ISHL = new Instruction(Constants.ISHL); + public static final Instruction LSHL = new Instruction(Constants.LSHL); + public static final Instruction ISHR = new Instruction(Constants.ISHR); + public static final Instruction LSHR = new Instruction(Constants.LSHR); + public static final Instruction IUSHR = new Instruction(Constants.IUSHR); + public static final Instruction LUSHR = new Instruction(Constants.LUSHR); + public static final Instruction IAND = new Instruction(Constants.IAND); + public static final Instruction LAND = new Instruction(Constants.LAND); + public static final Instruction IOR = new Instruction(Constants.IOR); + public static final Instruction LOR = new Instruction(Constants.LOR); + public static final Instruction IXOR = new Instruction(Constants.IXOR); + public static final Instruction LXOR = new Instruction(Constants.LXOR); + public static final Instruction I2L = new Instruction(Constants.I2L); + public static final Instruction I2F = new Instruction(Constants.I2F); + public static final Instruction I2D = new Instruction(Constants.I2D); + public static final Instruction L2I = new Instruction(Constants.L2I); + public static final Instruction L2F = new Instruction(Constants.L2F); + public static final Instruction L2D = new Instruction(Constants.L2D); + public static final Instruction F2I = new Instruction(Constants.F2I); + public static final Instruction F2L = new Instruction(Constants.F2L); + public static final Instruction F2D = new Instruction(Constants.F2D); + public static final Instruction D2I = new Instruction(Constants.D2I); + public static final Instruction D2L = new Instruction(Constants.D2L); + public static final Instruction D2F = new Instruction(Constants.D2F); + public static final Instruction I2B = new Instruction(Constants.I2B); + public static final Instruction I2C = new Instruction(Constants.I2C); + public static final Instruction I2S = new Instruction(Constants.I2S); + public static final Instruction LCMP = new Instruction(Constants.LCMP); + public static final Instruction FCMPL = new Instruction(Constants.FCMPL); + public static final Instruction FCMPG = new Instruction(Constants.FCMPG); + public static final Instruction DCMPL = new Instruction(Constants.DCMPL); + public static final Instruction DCMPG = new Instruction(Constants.DCMPG); + public static final Instruction IRETURN = new Instruction(Constants.IRETURN); + public static final Instruction LRETURN = new Instruction(Constants.LRETURN); + public static final Instruction FRETURN = new Instruction(Constants.FRETURN); + public static final Instruction DRETURN = new Instruction(Constants.DRETURN); + public static final Instruction ARETURN = new Instruction(Constants.ARETURN); + public static final Instruction RETURN = new Instruction(Constants.RETURN); + public static final Instruction ARRAYLENGTH = new Instruction(Constants.ARRAYLENGTH); + public static final Instruction ATHROW = new Instruction(Constants.ATHROW); + public static final Instruction MONITORENTER = new Instruction(Constants.MONITORENTER); + public static final Instruction MONITOREXIT = new Instruction(Constants.MONITOREXIT); + public static final Instruction IMPDEP1 = new Instruction(Constants.IMPDEP1); + public static final Instruction IMPDEP2 = new Instruction(Constants.IMPDEP2); + + // You can use these constants in multiple places safely, any attempt to change the index + // for these constants will cause an exception + public static final InstructionLV THIS = new InstructionCLV(Constants.ALOAD,0); + public static final InstructionLV ALOAD_0 = new InstructionCLV(Constants.ALOAD_0); + public static final InstructionLV ALOAD_1 = new InstructionCLV(Constants.ALOAD_1); + public static final InstructionLV ALOAD_2 = new InstructionCLV(Constants.ALOAD_2); + public static final InstructionLV ALOAD_3 = new InstructionCLV(Constants.ALOAD_3); + public static final InstructionLV ILOAD_0 = new InstructionCLV(Constants.ILOAD_0); + public static final InstructionLV ILOAD_1 = new InstructionCLV(Constants.ILOAD_1); + public static final InstructionLV ILOAD_2 = new InstructionCLV(Constants.ILOAD_2); + public static final InstructionLV ILOAD_3 = new InstructionCLV(Constants.ILOAD_3); + public static final InstructionLV DLOAD_0 = new InstructionCLV(Constants.DLOAD_0); + public static final InstructionLV DLOAD_1 = new InstructionCLV(Constants.DLOAD_1); + public static final InstructionLV DLOAD_2 = new InstructionCLV(Constants.DLOAD_2); + public static final InstructionLV DLOAD_3 = new InstructionCLV(Constants.DLOAD_3); + public static final InstructionLV FLOAD_0 = new InstructionCLV(Constants.FLOAD_0); + public static final InstructionLV FLOAD_1 = new InstructionCLV(Constants.FLOAD_1); + public static final InstructionLV FLOAD_2 = new InstructionCLV(Constants.FLOAD_2); + public static final InstructionLV FLOAD_3 = new InstructionCLV(Constants.FLOAD_3); + public static final InstructionLV LLOAD_0 = new InstructionCLV(Constants.LLOAD_0); + public static final InstructionLV LLOAD_1 = new InstructionCLV(Constants.LLOAD_1); + public static final InstructionLV LLOAD_2 = new InstructionCLV(Constants.LLOAD_2); + public static final InstructionLV LLOAD_3 = new InstructionCLV(Constants.LLOAD_3); + public static final InstructionLV ASTORE_0 = new InstructionCLV(Constants.ASTORE_0); + public static final InstructionLV ASTORE_1 = new InstructionCLV(Constants.ASTORE_1); + public static final InstructionLV ASTORE_2 = new InstructionCLV(Constants.ASTORE_2); + public static final InstructionLV ASTORE_3 = new InstructionCLV(Constants.ASTORE_3); + public static final InstructionLV ISTORE_0 = new InstructionCLV(Constants.ISTORE_0); + public static final InstructionLV ISTORE_1 = new InstructionCLV(Constants.ISTORE_1); + public static final InstructionLV ISTORE_2 = new InstructionCLV(Constants.ISTORE_2); + public static final InstructionLV ISTORE_3 = new InstructionCLV(Constants.ISTORE_3); + public static final InstructionLV LSTORE_0 = new InstructionCLV(Constants.LSTORE_0); + public static final InstructionLV LSTORE_1 = new InstructionCLV(Constants.LSTORE_1); + public static final InstructionLV LSTORE_2 = new InstructionCLV(Constants.LSTORE_2); + public static final InstructionLV LSTORE_3 = new InstructionCLV(Constants.LSTORE_3); + public static final InstructionLV FSTORE_0 = new InstructionCLV(Constants.FSTORE_0); + public static final InstructionLV FSTORE_1 = new InstructionCLV(Constants.FSTORE_1); + public static final InstructionLV FSTORE_2 = new InstructionCLV(Constants.FSTORE_2); + public static final InstructionLV FSTORE_3 = new InstructionCLV(Constants.FSTORE_3); + public static final InstructionLV DSTORE_0 = new InstructionCLV(Constants.DSTORE_0); + public static final InstructionLV DSTORE_1 = new InstructionCLV(Constants.DSTORE_1); + public static final InstructionLV DSTORE_2 = new InstructionCLV(Constants.DSTORE_2); + public static final InstructionLV DSTORE_3 = new InstructionCLV(Constants.DSTORE_3); + + + /** Get object via its opcode, for immutable instructions like + * branch instructions entries are set to null. + */ + public static final Instruction[] INSTRUCTIONS = new Instruction[256]; + + /** Interfaces may have no static initializers, so we simulate this + * with an inner class. + */ + static final Clinit bla = new Clinit(); + + static class Clinit { + Clinit() { + INSTRUCTIONS[Constants.NOP] = NOP; + INSTRUCTIONS[Constants.ACONST_NULL] = ACONST_NULL; + INSTRUCTIONS[Constants.ICONST_M1] = ICONST_M1; + INSTRUCTIONS[Constants.ICONST_0] = ICONST_0; + INSTRUCTIONS[Constants.ICONST_1] = ICONST_1; + INSTRUCTIONS[Constants.ICONST_2] = ICONST_2; + INSTRUCTIONS[Constants.ICONST_3] = ICONST_3; + INSTRUCTIONS[Constants.ICONST_4] = ICONST_4; + INSTRUCTIONS[Constants.ICONST_5] = ICONST_5; + INSTRUCTIONS[Constants.LCONST_0] = LCONST_0; + INSTRUCTIONS[Constants.LCONST_1] = LCONST_1; + INSTRUCTIONS[Constants.FCONST_0] = FCONST_0; + INSTRUCTIONS[Constants.FCONST_1] = FCONST_1; + INSTRUCTIONS[Constants.FCONST_2] = FCONST_2; + INSTRUCTIONS[Constants.DCONST_0] = DCONST_0; + INSTRUCTIONS[Constants.DCONST_1] = DCONST_1; + INSTRUCTIONS[Constants.IALOAD] = IALOAD; + INSTRUCTIONS[Constants.LALOAD] = LALOAD; + INSTRUCTIONS[Constants.FALOAD] = FALOAD; + INSTRUCTIONS[Constants.DALOAD] = DALOAD; + INSTRUCTIONS[Constants.AALOAD] = AALOAD; + INSTRUCTIONS[Constants.BALOAD] = BALOAD; + INSTRUCTIONS[Constants.CALOAD] = CALOAD; + INSTRUCTIONS[Constants.SALOAD] = SALOAD; + INSTRUCTIONS[Constants.IASTORE] = IASTORE; + INSTRUCTIONS[Constants.LASTORE] = LASTORE; + INSTRUCTIONS[Constants.FASTORE] = FASTORE; + INSTRUCTIONS[Constants.DASTORE] = DASTORE; + INSTRUCTIONS[Constants.AASTORE] = AASTORE; + INSTRUCTIONS[Constants.BASTORE] = BASTORE; + INSTRUCTIONS[Constants.CASTORE] = CASTORE; + INSTRUCTIONS[Constants.SASTORE] = SASTORE; + INSTRUCTIONS[Constants.POP] = POP; + INSTRUCTIONS[Constants.POP2] = POP2; + INSTRUCTIONS[Constants.DUP] = DUP; + INSTRUCTIONS[Constants.DUP_X1] = DUP_X1; + INSTRUCTIONS[Constants.DUP_X2] = DUP_X2; + INSTRUCTIONS[Constants.DUP2] = DUP2; + INSTRUCTIONS[Constants.DUP2_X1] = DUP2_X1; + INSTRUCTIONS[Constants.DUP2_X2] = DUP2_X2; + INSTRUCTIONS[Constants.SWAP] = SWAP; + INSTRUCTIONS[Constants.IADD] = IADD; + INSTRUCTIONS[Constants.LADD] = LADD; + INSTRUCTIONS[Constants.FADD] = FADD; + INSTRUCTIONS[Constants.DADD] = DADD; + INSTRUCTIONS[Constants.ISUB] = ISUB; + INSTRUCTIONS[Constants.LSUB] = LSUB; + INSTRUCTIONS[Constants.FSUB] = FSUB; + INSTRUCTIONS[Constants.DSUB] = DSUB; + INSTRUCTIONS[Constants.IMUL] = IMUL; + INSTRUCTIONS[Constants.LMUL] = LMUL; + INSTRUCTIONS[Constants.FMUL] = FMUL; + INSTRUCTIONS[Constants.DMUL] = DMUL; + INSTRUCTIONS[Constants.IDIV] = IDIV; + INSTRUCTIONS[Constants.LDIV] = LDIV; + INSTRUCTIONS[Constants.FDIV] = FDIV; + INSTRUCTIONS[Constants.DDIV] = DDIV; + INSTRUCTIONS[Constants.IREM] = IREM; + INSTRUCTIONS[Constants.LREM] = LREM; + INSTRUCTIONS[Constants.FREM] = FREM; + INSTRUCTIONS[Constants.DREM] = DREM; + INSTRUCTIONS[Constants.INEG] = INEG; + INSTRUCTIONS[Constants.LNEG] = LNEG; + INSTRUCTIONS[Constants.FNEG] = FNEG; + INSTRUCTIONS[Constants.DNEG] = DNEG; + INSTRUCTIONS[Constants.ISHL] = ISHL; + INSTRUCTIONS[Constants.LSHL] = LSHL; + INSTRUCTIONS[Constants.ISHR] = ISHR; + INSTRUCTIONS[Constants.LSHR] = LSHR; + INSTRUCTIONS[Constants.IUSHR] = IUSHR; + INSTRUCTIONS[Constants.LUSHR] = LUSHR; + INSTRUCTIONS[Constants.IAND] = IAND; + INSTRUCTIONS[Constants.LAND] = LAND; + INSTRUCTIONS[Constants.IOR] = IOR; + INSTRUCTIONS[Constants.LOR] = LOR; + INSTRUCTIONS[Constants.IXOR] = IXOR; + INSTRUCTIONS[Constants.LXOR] = LXOR; + INSTRUCTIONS[Constants.I2L] = I2L; + INSTRUCTIONS[Constants.I2F] = I2F; + INSTRUCTIONS[Constants.I2D] = I2D; + INSTRUCTIONS[Constants.L2I] = L2I; + INSTRUCTIONS[Constants.L2F] = L2F; + INSTRUCTIONS[Constants.L2D] = L2D; + INSTRUCTIONS[Constants.F2I] = F2I; + INSTRUCTIONS[Constants.F2L] = F2L; + INSTRUCTIONS[Constants.F2D] = F2D; + INSTRUCTIONS[Constants.D2I] = D2I; + INSTRUCTIONS[Constants.D2L] = D2L; + INSTRUCTIONS[Constants.D2F] = D2F; + INSTRUCTIONS[Constants.I2B] = I2B; + INSTRUCTIONS[Constants.I2C] = I2C; + INSTRUCTIONS[Constants.I2S] = I2S; + INSTRUCTIONS[Constants.LCMP] = LCMP; + INSTRUCTIONS[Constants.FCMPL] = FCMPL; + INSTRUCTIONS[Constants.FCMPG] = FCMPG; + INSTRUCTIONS[Constants.DCMPL] = DCMPL; + INSTRUCTIONS[Constants.DCMPG] = DCMPG; + INSTRUCTIONS[Constants.IRETURN] = IRETURN; + INSTRUCTIONS[Constants.LRETURN] = LRETURN; + INSTRUCTIONS[Constants.FRETURN] = FRETURN; + INSTRUCTIONS[Constants.DRETURN] = DRETURN; + INSTRUCTIONS[Constants.ARETURN] = ARETURN; + INSTRUCTIONS[Constants.RETURN] = RETURN; + INSTRUCTIONS[Constants.ARRAYLENGTH] = ARRAYLENGTH; + INSTRUCTIONS[Constants.ATHROW] = ATHROW; + INSTRUCTIONS[Constants.MONITORENTER] = MONITORENTER; + INSTRUCTIONS[Constants.MONITOREXIT] = MONITOREXIT; + INSTRUCTIONS[Constants.IMPDEP1] = IMPDEP1; + INSTRUCTIONS[Constants.IMPDEP2] = IMPDEP2; + + INSTRUCTIONS[Constants.ALOAD_0] = ALOAD_0;INSTRUCTIONS[Constants.ALOAD_1] = ALOAD_1; + INSTRUCTIONS[Constants.ALOAD_2] = ALOAD_2;INSTRUCTIONS[Constants.ALOAD_3] = ALOAD_3; + INSTRUCTIONS[Constants.LLOAD_0] = LLOAD_0;INSTRUCTIONS[Constants.LLOAD_1] = LLOAD_1; + INSTRUCTIONS[Constants.LLOAD_2] = LLOAD_2;INSTRUCTIONS[Constants.LLOAD_3] = LLOAD_3; + INSTRUCTIONS[Constants.DLOAD_0] = DLOAD_0;INSTRUCTIONS[Constants.DLOAD_1] = DLOAD_1; + INSTRUCTIONS[Constants.DLOAD_2] = DLOAD_2;INSTRUCTIONS[Constants.DLOAD_3] = DLOAD_3; + INSTRUCTIONS[Constants.FLOAD_0] = FLOAD_0;INSTRUCTIONS[Constants.FLOAD_1] = FLOAD_1; + INSTRUCTIONS[Constants.FLOAD_2] = FLOAD_2;INSTRUCTIONS[Constants.FLOAD_3] = FLOAD_3; + INSTRUCTIONS[Constants.ILOAD_0] = ILOAD_0;INSTRUCTIONS[Constants.ILOAD_1] = ILOAD_1; + INSTRUCTIONS[Constants.ILOAD_2] = ILOAD_2;INSTRUCTIONS[Constants.ILOAD_3] = ILOAD_3; + + INSTRUCTIONS[Constants.ASTORE_0] = ASTORE_0;INSTRUCTIONS[Constants.ASTORE_1] = ASTORE_1; + INSTRUCTIONS[Constants.ASTORE_2] = ASTORE_2;INSTRUCTIONS[Constants.ASTORE_3] = ASTORE_3; + INSTRUCTIONS[Constants.LSTORE_0] = LSTORE_0;INSTRUCTIONS[Constants.LSTORE_1] = LSTORE_1; + INSTRUCTIONS[Constants.LSTORE_2] = LSTORE_2;INSTRUCTIONS[Constants.LSTORE_3] = LSTORE_3; + INSTRUCTIONS[Constants.DSTORE_0] = DSTORE_0;INSTRUCTIONS[Constants.DSTORE_1] = DSTORE_1; + INSTRUCTIONS[Constants.DSTORE_2] = DSTORE_2;INSTRUCTIONS[Constants.DSTORE_3] = DSTORE_3; + INSTRUCTIONS[Constants.FSTORE_0] = FSTORE_0;INSTRUCTIONS[Constants.FSTORE_1] = FSTORE_1; + INSTRUCTIONS[Constants.FSTORE_2] = FSTORE_2;INSTRUCTIONS[Constants.FSTORE_3] = FSTORE_3; + INSTRUCTIONS[Constants.ISTORE_0] = ISTORE_0;INSTRUCTIONS[Constants.ISTORE_1] = ISTORE_1; + INSTRUCTIONS[Constants.ISTORE_2] = ISTORE_2;INSTRUCTIONS[Constants.ISTORE_3] = ISTORE_3; + } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionFactory.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionFactory.java new file mode 100644 index 000000000..4e1e6c8a8 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionFactory.java @@ -0,0 +1,771 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.Utility; + +/** + * Instances of this class may be used, e.g., to generate typed versions of instructions. Its main purpose is to be used as the byte + * code generating backend of a compiler. You can subclass it to add your own create methods. + * + * @version $Id: InstructionFactory.java,v 1.7 2010/08/23 20:44:10 aclement Exp $ + * @author M. Dahm + * @see Constants + */ +public class InstructionFactory implements InstructionConstants { + protected ClassGen cg; + protected ConstantPool cp; + + public InstructionFactory(ClassGen cg, ConstantPool cp) { + this.cg = cg; + this.cp = cp; + } + + public InstructionFactory(ClassGen cg) { + this(cg, cg.getConstantPool()); + } + + public InstructionFactory(ConstantPool cp) { + this(null, cp); + } + + public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind) { + return createInvoke(class_name, name, ret_type, arg_types, kind, false); + } + + /** + * Create an invoke instruction. + * + * @param class_name name of the called class + * @param name name of the called method + * @param ret_type return type of method + * @param arg_types argument types of method + * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL + * @param isInterface for an invokestatic on an interface allows us to tell this method the target is an interface + * @see Constants + */ + public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind, boolean isInterface) { + + String signature = Utility.toMethodSignature(ret_type, arg_types); + + int index; + if (kind == Constants.INVOKEINTERFACE || isInterface) { + index = cp.addInterfaceMethodref(class_name, name, signature); + } else if (kind == Constants.INVOKEDYNAMIC){ + throw new IllegalStateException("NYI"); + } else { + index = cp.addMethodref(class_name, name, signature); + } + + switch (kind) { + case Constants.INVOKESPECIAL: + return new InvokeInstruction(Constants.INVOKESPECIAL, index); + case Constants.INVOKEVIRTUAL: + return new InvokeInstruction(Constants.INVOKEVIRTUAL, index); + case Constants.INVOKESTATIC: + return new InvokeInstruction(Constants.INVOKESTATIC, index); + case Constants.INVOKEINTERFACE: + int nargs = 0; + for (int i = 0; i < arg_types.length; i++) { + nargs += arg_types[i].getSize(); + } + return new INVOKEINTERFACE(index, nargs + 1, 0); + default: + throw new RuntimeException("Oops: Unknown invoke kind:" + kind); + } + } + + public InvokeInstruction createInvoke(String class_name, String name, String signature, short kind) { + int index; + if (kind == Constants.INVOKEINTERFACE) { + index = cp.addInterfaceMethodref(class_name, name, signature); + } else if (kind == Constants.INVOKEDYNAMIC){ + throw new IllegalStateException("NYI"); + } else { + index = cp.addMethodref(class_name, name, signature); + } + + switch (kind) { + case Constants.INVOKESPECIAL: + return new InvokeInstruction(Constants.INVOKESPECIAL, index); + case Constants.INVOKEVIRTUAL: + return new InvokeInstruction(Constants.INVOKEVIRTUAL, index); + case Constants.INVOKESTATIC: + return new InvokeInstruction(Constants.INVOKESTATIC, index); + case Constants.INVOKEINTERFACE: + Type[] argumentTypes = Type.getArgumentTypes(signature); + int nargs = 0; + for (int i = 0; i < argumentTypes.length; i++) {// Count size of arguments + nargs += argumentTypes[i].getSize(); + } + return new INVOKEINTERFACE(index, nargs + 1, 0); + default: + throw new RuntimeException("Oops: Unknown invoke kind:" + kind); + } + } + + public static Instruction createALOAD(int n) { + if (n < 4) { + return new InstructionLV((short) (Constants.ALOAD_0 + n)); + } + return new InstructionLV(Constants.ALOAD, n); + } + + public static Instruction createASTORE(int n) { + if (n < 4) { + return new InstructionLV((short) (Constants.ASTORE_0 + n)); + } + return new InstructionLV(Constants.ASTORE, n); + } + + /** + * Uses PUSH to push a constant value onto the stack. + * + * @param value must be of type Number, Boolean, Character or String + */ + // OPTIMIZE callers should use the PUSH methods where possible if they know the types + public Instruction createConstant(Object value) { + Instruction instruction; + + if (value instanceof Number) { + instruction = InstructionFactory.PUSH(cp, (Number) value); + } else if (value instanceof String) { + instruction = InstructionFactory.PUSH(cp, (String) value); + } else if (value instanceof Boolean) { + instruction = InstructionFactory.PUSH(cp, (Boolean) value); + } else if (value instanceof Character) { + instruction = InstructionFactory.PUSH(cp, (Character) value); + } else if (value instanceof ObjectType) { + instruction = InstructionFactory.PUSH(cp, (ObjectType) value); + } else { + throw new ClassGenException("Illegal type: " + value.getClass()); + } + + return instruction; + } + + /** + * Create a field instruction. + * + * @param class_name name of the accessed class + * @param name name of the referenced field + * @param type type of field + * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC + * @see Constants + */ + public FieldInstruction createFieldAccess(String class_name, String name, Type type, short kind) { + int index; + String signature = type.getSignature(); + + index = cp.addFieldref(class_name, name, signature); + + switch (kind) { + case Constants.GETFIELD: + return new FieldInstruction(Constants.GETFIELD, index); + case Constants.PUTFIELD: + return new FieldInstruction(Constants.PUTFIELD, index); + case Constants.GETSTATIC: + return new FieldInstruction(Constants.GETSTATIC, index); + case Constants.PUTSTATIC: + return new FieldInstruction(Constants.PUTSTATIC, index); + + default: + throw new RuntimeException("Oops: Unknown getfield kind:" + kind); + } + } + + /** + * Create reference to `this' + */ + public static Instruction createThis() { + return new InstructionLV(Constants.ALOAD, 0); + } + + /** + * Create typed return + */ + public static Instruction createReturn(Type type) { + switch (type.getType()) { + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return ARETURN; + case Constants.T_INT: + case Constants.T_SHORT: + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_BYTE: + return IRETURN; + case Constants.T_FLOAT: + return FRETURN; + case Constants.T_DOUBLE: + return DRETURN; + case Constants.T_LONG: + return LRETURN; + case Constants.T_VOID: + return RETURN; + + default: + throw new RuntimeException("Invalid type: " + type); + } + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static Instruction createPop(int size) { + return (size == 2) ? POP2 : POP; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static Instruction createDup(int size) { + return (size == 2) ? DUP2 : DUP; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static Instruction createDup_2(int size) { + return (size == 2) ? DUP2_X2 : DUP_X2; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static Instruction createDup_1(int size) { + return (size == 2) ? DUP2_X1 : DUP_X1; + } + + /** + * @param index index of local variable + */ + public static InstructionLV createStore(Type type, int index) { + switch (type.getType()) { + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_BYTE: + case Constants.T_SHORT: + case Constants.T_INT: + return new InstructionLV(Constants.ISTORE, index); + case Constants.T_FLOAT: + return new InstructionLV(Constants.FSTORE, index); + case Constants.T_DOUBLE: + return new InstructionLV(Constants.DSTORE, index); + case Constants.T_LONG: + return new InstructionLV(Constants.LSTORE, index); + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return new InstructionLV(Constants.ASTORE, index); + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param index index of local variable + */ + public static InstructionLV createLoad(Type type, int index) { + switch (type.getType()) { + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_BYTE: + case Constants.T_SHORT: + case Constants.T_INT: + return new InstructionLV(Constants.ILOAD, index); + case Constants.T_FLOAT: + return new InstructionLV(Constants.FLOAD, index); + case Constants.T_DOUBLE: + return new InstructionLV(Constants.DLOAD, index); + case Constants.T_LONG: + return new InstructionLV(Constants.LLOAD, index); + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return new InstructionLV(Constants.ALOAD, index); + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param type type of elements of array, i.e., array.getElementType() + */ + public static Instruction createArrayLoad(Type type) { + switch (type.getType()) { + case Constants.T_BOOLEAN: + case Constants.T_BYTE: + return BALOAD; + case Constants.T_CHAR: + return CALOAD; + case Constants.T_SHORT: + return SALOAD; + case Constants.T_INT: + return IALOAD; + case Constants.T_FLOAT: + return FALOAD; + case Constants.T_DOUBLE: + return DALOAD; + case Constants.T_LONG: + return LALOAD; + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return AALOAD; + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param type type of elements of array, i.e., array.getElementType() + */ + public static Instruction createArrayStore(Type type) { + switch (type.getType()) { + case Constants.T_BOOLEAN: + case Constants.T_BYTE: + return BASTORE; + case Constants.T_CHAR: + return CASTORE; + case Constants.T_SHORT: + return SASTORE; + case Constants.T_INT: + return IASTORE; + case Constants.T_FLOAT: + return FASTORE; + case Constants.T_DOUBLE: + return DASTORE; + case Constants.T_LONG: + return LASTORE; + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return AASTORE; + default: + throw new RuntimeException("Invalid type " + type); + } + } + + private static final char[] shortNames = { 'C', 'F', 'D', 'B', 'S', 'I', 'L' }; + + /** + * Create conversion operation for two stack operands, this may be an I2C, instruction, e.g., if the operands are basic types + * and CHECKCAST if they are reference types. + */ + public Instruction createCast(Type src_type, Type dest_type) { + if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { + byte dest = dest_type.getType(); + byte src = src_type.getType(); + + if (dest == Constants.T_LONG && (src == Constants.T_CHAR || src == Constants.T_BYTE || src == Constants.T_SHORT)) { + src = Constants.T_INT; + } + + if (src == Constants.T_DOUBLE) { + switch (dest) { + case Constants.T_FLOAT: + return InstructionConstants.D2F; + case Constants.T_INT: + return InstructionConstants.D2I; + case Constants.T_LONG: + return InstructionConstants.D2L; + } + } else if (src == Constants.T_FLOAT) { + switch (dest) { + case Constants.T_DOUBLE: + return InstructionConstants.F2D; + case Constants.T_INT: + return InstructionConstants.F2I; + case Constants.T_LONG: + return InstructionConstants.F2L; + } + } else if (src == Constants.T_INT) { + switch (dest) { + case Constants.T_BYTE: + return InstructionConstants.I2B; + case Constants.T_CHAR: + return InstructionConstants.I2C; + case Constants.T_DOUBLE: + return InstructionConstants.I2D; + case Constants.T_FLOAT: + return InstructionConstants.I2F; + case Constants.T_LONG: + return InstructionConstants.I2L; + case Constants.T_SHORT: + return InstructionConstants.I2S; + } + } else if (src == Constants.T_LONG) { + switch (dest) { + case Constants.T_DOUBLE: + return InstructionConstants.L2D; + case Constants.T_FLOAT: + return InstructionConstants.L2F; + case Constants.T_INT: + return InstructionConstants.L2I; + } + } + + // String name = "org.aspectj.apache.bcel.generic." + short_names[src - Constants.T_CHAR] + + // "2" + short_names[dest - Constants.T_CHAR]; + + // Instruction i = null; + // try { + // i = (Instruction)java.lang.Class.forName(name).newInstance(); + // } catch(Exception e) { + // throw new RuntimeException("Could not find instruction: " + name); + // } + + return null; + // return i; + } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { + if (dest_type instanceof ArrayType) { + return new InstructionCP(Constants.CHECKCAST, cp.addArrayClass((ArrayType) dest_type)); + } else { + return new InstructionCP(Constants.CHECKCAST, cp.addClass(((ObjectType) dest_type).getClassName())); + } + } else { + throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); + } + } + + public FieldInstruction createGetField(String class_name, String name, Type t) { + return new FieldInstruction(Constants.GETFIELD, cp.addFieldref(class_name, name, t.getSignature())); + } + + public FieldInstruction createGetStatic(String class_name, String name, Type t) { + return new FieldInstruction(Constants.GETSTATIC, cp.addFieldref(class_name, name, t.getSignature())); + } + + public FieldInstruction createPutField(String class_name, String name, Type t) { + return new FieldInstruction(Constants.PUTFIELD, cp.addFieldref(class_name, name, t.getSignature())); + } + + public FieldInstruction createPutStatic(String class_name, String name, Type t) { + return new FieldInstruction(Constants.PUTSTATIC, cp.addFieldref(class_name, name, t.getSignature())); + } + + public Instruction createCheckCast(ReferenceType t) { + if (t instanceof ArrayType) { + return new InstructionCP(Constants.CHECKCAST, cp.addArrayClass((ArrayType) t)); + } else { + return new InstructionCP(Constants.CHECKCAST, cp.addClass((ObjectType) t)); + } + } + + public Instruction createInstanceOf(ReferenceType t) { + if (t instanceof ArrayType) { + return new InstructionCP(Constants.INSTANCEOF, cp.addArrayClass((ArrayType) t)); + } else { + return new InstructionCP(Constants.INSTANCEOF, cp.addClass((ObjectType) t)); + } + } + + public Instruction createNew(ObjectType t) { + return new InstructionCP(Constants.NEW, cp.addClass(t)); + } + + public Instruction createNew(String s) { + return createNew(new ObjectType(s)); + } + + /** + * Create new array of given size and type. + * + * @return an instruction that creates the corresponding array at runtime, i.e. is an AllocationInstruction + */ + public Instruction createNewArray(Type t, short dim) { + if (dim == 1) { + if (t instanceof ObjectType) { + return new InstructionCP(Constants.ANEWARRAY, cp.addClass((ObjectType) t)); + } else if (t instanceof ArrayType) { + return new InstructionCP(Constants.ANEWARRAY, cp.addArrayClass((ArrayType) t)); + } else { + return new InstructionByte(Constants.NEWARRAY, ((BasicType) t).getType()); + } + } else { + ArrayType at; + + if (t instanceof ArrayType) { + at = (ArrayType) t; + } else { + at = new ArrayType(t, dim); + } + + return new MULTIANEWARRAY(cp.addArrayClass(at), dim); + } + } + + /** + * Create "null" value for reference types, 0 for basic types like int + */ + public static Instruction createNull(Type type) { + switch (type.getType()) { + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return ACONST_NULL; + case Constants.T_INT: + case Constants.T_SHORT: + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_BYTE: + return ICONST_0; + case Constants.T_FLOAT: + return FCONST_0; + case Constants.T_DOUBLE: + return DCONST_0; + case Constants.T_LONG: + return LCONST_0; + case Constants.T_VOID: + return NOP; + + default: + throw new RuntimeException("Invalid type: " + type); + } + } + + /** + * Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH. For those you should use the SWITCH compound + * instruction. + */ + public static InstructionBranch createBranchInstruction(short opcode, InstructionHandle target) { + switch (opcode) { + case Constants.IFEQ: + return new InstructionBranch(Constants.IFEQ, target); + case Constants.IFNE: + return new InstructionBranch(Constants.IFNE, target); + case Constants.IFLT: + return new InstructionBranch(Constants.IFLT, target); + case Constants.IFGE: + return new InstructionBranch(Constants.IFGE, target); + case Constants.IFGT: + return new InstructionBranch(Constants.IFGT, target); + case Constants.IFLE: + return new InstructionBranch(Constants.IFLE, target); + case Constants.IF_ICMPEQ: + return new InstructionBranch(Constants.IF_ICMPEQ, target); + case Constants.IF_ICMPNE: + return new InstructionBranch(Constants.IF_ICMPNE, target); + case Constants.IF_ICMPLT: + return new InstructionBranch(Constants.IF_ICMPLT, target); + case Constants.IF_ICMPGE: + return new InstructionBranch(Constants.IF_ICMPGE, target); + case Constants.IF_ICMPGT: + return new InstructionBranch(Constants.IF_ICMPGT, target); + case Constants.IF_ICMPLE: + return new InstructionBranch(Constants.IF_ICMPLE, target); + case Constants.IF_ACMPEQ: + return new InstructionBranch(Constants.IF_ACMPEQ, target); + case Constants.IF_ACMPNE: + return new InstructionBranch(Constants.IF_ACMPNE, target); + case Constants.GOTO: + return new InstructionBranch(Constants.GOTO, target); + case Constants.JSR: + return new InstructionBranch(Constants.JSR, target); + case Constants.IFNULL: + return new InstructionBranch(Constants.IFNULL, target); + case Constants.IFNONNULL: + return new InstructionBranch(Constants.IFNONNULL, target); + case Constants.GOTO_W: + return new InstructionBranch(Constants.GOTO_W, target); + case Constants.JSR_W: + return new InstructionBranch(Constants.JSR_W, target); + default: + throw new RuntimeException("Invalid opcode: " + opcode); + } + } + + public void setClassGen(ClassGen c) { + cg = c; + } + + public ClassGen getClassGen() { + return cg; + } + + public void setConstantPool(ConstantPool c) { + cp = c; + } + + public ConstantPool getConstantPool() { + return cp; + } + + /** + * Returns the right instruction for putting whatever you want onto the stack + */ + public static Instruction PUSH(ConstantPool cp, int value) { + Instruction instruction = null; + if ((value >= -1) && (value <= 5)) { + return INSTRUCTIONS[Constants.ICONST_0 + value]; + } else if ((value >= -128) && (value <= 127)) { + instruction = new InstructionByte(Constants.BIPUSH, (byte) value); + } else if ((value >= -32768) && (value <= 32767)) { + instruction = new InstructionShort(Constants.SIPUSH, (short) value); + } else // If everything fails create a Constant pool entry + { + int pos = cp.addInteger(value); + if (pos <= Constants.MAX_BYTE) { + instruction = new InstructionCP(Constants.LDC, pos); + } else { + instruction = new InstructionCP(Constants.LDC_W, pos); + } + } + return instruction; + } + + public static Instruction PUSH(ConstantPool cp, ObjectType t) { + return new InstructionCP(Constants.LDC_W, cp.addClass(t)); + } + + public static Instruction PUSH(ConstantPool cp, boolean value) { + return INSTRUCTIONS[Constants.ICONST_0 + (value ? 1 : 0)]; + } + + public static Instruction PUSH(ConstantPool cp, float value) { + Instruction instruction = null; + if (value == 0.0) { + instruction = FCONST_0; + } else if (value == 1.0) { + instruction = FCONST_1; + } else if (value == 2.0) { + instruction = FCONST_2; + } else { + // Create a Constant pool entry + int i = cp.addFloat(value); + instruction = new InstructionCP(i <= Constants.MAX_BYTE ? Constants.LDC : Constants.LDC_W, i); + } + return instruction; + } + + public static Instruction PUSH(ConstantPool cp, long value) { + Instruction instruction = null; + if (value == 0) { + instruction = LCONST_0; + } else if (value == 1) { + instruction = LCONST_1; + } else { + instruction = new InstructionCP(Constants.LDC2_W, cp.addLong(value)); + } + return instruction; + } + + public static Instruction PUSH(ConstantPool cp, double value) { + Instruction instruction = null; + if (value == 0.0) { + instruction = DCONST_0; + } else if (value == 1.0) { + instruction = DCONST_1; + } else { + // Create a Constant pool entry + instruction = new InstructionCP(Constants.LDC2_W, cp.addDouble(value)); + } + return instruction; + } + + public static Instruction PUSH(ConstantPool cp, String value) { + Instruction instruction = null; + if (value == null) { + instruction = ACONST_NULL; + } else { + int i = cp.addString(value); + instruction = new InstructionCP(i <= Constants.MAX_BYTE ? Constants.LDC : Constants.LDC_W, i); + } + return instruction; + } + + public static Instruction PUSH(ConstantPool cp, Number value) { + Instruction instruction = null; + if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) { + instruction = PUSH(cp, value.intValue()); + } else if (value instanceof Double) { + instruction = PUSH(cp, value.doubleValue()); + } else if (value instanceof Float) { + instruction = PUSH(cp, value.floatValue()); + } else if (value instanceof Long) { + instruction = PUSH(cp, value.longValue()); + } else { + throw new ClassGenException("What's this: " + value); + } + return instruction; + } + + public static Instruction PUSH(ConstantPool cp, Character value) { + return PUSH(cp, value.charValue()); + } + + public static Instruction PUSH(ConstantPool cp, Boolean value) { + return PUSH(cp, value.booleanValue()); + } + + /** + * Return a list that will load the Class object - on 1.5 or later use the class variant of ldc, whilst on earlier JVMs use the + * regular Class.forName. + */ + public InstructionList PUSHCLASS(ConstantPool cp, String className) { + InstructionList iList = new InstructionList(); + int classIndex = cp.addClass(className); + if (cg != null && cg.getMajor() >= Constants.MAJOR_1_5) { + if (classIndex <= Constants.MAX_BYTE) { + iList.append(new InstructionCP(Instruction.LDC, classIndex)); + } else { + iList.append(new InstructionCP(Instruction.LDC_W, classIndex)); + } + } else { + className = className.replace('/', '.'); + iList.append(InstructionFactory.PUSH(cp, className)); + iList.append(this.createInvoke("java.lang.Class", "forName", ObjectType.CLASS, Type.STRINGARRAY1, + Constants.INVOKESTATIC)); + } + return iList; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionHandle.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionHandle.java new file mode 100644 index 000000000..2f2691df1 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionHandle.java @@ -0,0 +1,189 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.aspectj.apache.bcel.classfile.Utility; + +/** + * Instances of this class give users a handle to the instructions contained in an InstructionList. Instruction objects may be used + * more than once within a list, this is useful because it saves memory and may be much faster. + * + * Within an InstructionList an InstructionHandle object is wrapped around all instructions, i.e., it implements a cell in a + * doubly-linked list. From the outside only the next and the previous instruction (handle) are accessible. One can traverse the + * list via an Enumeration returned by InstructionList.elements(). + * + * @version $Id: InstructionHandle.java,v 1.9 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + * @see Instruction + * @see BranchHandle + * @see InstructionList + */ +public class InstructionHandle implements java.io.Serializable { + InstructionHandle next, prev; // Will be set from the outside + Instruction instruction; + protected int pos = -1; // byte code offset of instruction + private Set targeters = Collections.emptySet(); + + protected InstructionHandle(Instruction i) { + setInstruction(i); + } + + static final InstructionHandle getInstructionHandle(Instruction i) { + return new InstructionHandle(i); + } + + public final InstructionHandle getNext() { + return next; + } + + public final InstructionHandle getPrev() { + return prev; + } + + public final Instruction getInstruction() { + return instruction; + } + + /** + * Replace current instruction contained in this handle. Old instruction is disposed using Instruction.dispose(). + */ + public void setInstruction(Instruction i) { // Overridden in BranchHandle + if (instruction != null) { + instruction.dispose(); + } + instruction = i; + } + + /** + * @return the position, i.e., the byte code offset of the contained instruction. This is accurate only after + * InstructionList.setPositions() has been called. + */ + public int getPosition() { + return pos; + } + + /** + * Set the position, i.e., the byte code offset of the contained instruction. + */ + void setPosition(int pos) { + this.pos = pos; + } + + /** + * Delete contents, i.e., remove user access and make handle reusable. + */ + // OPTIMIZE get rid of this? why do we need it + void dispose() { + next = prev = null; + instruction.dispose(); + instruction = null; + pos = -1; + removeAllTargeters(); + } + + /** + * Remove all targeters, if any. + */ + public void removeAllTargeters() { + targeters.clear(); + } + + /** + * Denote this handle isn't referenced anymore by t. + */ + public void removeTargeter(InstructionTargeter t) { + targeters.remove(t); + } + + /** + * Denote this handle is being referenced by t. + */ + public void addTargeter(InstructionTargeter t) { + if (targeters == Collections.EMPTY_SET) { + targeters = new HashSet(); + } + targeters.add(t); + } + + public boolean hasTargeters() { + return !targeters.isEmpty(); + } + + public Set getTargeters() { + return targeters; + } + + public Set getTargetersCopy() { + Set copy = new HashSet(); + copy.addAll(targeters); + return copy; + } + + /** + * @return a (verbose) string representation of the contained instruction. + */ + public String toString(boolean verbose) { + return Utility.format(pos, 4, false, ' ') + ": " + instruction.toString(verbose); + } + + public String toString() { + return toString(true); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionLV.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionLV.java new file mode 100644 index 000000000..73c278016 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionLV.java @@ -0,0 +1,278 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Abstract super class for instructions dealing with local variables. + * + * @version $Id: InstructionLV.java,v 1.5 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public class InstructionLV extends Instruction { + protected int lvar = -1; + + public InstructionLV(short opcode, int lvar) { + super(opcode); + this.lvar = lvar; + } + + public InstructionLV(short opcode) { + super(opcode); + } + + public void dump(DataOutputStream out) throws IOException { + if (lvar == -1) { + out.writeByte(opcode); + } else { + if (lvar < 4) { + if (opcode == ALOAD) { + out.writeByte(ALOAD_0 + lvar); + } else if (opcode == ASTORE) { + out.writeByte(ASTORE_0 + lvar); + } else if (opcode == ILOAD) { + out.writeByte(ILOAD_0 + lvar); + } else if (opcode == ISTORE) { + out.writeByte(ISTORE_0 + lvar); + } else if (opcode == DLOAD) { + out.writeByte(DLOAD_0 + lvar); + } else if (opcode == DSTORE) { + out.writeByte(DSTORE_0 + lvar); + } else if (opcode == FLOAD) { + out.writeByte(FLOAD_0 + lvar); + } else if (opcode == FSTORE) { + out.writeByte(FSTORE_0 + lvar); + } else if (opcode == LLOAD) { + out.writeByte(LLOAD_0 + lvar); + } else if (opcode == LSTORE) { + out.writeByte(LSTORE_0 + lvar); + } else { + if (wide()) { + out.writeByte(Constants.WIDE); + } + out.writeByte(opcode); + if (wide()) { + out.writeShort(lvar); + } else { + out.writeByte(lvar); + } + } + } else { + if (wide()) { + out.writeByte(Constants.WIDE); + } + out.writeByte(opcode); + if (wide()) { + out.writeShort(lvar); + } else { + out.writeByte(lvar); + } + } + } + } + + /** + * Long output format: + * + * 'name of opcode' "[" 'opcode number' "]" "(" 'length of instruction' ")" "<" 'local variable index' ">" + */ + public String toString(boolean verbose) { + if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3 || opcode >= Constants.ISTORE_0 + && opcode <= Constants.ASTORE_3) { + return super.toString(verbose); + } else { + return super.toString(verbose) + (lvar != -1 && lvar < 4 ? "_" : " ") + lvar; + } + } + + public boolean isALOAD() { + return opcode == ALOAD || opcode >= ALOAD_0 && opcode <= ALOAD_3; + } + + public boolean isASTORE() { + return opcode == ASTORE || opcode >= ASTORE_0 && opcode <= ASTORE_3; + } + + public int getBaseOpcode() { + if (opcode >= ILOAD && opcode <= ALOAD || opcode >= ISTORE && opcode <= ASTORE) { + // not an optimized instruction + return opcode; + } + if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) { + int ret = opcode - ILOAD_0; + ret = ret - ret % 4; + ret = ret / 4; + return ret + ILOAD; + } + int ret = opcode - ISTORE_0; + ret = ret - ret % 4; + ret = ret / 4; + return ret + ISTORE; + } + + /** + * @return local variable index referred by this instruction. + */ + // optimize! + public final int getIndex() { + if (lvar != -1) { + return lvar; + } + if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) { + return (opcode - Constants.ILOAD_0) % 4; + } else if (opcode >= Constants.ISTORE_0 && opcode <= Constants.ASTORE_3) { + return (opcode - Constants.ISTORE_0) % 4; + } + return -1; + } + + public void setIndex(int i) { + // Switching the index for a load/store without a current index specified (ie. an aload_1 or istore_2) + // means we need to should adjust to a normal aload/istore opcode + if (getIndex() != i) { + if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) { + opcode = (short) (ILOAD + (opcode - ILOAD_0) / 4); + } else if (opcode >= Constants.ISTORE_0 && opcode <= Constants.ASTORE_3) { + opcode = (short) (ISTORE + (opcode - ISTORE_0) / 4); + } + this.lvar = i; + } + } + + public boolean canSetIndex() { + return true; + } + + public InstructionLV setIndexAndCopyIfNecessary(int newIndex) { + if (canSetIndex()) { + setIndex(newIndex); + return this; + } else { + if (getIndex() == newIndex) { + return this; + } + InstructionLV newInstruction = null; + int baseOpCode = getBaseOpcode(); + if (newIndex < 4) { + if (isStoreInstruction()) { + newInstruction = (InstructionLV) InstructionConstants.INSTRUCTIONS[(baseOpCode - Constants.ISTORE) * 4 + + Constants.ISTORE_0 + newIndex]; + } else { + newInstruction = (InstructionLV) InstructionConstants.INSTRUCTIONS[(baseOpCode - Constants.ILOAD) * 4 + + Constants.ILOAD_0 + newIndex]; + } + } else { + newInstruction = new InstructionLV((short) baseOpCode, newIndex); + } + // if (getBaseOpcode()!=newInstruction.getBaseOpcode() || newInstruction.getIndex()!=newIndex) { + // throw new + // RuntimeException("New Instruction created does not appear to be valid: originalBaseOpcode="+getBaseOpcode()+ + // " newBaseOpcode="+newInstruction.getBaseOpcode()); + // } + return newInstruction; + } + } + + public int getLength() { + int size = Constants.iLen[opcode]; + if (lvar == -1) { + return size; + } else { + if (lvar < 4) { + if (opcode == ALOAD || opcode == ASTORE) { + return 1; + } else if (opcode == ILOAD || opcode == ISTORE) { + return 1; + } else if (opcode == DLOAD || opcode == DSTORE) { + return 1; + } else if (opcode == FLOAD || opcode == FSTORE) { + return 1; + } else if (opcode == LLOAD || opcode == LSTORE) { + return 1; + } else { + if (wide()) { + return size + 2; + } + return size; + } + } else { + if (wide()) { + return size + 2; + } + return size; + } + } + } + + private final boolean wide() { + return lvar > Constants.MAX_BYTE; + } + + public boolean equals(Object other) { + if (!(other instanceof InstructionLV)) { + return false; + } + InstructionLV o = (InstructionLV) other; + return o.opcode == opcode && o.lvar == lvar; + } + + public int hashCode() { + return opcode * 37 + lvar; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionList.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionList.java new file mode 100644 index 000000000..b08a2b77c --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionList.java @@ -0,0 +1,1287 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Constant; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.util.ByteSequence; + +/** + * This class is a container for a list of Instruction objects. Instructions can be appended, + * inserted, moved, deleted, etc.. Instructions are being wrapped into InstructionHandles + * objects that are returned upon append/insert operations. They give the user (read only) access to the list structure, such that + * it can be traversed and manipulated in a controlled way. + * + * A list is finally dumped to a byte code array with getByteCode. + * + * @version $Id: InstructionList.java,v 1.12 2011/09/02 22:33:04 aclement Exp $ + * @author M. Dahm + * @author Abraham Nevado + * @see Instruction + * @see InstructionHandle + * @see BranchHandle + */ +public class InstructionList implements Serializable { + private InstructionHandle start = null, end = null; + private int length = 0; + private int[] positions; // byte code offsets corresponding to instructions + + public InstructionList() { + } + + public InstructionList(Instruction i) { + append(i); + } + + public boolean isEmpty() { + return start == null; + } // && end == null + + public static InstructionHandle findHandle(InstructionHandle[] ihs, int[] pos, int count, int target) { + return findHandle(ihs, pos, count, target, false); + } + + /** + * Find the target instruction (handle) that corresponds to the given target position (byte code offset). + * + * @param ihs array of instruction handles, i.e. il.getInstructionHandles() + * @param pos array of positions corresponding to ihs, i.e. il.getInstructionPositions() + * @param count length of arrays + * @param target target position to search for + * @return target position's instruction handle if available + */ + public static InstructionHandle findHandle(InstructionHandle[] ihs, int[] pos, int count, int target, + boolean returnClosestIfNoExactMatch) { + int l = 0, r = count - 1; + // Do a binary search since the pos array is ordered + int i, j; + do { + i = (l + r) / 2; + j = pos[i]; + if (j == target) { + return ihs[i]; // found it + } else if (target < j) { + r = i - 1; // else constrain search area + } else { + l = i + 1; // target > j + } + } while (l <= r); + + if (returnClosestIfNoExactMatch) { + i = (l + r) / 2; + if (i < 0) { + i = 0; + } + return ihs[i]; + } + return null; + } + + /** + * Get instruction handle for instruction at byte code position pos. This only works properly, if the list is freshly + * initialized from a byte array or setPositions() has been called before this method. + * + * @param pos byte code position to search for + * @return target position's instruction handle if available + */ + public InstructionHandle findHandle(int pos) { + InstructionHandle[] ihs = getInstructionHandles(); + return findHandle(ihs, positions, length, pos); + } + + public InstructionHandle[] getInstructionsAsArray() { + return getInstructionHandles(); + } + + public InstructionHandle findHandle(int pos, InstructionHandle[] instructionArray) { + return findHandle(instructionArray, positions, length, pos); + } + + public InstructionHandle findHandle(int pos, InstructionHandle[] instructionArray, boolean useClosestApproximationIfNoExactFound) { + return findHandle(instructionArray, positions, length, pos, useClosestApproximationIfNoExactFound); + } + + /** + * Initialize instruction list from byte array. + * + * @param code byte array containing the instructions + */ + public InstructionList(byte[] code) { + ByteSequence bytes = new ByteSequence(code); + InstructionHandle[] ihs = new InstructionHandle[code.length]; + int[] pos = new int[code.length]; // Can't be more than that + int count = 0; // Contains actual length + + /* + * Pass 1: Create an object for each byte code and append them to the list. + */ + try { + while (bytes.available() > 0) { + // Remember byte offset and associate it with the instruction + int off = bytes.getIndex(); + pos[count] = off; + + /* + * Read one instruction from the byte stream, the byte position is set accordingly. + */ + Instruction i = Instruction.readInstruction(bytes); + InstructionHandle ih; + if (i instanceof InstructionBranch) { + ih = append((InstructionBranch) i); + } else { + ih = append(i); + } + + ih.setPosition(off); + ihs[count] = ih; + + count++; + } + } catch (IOException e) { + throw new ClassGenException(e.toString()); + } + + positions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, positions, 0, count); + + /* + * Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles. + */ + // OPTIMIZE better way of doing this? keep little map from earlier from pos -> instruction handle? + for (int i = 0; i < count; i++) { + if (ihs[i] instanceof BranchHandle) { + InstructionBranch bi = (InstructionBranch) ihs[i].instruction; + int target = bi.positionOfThisInstruction + bi.getIndex(); /* + * Byte code position: relative -> absolute. + */ + // Search for target position + InstructionHandle ih = findHandle(ihs, pos, count, target); + + if (ih == null) { + throw new ClassGenException("Couldn't find target for branch: " + bi); + } + + bi.setTarget(ih); // Update target + + // If it is a Select instruction, update all branch targets + if (bi instanceof InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH + InstructionSelect s = (InstructionSelect) bi; + int[] indices = s.getIndices(); + + for (int j = 0; j < indices.length; j++) { + target = bi.positionOfThisInstruction + indices[j]; + ih = findHandle(ihs, pos, count, target); + + if (ih == null) { + throw new ClassGenException("Couldn't find target for switch: " + bi); + } + + s.setTarget(j, ih); // Update target + } + } + } + } + } + + /** + * Append another list after instruction (handle) ih contained in this list. Consumes argument list, i.e., it becomes empty. + * + * @param appendTo where to append the instruction list + * @param appendee Instruction list to append to this one + * @return instruction handle pointing to the first appended instruction + */ + public InstructionHandle append(InstructionHandle appendTo, InstructionList appendee) { + assert appendee != null; + + if (appendee.isEmpty()) { + return appendTo; + } + + InstructionHandle next = appendTo.next; + InstructionHandle ret = appendee.start; + + appendTo.next = appendee.start; + appendee.start.prev = appendTo; + + appendee.end.next = next; + + if (next != null) { + next.prev = appendee.end; + } else { + end = appendee.end; // Update end ... + } + + length += appendee.length; // Update length + + appendee.clear(); + + return ret; + } + + /** + * Append another list after instruction i contained in this list. Consumes argument list, i.e., it becomes empty. + * + * @param i where to append the instruction list + * @param il Instruction list to append to this one + * @return instruction handle pointing to the first appended instruction + */ + public InstructionHandle append(Instruction i, InstructionList il) { + InstructionHandle ih; + + if ((ih = findInstruction2(i)) == null) { + throw new ClassGenException("Instruction " + i + " is not contained in this list."); + } + + return append(ih, il); + } + + /** + * Append another list to this one. Consumes argument list, i.e., it becomes empty. + * + * @param il list to append to end of this list + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(InstructionList il) { + assert il != null; + + if (il.isEmpty()) { + return null; + } + + if (isEmpty()) { + start = il.start; + end = il.end; + length = il.length; + + il.clear(); + + return start; + } else { + return append(end, il); // was end.instruction + } + } + + /** + * Append an instruction to the end of this list. + * + * @param ih instruction to append + */ + private void append(InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.next = ih.prev = null; + } else { + end.next = ih; + ih.prev = end; + ih.next = null; + end = ih; + } + + length++; // Update length + } + + /** + * Append an instruction to the end of this list. + * + * @param i instruction to append + * @return instruction handle of the appended instruction + */ + public InstructionHandle append(Instruction i) { + InstructionHandle ih = InstructionHandle.getInstructionHandle(i); + append(ih); + + return ih; + } + + public InstructionHandle appendDUP() { + InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.DUP); + append(ih); + return ih; + } + + public InstructionHandle appendNOP() { + InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.NOP); + append(ih); + return ih; + } + + public InstructionHandle appendPOP() { + InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.POP); + append(ih); + return ih; + } + + /** + * Append a branch instruction to the end of this list. + * + * @param i branch instruction to append + * @return branch instruction handle of the appended instruction + */ + public BranchHandle append(InstructionBranch i) { + BranchHandle ih = BranchHandle.getBranchHandle(i); + append(ih); + + return ih; + } + + /** + * Append a single instruction j after another instruction i, which must be in this list of course! + * + * @param i Instruction in list + * @param j Instruction to append after i in list + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(Instruction i, Instruction j) { + return append(i, new InstructionList(j)); + } + + /** + * Append an instruction after instruction (handle) ih contained in this list. + * + * @param ih where to append the instruction list + * @param i Instruction to append + * @return instruction handle pointing to the first appended instruction + */ + public InstructionHandle append(InstructionHandle ih, Instruction i) { + return append(ih, new InstructionList(i)); + } + + /** + * Append an instruction after instruction (handle) ih contained in this list. + * + * @param ih where to append the instruction list + * @param i Instruction to append + * @return instruction handle pointing to the first appended instruction + */ + public BranchHandle append(InstructionHandle ih, InstructionBranch i) { + BranchHandle bh = BranchHandle.getBranchHandle(i); + InstructionList il = new InstructionList(); + il.append(bh); + + append(ih, il); + + return bh; + } + + /** + * Insert another list before Instruction handle ih contained in this list. Consumes argument list, i.e., it becomes empty. + * + * @param i where to append the instruction list + * @param il Instruction list to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(InstructionHandle ih, InstructionList il) { + if (il == null) { + throw new ClassGenException("Inserting null InstructionList"); + } + + if (il.isEmpty()) { + return ih; + } + + InstructionHandle prev = ih.prev, ret = il.start; + + ih.prev = il.end; + il.end.next = ih; + + il.start.prev = prev; + + if (prev != null) { + prev.next = il.start; + } else { + start = il.start; // Update start ... + } + + length += il.length; // Update length + + il.clear(); + + return ret; + } + + /** + * Insert another list. + * + * @param il list to insert before start of this list + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(InstructionList il) { + if (isEmpty()) { + append(il); // Code is identical for this case + return start; + } else { + return insert(start, il); + } + } + + /** + * Insert an instruction at start of this list. + * + * @param ih instruction to insert + */ + private void insert(InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.next = ih.prev = null; + } else { + start.prev = ih; + ih.next = start; + ih.prev = null; + start = ih; + } + + length++; + } + + /** + * Insert another list before Instruction i contained in this list. Consumes argument list, i.e., it becomes empty. + * + * @param i where to append the instruction list + * @param il Instruction list to insert + * @return instruction handle pointing to the first inserted instruction, i.e., il.getStart() + */ + public InstructionHandle insert(Instruction i, InstructionList il) { + InstructionHandle ih; + + if ((ih = findInstruction1(i)) == null) { + throw new ClassGenException("Instruction " + i + " is not contained in this list."); + } + + return insert(ih, il); + } + + /** + * Insert an instruction at start of this list. + * + * @param i instruction to insert + * @return instruction handle of the inserted instruction + */ + public InstructionHandle insert(Instruction i) { + InstructionHandle ih = InstructionHandle.getInstructionHandle(i); + insert(ih); + + return ih; + } + + /** + * Insert a branch instruction at start of this list. + * + * @param i branch instruction to insert + * @return branch instruction handle of the appended instruction + */ + public BranchHandle insert(InstructionBranch i) { + BranchHandle ih = BranchHandle.getBranchHandle(i); + insert(ih); + return ih; + } + + /** + * Insert a single instruction j before another instruction i, which must be in this list of course! + * + * @param i Instruction in list + * @param j Instruction to insert before i in list + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(Instruction i, Instruction j) { + return insert(i, new InstructionList(j)); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this list. + * + * @param ih where to insert to the instruction list + * @param i Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(InstructionHandle ih, Instruction i) { + return insert(ih, new InstructionList(i)); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this list. + * + * @param ih where to insert to the instruction list + * @param i Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public BranchHandle insert(InstructionHandle ih, InstructionBranch i) { + BranchHandle bh = BranchHandle.getBranchHandle(i); + InstructionList il = new InstructionList(); + il.append(bh); + + insert(ih, il); + + return bh; + } + + /** + * Take all instructions (handles) from "start" to "end" and append them after the new location "target". Of course, "end" must + * be after "start" and target must not be located withing this range. If you want to move something to the start of the list + * use null as value for target.
+ * Any instruction targeters pointing to handles within the block, keep their targets. + * + * @param start of moved block + * @param end of moved block + * @param target of moved block + */ + public void move(InstructionHandle start, InstructionHandle end, InstructionHandle target) { + // Step 1: Check constraints + + if (start == null || end == null) { + throw new ClassGenException("Invalid null handle: From " + start + " to " + end); + } + + if (target == start || target == end) { + throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target); + } + + for (InstructionHandle ih = start; ih != end.next; ih = ih.next) { + if (ih == null) { + throw new ClassGenException("Invalid range: From " + start + " to " + end); + } else if (ih == target) { + throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target); + } + } + + // Step 2: Temporarily remove the given instructions from the list + + InstructionHandle prev = start.prev, next = end.next; + + if (prev != null) { + prev.next = next; + } else { + this.start = next; + } + + if (next != null) { + next.prev = prev; + } else { + this.end = prev; + } + + start.prev = end.next = null; + + // Step 3: append after target + + if (target == null) { // append to start of list + end.next = this.start; + this.start = start; + } else { + next = target.next; + + target.next = start; + start.prev = target; + end.next = next; + + if (next != null) { + next.prev = end; + } + } + } + + /** + * Move a single instruction (handle) to a new location. + * + * @param ih moved instruction + * @param target new location of moved instruction + */ + public void move(InstructionHandle ih, InstructionHandle target) { + move(ih, ih, target); + } + + /** + * Remove from instruction 'prev' to instruction 'next' both contained in this list. + * + * If careAboutLostTargeters is true then this method will throw a TargetLostException when one of the removed instruction + * handles is still being targeted. + * + * @param prev where to start deleting (predecessor, exclusive) + * @param next where to end deleting (successor, exclusive) + */ + private void remove(InstructionHandle prev, InstructionHandle next, boolean careAboutLostTargeters) throws TargetLostException { + InstructionHandle first, last; // First and last deleted instruction + + if (prev == null && next == null) { // singleton list + first = last = start; + start = end = null; + } else { + if (prev == null) { // At start of list + first = start; + start = next; + } else { + first = prev.next; + prev.next = next; + } + if (next == null) { // At end of list + last = end; + end = prev; + } else { + last = next.prev; + next.prev = prev; + } + } + + first.prev = null; // Completely separated from rest of list + last.next = null; + + if (!careAboutLostTargeters) { + return; + } + + ArrayList target_vec = new ArrayList(); + + for (InstructionHandle ih = first; ih != null; ih = ih.next) { + ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets + } + + StringBuffer buf = new StringBuffer("{ "); + for (InstructionHandle ih = first; ih != null; ih = next) { + next = ih.next; + length--; + + Set targeters = ih.getTargeters(); + boolean isOK = false; + Iterator tIter = targeters.iterator(); + while (tIter.hasNext()) { + InstructionTargeter instructionTargeter = tIter.next(); + if (instructionTargeter.getClass().getName().endsWith("ShadowRange") + || instructionTargeter.getClass().getName().endsWith("ExceptionRange") + || instructionTargeter.getClass().getName().endsWith("LineNumberTag")) { + isOK = true; + } else { + System.out.println(instructionTargeter.getClass()); + } + } + if (!isOK) { + target_vec.add(ih); + buf.append(ih.toString(true) + " "); + ih.next = ih.prev = null; + } else { + ih.dispose(); + } + + // if (ih.hasTargeters()) { // Still got targeters? + // InstructionTargeter[] targeters = ih.getTargeters(); + // boolean isOK = false; + // for (int i = 0; i < targeters.length; i++) { + // InstructionTargeter instructionTargeter = targeters[i]; + // if (instructionTargeter.getClass().getName().endsWith("ShadowRange") + // || instructionTargeter.getClass().getName().endsWith("ExceptionRange") + // || instructionTargeter.getClass().getName().endsWith("LineNumberTag")) { + // isOK = true; + // } else { + // System.out.println(instructionTargeter.getClass()); + // } + // } + // if (!isOK) { + // target_vec.add(ih); + // buf.append(ih.toString(true) + " "); + // ih.next = ih.prev = null; + // } else { + // ih.dispose(); + // } + // } else { + // ih.dispose(); + // } + } + + buf.append("}"); + + if (!target_vec.isEmpty()) { + InstructionHandle[] targeted = new InstructionHandle[target_vec.size()]; + target_vec.toArray(targeted); + throw new TargetLostException(targeted, buf.toString()); + } + } + + /** + * Remove instruction from this list. The corresponding Instruction handles must not be reused! + * + * @param ih instruction (handle) to remove + */ + public void delete(InstructionHandle ih) throws TargetLostException { + remove(ih.prev, ih.next, false); + } + + /** + * Remove instruction from this list. The corresponding Instruction handles must not be reused! + * + * @param i instruction to remove + */ + // public void delete(Instruction i) throws TargetLostException { + // InstructionHandle ih; + // + // if((ih = findInstruction1(i)) == null) + // throw new ClassGenException("Instruction " + i + + // " is not contained in this list."); + // delete(ih); + // } + /** + * Remove instructions from instruction `from' to instruction `to' contained in this list. The user must ensure that `from' is + * an instruction before `to', or risk havoc. The corresponding Instruction handles must not be reused! + * + * @param from where to start deleting (inclusive) + * @param to where to end deleting (inclusive) + */ + public void delete(InstructionHandle from, InstructionHandle to) throws TargetLostException { + remove(from.prev, to.next, false); + } + + /** + * Remove instructions from instruction `from' to instruction `to' contained in this list. The user must ensure that `from' is + * an instruction before `to', or risk havoc. The corresponding Instruction handles must not be reused! + * + * @param from where to start deleting (inclusive) + * @param to where to end deleting (inclusive) + */ + public void delete(Instruction from, Instruction to) throws TargetLostException { + InstructionHandle from_ih, to_ih; + + if ((from_ih = findInstruction1(from)) == null) { + throw new ClassGenException("Instruction " + from + " is not contained in this list."); + } + + if ((to_ih = findInstruction2(to)) == null) { + throw new ClassGenException("Instruction " + to + " is not contained in this list."); + } + delete(from_ih, to_ih); + } + + /** + * Search for given Instruction reference, start at beginning of list. + * + * @param i instruction to search for + * @return instruction found on success, null otherwise + */ + private InstructionHandle findInstruction1(Instruction i) { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + if (ih.instruction == i) { + return ih; + } + } + + return null; + } + + /** + * Search for given Instruction reference, start at end of list + * + * @param i instruction to search for + * @return instruction found on success, null otherwise + */ + private InstructionHandle findInstruction2(Instruction i) { + for (InstructionHandle ih = end; ih != null; ih = ih.prev) { + if (ih.instruction == i) { + return ih; + } + } + + return null; + } + + public boolean contains(InstructionHandle i) { + if (i == null) { + return false; + } + + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + if (ih == i) { + return true; + } + } + + return false; + } + + public boolean contains(Instruction i) { + return findInstruction1(i) != null; + } + + public void setPositions() { + setPositions(false); + } + + /** + * Give all instructions their position number (offset in byte stream), i.e., make the list ready to be dumped. + * + * @param check Perform sanity checks, e.g. if all targeted instructions really belong to this list + */ + public void setPositions(boolean check) { + int maxAdditionalBytes = 0; + int index = 0, count = 0; + int[] pos = new int[length]; + + // Pass 0: Sanity checks + if (check) { + checkInstructionList(); + } + + // Pass 1: Set position numbers and sum up the maximum number of bytes an + // instruction may be shifted. + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + ih.setPosition(index); + pos[count++] = index; + + /* + * Get an estimate about how many additional bytes may be added, because BranchInstructions may have variable length + * depending on the target offset (short vs. int) or alignment issues (TABLESWITCH and LOOKUPSWITCH). + */ + switch (i.opcode) { + case Constants.JSR: + case Constants.GOTO: + maxAdditionalBytes += 2; + break; + + case Constants.TABLESWITCH: + case Constants.LOOKUPSWITCH: + maxAdditionalBytes += 3; + break; + } + index += i.getLength(); + } + + // OPTIMIZE positions will only move around if there have been expanding instructions + // if (max_additional_bytes==0...) { + // + // } + + /* + * Pass 2: Expand the variable-length (Branch)Instructions depending on the target offset (short or int) and ensure that + * branch targets are within this list. + */ + boolean nonZeroOffset = false; + int offset = 0; + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + if (ih instanceof BranchHandle) { + offset += ((BranchHandle) ih).updatePosition(offset, maxAdditionalBytes); + if (offset != 0) { + nonZeroOffset = true; + } + } + } + if (nonZeroOffset) { + /* + * Pass 3: Update position numbers (which may have changed due to the preceding expansions), like pass 1. + */ + index = count = 0; + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + ih.setPosition(index); + pos[count++] = index; + index += i.getLength(); + } + } + + positions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, positions, 0, count); + } + + private void checkInstructionList() { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + + if (i instanceof InstructionBranch) { // target instruction within list? + Instruction inst = ((InstructionBranch) i).getTarget().instruction; + if (!contains(inst)) { + throw new ClassGenException("Branch target of " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst + + " not in instruction list"); + } + + if (i instanceof InstructionSelect) { + InstructionHandle[] targets = ((InstructionSelect) i).getTargets(); + + for (int j = 0; j < targets.length; j++) { + inst = targets[j].instruction; + if (!contains(inst)) { + throw new ClassGenException("Branch target of " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst + + " not in instruction list"); + } + } + } + + if (!(ih instanceof BranchHandle)) { + throw new ClassGenException("Branch instruction " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst + + " not contained in BranchHandle."); + } + + } + } + } + + /** + * When everything is finished, use this method to convert the instruction list into an array of bytes. + * + * @return the byte code ready to be dumped + */ + public byte[] getByteCode() { + // Update position indices of instructions + setPositions(); + + ByteArrayOutputStream b = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(b); + + try { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + i.dump(out); // Traverse list + } + } catch (IOException e) { + System.err.println(e); + return null; + } + byte[] byteCode = b.toByteArray(); + if (byteCode.length > Constants.MAX_CODE_SIZE) { + throw new ClassGenException("Code size too big: " + byteCode.length); + } + + return byteCode; + } + + /** + * @return an array of instructions without target information for branch instructions. + */ + public Instruction[] getInstructions() { + ByteSequence bytes = new ByteSequence(getByteCode()); + ArrayList instructions = new ArrayList(); + + try { + while (bytes.available() > 0) { + instructions.add(Instruction.readInstruction(bytes)); + } + } catch (IOException e) { + throw new ClassGenException(e.toString()); + } + + Instruction[] result = new Instruction[instructions.size()]; + instructions.toArray(result); + return result; + } + + @Override + public String toString() { + return toString(true); + } + + /** + * @param verbose toggle output format + * @return String containing all instructions in this list. + */ + public String toString(boolean verbose) { + StringBuffer buf = new StringBuffer(); + + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + buf.append(ih.toString(verbose) + "\n"); + } + + return buf.toString(); + } + + /** + * @return Enumeration that lists all instructions (handles) + */ + public Iterator iterator() { + return new Iterator() { + private InstructionHandle ih = start; + + public Object next() { + InstructionHandle i = ih; + ih = ih.next; + return i; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public boolean hasNext() { + return ih != null; + } + }; + } + + /** + * @return array containing all instructions (handles) + */ + public InstructionHandle[] getInstructionHandles() { + InstructionHandle[] ihs = new InstructionHandle[length]; + InstructionHandle ih = start; + + for (int i = 0; i < length; i++) { + ihs[i] = ih; + ih = ih.next; + } + + return ihs; + } + + /** + * Get positions (offsets) of all instructions in the list. This relies on that the list has been freshly created from an byte + * code array, or that setPositions() has been called. Otherwise this may be inaccurate. + * + * @return array containing all instruction's offset in byte code + */ + public int[] getInstructionPositions() { + return positions; + } + + /** + * @return complete, i.e., deep copy of this list + */ + public InstructionList copy() { + HashMap map = new HashMap(); + InstructionList il = new InstructionList(); + + /* + * Pass 1: Make copies of all instructions, append them to the new list and associate old instruction references with the + * new ones, i.e., a 1:1 mapping. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + Instruction c = i.copy(); // Use clone for shallow copy + + if (c instanceof InstructionBranch) { + map.put(ih, il.append((InstructionBranch) c)); + } else { + map.put(ih, il.append(c)); + } + } + + /* + * Pass 2: Update branch targets. + */ + InstructionHandle ih = start; + InstructionHandle ch = il.start; + + while (ih != null) { + Instruction i = ih.instruction; + Instruction c = ch.instruction; + + if (i instanceof InstructionBranch) { + InstructionBranch bi = (InstructionBranch) i; + InstructionBranch bc = (InstructionBranch) c; + InstructionHandle itarget = bi.getTarget(); // old target + + // New target is in hash map + bc.setTarget(map.get(itarget)); + + if (bi instanceof InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH + InstructionHandle[] itargets = ((InstructionSelect) bi).getTargets(); + InstructionHandle[] ctargets = ((InstructionSelect) bc).getTargets(); + + for (int j = 0; j < itargets.length; j++) { // Update all targets + ctargets[j] = map.get(itargets[j]); + } + } + } + + ih = ih.next; + ch = ch.next; + } + + return il; + } + + /** + * Replace all references to the old constant pool with references to the new constant pool + */ + public void replaceConstantPool(ConstantPool old_cp, ConstantPool new_cp) { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + if (i.isConstantPoolInstruction()) { + InstructionCP ci = (InstructionCP) i; + Constant c = old_cp.getConstant(ci.getIndex()); + ci.setIndex(new_cp.addConstant(c, old_cp)); + } + } + } + + private void clear() { + start = end = null; + length = 0; + } + + /** + * Delete contents of list. Provides better memory utilization, because the system then may reuse the instruction handles. This + * method is typically called right after MethodGen.getMethod(). + */ + public void dispose() { + // Traverse in reverse order, because ih.next is overwritten + for (InstructionHandle ih = end; ih != null; ih = ih.prev) { + /* + * Causes BranchInstructions to release target and targeters, because it calls dispose() on the contained instruction. + */ + ih.dispose(); + } + + clear(); + } + + /** + * @return start of list + */ + public InstructionHandle getStart() { + return start; + } + + /** + * @return end of list + */ + public InstructionHandle getEnd() { + return end; + } + + /** + * @return length of list (Number of instructions, not bytes) + */ + public int getLength() { + return length; + } + + /** + * @return length of list (Number of instructions, not bytes) + */ + public int size() { + return length; + } + + /** + * Redirect all references from old_target to new_target, i.e., update targets of branch instructions. + * + * @param old_target the old target instruction handle + * @param new_target the new target instruction handle + */ + public void redirectBranches(InstructionHandle old_target, InstructionHandle new_target) { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.getInstruction(); + + if (i instanceof InstructionBranch) { + InstructionBranch b = (InstructionBranch) i; + InstructionHandle target = b.getTarget(); + + if (target == old_target) { + b.setTarget(new_target); + } + + if (b instanceof InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH + InstructionHandle[] targets = ((InstructionSelect) b).getTargets(); + + for (int j = 0; j < targets.length; j++) { + if (targets[j] == old_target) { + ((InstructionSelect) b).setTarget(j, new_target); + } + } + } + } + } + } + + /** + * Redirect all references of local variables from old_target to new_target. + * + * @param lg array of local variables + * @param old_target the old target instruction handle + * @param new_target the new target instruction handle + * @see MethodGen + */ + public void redirectLocalVariables(LocalVariableGen[] lg, InstructionHandle old_target, InstructionHandle new_target) { + for (int i = 0; i < lg.length; i++) { + InstructionHandle start = lg[i].getStart(); + InstructionHandle end = lg[i].getEnd(); + + if (start == old_target) { + lg[i].setStart(new_target); + } + if (end == old_target) { + lg[i].setEnd(new_target); + } + } + } + + /** + * Redirect all references of exception handlers from old_target to new_target. + * + * @param exceptions array of exception handlers + * @param old_target the old target instruction handle + * @param new_target the new target instruction handle + * @see MethodGen + */ + public void redirectExceptionHandlers(CodeExceptionGen[] exceptions, InstructionHandle old_target, InstructionHandle new_target) { + for (int i = 0; i < exceptions.length; i++) { + if (exceptions[i].getStartPC() == old_target) { + exceptions[i].setStartPC(new_target); + } + + if (exceptions[i].getEndPC() == old_target) { + exceptions[i].setEndPC(new_target); + } + + if (exceptions[i].getHandlerPC() == old_target) { + exceptions[i].setHandlerPC(new_target); + } + } + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionSelect.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionSelect.java new file mode 100644 index 000000000..b4e00c027 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionSelect.java @@ -0,0 +1,291 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.util.ByteSequence; + +/** + * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions. + * + * @version $Id: InstructionSelect.java,v 1.4 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + * @see LOOKUPSWITCH + * @see TABLESWITCH + * @see InstructionList + */ +public abstract class InstructionSelect extends InstructionBranch { + protected int[] match; // matches, i.e., case 1: ... + protected int[] indices; // target offsets + protected InstructionHandle[] targets; // target objects in instruction list + protected int fixedLength; // fixed length defined by subclasses + protected int matchLength; // number of cases + protected int padding = 0; // number of pad bytes for alignment + + protected short length; + + /** + * (Match, target) pairs for switch. `Match' and `targets' must have the same length of course. + * + * @param match array of matching values + * @param targets instruction targets + * @param target default instruction target + */ + InstructionSelect(short opcode, int[] match, InstructionHandle[] targets, InstructionHandle target) { + super(opcode, target); + + this.targets = targets; + for (int i = 0; i < targets.length; i++) { + notifyTarget(null, targets[i], this); + } + + this.match = match; + + if ((matchLength = match.length) != targets.length) { + throw new ClassGenException("Match and target array have not the same length"); + } + + indices = new int[matchLength]; + } + + protected int getTargetOffset(InstructionHandle target) { + if (target == null) { + throw new ClassGenException("Target of " + super.toString(true) + " is invalid null handle"); + } + + int t = target.getPosition(); + + if (t < 0) { + throw new ClassGenException("Invalid branch target position offset for " + super.toString(true) + ":" + t + ":" + + target); + } + + return t - positionOfThisInstruction; + } + + /** + * Since this is a variable length instruction, it may shift the following instructions which then need to update their + * position. + * + * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length + * instructions `setPositions' performs multiple passes over the instruction list to calculate the correct (byte) positions and + * offsets by calling this function. + * + * @param offset additional offset caused by preceding (variable length) instructions + * @param max_offset the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's length + */ + protected int updatePosition(int offset, int max_offset) { + positionOfThisInstruction += offset; // Additional offset caused by + // preceding SWITCHs, GOTOs, + // etc. + + short old_length = length; + + /* + * Alignment on 4-byte-boundary, + 1, because of tag byte. + */ + padding = (4 - (positionOfThisInstruction + 1) % 4) % 4; + length = (short) (fixedLength + padding); // Update length + + return length - old_length; + } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + + for (int i = 0; i < padding; i++) { + out.writeByte(0); + } + + targetIndex = getTargetOffset(); // Write default target offset + out.writeInt(targetIndex); + } + + public InstructionSelect(short opcode, ByteSequence bytes) throws IOException { + super(opcode); + padding = (4 - bytes.getIndex() % 4) % 4; // Compute number of pad bytes + + for (int i = 0; i < padding; i++) { + bytes.readByte(); + } + + // Default branch target common for both cases (TABLESWITCH, + // LOOKUPSWITCH) + targetIndex = bytes.readInt(); + } + + /** + * @return mnemonic for instruction + */ + public String toString(boolean verbose) { + StringBuffer buf = new StringBuffer(super.toString(verbose)); + + if (verbose) { + for (int i = 0; i < matchLength; i++) { + String s = "null"; + + if (targets[i] != null) { + s = targets[i].getInstruction().toString(); + } + + buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})"); + } + } else { + buf.append(" ..."); + } + + return buf.toString(); + } + + /** + * Set branch target for `i'th case + */ + public void setTarget(int i, InstructionHandle target) { + notifyTarget(targets[i], target, this); + targets[i] = target; + } + + /** + * @param old_ih old target + * @param new_ih new target + */ + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + boolean targeted = false; + + if (targetInstruction == old_ih) { + targeted = true; + setTarget(new_ih); + } + + for (int i = 0; i < targets.length; i++) { + if (targets[i] == old_ih) { + targeted = true; + setTarget(i, new_ih); + } + } + + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih); + } + } + + /** + * @return true, if ih is target of this instruction + */ + public boolean containsTarget(InstructionHandle ih) { + if (targetInstruction == ih) { + return true; + } + + for (int i = 0; i < targets.length; i++) { + if (targets[i] == ih) { + return true; + } + } + + return false; + } + + /** + * Inform targets that they're not targeted anymore. + */ + void dispose() { + super.dispose(); + + for (int i = 0; i < targets.length; i++) { + targets[i].removeTargeter(this); + } + } + + /** + * @return array of match indices + */ + public int[] getMatchs() { + return match; + } + + /** + * @return array of match target offsets + */ + public int[] getIndices() { + return indices; + } + + public boolean equals(Object other) { + return this == other; + } + + public int hashCode() { + return opcode * 37; + } + + /** + * @return array of match targets + */ + public InstructionHandle[] getTargets() { + return targets; + } + + public int getLength() { + return length; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionShort.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionShort.java new file mode 100644 index 000000000..99054cbff --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionShort.java @@ -0,0 +1,92 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Instruction that needs one short + */ +public class InstructionShort extends Instruction { + private final short value; + + public InstructionShort(short opcode, short value) { + super(opcode); + this.value = value; + } + + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeShort(value); + } + + public String toString(boolean verbose) { + return super.toString(verbose) + " " + value; + } + + public boolean equals(Object other) { + if (!(other instanceof InstructionShort)) { + return false; + } + InstructionShort o = (InstructionShort) other; + return o.opcode == opcode && o.value == value; + } + + public int hashCode() { + return opcode * 37 + value; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionTargeter.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionTargeter.java new file mode 100644 index 000000000..950ed3fa9 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionTargeter.java @@ -0,0 +1,70 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Denote that a class targets InstructionHandles within an InstructionList. Namely + * the following implementers: + * + * @see BranchHandle + * @see LocalVariableGen + * @see CodeExceptionGen + * @version $Id: InstructionTargeter.java,v 1.3 2008/05/28 23:52:57 aclement Exp $ + * @author M. Dahm + */ +public interface InstructionTargeter { + public boolean containsTarget(InstructionHandle ih); + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih); +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeDynamic.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeDynamic.java new file mode 100644 index 000000000..b3c7ba85a --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeDynamic.java @@ -0,0 +1,129 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.aspectj.apache.bcel.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantInvokeDynamic; +import org.aspectj.apache.bcel.classfile.ConstantNameAndType; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +/** + * INVOKEDYNAMIC + * + * @author Andy Clement + */ +public final class InvokeDynamic extends InvokeInstruction { + + public InvokeDynamic(int index, int zeroes) { + super(Constants.INVOKEDYNAMIC, index); + } + + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeShort(index); + out.writeShort(0); + } + + public String toString(ConstantPool cp) { + return super.toString(cp) + " " + index; + } + + public boolean equals(Object other) { + if (!(other instanceof InvokeDynamic)) { + return false; + } + InvokeDynamic o = (InvokeDynamic) other; + return o.opcode == opcode && o.index == index; + } + + public int hashCode() { + return opcode * 37 + index; + } + + public Type getReturnType(ConstantPool cp) { + return Type.getReturnType(getSignature(cp)); + } + + public Type[] getArgumentTypes(ConstantPool cp) { + return Type.getArgumentTypes(getSignature(cp)); + } + + public String getSignature(ConstantPool cp) { + if (signature == null) { + ConstantInvokeDynamic cid = (ConstantInvokeDynamic)cp.getConstant(index); + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex()); + signature = cp.getConstantUtf8(cnat.getSignatureIndex()).getValue(); + } + return signature; + } + + @Override + public String getName(ConstantPool cp) { + if (name == null) { + ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(index); + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex()); + name = cp.getConstantUtf8(cnat.getNameIndex()).getValue(); + } + return name; + } + + public String getClassName(ConstantPool cp) { + throw new IllegalStateException("there is no classname for invokedynamic"); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeInstruction.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeInstruction.java new file mode 100644 index 000000000..89cd43474 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeInstruction.java @@ -0,0 +1,137 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.util.StringTokenizer; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Constant; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +/** + * Super class for the INVOKExxx family of instructions. + * + * @version $Id: InvokeInstruction.java,v 1.6 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public class InvokeInstruction extends FieldOrMethod { + + /** + * @param index to constant pool + */ + public InvokeInstruction(short opcode, int index) { + super(opcode, index); + } + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + public String toString(ConstantPool cp) { + Constant c = cp.getConstant(index); + StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); + + return Constants.OPCODE_NAMES[opcode] + " " + tok.nextToken().replace('.', '/') + tok.nextToken(); + } + + /** + * Also works for instructions whose stack effect depends on the constant pool entry they reference. + * + * @return Number of words consumed from stack by this instruction + */ + public int consumeStack(ConstantPool cpg) { + String signature = getSignature(cpg); + int sum = Type.getArgumentSizes(signature); + if (opcode != Constants.INVOKESTATIC) { + sum += 1; + } + return sum; + } + + /** + * Also works for instructions whose stack effect depends on the constant pool entry they reference. + * + * @return Number of words produced onto stack by this instruction + */ + public int produceStack(ConstantPool cpg) { + return getReturnType(cpg).getSize(); + } + + /** + * @return return type of referenced method. + */ + public Type getType(ConstantPool cpg) { + return getReturnType(cpg); + } + + /** + * @return name of referenced method. + */ + public String getMethodName(ConstantPool cpg) { + return getName(cpg); + } + + /** + * @return return type of referenced method. + */ + public Type getReturnType(ConstantPool cpg) { + return Type.getReturnType(getSignature(cpg)); + } + + /** + * @return argument types of referenced method. + */ + public Type[] getArgumentTypes(ConstantPool cpg) { + return Type.getArgumentTypes(getSignature(cpg)); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java new file mode 100644 index 000000000..c8ebcba4c --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java @@ -0,0 +1,112 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.util.ByteSequence; + +/** + * LOOKUPSWITCH - Switch with unordered set of values + * + * @version $Id: LOOKUPSWITCH.java,v 1.5 2011/04/05 15:15:33 aclement Exp $ + * @author M. Dahm + */ +public class LOOKUPSWITCH extends InstructionSelect { + + public LOOKUPSWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target) { + super(LOOKUPSWITCH, match, targets, target); + // Alignment remainer assumed 0 here, until dump time + length = (short) (9 + matchLength * 8); + fixedLength = length; + } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + public void dump(DataOutputStream out) throws IOException { + super.dump(out); + out.writeInt(matchLength); // npairs + + for (int i = 0; i < matchLength; i++) { + out.writeInt(match[i]); // match-offset pairs + out.writeInt(indices[i] = getTargetOffset(targets[i])); + } + } + + /** + * Read needed data (e.g. index) from file. + */ + public LOOKUPSWITCH(ByteSequence bytes) throws IOException { + super(Constants.LOOKUPSWITCH, bytes); // reads padding + + matchLength = bytes.readInt(); + fixedLength = (short) (9 + matchLength * 8); + length = (short) (fixedLength + padding); + + match = new int[matchLength]; + indices = new int[matchLength]; + targets = new InstructionHandle[matchLength]; + + for (int i = 0; i < matchLength; i++) { + match[i] = bytes.readInt(); + indices[i] = bytes.readInt(); + } + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberGen.java new file mode 100644 index 000000000..237720c7b --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberGen.java @@ -0,0 +1,130 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.classfile.LineNumber; + +/** + * This class represents a line number within a method, i.e., give an instruction + * a line number corresponding to the source code line. + * + * @version $Id: LineNumberGen.java,v 1.5 2008/05/28 23:53:00 aclement Exp $ + * @author M. Dahm + * @see LineNumber + * @see MethodGen + */ +public class LineNumberGen + implements InstructionTargeter, Cloneable, java.io.Serializable +{ + private InstructionHandle ih; + private int src_line; + + /** + * Create a line number. + * + * @param ih instruction handle to reference + */ + public LineNumberGen(InstructionHandle ih, int src_line) { + setInstruction(ih); + setSourceLine(src_line); + } + + /** + * @return true, if ih is target of this line number + */ + public boolean containsTarget(InstructionHandle ih) { + return this.ih == ih; + } + + /** + * @param old_ih old target + * @param new_ih new target + */ + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + if(old_ih != ih) + throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); + else + setInstruction(new_ih); + } + + /** + * Get LineNumber attribute . + * + * This relies on that the instruction list has already been dumped to byte code or + * or that the `setPositions' methods has been called for the instruction list. + */ + public LineNumber getLineNumber() { + return new LineNumber(ih.getPosition(), src_line); + } + + public void setInstruction(InstructionHandle ih) { + InstructionBranch.notifyTarget(this.ih, ih, this); + + this.ih = ih; + } + + public Object clone() { + try { + return super.clone(); + } catch(CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } + + public InstructionHandle getInstruction() { return ih; } + public void setSourceLine(int src_line) { this.src_line = src_line; } + public int getSourceLine() { return src_line; } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberTag.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberTag.java new file mode 100644 index 000000000..fe1d56c27 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberTag.java @@ -0,0 +1,44 @@ +/* ******************************************************************* + * Copyright (c) 2002 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * Andy Clement pushed down into bcel module + * ******************************************************************/ + + +package org.aspectj.apache.bcel.generic; + +/** + * we don't actually target instructions, but instructions target us. + */ +public class LineNumberTag extends Tag { + + private final int lineNumber; + + public LineNumberTag(int lineNumber) { + this.lineNumber = lineNumber; + } + + public int getLineNumber() { + return lineNumber; + } + + public String toString() { + return "line " + lineNumber; + } + + public boolean equals(Object other) { + if (!(other instanceof LineNumberTag)) return false; + return lineNumber == ((LineNumberTag)other).lineNumber; + } + + public int hashCode() { + return lineNumber; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableGen.java new file mode 100644 index 000000000..b701e7274 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableGen.java @@ -0,0 +1,220 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.LocalVariable; + +/** + * This class represents a local variable within a method. It contains its scope, name and type. The generated LocalVariable object + * can be obtained with getLocalVariable which needs the instruction list and the constant pool as parameters. + * + * @version $Id: LocalVariableGen.java,v 1.7 2008/08/28 00:04:23 aclement Exp $ + * @author M. Dahm + * @see LocalVariable + * @see MethodGen + */ +public class LocalVariableGen implements InstructionTargeter, Cloneable, java.io.Serializable { + private int index; + private String name; + private Type type; + private InstructionHandle start, end; + + /** + * Generate a local variable that with index `index'. Note that double and long variables need two indexs. Index indices have to + * be provided by the user. + * + * @param index index of local variable + * @param name its name + * @param type its type + * @param start from where the instruction is valid (null means from the start) + * @param end until where the instruction is valid (null means to the end) + */ + public LocalVariableGen(int index, String name, Type type, InstructionHandle start, InstructionHandle end) { + if (index < 0 || index > Constants.MAX_SHORT) { + throw new ClassGenException("Invalid index index: " + index); + } + + this.name = name; + this.type = type; + this.index = index; + setStart(start); + setEnd(end); + } + + /** + * Get LocalVariable object. + * + * This relies on that the instruction list has already been dumped to byte code or or that the `setPositions' methods has been + * called for the instruction list. + * + * Note that for local variables whose scope end at the last instruction of the method's code, the JVM specification is + * ambiguous: both a start_pc+length ending at the last instruction and start_pc+length ending at first index beyond the end of + * the code are valid. + * + * @param il instruction list (byte code) which this variable belongs to + * @param cp constant pool + */ + public LocalVariable getLocalVariable(ConstantPool cp) { + int start_pc = start.getPosition(); + int length = end.getPosition() - start_pc; + + if (length > 0) { + length += end.getInstruction().getLength(); + } + + int name_index = cp.addUtf8(name); + int signature_index = cp.addUtf8(type.getSignature()); + + return new LocalVariable(start_pc, length, name_index, signature_index, index, cp); + } + + public void setIndex(int index) { + this.index = index; + } + + public int getIndex() { + return index; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setType(Type type) { + this.type = type; + } + + public Type getType() { + return type; + } + + public InstructionHandle getStart() { + return start; + } + + public InstructionHandle getEnd() { + return end; + } + + public void setStart(InstructionHandle start) { + InstructionBranch.notifyTarget(this.start, start, this); + this.start = start; + } + + public void setEnd(InstructionHandle end) { + InstructionBranch.notifyTarget(this.end, end, this); + this.end = end; + } + + /** + * @param old_ih old target, either start or end + * @param new_ih new target + */ + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + boolean targeted = false; + + if (start == old_ih) { + targeted = true; + setStart(new_ih); + } + + if (end == old_ih) { + targeted = true; + setEnd(new_ih); + } + + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + end + "}"); + } + } + + /** + * @return true, if ih is target of this variable + */ + public boolean containsTarget(InstructionHandle ih) { + return start == ih || end == ih; + } + + /** + * We consider to local variables to be equal, if the use the same index and are valid in the same range. + */ + public boolean equals(Object o) { + if (!(o instanceof LocalVariableGen)) { + return false; + } + + LocalVariableGen l = (LocalVariableGen) o; + return l.index == index && l.start == start && l.end == end; + } + + public String toString() { + return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableTag.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableTag.java new file mode 100644 index 000000000..7a4fab4e9 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableTag.java @@ -0,0 +1,96 @@ +/* ******************************************************************* + * Copyright (c) 2002 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * Andy Clement pushed down into bcel module + * ******************************************************************/ + +package org.aspectj.apache.bcel.generic; + +public final class LocalVariableTag extends Tag { + private final String signature; + private String name; + private int slot; + private final int startPosition; + private boolean remapped = false; + + private int hashCode = 0; + private Type type; // not always known, in which case signature has to be used + + // AMC - pr101047, two local vars with the same name can share the same slot, but must in that case + // have different start positions. + public LocalVariableTag(String signature, String name, int slot, int startPosition) { + this.signature = signature; + this.name = name; + this.slot = slot; + this.startPosition = startPosition; + } + + public LocalVariableTag(Type type, String signature, String name, int slot, int startPosition) { + this.type = type; + this.signature = signature; + this.name = name; + this.slot = slot; + this.startPosition = startPosition; + } + + public String getName() { + return name; + } + + public int getSlot() { + return slot; + } + + public String getType() { + return signature; + } + + public Type getRealType() { + return type; + } + + public void updateSlot(int newSlot) { + this.slot = newSlot; + this.remapped = true; + this.hashCode = 0; + } + + public void setName(String name) { + this.name = name; + this.hashCode = 0; + } + + public boolean isRemapped() { + return this.remapped; + } + + public String toString() { + return "local " + slot + ": " + signature + " " + name; + } + + public boolean equals(Object other) { + if (!(other instanceof LocalVariableTag)) { + return false; + } + LocalVariableTag o = (LocalVariableTag) other; + return o.slot == slot && o.startPosition == startPosition && o.signature.equals(signature) && o.name.equals(name); + } + + public int hashCode() { + if (hashCode == 0) { + int ret = signature.hashCode(); + ret = 37 * ret + name.hashCode(); + ret = 37 * ret + slot; + ret = 37 * ret + startPosition; + hashCode = ret; + } + return hashCode; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java new file mode 100644 index 000000000..94a213a25 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java @@ -0,0 +1,183 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.ExceptionConstants; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +/** + * MULTIANEWARRAY - Create new mutidimensional array of references + * + *
+ * Stack: ..., count1, [count2, ...] -> ..., arrayref
+ * 
+ * + * @version $Id: MULTIANEWARRAY.java,v 1.4 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public class MULTIANEWARRAY extends InstructionCP { + private short dimensions; + + public MULTIANEWARRAY(int index, short dimensions) { + super(Constants.MULTIANEWARRAY, index); + this.dimensions = dimensions; + } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeShort(index); + out.writeByte(dimensions); + } + + /** + * Read needed data (i.e., no. dimension) from file. + */ + // protected void initFromFile(ByteSequence bytes, boolean wide) + // throws IOException + // { + // super.initFromFile(bytes, wide); + // dimensions = bytes.readByte(); + // // length = 4; + // } + + /** + * @return number of dimensions to be created + */ + public final short getDimensions() { + return dimensions; + } + + /** + * @return mnemonic for instruction + */ + public String toString(boolean verbose) { + return super.toString(verbose) + " " + index + " " + dimensions; + } + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + public String toString(ConstantPool cp) { + return super.toString(cp) + " " + dimensions; + } + + /** + * Also works for instructions whose stack effect depends on the constant pool entry they reference. + * + * @return Number of words consumed from stack by this instruction + */ + public int consumeStack(ConstantPool cpg) { + return dimensions; + } + + public Class[] getExceptions() { + Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; + + System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0, + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); + + cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; + cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; + + return cs; + } + + public ObjectType getLoadClassType(ConstantPool cpg) { + Type t = getType(cpg); + + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + + return (t instanceof ObjectType) ? (ObjectType) t : null; + } + + // /** + // * Call corresponding visitor method(s). The order is: + // * Call visitor methods of implemented interfaces first, then + // * call methods according to the class hierarchy in descending order, + // * i.e., the most specific visitXXX() call comes last. + // * + // * @param v Visitor object + // */ + // public void accept(Visitor v) { + // v.visitLoadClass(this); + // v.visitAllocationInstruction(this); + // v.visitExceptionThrower(this); + // v.visitTypedInstruction(this); + // v.visitCPInstruction(this); + // v.visitMULTIANEWARRAY(this); + // } + + public boolean equals(Object other) { + if (!(other instanceof MULTIANEWARRAY)) { + return false; + } + MULTIANEWARRAY o = (MULTIANEWARRAY) other; + return o.opcode == opcode && o.index == index && o.dimensions == dimensions; + } + + public int hashCode() { + return opcode * 37 + index * (dimensions + 17); + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MethodGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MethodGen.java new file mode 100644 index 000000000..3938beb35 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MethodGen.java @@ -0,0 +1,1169 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Stack; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.Code; +import org.aspectj.apache.bcel.classfile.CodeException; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.ExceptionTable; +import org.aspectj.apache.bcel.classfile.LineNumber; +import org.aspectj.apache.bcel.classfile.LineNumberTable; +import org.aspectj.apache.bcel.classfile.LocalVariable; +import org.aspectj.apache.bcel.classfile.LocalVariableTable; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.Utility; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeParamAnnos; + +/** + * Template class for building up a method. This is done by defining exception handlers, adding thrown exceptions, local variables + * and attributes, whereas the 'LocalVariableTable' and 'LineNumberTable' attributes will be set automatically for the code. Use + * stripAttributes() if you don't like this. + * + * While generating code it may be necessary to insert NOP operations. You can use the `removeNOPs' method to get rid off them. The + * resulting method object can be obtained via the `getMethod()' method. + * + * @version $Id: MethodGen.java,v 1.17 2011/05/19 23:23:46 aclement Exp $ + * @author M. Dahm + * @author Patrick C. Beard [setMaxStack()] + * @see InstructionList + * @see Method + */ +public class MethodGen extends FieldGenOrMethodGen { + private String classname; + private Type[] parameterTypes; + private String[] parameterNames; + private int maxLocals; + private int maxStack; + private InstructionList il; + + // Indicates whether to produce code attributes for LineNumberTable and LocalVariableTable, like javac -O + private boolean stripAttributes; + + private int highestLineNumber = 0; + + private ArrayList localVariablesList = new ArrayList(); + private ArrayList lineNumbersList = new ArrayList(); + private ArrayList exceptionsList = new ArrayList(); + private ArrayList exceptionsThrown = new ArrayList(); + private ArrayList codeAttributesList = new ArrayList(); + private List[] param_annotations; // Array of lists containing AnnotationGen objects + private boolean hasParameterAnnotations = false; + private boolean haveUnpackedParameterAnnotations = false; + + /** + * Declare method. If the method is non-static the constructor automatically declares a local variable `$this' in slot 0. The + * actual code is contained in the `il' parameter, which may further manipulated by the user. But he must take care not to + * remove any instruction (handles) that are still referenced from this object. + * + * For example one may not add a local variable and later remove the instructions it refers to without causing havoc. It is safe + * however if you remove that local variable, too. + * + * @param access_flags access qualifiers + * @param return_type method type + * @param arg_types argument types + * @param arg_names argument names (if this is null, default names will be provided for them) + * @param method_name name of method + * @param class_name class name containing this method (may be null, if you don't care) + * @param il instruction list associated with this method, may be null only for abstract or native methods + * @param cp constant pool + */ + public MethodGen(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, String method_name, + String class_name, InstructionList il, ConstantPool cp) { + + this.modifiers = access_flags; + this.type = return_type; + this.parameterTypes = arg_types; + this.parameterNames = arg_names; + this.name = method_name; + this.classname = class_name; + this.il = il; + this.cp = cp; + + // OPTIMIZE this code messes with the local variables - do we need it? + // boolean abstract_ = isAbstract() || isNative(); + // InstructionHandle start = null; + // InstructionHandle end = null; + // + // if (!abstract_) { + // start = il.getStart(); + // end = il.getEnd(); + // + // /* Add local variables, namely the implicit `this' and the arguments + // */ + // // if(!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0 + // // addLocalVariable("this", new ObjectType(class_name), start, end); + // // } + // } + + // if(arg_types != null) { + // int size = arg_types.length; + // + // for(int i=0; i < size; i++) { + // if(Type.VOID == arg_types[i]) { + // throw new ClassGenException("'void' is an illegal argument type for a method"); + // } + // } + // + // if(arg_names != null) { // Names for variables provided? + // if(size != arg_names.length) + // throw new ClassGenException("Mismatch in argument array lengths: " + + // size + " vs. " + arg_names.length); + // } else { // Give them dummy names + // // arg_names = new String[size]; + // // + // // for(int i=0; i < size; i++) + // // arg_names[i] = "arg" + i; + // // + // // setArgumentNames(arg_names); + // } + + // if(!abstract_) { + // for(int i=0; i < size; i++) { + // // addLocalVariable(arg_names[i], arg_types[i], start, end); + // } + // } + // } + } + + public int getHighestlinenumber() { + return highestLineNumber; + } + + /** + * Instantiate from existing method. + * + * @param m method + * @param class_name class name containing this method + * @param cp constant pool + */ + + public MethodGen(Method m, String class_name, ConstantPool cp) { + this(m, class_name, cp, false); + } + + // OPTIMIZE should always use tags and never anything else! + public MethodGen(Method m, String class_name, ConstantPool cp, boolean useTags) { + this(m.getModifiers(), + // OPTIMIZE implementation of getReturnType() and getArgumentTypes() on Method seems weak + m.getReturnType(), m.getArgumentTypes(), null /* may be overridden anyway */, m.getName(), class_name, ((m + .getModifiers() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0) ? new InstructionList(m.getCode() + .getCode()) : null, cp); + + Attribute[] attributes = m.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + Attribute a = attributes[i]; + + if (a instanceof Code) { + Code code = (Code) a; + setMaxStack(code.getMaxStack()); + setMaxLocals(code.getMaxLocals()); + + CodeException[] ces = code.getExceptionTable(); + + InstructionHandle[] arrayOfInstructions = il.getInstructionsAsArray(); + + // process the exception table + // - + if (ces != null) { + for (CodeException ce : ces) { + int type = ce.getCatchType(); + ObjectType catchType = null; + + if (type > 0) { + String cen = m.getConstantPool().getConstantString_CONSTANTClass(type); + catchType = new ObjectType(cen); + } + + int end_pc = ce.getEndPC(); + int length = m.getCode().getCode().length; + + InstructionHandle end; + + if (length == end_pc) { // May happen, because end_pc is exclusive + end = il.getEnd(); + } else { + end = il.findHandle(end_pc, arrayOfInstructions);// il.findHandle(end_pc); + end = end.getPrev(); // Make it inclusive + } + + addExceptionHandler(il.findHandle(ce.getStartPC(), arrayOfInstructions), end, il.findHandle(ce + .getHandlerPC(), arrayOfInstructions), catchType); + } + } + + Attribute[] codeAttrs = code.getAttributes(); + for (int j = 0; j < codeAttrs.length; j++) { + a = codeAttrs[j]; + + if (a instanceof LineNumberTable) { + LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable(); + if (useTags) { + // abracadabra, lets create tags rather than linenumbergens. + for (int k = 0; k < ln.length; k++) { + LineNumber l = ln[k]; + int lnum = l.getLineNumber(); + if (lnum > highestLineNumber) { + highestLineNumber = lnum; + } + LineNumberTag lt = new LineNumberTag(lnum); + il.findHandle(l.getStartPC(), arrayOfInstructions, true).addTargeter(lt); + } + } else { + for (int k = 0; k < ln.length; k++) { + LineNumber l = ln[k]; + addLineNumber(il.findHandle(l.getStartPC(), arrayOfInstructions, true), l.getLineNumber()); + } + } + } else if (a instanceof LocalVariableTable) { + + // Lets have a go at creating Tags directly + if (useTags) { + LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable(); + + for (int k = 0; k < lv.length; k++) { + LocalVariable l = lv[k]; + Type t = Type.getType(l.getSignature()); + LocalVariableTag lvt = new LocalVariableTag(t, l.getSignature(), l.getName(), l.getIndex(), l + .getStartPC()); + InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions, true); + byte b = t.getType(); + if (b != Constants.T_ADDRESS) { + int increment = t.getSize(); + if (l.getIndex() + increment > maxLocals) { + maxLocals = l.getIndex() + increment; + } + } + int end = l.getStartPC() + l.getLength(); + do { + start.addTargeter(lvt); + start = start.getNext(); + } while (start != null && start.getPosition() < end); + } + } else { + + LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable(); + + removeLocalVariables(); + + for (int k = 0; k < lv.length; k++) { + LocalVariable l = lv[k]; + InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions); + InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength(), arrayOfInstructions); + // AMC, this actually gives us the first instruction AFTER the range, + // so move back one... (findHandle can't cope with mid-instruction indices) + if (end != null) { + end = end.getPrev(); + } + // Repair malformed handles + if (null == start) { + start = il.getStart(); + } + if (null == end) { + end = il.getEnd(); + } + + addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end); + } + } + } else { + addCodeAttribute(a); + } + } + } else if (a instanceof ExceptionTable) { + String[] names = ((ExceptionTable) a).getExceptionNames(); + for (int j = 0; j < names.length; j++) { + addException(names[j]); + } + } else if (a instanceof RuntimeAnnos) { + RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) a; + List l = runtimeAnnotations.getAnnotations(); + annotationList.addAll(l); + // for (Iterator it = l.iterator(); it.hasNext();) { + // AnnotationGen element = it.next(); + // addAnnotation(new AnnotationGen(element, cp, false)); + // } + } else { + addAttribute(a); + } + } + } + + public LocalVariableGen addLocalVariable(String name, Type type, int slot, InstructionHandle start, InstructionHandle end) { + int size = type.getSize(); + if (slot + size > maxLocals) { + maxLocals = slot + size; + } + LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); + int i = localVariablesList.indexOf(l); + if (i >= 0) { + localVariablesList.set(i, l); // Overwrite if necessary + } else { + localVariablesList.add(l); + } + return l; + } + + /** + * Adds a local variable to this method and assigns an index automatically. + * + * @param name variable name + * @param type variable type + * @param start from where the variable is valid, if this is null, it is valid from the start + * @param end until where the variable is valid, if this is null, it is valid to the end + * @return new local variable object + * @see LocalVariable + */ + public LocalVariableGen addLocalVariable(String name, Type type, InstructionHandle start, InstructionHandle end) { + return addLocalVariable(name, type, maxLocals, start, end); + } + + /** + * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable with an explicit index argument. + */ + public void removeLocalVariable(LocalVariableGen l) { + localVariablesList.remove(l); + } + + /** + * Remove all local variables. + */ + public void removeLocalVariables() { + localVariablesList.clear(); + } + + /** + * Sort local variables by index + */ + private static final void sort(LocalVariableGen[] vars, int l, int r) { + int i = l, j = r; + int m = vars[(l + r) / 2].getIndex(); + LocalVariableGen h; + + do { + while (vars[i].getIndex() < m) { + i++; + } + while (m < vars[j].getIndex()) { + j--; + } + + if (i <= j) { + h = vars[i]; + vars[i] = vars[j]; + vars[j] = h; // Swap elements + i++; + j--; + } + } while (i <= j); + + if (l < j) { + sort(vars, l, j); + } + if (i < r) { + sort(vars, i, r); + } + } + + /* + * If the range of the variable has not been set yet, it will be set to be valid from the start to the end of the instruction + * list. + * + * @return array of declared local variables sorted by index + */ + public LocalVariableGen[] getLocalVariables() { + int size = localVariablesList.size(); + LocalVariableGen[] lg = new LocalVariableGen[size]; + localVariablesList.toArray(lg); + + for (int i = 0; i < size; i++) { + if (lg[i].getStart() == null) { + lg[i].setStart(il.getStart()); + } + + if (lg[i].getEnd() == null) { + lg[i].setEnd(il.getEnd()); + } + } + + if (size > 1) { + sort(lg, 0, size - 1); + } + + return lg; + } + + /** + * @return `LocalVariableTable' attribute of all the local variables of this method. + */ + public LocalVariableTable getLocalVariableTable(ConstantPool cp) { + LocalVariableGen[] lg = getLocalVariables(); + int size = lg.length; + LocalVariable[] lv = new LocalVariable[size]; + + for (int i = 0; i < size; i++) { + lv[i] = lg[i].getLocalVariable(cp); + } + + return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp); + } + + /** + * Give an instruction a line number corresponding to the source code line. + * + * @param ih instruction to tag + * @return new line number object + * @see LineNumber + */ + public LineNumberGen addLineNumber(InstructionHandle ih, int src_line) { + LineNumberGen l = new LineNumberGen(ih, src_line); + lineNumbersList.add(l); + return l; + } + + /** + * Remove a line number. + */ + public void removeLineNumber(LineNumberGen l) { + lineNumbersList.remove(l); + } + + /** + * Remove all line numbers. + */ + public void removeLineNumbers() { + lineNumbersList.clear(); + } + + /* + * @return array of line numbers + */ + public LineNumberGen[] getLineNumbers() { + LineNumberGen[] lg = new LineNumberGen[lineNumbersList.size()]; + lineNumbersList.toArray(lg); + return lg; + } + + /** + * @return 'LineNumberTable' attribute for all the local variables of this method. + */ + public LineNumberTable getLineNumberTable(ConstantPool cp) { + int size = lineNumbersList.size(); + LineNumber[] ln = new LineNumber[size]; + + for (int i = 0; i < size; i++) { + ln[i] = lineNumbersList.get(i).getLineNumber(); + } + + return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp); + } + + /** + * Add an exception handler, i.e., specify region where a handler is active and an instruction where the actual handling is + * done. + * + * @param start_pc Start of region (inclusive) + * @param end_pc End of region (inclusive) + * @param handler_pc Where handling is done + * @param catch_type class type of handled exception or null if any exception is handled + * @return new exception handler object + */ + public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc, InstructionHandle end_pc, InstructionHandle handler_pc, + ObjectType catch_type) { + if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) { + throw new ClassGenException("Exception handler target is null instruction"); + } + + CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type); + exceptionsList.add(c); + return c; + } + + /** + * Remove an exception handler. + */ + public void removeExceptionHandler(CodeExceptionGen c) { + exceptionsList.remove(c); + } + + /** + * Remove all line numbers. + */ + public void removeExceptionHandlers() { + exceptionsList.clear(); + } + + /* + * @return array of declared exception handlers + */ + public CodeExceptionGen[] getExceptionHandlers() { + CodeExceptionGen[] cg = new CodeExceptionGen[exceptionsList.size()]; + exceptionsList.toArray(cg); + return cg; + } + + /** + * @return code exceptions for `Code' attribute + */ + private CodeException[] getCodeExceptions() { + int size = exceptionsList.size(); + CodeException[] c_exc = new CodeException[size]; + + try { + for (int i = 0; i < size; i++) { + CodeExceptionGen c = exceptionsList.get(i); + c_exc[i] = c.getCodeException(cp); + } + } catch (ArrayIndexOutOfBoundsException e) { + } + + return c_exc; + } + + /** + * Add an exception possibly thrown by this method. + * + * @param class_name (fully qualified) name of exception + */ + public void addException(String class_name) { + exceptionsThrown.add(class_name); + } + + /** + * Remove an exception. + */ + public void removeException(String c) { + exceptionsThrown.remove(c); + } + + /** + * Remove all exceptions. + */ + public void removeExceptions() { + exceptionsThrown.clear(); + } + + /* + * @return array of thrown exceptions + */ + public String[] getExceptions() { + String[] e = new String[exceptionsThrown.size()]; + exceptionsThrown.toArray(e); + return e; + } + + /** + * @return `Exceptions' attribute of all the exceptions thrown by this method. + */ + private ExceptionTable getExceptionTable(ConstantPool cp) { + int size = exceptionsThrown.size(); + int[] ex = new int[size]; + + try { + for (int i = 0; i < size; i++) { + ex[i] = cp.addClass(exceptionsThrown.get(i)); + } + } catch (ArrayIndexOutOfBoundsException e) { + } + + return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp); + } + + /** + * Add an attribute to the code. Currently, the JVM knows about the LineNumberTable, LocalVariableTable and StackMap attributes, + * where the former two will be generated automatically and the latter is used for the MIDP only. Other attributes will be + * ignored by the JVM but do no harm. + * + * @param a attribute to be added + */ + public void addCodeAttribute(Attribute a) { + codeAttributesList.add(a); + } + + public void addParameterAnnotationsAsAttribute(ConstantPool cp) { + if (!hasParameterAnnotations) { + return; + } + Attribute[] attrs = Utility.getParameterAnnotationAttributes(cp, param_annotations); + if (attrs != null) { + for (int i = 0; i < attrs.length; i++) { + addAttribute(attrs[i]); + } + } + } + + /** + * Remove a code attribute. + */ + public void removeCodeAttribute(Attribute a) { + codeAttributesList.remove(a); + } + + /** + * Remove all code attributes. + */ + public void removeCodeAttributes() { + codeAttributesList.clear(); + } + + /** + * @return all attributes of this method. + */ + public Attribute[] getCodeAttributes() { + Attribute[] attributes = new Attribute[codeAttributesList.size()]; + codeAttributesList.toArray(attributes); + return attributes; + } + + /** + * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively, before calling this method (the same + * applies for max locals). + * + * @return method object + */ + public Method getMethod() { + String signature = getSignature(); + int name_index = cp.addUtf8(name); + int signature_index = cp.addUtf8(signature); + + /* + * Also updates positions of instructions, i.e., their indices + */ + byte[] byte_code = null; + + if (il != null) { + try { + byte_code = il.getByteCode(); + } catch (Exception e) { + throw new IllegalStateException("Unexpected problem whilst preparing bytecode for " + this.getClassName() + "." + + this.getName() + this.getSignature(), e); + } + } + + LineNumberTable lnt = null; + LocalVariableTable lvt = null; + // J5TODO: LocalVariableTypeTable support! + + /* + * Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.) + */ + if ((localVariablesList.size() > 0) && !stripAttributes) { + addCodeAttribute(lvt = getLocalVariableTable(cp)); + } + + if ((lineNumbersList.size() > 0) && !stripAttributes) { + addCodeAttribute(lnt = getLineNumberTable(cp)); + } + + Attribute[] code_attrs = getCodeAttributes(); + + /* + * Each attribute causes 6 additional header bytes + */ + int attrs_len = 0; + for (int i = 0; i < code_attrs.length; i++) { + attrs_len += (code_attrs[i].getLength() + 6); + } + + CodeException[] c_exc = getCodeExceptions(); + int exc_len = c_exc.length * 8; // Every entry takes 8 bytes + + Code code = null; + + if ((il != null) && !isAbstract()) { + // Remove any stale code attribute + List attributes = getAttributes(); + for (int i = 0; i < attributes.size(); i++) { + Attribute a = attributes.get(i); + if (a instanceof Code) { + removeAttribute(a); + } + } + + code = new Code(cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code + 2 + exc_len + // exceptions + 2 + attrs_len, // attributes + maxStack, maxLocals, byte_code, c_exc, code_attrs, cp); + + addAttribute(code); + } + + addAnnotationsAsAttribute(cp); + addParameterAnnotationsAsAttribute(cp); + + ExceptionTable et = null; + + if (exceptionsThrown.size() > 0) { + addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses + } + + Method m = new Method(modifiers, name_index, signature_index, getAttributesImmutable(), cp); + + // Undo effects of adding attributes + // OPTIMIZE why redo this? is there a better way to clean up? + if (lvt != null) { + removeCodeAttribute(lvt); + } + if (lnt != null) { + removeCodeAttribute(lnt); + } + if (code != null) { + removeAttribute(code); + } + if (et != null) { + removeAttribute(et); + } + // J5TODO: Remove the annotation attributes that may have been added + return m; + } + + /** + * Set maximum number of local variables. + */ + public void setMaxLocals(int m) { + maxLocals = m; + } + + public int getMaxLocals() { + return maxLocals; + } + + /** + * Set maximum stack size for this method. + */ + public void setMaxStack(int m) { + maxStack = m; + } + + public int getMaxStack() { + return maxStack; + } + + /** + * @return class that contains this method + */ + public String getClassName() { + return classname; + } + + public void setClassName(String class_name) { + this.classname = class_name; + } + + public void setReturnType(Type return_type) { + setType(return_type); + } + + public Type getReturnType() { + return getType(); + } + + public void setArgumentTypes(Type[] arg_types) { + this.parameterTypes = arg_types; + } + + public Type[] getArgumentTypes() { + return this.parameterTypes; + }// OPTIMIZE dont need clone here? (Type[])arg_types.clone(); } + + public void setArgumentType(int i, Type type) { + parameterTypes[i] = type; + } + + public Type getArgumentType(int i) { + return parameterTypes[i]; + } + + public void setArgumentNames(String[] arg_names) { + this.parameterNames = arg_names; + } + + public String[] getArgumentNames() { + if (parameterNames != null) { + return parameterNames.clone(); + } else { + return new String[0]; + } + } + + public void setArgumentName(int i, String name) { + parameterNames[i] = name; + } + + public String getArgumentName(int i) { + return parameterNames[i]; + } + + public InstructionList getInstructionList() { + return il; + } + + public void setInstructionList(InstructionList il) { + this.il = il; + } + + @Override + public String getSignature() { + return Utility.toMethodSignature(type, parameterTypes); + } + + /** + * Computes max. stack size by performing control flow analysis. + */ + public void setMaxStack() { + if (il != null) { + maxStack = getMaxStack(cp, il, getExceptionHandlers()); + } else { + maxStack = 0; + } + } + + /** + * Compute maximum number of local variables based on the parameter count and bytecode usage of variables. + */ + public void setMaxLocals() { + setMaxLocals(false); + } + + /** + * Compute maximum number of local variables. + * + * @param respectLocalVariableTable if true and the local variable table indicates more are in use + * than the code suggests, respect the higher value from the local variable table data. + */ + public void setMaxLocals(boolean respectLocalVariableTable) { + if (il != null) { + int max = isStatic() ? 0 : 1; + + if (parameterTypes != null) { + for (int i = 0; i < parameterTypes.length; i++) { + max += parameterTypes[i].getSize(); + } + } + + for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { + Instruction ins = ih.getInstruction(); + + if ((ins instanceof InstructionLV) || (ins instanceof RET)) { + int index = ins.getIndex() + ins.getType(cp).getSize(); + + if (index > max) { + max = index; + } + } + } + if (!respectLocalVariableTable || max > maxLocals) { + maxLocals = max; + } + } else { + if (!respectLocalVariableTable) { + maxLocals = 0; + } + } + } + + public void stripAttributes(boolean flag) { + stripAttributes = flag; + } + + static final class BranchTarget { + InstructionHandle target; + int stackDepth; + + BranchTarget(InstructionHandle target, int stackDepth) { + this.target = target; + this.stackDepth = stackDepth; + } + } + + static final class BranchStack { + Stack branchTargets = new Stack(); + Hashtable visitedTargets = new Hashtable(); + + public void push(InstructionHandle target, int stackDepth) { + if (visited(target)) { + return; + } + + branchTargets.push(visit(target, stackDepth)); + } + + public BranchTarget pop() { + if (!branchTargets.empty()) { + BranchTarget bt = branchTargets.pop(); + return bt; + } + + return null; + } + + private final BranchTarget visit(InstructionHandle target, int stackDepth) { + BranchTarget bt = new BranchTarget(target, stackDepth); + visitedTargets.put(target, bt); + + return bt; + } + + private final boolean visited(InstructionHandle target) { + return (visitedTargets.get(target) != null); + } + } + + /** + * Computes stack usage of an instruction list by performing control flow analysis. + * + * @return maximum stack depth used by method + */ + public static int getMaxStack(ConstantPool cp, InstructionList il, CodeExceptionGen[] et) { + BranchStack branchTargets = new BranchStack(); + + int stackDepth = 0; + int maxStackDepth = 0; + + /* + * Initially, populate the branch stack with the exception handlers, because these aren't (necessarily) branched to + * explicitly. In each case, the stack will have depth 1, containing the exception object. + */ + for (int i = 0, max = et.length; i < max; i++) { + InstructionHandle handlerPos = et[i].getHandlerPC(); + if (handlerPos != null) { + // it must be at least 1 since there is an exception handler + maxStackDepth = 1; + branchTargets.push(handlerPos, 1); + } + } + + InstructionHandle ih = il.getStart(); + while (ih != null) { + Instruction instruction = ih.getInstruction(); + short opcode = instruction.opcode; + int prod = instruction.produceStack(cp); + int con = instruction.consumeStack(cp); + int delta = prod - con; + + stackDepth += delta; + if (stackDepth > maxStackDepth) { + maxStackDepth = stackDepth; + } + + // choose the next instruction based on whether current is a branch. + if (instruction instanceof InstructionBranch) { + InstructionBranch branch = (InstructionBranch) instruction; + if (instruction instanceof InstructionSelect) { + // explore all of the select's targets. the default target is handled below. + InstructionSelect select = (InstructionSelect) branch; + InstructionHandle[] targets = select.getTargets(); + for (int i = 0; i < targets.length; i++) { + branchTargets.push(targets[i], stackDepth); + } + // nothing to fall through to. + ih = null; + } else if (!(branch.isIfInstruction())) { + // if an instruction that comes back to following PC, + // push next instruction, with stack depth reduced by 1. + if (opcode == Constants.JSR || opcode == Constants.JSR_W) { + branchTargets.push(ih.getNext(), stackDepth - 1); + } + ih = null; + } + // for all branches, the target of the branch is pushed on the branch stack. + // conditional branches have a fall through case, selects don't, and + // jsr/jsr_w return to the next instruction. + branchTargets.push(branch.getTarget(), stackDepth); + } else { + // check for instructions that terminate the method. + if (opcode == Constants.ATHROW || opcode == Constants.RET + || (opcode >= Constants.IRETURN && opcode <= Constants.RETURN)) { + ih = null; + } + } + // normal case, go to the next instruction. + if (ih != null) { + ih = ih.getNext(); + } + // if we have no more instructions, see if there are any deferred branches to explore. + if (ih == null) { + BranchTarget bt = branchTargets.pop(); + if (bt != null) { + ih = bt.target; + stackDepth = bt.stackDepth; + } + } + } + return maxStackDepth; + } + + /** + * Return string representation close to declaration format, `public static void main(String[]) throws IOException', e.g. + * + * @return String representation of the method. + */ + @Override + public final String toString() { + String access = Utility.accessToString(modifiers); + String signature = Utility.toMethodSignature(type, parameterTypes); + + signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable(cp)); + + StringBuffer buf = new StringBuffer(signature); + + if (exceptionsThrown.size() > 0) { + for (Iterator e = exceptionsThrown.iterator(); e.hasNext();) { + buf.append("\n\t\tthrows " + e.next()); + } + } + + return buf.toString(); + } + + // J5TODO: Should param_annotations be an array of arrays? Rather than an array of lists, this + // is more likely to suggest to the caller it is readonly (which a List does not). + /** + * Return a list of AnnotationGen objects representing parameter annotations + */ + public List getAnnotationsOnParameter(int i) { + ensureExistingParameterAnnotationsUnpacked(); + if (!hasParameterAnnotations || i > parameterTypes.length) { + return null; + } + return param_annotations[i]; + } + + /** + * Goes through the attributes on the method and identifies any that are RuntimeParameterAnnotations, extracting their contents + * and storing them as parameter annotations. There are two kinds of parameter annotation - visible and invisible. Once they + * have been unpacked, these attributes are deleted. (The annotations will be rebuilt as attributes when someone builds a Method + * object out of this MethodGen object). + */ + private void ensureExistingParameterAnnotationsUnpacked() { + if (haveUnpackedParameterAnnotations) { + return; + } + // Find attributes that contain parameter annotation data + List attrs = getAttributes(); + RuntimeParamAnnos paramAnnVisAttr = null; + RuntimeParamAnnos paramAnnInvisAttr = null; + + for (Attribute attribute : attrs) { + if (attribute instanceof RuntimeParamAnnos) { + + if (!hasParameterAnnotations) { + param_annotations = new List[parameterTypes.length]; + for (int j = 0; j < parameterTypes.length; j++) { + param_annotations[j] = new ArrayList(); + } + } + + hasParameterAnnotations = true; + RuntimeParamAnnos rpa = (RuntimeParamAnnos) attribute; + if (rpa.areVisible()) { + paramAnnVisAttr = rpa; + } else { + paramAnnInvisAttr = rpa; + } + for (int j = 0; j < parameterTypes.length; j++) { + // This returns Annotation[] ... + AnnotationGen[] annos = rpa.getAnnotationsOnParameter(j); + // ... which needs transforming into an AnnotationGen[] ... + // List mutable = makeMutableVersion(immutableArray); + // ... then add these to any we already know about + for (AnnotationGen anAnnotation : annos) { + param_annotations[j].add(anAnnotation); + } + } + } + } + if (paramAnnVisAttr != null) { + removeAttribute(paramAnnVisAttr); + } + if (paramAnnInvisAttr != null) { + removeAttribute(paramAnnInvisAttr); + } + haveUnpackedParameterAnnotations = true; + } + + private List /* AnnotationGen */ makeMutableVersion(AnnotationGen[] mutableArray) { + List result = new ArrayList(); + for (int i = 0; i < mutableArray.length; i++) { + result.add(new AnnotationGen(mutableArray[i], getConstantPool(), false)); + } + return result; + } + + public void addParameterAnnotation(int parameterIndex, AnnotationGen annotation) { + ensureExistingParameterAnnotationsUnpacked(); + if (!hasParameterAnnotations) { + param_annotations = new List[parameterTypes.length]; + hasParameterAnnotations = true; + } + List existingAnnotations = param_annotations[parameterIndex]; + if (existingAnnotations != null) { + existingAnnotations.add(annotation); + } else { + List l = new ArrayList(); + l.add(annotation); + param_annotations[parameterIndex] = l; + } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ObjectType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ObjectType.java new file mode 100644 index 000000000..544363f16 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ObjectType.java @@ -0,0 +1,161 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.Repository; +import org.aspectj.apache.bcel.classfile.JavaClass; + +/** + * Denotes reference such as java.lang.String. + * + * @version $Id: ObjectType.java,v 1.7 2009/09/28 16:39:46 aclement Exp $ + * @author M. Dahm + */ +public class ObjectType extends ReferenceType { + private String classname; + + /** + * @param class_name fully qualified class name, e.g. java.lang.String + */ + public ObjectType(String class_name) { + super(Constants.T_REFERENCE, toSignature(class_name));// "L" + class_name.replace('.', '/') + ";"); + this.classname = class_name;// .replace('/', '.'); + } + + /** + * @param classname eg. java.lang.String + * @param signature eg. Ljava/lang/String; + */ + public ObjectType(String classname, String signature) { + super(Constants.T_REFERENCE, signature); + this.classname = classname; + } + + private static String toSignature(String classname) { + StringBuffer sig = new StringBuffer(); + sig.append("L").append(classname.replace('.', '/')); + sig.append(";"); + return sig.toString(); + } + + /** + * @return name of referenced class + */ + public String getClassName() { + return classname; + } + + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return classname.hashCode(); + } + + /** + * @return true if both type objects refer to the same class. + */ + @Override + public boolean equals(Object type) { + return (type instanceof ObjectType) ? ((ObjectType) type).classname.equals(classname) : false; + } + + /** + * If "this" doesn't reference a class, it references an interface or a non-existant entity. + */ + public boolean referencesClass() { + JavaClass jc = Repository.lookupClass(classname); + if (jc == null) { + return false; + } else { + return jc.isClass(); + } + } + + /** + * If "this" doesn't reference an interface, it references a class or a non-existant entity. + */ + public boolean referencesInterface() { + JavaClass jc = Repository.lookupClass(classname); + if (jc == null) { + return false; + } else { + return !jc.isClass(); + } + } + + public boolean subclassOf(ObjectType superclass) { + if (this.referencesInterface() || superclass.referencesInterface()) { + return false; + } + + return Repository.instanceOf(this.classname, superclass.classname); + } + + /** + * Java Virtual Machine Specification edition 2, 5.4.4 Access Control + */ + public boolean accessibleTo(ObjectType accessor) { + JavaClass jc = Repository.lookupClass(classname); + + if (jc.isPublic()) { + return true; + } else { + JavaClass acc = Repository.lookupClass(accessor.classname); + return acc.getPackageName().equals(jc.getPackageName()); + } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/RET.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/RET.java new file mode 100644 index 000000000..0fd2f498d --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/RET.java @@ -0,0 +1,132 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; + +/** + * RET - Return from subroutine + * + *
+ * Stack: ..., -> ..., address
+ * 
+ * + * @version $Id: RET.java,v 1.5 2009/10/05 17:35:36 aclement Exp $ + * @author M. Dahm + */ +public class RET extends Instruction { + private boolean wide; + private int index; // index to local variable containing the return address + + public RET(int index, boolean wide) { + super(Constants.RET); + this.index = index; + this.wide = wide; + // this.wide = index > org.aspectj.apache.bcel.Constants.MAX_BYTE; + } + + public void dump(DataOutputStream out) throws IOException { + if (wide) { + out.writeByte(Constants.WIDE); + } + out.writeByte(opcode); + if (wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } + + public int getLength() { + if (wide) { + return 4; + } else { + return 2; + } + } + + public final int getIndex() { + return index; + } + + public final void setIndex(int index) { + this.index = index; + this.wide = index > Constants.MAX_BYTE; + } + + public String toString(boolean verbose) { + return super.toString(verbose) + " " + index; + } + + public Type getType(ConstantPool cp) { + return ReturnaddressType.NO_TARGET; + } + + public boolean equals(Object other) { + if (!(other instanceof RET)) { + return false; + } + RET o = (RET) other; + return o.opcode == opcode && o.index == index; + } + + public int hashCode() { + return opcode * 37 + index; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReferenceType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReferenceType.java new file mode 100644 index 000000000..1e290f5a4 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReferenceType.java @@ -0,0 +1,365 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.Repository; +import org.aspectj.apache.bcel.classfile.JavaClass; + +/** + * Super class for object and array types. + * + * @version $Id: ReferenceType.java,v 1.6 2009/09/09 22:18:20 aclement Exp $ + * @author M. Dahm + */ +public abstract class ReferenceType extends Type { + + protected ReferenceType(byte t, String s) { + super(t, s); + } + + ReferenceType() { + super(Constants.T_OBJECT, ""); + } + + /** + * Return true iff this type is castable to another type t as defined in the JVM specification. The case where this is Type.NULL + * is not defined (see the CHECKCAST definition in the JVM specification). However, because e.g. CHECKCAST doesn't throw a + * ClassCastException when casting a null reference to any Object, true is returned in this case. + */ + public boolean isCastableTo(Type t) { + if (this.equals(Type.NULL)) { + return true; // If this is ever changed in isAssignmentCompatible() + } + + return isAssignmentCompatibleWith(t); + /* + * Yes, it's true: It's the same definition. See vmspec2 AASTORE / CHECKCAST definitions. + */ + } + + /** + * Return true iff this is assignment compatible with another type t as defined in the JVM specification; see the AASTORE + * definition there. + */ + public boolean isAssignmentCompatibleWith(Type t) { + if (!(t instanceof ReferenceType)) { + return false; + } + + ReferenceType T = (ReferenceType) t; + + if (this.equals(Type.NULL)) { + return true; // This is not explicitely stated, but clear. Isn't it? + } + + /* + * If this is a class type then + */ + if (this instanceof ObjectType && ((ObjectType) this).referencesClass()) { + /* + * If T is a class type, then this must be the same class as T, or this must be a subclass of T; + */ + if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) { + if (this.equals(T)) { + return true; + } + + if (Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName())) { + return true; + } + } + + /* + * If T is an interface type, this must implement interface T. + */ + if (T instanceof ObjectType && ((ObjectType) T).referencesInterface()) { + if (Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName())) { + return true; + } + } + } + + /* + * If this is an interface type, then: + */ + if (this instanceof ObjectType && ((ObjectType) this).referencesInterface()) { + /* + * If T is a class type, then T must be Object (2.4.7). + */ + if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) { + if (T.equals(Type.OBJECT)) { + return true; + } + } + + /* + * If T is an interface type, then T must be the same interface as this or a superinterface of this (2.13.2). + */ + if (T instanceof ObjectType && ((ObjectType) T).referencesInterface()) { + if (this.equals(T)) { + return true; + } + if (Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName())) { + return true; + } + } + } + + /* + * If this is an array type, namely, the type SC[], that is, an array of components of type SC, then: + */ + if (this instanceof ArrayType) { + /* + * If T is a class type, then T must be Object (2.4.7). + */ + if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) { + if (T.equals(Type.OBJECT)) { + return true; + } + } + + /* + * If T is an array type TC[], that is, an array of components of type TC, then one of the following must be true: + */ + if (T instanceof ArrayType) { + /* + * TC and SC are the same primitive type (2.4.1). + */ + Type sc = ((ArrayType) this).getElementType(); + Type tc = ((ArrayType) this).getElementType(); + + if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) { + return true; + } + + /* + * TC and SC are reference types (2.4.6), and type SC is assignable to TC by these runtime rules. + */ + if (tc instanceof ReferenceType && sc instanceof ReferenceType + && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { + return true; + } + } + + /* If T is an interface type, T must be one of the interfaces implemented by arrays (2.15). */ + // TODO: Check if this is still valid or find a way to dynamically find out which + // interfaces arrays implement. However, as of the JVM specification edition 2, there + // are at least two different pages where assignment compatibility is defined and + // on one of them "interfaces implemented by arrays" is exchanged with "'Cloneable' or + // 'java.io.Serializable'" + if (T instanceof ObjectType && ((ObjectType) T).referencesInterface()) { + for (int ii = 0; ii < Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS.length; ii++) { + if (T.equals(new ObjectType(Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS[ii]))) { + return true; + } + } + } + } + return false; // default. + } + + /** + * This commutative operation returns the first common superclass (narrowest ReferenceType referencing a class, not an + * interface). If one of the types is a superclass of the other, the former is returned. If "this" is Type.NULL, then t is + * returned. If t is Type.NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If "this" or + * t is an ArrayType, then Type.OBJECT is returned; unless their dimensions match. Then an ArrayType of the same number of + * dimensions is returned, with its basic type being the first common super class of the basic types of "this" and t. If "this" + * or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. If not all of the two classes' superclasses + * cannot be found, "null" is returned. See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". + */ + public ReferenceType getFirstCommonSuperclass(ReferenceType t) { + if (this.equals(Type.NULL)) { + return t; + } + if (t.equals(Type.NULL)) { + return this; + } + if (this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by Type.NULL so we can also + * say all the objects referenced by Type.NULL were derived from java.lang.Object. However, the Java Language's + * "instanceof" operator proves us wrong: "null" is not referring to an instance of java.lang.Object :) + */ + } + + /* This code is from a bug report by Konstantin Shagin */ + + if (this instanceof ArrayType && t instanceof ArrayType) { + ArrayType arrType1 = (ArrayType) this; + ArrayType arrType2 = (ArrayType) t; + if (arrType1.getDimensions() == arrType2.getDimensions() && arrType1.getBasicType() instanceof ObjectType + && arrType2.getBasicType() instanceof ObjectType) { + return new ArrayType(((ObjectType) arrType1.getBasicType()).getFirstCommonSuperclass((ObjectType) arrType2 + .getBasicType()), arrType1.getDimensions()); + + } + } + + if (this instanceof ArrayType || t instanceof ArrayType) { + return Type.OBJECT; + // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + } + + if (this instanceof ObjectType && ((ObjectType) this).referencesInterface() || t instanceof ObjectType + && ((ObjectType) t).referencesInterface()) { + return Type.OBJECT; + // TODO: The above line is correct comparing to the vmspec2. But one could + // make class file verification a bit stronger here by using the notion of + // superinterfaces or even castability or assignment compatibility. + } + + // this and t are ObjectTypes, see above. + ObjectType thiz = (ObjectType) this; + ObjectType other = (ObjectType) t; + JavaClass[] thiz_sups = Repository.lookupClass(thiz.getClassName()).getSuperClasses();// getSuperClasses(thiz.getClassName()); + JavaClass[] other_sups = Repository.lookupClass(other.getClassName()).getSuperClasses();// getSuperClasses(other.getClassName()); + + if (thiz_sups == null || other_sups == null) { + return null; + } + + // Waaahh... + JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; + JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; + System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); + System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); + this_sups[0] = Repository.lookupClass(thiz.getClassName()); + t_sups[0] = Repository.lookupClass(other.getClassName()); + + for (int i = 0; i < t_sups.length; i++) { + for (int j = 0; j < this_sups.length; j++) { + if (this_sups[j].equals(t_sups[i])) { + return new ObjectType(this_sups[j].getClassName()); + } + } + } + + // Huh? Did you ask for Type.OBJECT's superclass?? + return null; + } + + // /** + // * This commutative operation returns the first common superclass (narrowest ReferenceType referencing a class, not an + // * interface). If one of the types is a superclass of the other, the former is returned. If "this" is Type.NULL, then t is + // * returned. If t is Type.NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If "this" + // or + // * t is an ArrayType, then Type.OBJECT is returned. If "this" or t is a ReferenceType referencing an interface, then + // Type.OBJECT + // * is returned. If not all of the two classes' superclasses cannot be found, "null" is returned. See the JVM specification + // * edition 2, "4.9.2 The Bytecode Verifier". + // * + // * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has slightly changed semantics. + // */ + // public ReferenceType firstCommonSuperclass(ReferenceType t) { + // if (this.equals(Type.NULL)) { + // return t; + // } + // if (t.equals(Type.NULL)) { + // return this; + // } + // if (this.equals(t)) { + // return this; + // /* + // * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by Type.NULL so we can also + // * say all the objects referenced by Type.NULL were derived from java.lang.Object. However, the Java Language's + // * "instanceof" operator proves us wrong: "null" is not referring to an instance of java.lang.Object :) + // */ + // } + // + // if (this instanceof ArrayType || t instanceof ArrayType) { + // return Type.OBJECT; + // // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + // } + // + // if (this instanceof ObjectType && ((ObjectType) this).referencesInterface() || t instanceof ObjectType + // && ((ObjectType) t).referencesInterface()) { + // return Type.OBJECT; + // // TODO: The above line is correct comparing to the vmspec2. But one could + // // make class file verification a bit stronger here by using the notion of + // // superinterfaces or even castability or assignment compatibility. + // } + // + // // this and t are ObjectTypes, see above. + // ObjectType thiz = (ObjectType) this; + // ObjectType other = (ObjectType) t; + // JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); + // JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); + // + // if (thiz_sups == null || other_sups == null) { + // return null; + // } + // + // // Waaahh... + // JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; + // JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; + // System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); + // System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); + // this_sups[0] = Repository.lookupClass(thiz.getClassName()); + // t_sups[0] = Repository.lookupClass(other.getClassName()); + // + // for (int i = 0; i < t_sups.length; i++) { + // for (int j = 0; j < this_sups.length; j++) { + // if (this_sups[j].equals(t_sups[i])) { + // return new ObjectType(this_sups[j].getClassName()); + // } + // } + // } + // + // // Huh? Did you ask for Type.OBJECT's superclass?? + // return null; + // } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReturnaddressType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReturnaddressType.java new file mode 100644 index 000000000..a38ffedfd --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReturnaddressType.java @@ -0,0 +1,102 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.generic.InstructionHandle; + +/** + * Returnaddress, the type JSR or JSR_W instructions push upon the stack. + * + * see vmspec2 3.3.3 + * @version $Id: ReturnaddressType.java,v 1.3 2008/05/28 23:52:56 aclement Exp $ + * @author Enver Haase + */ +public class ReturnaddressType extends Type { + + public static final ReturnaddressType NO_TARGET = new ReturnaddressType(); + private InstructionHandle returnTarget; + + /** + * A Returnaddress [that doesn't know where to return to]. + */ + private ReturnaddressType(){ + super(Constants.T_ADDRESS, ""); + } + + /** + * Creates a ReturnaddressType object with a target. + */ + public ReturnaddressType(InstructionHandle returnTarget) { + super(Constants.T_ADDRESS, ""); + this.returnTarget = returnTarget; + } + + /** + * Returns if the two Returnaddresses refer to the same target. + */ + public boolean equals(Object rat){ + if(!(rat instanceof ReturnaddressType)) + return false; + + return ((ReturnaddressType)rat).returnTarget.equals(this.returnTarget); + } + + /** + * @return the target of this ReturnaddressType + */ + public InstructionHandle getTarget(){ + return returnTarget; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/SwitchBuilder.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/SwitchBuilder.java new file mode 100644 index 000000000..eac6bf364 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/SwitchBuilder.java @@ -0,0 +1,181 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or + * TABLESWITCH instruction, depending on whether the match values (int[]) can be + * sorted with no gaps between the numbers. + * + * @version $Id: SwitchBuilder.java,v 1.2 2008/05/28 23:52:57 aclement Exp $ + * @author M. Dahm + */ +public final class SwitchBuilder { + private int[] match; + private InstructionHandle[] targets; + private InstructionSelect instruction; + private int match_length; + + /** + * Template for switch() constructs. If the match array can be + * sorted in ascending order with gaps no larger than max_gap + * between the numbers, a TABLESWITCH instruction is generated, and + * a LOOKUPSWITCH otherwise. The former may be more efficient, but + * needs more space. + * + * Note, that the key array always will be sorted, though we leave + * the original arrays unaltered. + * + * @param match array of match values (case 2: ... case 7: ..., etc.) + * @param targets the instructions to be branched to for each case + * @param target the default target + * @param max_gap maximum gap that may between case branches + */ + public SwitchBuilder(int[] match, InstructionHandle[] targets,InstructionHandle target, int max_gap) { + this.match = (int[])match.clone(); + this.targets = (InstructionHandle[])targets.clone(); + + if((match_length = match.length) < 2) // (almost) empty switch, or just default + if (match.length==0) { + instruction = new LOOKUPSWITCH(match,targets,target); + } else { + instruction = new TABLESWITCH(match,targets,target); + } + else { + sort(0, match_length - 1); + + if(matchIsOrdered(max_gap)) { + fillup(max_gap, target); + + instruction = new TABLESWITCH(this.match, this.targets, target); + } + else + instruction = new LOOKUPSWITCH(this.match, this.targets, target); + } + } + + public SwitchBuilder(int[] match, InstructionHandle[] targets, InstructionHandle target) { + this(match, targets, target, 1); + } + + private final void fillup(int max_gap, InstructionHandle target) { + int max_size = match_length + match_length * max_gap; + int[] m_vec = new int[max_size]; + InstructionHandle[] t_vec = new InstructionHandle[max_size]; + int count = 1; + + m_vec[0] = match[0]; + t_vec[0] = targets[0]; + + for(int i=1; i < match_length; i++) { + int prev = match[i-1]; + int gap = match[i] - prev; + + for(int j=1; j < gap; j++) { + m_vec[count] = prev + j; + t_vec[count] = target; + count++; + } + + m_vec[count] = match[i]; + t_vec[count] = targets[i]; + count++; + } + + match = new int[count]; + targets = new InstructionHandle[count]; + + System.arraycopy(m_vec, 0, match, 0, count); + System.arraycopy(t_vec, 0, targets, 0, count); + } + + /** + * Sort match and targets array with QuickSort. + */ + private final void sort(int l, int r) { + int i = l, j = r; + int h, m = match[(l + r) / 2]; + InstructionHandle h2; + + do { + while(match[i] < m) i++; + while(m < match[j]) j--; + + if(i <= j) { + h=match[i]; match[i]=match[j]; match[j]=h; // Swap elements + h2=targets[i]; targets[i]=targets[j]; targets[j]=h2; // Swap instructions, too + i++; j--; + } + } while(i <= j); + + if(l < j) sort(l, j); + if(i < r) sort(i, r); + } + + /** + * @return match is sorted in ascending order with no gap bigger than max_gap? + */ + private final boolean matchIsOrdered(int max_gap) { + for(int i=1; i < match_length; i++) { + int diff = (match[i]-match[i-1]); + if(diff > max_gap || diff<0) return false; + } + return true; + } + + public final InstructionSelect getInstruction() { + return instruction; + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TABLESWITCH.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TABLESWITCH.java new file mode 100644 index 000000000..5dc26346b --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TABLESWITCH.java @@ -0,0 +1,138 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.util.ByteSequence; + +import com.sun.org.apache.bcel.internal.generic.SWITCH; + +/** + * TABLESWITCH - Switch within given range of values, i.e., low..high + * + * @version $Id: TABLESWITCH.java,v 1.5 2008/08/28 00:05:29 aclement Exp $ + * @author M. Dahm + * @see SWITCH + */ +public class TABLESWITCH extends InstructionSelect { + + /** + * @param match sorted array of match values, match[0] must be low value, match[match_length - 1] high value + * @param targets where to branch for matched values + * @param target default branch + */ + public TABLESWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target) { + super(org.aspectj.apache.bcel.Constants.TABLESWITCH, match, targets, target); + + // if (match_length==0) { + // throw new RuntimeException("A tableswitch with no targets should be represented as a LOOKUPSWITCH"); + // } + + // Alignment remainder assumed 0 here, until dump time + length = (short) (13 + matchLength * 4); + fixedLength = length; + } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + public void dump(DataOutputStream out) throws IOException { + super.dump(out); + + int low = matchLength > 0 ? match[0] : 0; + out.writeInt(low); + + int high = matchLength > 0 ? match[matchLength - 1] : 0; + out.writeInt(high); + + // See aj bug pr104720 + // if (match_length==0) out.writeInt(0); // following the switch you need to supply "HIGH-LOW+1" entries + + for (int i = 0; i < matchLength; i++) { + out.writeInt(indices[i] = getTargetOffset(targets[i])); + } + } + + /** + * Read needed data (e.g. index) from file. + */ + public TABLESWITCH(ByteSequence bytes) throws IOException { + super(Constants.TABLESWITCH, bytes); + + int low = bytes.readInt(); + int high = bytes.readInt(); + + matchLength = high - low + 1; + fixedLength = (short) (13 + matchLength * 4); + length = (short) (fixedLength + padding); + + match = new int[matchLength]; + indices = new int[matchLength]; + targets = new InstructionHandle[matchLength]; + + for (int i = low; i <= high; i++) { + match[i - low] = i; + } + + for (int i = 0; i < matchLength; i++) { + indices[i] = bytes.readInt(); + } + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Tag.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Tag.java new file mode 100644 index 000000000..1d6935e6d --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Tag.java @@ -0,0 +1,45 @@ +/* ******************************************************************* + * Copyright (c) 2002 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * Andy Clement pushed down into bcel module + * ******************************************************************/ + +package org.aspectj.apache.bcel.generic; + +/** + * A tag is an instruction-targeter that does not remember its target. Instruction handles will maintain a list of targeters but + * there won't be a way to get back from the tag to the instruction. Maintaining these backward/forward links just slows everything + * down. + */ +public abstract class Tag implements InstructionTargeter, Cloneable { + + public Tag() { + } + + // ---- from InstructionTargeter + public boolean containsTarget(InstructionHandle ih) { + return false; + } + + public void updateTarget(InstructionHandle oldHandle, InstructionHandle newHandle) { + oldHandle.removeTargeter(this); + if (newHandle != null) { + newHandle.addTargeter(this); + } + } + + public Tag copy() { + try { + return (Tag) clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeException("Sanity check, can't clone me"); + } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TargetLostException.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TargetLostException.java new file mode 100644 index 000000000..3a195705c --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TargetLostException.java @@ -0,0 +1,101 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Thrown by InstructionList.remove() when one or multiple disposed instruction + * are still being referenced by a InstructionTargeter object. I.e. the + * InstructionTargeter has to be notified that (one of) the InstructionHandle it + * is referencing is being removed from the InstructionList and thus not valid anymore. + * + * Making this an exception instead of a return value forces the user to handle + * these case explicitely in a try { ... } catch. The following code illustrates + * how this may be done: + * + *
+ *     ...
+ *     try {
+ *	il.delete(start_ih, end_ih);
+ *     } catch(TargetLostException e) {
+ *       InstructionHandle[] targets = e.getTargets();
+ *	 for(int i=0; i < targets.length; i++) {
+ *	   InstructionTargeter[] targeters = targets[i].getTargeters();
+ *     
+ *	   for(int j=0; j < targeters.length; j++)
+ *	     targeters[j].updateTarget(targets[i], new_target);
+ *       }
+ *     }
+ * 
+ * + * @see InstructionHandle + * @see InstructionList + * @see InstructionTargeter + * @version $Id: TargetLostException.java,v 1.3 2008/05/28 23:52:55 aclement Exp $ + * @author M. Dahm + */ +// OPTIMIZE make unchecked, or get rid of it! +public final class TargetLostException extends Exception { + private InstructionHandle[] targets; + + TargetLostException(InstructionHandle[] t, String mesg) { + super(mesg); + targets = t; + } + + /** + * @return list of instructions still being targeted. + */ + public InstructionHandle[] getTargets() { return targets; } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Type.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Type.java new file mode 100644 index 000000000..9ce007b4f --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Type.java @@ -0,0 +1,508 @@ +package org.aspectj.apache.bcel.generic; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.ConstantsInitializer; +import org.aspectj.apache.bcel.classfile.ClassFormatException; +import org.aspectj.apache.bcel.classfile.Utility; + +/** + * Abstract super class for all possible java types, namely basic types such as int, object types like String and array types, e.g. + * int[] + * + * @version $Id: Type.java,v 1.14 2011/09/28 01:14:54 aclement Exp $ + * @author M. Dahm + * + * modified: AndyClement 2-mar-05: Removed unnecessary static and optimized + */ +public abstract class Type { + protected byte type; + protected String signature; + + /* Predefined constants */ + public static final BasicType VOID = new BasicType(Constants.T_VOID); + public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN); + public static final BasicType INT = new BasicType(Constants.T_INT); + public static final BasicType SHORT = new BasicType(Constants.T_SHORT); + public static final BasicType BYTE = new BasicType(Constants.T_BYTE); + public static final BasicType LONG = new BasicType(Constants.T_LONG); + public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE); + public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT); + public static final BasicType CHAR = new BasicType(Constants.T_CHAR); + public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); + public static final ObjectType STRING = new ObjectType("java.lang.String"); + public static final ArrayType OBJECT_ARRAY = new ArrayType("java.lang.Object",1); + public static final ArrayType STRING_ARRAY = new ArrayType("java.lang.String",1); + public static final ArrayType CLASS_ARRAY = new ArrayType("java.lang.Class",1); + public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); + public static final ObjectType STRINGBUILDER = new ObjectType("java.lang.StringBuilder"); + public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); + public static final ObjectType CLASS = new ObjectType("java.lang.Class"); + public static final ObjectType INTEGER = new ObjectType("java.lang.Integer"); + public static final ObjectType EXCEPTION = new ObjectType("java.lang.Exception"); + public static final ObjectType LIST = new ObjectType("java.util.List"); + public static final ObjectType ITERATOR = new ObjectType("java.util.Iterator"); + public static final Type[] NO_ARGS = new Type[0]; + public static final ReferenceType NULL = new ReferenceType() { + }; + public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, "") { + }; + public static final Type[] STRINGARRAY1 = new Type[] { STRING }; + public static final Type[] STRINGARRAY2 = new Type[] { STRING, STRING }; + public static final Type[] STRINGARRAY3 = new Type[] { STRING, STRING, STRING }; + public static final Type[] STRINGARRAY4 = new Type[] { STRING, STRING, STRING, STRING }; + public static final Type[] STRINGARRAY5 = new Type[] { STRING, STRING, STRING, STRING, STRING }; + public static final Type[] STRINGARRAY6 = new Type[] { STRING, STRING, STRING, STRING, STRING, STRING }; + public static final Type[] STRINGARRAY7 = new Type[] { STRING, STRING, STRING, STRING, STRING, STRING, STRING }; + + private static Map commonTypes = new HashMap(); + + static { + commonTypes.put(STRING.getSignature(), STRING); + commonTypes.put(THROWABLE.getSignature(), THROWABLE); + commonTypes.put(VOID.getSignature(), VOID); + commonTypes.put(BOOLEAN.getSignature(), BOOLEAN); + commonTypes.put(BYTE.getSignature(), BYTE); + commonTypes.put(SHORT.getSignature(), SHORT); + commonTypes.put(CHAR.getSignature(), CHAR); + commonTypes.put(INT.getSignature(), INT); + commonTypes.put(LONG.getSignature(), LONG); + commonTypes.put(DOUBLE.getSignature(), DOUBLE); + commonTypes.put(FLOAT.getSignature(), FLOAT); + commonTypes.put(CLASS.getSignature(), CLASS); + commonTypes.put(OBJECT.getSignature(), OBJECT); + commonTypes.put(STRING_ARRAY.getSignature(), STRING_ARRAY); + commonTypes.put(CLASS_ARRAY.getSignature(), CLASS_ARRAY); + commonTypes.put(OBJECT_ARRAY.getSignature(), OBJECT_ARRAY); + commonTypes.put(INTEGER.getSignature(), INTEGER); + commonTypes.put(EXCEPTION.getSignature(), EXCEPTION); + commonTypes.put(STRINGBUFFER.getSignature(), STRINGBUFFER); + commonTypes.put(STRINGBUILDER.getSignature(), STRINGBUILDER); + commonTypes.put(LIST.getSignature(), LIST); + commonTypes.put(ITERATOR.getSignature(), ITERATOR); + ConstantsInitializer.initialize(); // needs calling because it will not have run properly the first time + } + + protected Type(byte t, String s) { + type = t; + signature = s; + } + + public String getSignature() { + return signature; + } + + public byte getType() { + return type; + } + + /** + * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise) + */ + public int getSize() { + switch (type) { + case Constants.T_DOUBLE: + case Constants.T_LONG: + return 2; + case Constants.T_VOID: + return 0; + default: + return 1; + } + } + + /** + * @return Type string, e.g. 'int[]' + */ + @Override + public String toString() { + return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN))) ? signature : Utility + .signatureToString(signature, false); + } + + public static final Type getType(String signature) { + Type t = commonTypes.get(signature); + if (t != null) { + return t; + } + byte type = Utility.typeOfSignature(signature); + if (type <= Constants.T_VOID) { + return BasicType.getType(type); + } else if (type == Constants.T_ARRAY) { + int dim = 0; + do { + dim++; + } while (signature.charAt(dim) == '['); + // Recurse, but just once, if the signature is ok + Type componentType = getType(signature.substring(dim)); + return new ArrayType(componentType, dim); + } else { // type == T_REFERENCE + // generics awareness + int nextAngly = signature.indexOf('<'); + // Format is 'Lblahblah;' + int index = signature.indexOf(';'); // Look for closing ';' + + String typeString = null; + if (nextAngly == -1 || nextAngly > index) { + typeString = signature.substring(1, index).replace('/', '.'); + } else { + boolean endOfSigReached = false; + int posn = nextAngly; + int genericDepth = 0; + while (!endOfSigReached) { + switch (signature.charAt(posn++)) { + case '<': + genericDepth++; + break; + case '>': + genericDepth--; + break; + case ';': + if (genericDepth == 0) { + endOfSigReached = true; + } + break; + default: + } + } + index = posn - 1; + typeString = signature.substring(1, nextAngly).replace('/', '.'); + } + // ObjectType doesn't currently store parameterized info + return new ObjectType(typeString); + } + } + + /** + * Convert signature to a Type object. + * + * @param signature signature string such as Ljava/lang/String; + * @return type object + */ + public static final TypeHolder getTypeInternal(String signature) throws StringIndexOutOfBoundsException { + byte type = Utility.typeOfSignature(signature); + + if (type <= Constants.T_VOID) { + return new TypeHolder(BasicType.getType(type), 1); + } else if (type == Constants.T_ARRAY) { + int dim = 0; + do { + dim++; + } while (signature.charAt(dim) == '['); + // Recurse, but just once, if the signature is ok + TypeHolder th = getTypeInternal(signature.substring(dim)); + return new TypeHolder(new ArrayType(th.getType(), dim), dim + th.getConsumed()); + } else { // type == T_REFERENCE + // Format is 'Lblahblah;' + int index = signature.indexOf(';'); // Look for closing ';' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + + // generics awareness + int nextAngly = signature.indexOf('<'); + String typeString = null; + if (nextAngly == -1 || nextAngly > index) { + typeString = signature.substring(1, index).replace('/', '.'); + } else { + boolean endOfSigReached = false; + int posn = nextAngly; + int genericDepth = 0; + while (!endOfSigReached) { + switch (signature.charAt(posn++)) { + case '<': + genericDepth++; + break; + case '>': + genericDepth--; + break; + case ';': + if (genericDepth == 0) { + endOfSigReached = true; + } + break; + default: + } + } + index = posn - 1; + typeString = signature.substring(1, nextAngly).replace('/', '.'); + } + // ObjectType doesn't currently store parameterized info + return new TypeHolder(new ObjectType(typeString), index + 1); + } + } + + /** + * Convert return value of a method (signature) to a Type object. + * + * @param signature signature string such as (Ljava/lang/String;)V + * @return return type + */ + public static Type getReturnType(String signature) { + try { + // Read return type after ')' + int index = signature.lastIndexOf(')') + 1; + return getType(signature.substring(index)); + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature); + } + } + + /** + * Convert arguments of a method (signature) to an array of Type objects. + * + * @param signature signature string such as (Ljava/lang/String;)V + * @return array of argument types + */ + // OPTIMIZE crap impl + public static Type[] getArgumentTypes(String signature) { + List argumentTypes = new ArrayList(); + int index; + Type[] types; + + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + + index = 1; // current string position + + while (signature.charAt(index) != ')') { + TypeHolder th = getTypeInternal(signature.substring(index)); + argumentTypes.add(th.getType()); + index += th.getConsumed(); // update position + } + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature); + } + + types = new Type[argumentTypes.size()]; + argumentTypes.toArray(types); + return types; + } + + /** + * Work out the type of each argument in the signature and return the cumulative sizes of all the types (size means number of + * stack slots it consumes, eg double=2, int=1). Unlike the call above, this does minimal unpacking + */ + public static int getArgumentSizes(String signature) { + int size = 0; + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + + int index = 1; // current string position + try { + while (signature.charAt(index) != ')') { + byte type = Utility.typeOfSignature(signature.charAt(index)); + if (type <= Constants.T_VOID) { + size += BasicType.getType(type).getSize(); + index++; + } else if (type == Constants.T_ARRAY) { + int dim = 0; + do { + dim++; + } while (signature.charAt(dim + index) == '['); + TypeHolder th = getTypeInternal(signature.substring(dim + index)); + size += 1; + index += dim + th.getConsumed(); + } else { // type == T_REFERENCE + // Format is 'Lblahblah;' + int index2 = signature.indexOf(';', index); // Look for closing ';' + + // generics awareness + int nextAngly = signature.indexOf('<', index); + if (nextAngly == -1 || nextAngly > index2) { + } else { + boolean endOfSigReached = false; + int posn = nextAngly; + int genericDepth = 0; + while (!endOfSigReached) { + switch (signature.charAt(posn++)) { + case '<': + genericDepth++; + break; + case '>': + genericDepth--; + break; + case ';': + if (genericDepth == 0) { + endOfSigReached = true; + } + break; + default: + } + } + index2 = posn - 1; + } + size++; + index = index2 + 1; + } + } + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature); + } + return size; + } + + /** + * Return the size of the type expressed in the signature. The signature should contain only one type. + */ + public static int getTypeSize(String signature) { + byte type = Utility.typeOfSignature(signature.charAt(0)); + if (type <= Constants.T_VOID) { + return BasicType.getType(type).getSize(); + } else if (type == Constants.T_ARRAY) { + return 1; + } else { // type == T_REFERENCE + return 1; + } + } + + /** + * Convert runtime java.lang.Class to BCEL Type object. + * + * @param cl Java class + * @return corresponding Type object + */ + public static Type getType(java.lang.Class cl) { + if (cl == null) { + throw new IllegalArgumentException("Class must not be null"); + } + + /* + * That's an amazingly easy case, because getName() returns the signature. That's what we would have liked anyway. + */ + if (cl.isArray()) { + return getType(cl.getName()); + } else if (cl.isPrimitive()) { + if (cl == Integer.TYPE) { + return INT; + } else if (cl == Void.TYPE) { + return VOID; + } else if (cl == Double.TYPE) { + return DOUBLE; + } else if (cl == Float.TYPE) { + return FLOAT; + } else if (cl == Boolean.TYPE) { + return BOOLEAN; + } else if (cl == Byte.TYPE) { + return BYTE; + } else if (cl == Short.TYPE) { + return SHORT; + } else if (cl == Byte.TYPE) { + return BYTE; + } else if (cl == Long.TYPE) { + return LONG; + } else if (cl == Character.TYPE) { + return CHAR; + } else { + throw new IllegalStateException("Ooops, what primitive type is " + cl); + } + } else { // "Real" class + return new ObjectType(cl.getName()); + } + } + + public static String getSignature(java.lang.reflect.Method meth) { + StringBuffer sb = new StringBuffer("("); + Class[] params = meth.getParameterTypes(); // avoid clone + + for (int j = 0; j < params.length; j++) { + sb.append(getType(params[j]).getSignature()); + } + + sb.append(")"); + sb.append(getType(meth.getReturnType()).getSignature()); + return sb.toString(); + } + + public static String getSignature(java.lang.reflect.Constructor cons) { + StringBuffer sb = new StringBuffer("("); + Class[] params = cons.getParameterTypes(); // avoid clone + + for (int j = 0; j < params.length; j++) { + sb.append(getType(params[j]).getSignature()); + } + + sb.append(")V"); + return sb.toString(); + } + + public static class TypeHolder { + private Type t; + private int consumed; + + public Type getType() { + return t; + } + + public int getConsumed() { + return consumed; + } + + public TypeHolder(Type t, int i) { + this.t = t; + this.consumed = i; + } + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ByteSequence.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ByteSequence.java new file mode 100644 index 000000000..072a7ba52 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ByteSequence.java @@ -0,0 +1,82 @@ +package org.aspectj.apache.bcel.util; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.*; + +/** + * Utility class that implements a sequence of bytes which can be read + * via the `readByte()' method. This is used to implement a wrapper for the + * Java byte code stream to gain some more readability. + * + * @version $Id: ByteSequence.java,v 1.3 2008/05/28 23:52:53 aclement Exp $ + * @author M. Dahm + */ +public final class ByteSequence extends DataInputStream { + private ByteArrayStream byte_stream; + + public ByteSequence(byte[] bytes) { + super(new ByteArrayStream(bytes)); + byte_stream = (ByteArrayStream)in; + } + + public final int getIndex() { return byte_stream.getPosition(); } + final void unreadByte() { byte_stream.unreadByte(); } + + private static final class ByteArrayStream extends ByteArrayInputStream { + ByteArrayStream(byte[] bytes) { super(bytes); } + final int getPosition() { return pos; } // is protected in ByteArrayInputStream + final void unreadByte() { if(pos > 0) pos--; } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderReference.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderReference.java new file mode 100644 index 000000000..f6fcbf5f8 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderReference.java @@ -0,0 +1,67 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.aspectj.apache.bcel.util; + +/** + * Implementors should provide access to a ClassLoader instance. The reference can be passed around and cached + * but will not cause the code that caches it to have a hard reference to the classloader, so it is easier + * to manage the classloader instance. The default implementation will just wrap a classloader object but + * more sophisticated implementations could keep a WeakReference to the loader. + */ +public interface ClassLoaderReference { + + java.lang.ClassLoader getClassLoader(); + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderRepository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderRepository.java new file mode 100644 index 000000000..e3c59556b --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderRepository.java @@ -0,0 +1,394 @@ +package org.aspectj.apache.bcel.util; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.IOException; +import java.io.InputStream; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.AbstractMap; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; + +import org.aspectj.apache.bcel.classfile.ClassParser; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.ClassLoaderRepository.SoftHashMap.SpecialValue; + +/** + * The repository maintains information about which classes have been loaded. + * + * It loads its data from the ClassLoader implementation passed into its constructor. + * + * @see org.aspectj.apache.bcel.Repository + * + * @version $Id: ClassLoaderRepository.java,v 1.13 2009/09/09 19:56:20 aclement Exp $ + * @author M. Dahm + * @author David Dixon-Peugh + */ +public class ClassLoaderRepository implements Repository { + private static java.lang.ClassLoader bootClassLoader = null; + private ClassLoaderReference loaderRef; + + // Choice of cache... + private WeakHashMap> localCache = new WeakHashMap>(); + private static SoftHashMap /* */sharedCache = new SoftHashMap(Collections.synchronizedMap(new HashMap())); + + // For fast translation of the classname *intentionally not static* + private SoftHashMap /* */nameMap = new SoftHashMap(new HashMap(), false); + + public static boolean useSharedCache = System.getProperty("org.aspectj.apache.bcel.useSharedCache", "true").equalsIgnoreCase("true"); + + private static int cacheHitsShared = 0; + private static int missSharedEvicted = 0; // Misses in shared cache access due to reference GC + private long timeManipulatingURLs = 0L; + private long timeSpentLoading = 0L; + private int classesLoadedCount = 0; + private int misses = 0; + private int cacheHitsLocal = 0; + private int missLocalEvicted = 0; // Misses in local cache access due to reference GC + + public ClassLoaderRepository(java.lang.ClassLoader loader) { + this.loaderRef = new DefaultClassLoaderReference((loader != null) ? loader : getBootClassLoader()); + } + + public ClassLoaderRepository(ClassLoaderReference loaderRef) { + this.loaderRef = loaderRef; + } + + private static synchronized java.lang.ClassLoader getBootClassLoader() { + if (bootClassLoader == null) { + bootClassLoader = new URLClassLoader(new URL[0]); + } + return bootClassLoader; + } + + // Can track back to its key + public static class SoftHashMap extends AbstractMap { + private Map map; + boolean recordMiss = true; // only interested in recording miss stats sometimes + private ReferenceQueue rq = new ReferenceQueue(); + + public SoftHashMap(Map map) { + this.map = map; + } + + public SoftHashMap() { + this(new HashMap()); + } + + public SoftHashMap(Map map, boolean b) { + this(map); + this.recordMiss = b; + } + + class SpecialValue extends SoftReference { + private final Object key; + + SpecialValue(Object k, Object v) { + super(v, rq); + this.key = k; + } + } + + private void processQueue() { + SpecialValue sv = null; + while ((sv = (SpecialValue) rq.poll()) != null) { + map.remove(sv.key); + } + } + + @Override + public Object get(Object key) { + SpecialValue value = map.get(key); + if (value == null) + return null; + if (value.get() == null) { + // it got GC'd + map.remove(value.key); + if (recordMiss) + missSharedEvicted++; + return null; + } else { + return value.get(); + } + } + + @Override + public Object put(Object k, Object v) { + processQueue(); + return map.put(k, new SpecialValue(k, v)); + } + + @Override + public Set entrySet() { + return map.entrySet(); + } + + @Override + public void clear() { + processQueue(); + map.clear(); + } + + @Override + public int size() { + processQueue(); + return map.size(); + } + + @Override + public Object remove(Object k) { + processQueue(); + SpecialValue value = map.remove(k); + if (value == null) + return null; + if (value.get() != null) { + return value.get(); + } + return null; + } + } + + /** + * Store a new JavaClass into this repository as a soft reference and return the reference + */ + private void storeClassAsReference(URL url, JavaClass clazz) { + if (useSharedCache) { + clazz.setRepository(null); // can't risk setting repository, we'll get in a pickle! + sharedCache.put(url, clazz); + } else { + clazz.setRepository(this); + localCache.put(url, new SoftReference(clazz)); + } + } + + /** + * Store a new JavaClass into this Repository. + */ + public void storeClass(JavaClass clazz) { + storeClassAsReference(toURL(clazz.getClassName()), clazz); + } + + /** + * Remove class from repository + */ + public void removeClass(JavaClass clazz) { + if (useSharedCache) + sharedCache.remove(toURL(clazz.getClassName())); + else + localCache.remove(toURL(clazz.getClassName())); + } + + /** + * Find an already defined JavaClass in the local cache. + */ + public JavaClass findClass(String className) { + if (useSharedCache) + return findClassShared(toURL(className)); + else + return findClassLocal(toURL(className)); + } + + private JavaClass findClassLocal(URL url) { + Object o = localCache.get(url); + if (o != null) { + o = ((Reference) o).get(); + if (o != null) { + return (JavaClass) o; + } else { + missLocalEvicted++; + } + } + return null; + } + + /** + * Find an already defined JavaClass in the shared cache. + */ + private JavaClass findClassShared(URL url) { + return (JavaClass) sharedCache.get(url); + } + + private URL toURL(String className) { + URL url = (URL) nameMap.get(className); + if (url == null) { + String classFile = className.replace('.', '/'); + url = loaderRef.getClassLoader().getResource(classFile + ".class"); + nameMap.put(className, url); + } + return url; + } + + /** + * Lookup a JavaClass object from the Class Name provided. + */ + public JavaClass loadClass(String className) throws ClassNotFoundException { + + // translate to a URL + long time = System.currentTimeMillis(); + java.net.URL url = toURL(className); + timeManipulatingURLs += (System.currentTimeMillis() - time); + if (url == null) + throw new ClassNotFoundException(className + " not found - unable to determine URL"); + + JavaClass clazz = null; + + // Look in the appropriate cache + if (useSharedCache) { + clazz = findClassShared(url); + if (clazz != null) { + cacheHitsShared++; + return clazz; + } + } else { + clazz = findClassLocal(url); + if (clazz != null) { + cacheHitsLocal++; + return clazz; + } + } + + // Didn't find it in either cache + misses++; + + try { + // Load it + String classFile = className.replace('.', '/'); + InputStream is = (useSharedCache ? url.openStream() : loaderRef.getClassLoader().getResourceAsStream( + classFile + ".class")); + if (is == null) { + throw new ClassNotFoundException(className + " not found using url " + url); + } + ClassParser parser = new ClassParser(is, className); + clazz = parser.parse(); + + // Cache it + storeClassAsReference(url, clazz); + + timeSpentLoading += (System.currentTimeMillis() - time); + classesLoadedCount++; + return clazz; + } catch (IOException e) { + throw new ClassNotFoundException(e.toString()); + } + } + + /** + * Produce a report on cache usage. + */ + public String report() { + StringBuffer sb = new StringBuffer(); + sb.append("BCEL repository report."); + if (useSharedCache) + sb.append(" (shared cache)"); + else + sb.append(" (local cache)"); + sb.append(" Total time spent loading: " + timeSpentLoading + "ms."); + sb.append(" Time spent manipulating URLs: " + timeManipulatingURLs + "ms."); + sb.append(" Classes loaded: " + classesLoadedCount + "."); + if (useSharedCache) { + sb.append(" Shared cache size: " + sharedCache.size()); + sb.append(" Shared cache (hits/missDueToEviction): (" + cacheHitsShared + "/" + missSharedEvicted + ")."); + } else { + sb.append(" Local cache size: " + localCache.size()); + sb.append(" Local cache (hits/missDueToEviction): (" + cacheHitsLocal + "/" + missLocalEvicted + ")."); + } + return sb.toString(); + } + + /** + * Returns an array of the stats, for testing, the order is fixed: 0=time spent loading (static) 1=time spent manipulating URLs + * (static) 2=classes loaded (static) 3=cache hits shared (static) 4=misses in shared due to eviction (static) 5=cache hits + * local 6=misses in local due to eviction 7=shared cache size + */ + public long[] reportStats() { + return new long[] { timeSpentLoading, timeManipulatingURLs, classesLoadedCount, cacheHitsShared, missSharedEvicted, + cacheHitsLocal, missLocalEvicted, sharedCache.size() }; + } + + /** + * Reset statistics and clear all caches + */ + public void reset() { + timeManipulatingURLs = 0L; + timeSpentLoading = 0L; + classesLoadedCount = 0; + cacheHitsLocal = 0; + cacheHitsShared = 0; + missSharedEvicted = 0; + missLocalEvicted = 0; + misses = 0; + clear(); + } + + public JavaClass loadClass(Class clazz) throws ClassNotFoundException { + return loadClass(clazz.getName()); + } + + /** Clear all entries from the local cache */ + public void clear() { + if (useSharedCache) + sharedCache.clear(); + else + localCache.clear(); + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassPath.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassPath.java new file mode 100644 index 000000000..b7db332d2 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassPath.java @@ -0,0 +1,584 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001, 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.util; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URI; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * Responsible for loading (class) files from the CLASSPATH. Inspired by + * sun.tools.ClassPath. + * + * @author M. Dahm + * @author Mario Ivankovits + * @author Andy Clement + */ +public class ClassPath implements Serializable { + private static final String JRT_FS = "jrt-fs.jar"; + + private static ClassPath SYSTEM_CLASS_PATH = null; + + private PathEntry[] paths; + private String class_path; + + public static ClassPath getSystemClassPath() { + if (SYSTEM_CLASS_PATH == null) { + SYSTEM_CLASS_PATH = new ClassPath(); + } + return SYSTEM_CLASS_PATH; + } + + /** + * Search for classes in given path. + */ + public ClassPath(String class_path) { + this.class_path = class_path; + + ArrayList vec = new ArrayList(); + + for (StringTokenizer tok = new StringTokenizer(class_path, System.getProperty("path.separator")); tok + .hasMoreTokens();) { + String path = tok.nextToken(); + + if (!path.equals("")) { + File file = new File(path); + + try { + if (file.exists()) { + if (file.isDirectory()) { + vec.add(new Dir(path)); + } else if (file.getName().endsWith("jrt-fs.jar")) { // TODO a bit crude... + vec.add(new JImage()); + } else { + vec.add(new Zip(new ZipFile(file))); + } + } + } catch (IOException e) { + System.err.println("CLASSPATH component " + file + ": " + e); + } + } + } + + paths = new PathEntry[vec.size()]; + vec.toArray(paths); + } + + /** + * Search for classes in CLASSPATH. + * + * @deprecated Use SYSTEM_CLASS_PATH constant + */ + @Deprecated + public ClassPath() { + this(getClassPath()); + } + + /** + * @return used class path string + */ + @Override + public String toString() { + return class_path; + } + + @Override + public int hashCode() { + return class_path.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof ClassPath) { + return class_path.equals(((ClassPath) o).class_path); + } + + return false; + } + + private static final void getPathComponents(String path, ArrayList list) { + if (path != null) { + StringTokenizer tok = new StringTokenizer(path, File.pathSeparator); + + while (tok.hasMoreTokens()) { + String name = tok.nextToken(); + File file = new File(name); + + if (file.exists()) + list.add(name); + } + } + } + + /** + * Checks for class path components in the following properties: + * "java.class.path", "sun.boot.class.path", "java.ext.dirs" + * + * @return class path as used by default by BCEL + */ + public static final String getClassPath() { + String class_path = System.getProperty("java.class.path"); + String boot_path = System.getProperty("sun.boot.class.path"); + String ext_path = System.getProperty("java.ext.dirs"); + String vm_version = System.getProperty("java.version"); + + ArrayList list = new ArrayList(); + + getPathComponents(class_path, list); + getPathComponents(boot_path, list); + + ArrayList dirs = new ArrayList(); + getPathComponents(ext_path, dirs); + + for (Iterator e = dirs.iterator(); e.hasNext();) { + File ext_dir = new File(e.next()); + String[] extensions = ext_dir.list(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + name = name.toLowerCase(); + return name.endsWith(".zip") || name.endsWith(".jar"); + } + }); + + if (extensions != null) + for (int i = 0; i < extensions.length; i++) + list.add(ext_path + File.separatorChar + extensions[i]); + } + + StringBuffer buf = new StringBuffer(); + + for (Iterator e = list.iterator(); e.hasNext();) { + buf.append(e.next()); + + if (e.hasNext()) + buf.append(File.pathSeparatorChar); + } + + // On Java9 the sun.boot.class.path won't be set. System classes accessible through JRT filesystem + if (vm_version.startsWith("9") || vm_version.startsWith("10") || vm_version.startsWith("11")) { + buf.insert(0, File.pathSeparatorChar); + buf.insert(0, System.getProperty("java.home") + File.separator + "lib" + File.separator + JRT_FS); + } + + return buf.toString().intern(); + } + + /** + * @param name + * fully qualified class name, e.g. java.lang.String + * @return input stream for class + */ + public InputStream getInputStream(String name) throws IOException { + return getInputStream(name, ".class"); + } + + /** + * Return stream for class or resource on CLASSPATH. + * + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suff, e.g. .java + * @return input stream for file on class path + */ + public InputStream getInputStream(String name, String suffix) throws IOException { + InputStream is = null; + + try { + is = getClass().getClassLoader().getResourceAsStream(name + suffix); + } catch (Exception e) { + } + + if (is != null) + return is; + + return getClassFile(name, suffix).getInputStream(); + } + + /** + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suff, e.g. .java + * @return class file for the java class + */ + public ClassFile getClassFile(String name, String suffix) throws IOException { + for (int i = 0; i < paths.length; i++) { + ClassFile cf; + + if ((cf = paths[i].getClassFile(name, suffix)) != null) + return cf; + } + + throw new IOException("Couldn't find: " + name + suffix); + } + + /** + * @param name + * fully qualified class name, e.g. java.lang.String + * @return input stream for class + */ + public ClassFile getClassFile(String name) throws IOException { + return getClassFile(name, ".class"); + } + + /** + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suffix, e.g. .java + * @return byte array for file on class path + */ + public byte[] getBytes(String name, String suffix) throws IOException { + InputStream is = getInputStream(name, suffix); + + if (is == null) + throw new IOException("Couldn't find: " + name + suffix); + + DataInputStream dis = new DataInputStream(is); + byte[] bytes = new byte[is.available()]; + dis.readFully(bytes); + dis.close(); + is.close(); + + return bytes; + } + + /** + * @return byte array for class + */ + public byte[] getBytes(String name) throws IOException { + return getBytes(name, ".class"); + } + + /** + * @param name + * name of file to search for, e.g. java/lang/String.java + * @return full (canonical) path for file + */ + public String getPath(String name) throws IOException { + int index = name.lastIndexOf('.'); + String suffix = ""; + + if (index > 0) { + suffix = name.substring(index); + name = name.substring(0, index); + } + + return getPath(name, suffix); + } + + /** + * @param name + * name of file to search for, e.g. java/lang/String + * @param suffix + * file name suffix, e.g. .java + * @return full (canonical) path for file, if it exists + */ + public String getPath(String name, String suffix) throws IOException { + return getClassFile(name, suffix).getPath(); + } + + private static abstract class PathEntry implements Serializable { + abstract ClassFile getClassFile(String name, String suffix) throws IOException; + } + + /** + * Contains information about file/ZIP entry of the Java class. + */ + public interface ClassFile { + /** + * @return input stream for class file. + */ + public abstract InputStream getInputStream() throws IOException; + + /** + * @return canonical path to class file. + */ + public abstract String getPath(); + + /** + * @return base path of found class, i.e. class is contained relative to + * that path, which may either denote a directory, or zip file + */ + public abstract String getBase(); + + /** + * @return modification time of class file. + */ + public abstract long getTime(); + + /** + * @return size of class file. + */ + public abstract long getSize(); + } + + private static class Dir extends PathEntry { + private String dir; + + Dir(String d) { + dir = d; + } + + @Override + ClassFile getClassFile(String name, String suffix) throws IOException { + final File file = new File(dir + File.separatorChar + name.replace('.', File.separatorChar) + suffix); + + return file.exists() ? new ClassFile() { + @Override + public InputStream getInputStream() throws IOException { + return new FileInputStream(file); + } + + @Override + public String getPath() { + try { + return file.getCanonicalPath(); + } catch (IOException e) { + return null; + } + + } + + @Override + public long getTime() { + return file.lastModified(); + } + + @Override + public long getSize() { + return file.length(); + } + + @Override + public String getBase() { + return dir; + } + + } : null; + } + + @Override + public String toString() { + return dir; + } + } + + private static class JImage extends PathEntry { + + private static URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$ + private static String MODULES_PATH = "modules"; //$NON-NLS-1$ + private static String JAVA_BASE_PATH = "java.base"; //$NON-NLS-1$ + + private java.nio.file.FileSystem fs; + private final Map fileMap; + + JImage() { + fs = FileSystems.getFileSystem(JRT_URI); + fileMap = buildFileMap(); + } + + private Map buildFileMap() { + final Map fileMap = new HashMap<>(); + final java.nio.file.PathMatcher matcher = fs.getPathMatcher("glob:*.class"); + Iterable roots = fs.getRootDirectories(); + for (java.nio.file.Path path : roots) { + try { + Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (file.getNameCount() > 2 + && matcher.matches(file.getFileName())) { + Path classPath = file.subpath(2, file.getNameCount()); + fileMap.put(classPath.toString(), file); + } + + return FileVisitResult.CONTINUE; + } + }); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + return fileMap; + } + + private static class ByteBasedClassFile implements ClassFile { + + private byte[] bytes; + private ByteArrayInputStream bais; + private String path; + private String base; + private long time; + private long size; + + public ByteBasedClassFile(byte[] bytes, String path, String base, long time, long size) { + this.bytes = bytes; + this.path = path; + this.base = base; + this.time = time; + this.size = size; + } + + @Override + public InputStream getInputStream() throws IOException { + // TODO too costly to keep these in inflated form in memory? + this.bais = new ByteArrayInputStream(bytes); + return this.bais; + } + + @Override + public String getPath() { + return this.path; + } + + @Override + public String getBase() { + return this.base; + } + + @Override + public long getTime() { + return this.time; + } + + @Override + public long getSize() { + return this.size; + } + + } + + @Override + ClassFile getClassFile(String name, String suffix) throws IOException { + // Class files are in here under names like this: + // /modules/java.base/java/lang/Object.class (jdk9 b74) + // so within a modules top level qualifier and then the java.base module + String fileName = name.replace('.', '/') + suffix; + Path p = fileMap.get(fileName); + if (p == null) { + return null; + } + byte[] bs = Files.readAllBytes(p); + BasicFileAttributeView bfav = Files.getFileAttributeView(p, BasicFileAttributeView.class); + BasicFileAttributes bfas = bfav.readAttributes(); + long time = bfas.lastModifiedTime().toMillis(); + long size = bfas.size(); + ClassFile cf = new ByteBasedClassFile(bs, "jimage",fileName,time,size); + return cf; + } + } + + private static class Zip extends PathEntry { + private ZipFile zip; + + Zip(ZipFile z) { + zip = z; + } + + @Override + ClassFile getClassFile(String name, String suffix) throws IOException { + final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix); + + return (entry != null) ? new ClassFile() { + @Override + public InputStream getInputStream() throws IOException { + return zip.getInputStream(entry); + } + + @Override + public String getPath() { + return entry.toString(); + } + + @Override + public long getTime() { + return entry.getTime(); + } + + @Override + public long getSize() { + return entry.getSize(); + } + + @Override + public String getBase() { + return zip.getName(); + } + } : null; + } + } +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java new file mode 100644 index 000000000..259991308 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java @@ -0,0 +1,75 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.aspectj.apache.bcel.util; + +/** + * Simplistic ClassLoaderReference that merely delegates to a classloader. More sophisticated ones could allow for the + * loader to be weakly referenced. + * + * @author Andy Clement + */ +public class DefaultClassLoaderReference implements ClassLoaderReference { + + private java.lang.ClassLoader loader; + + public DefaultClassLoaderReference(java.lang.ClassLoader classLoader) { + this.loader = classLoader; + } + + public java.lang.ClassLoader getClassLoader() { + return loader; + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java new file mode 100644 index 000000000..a53b9dc35 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java @@ -0,0 +1,268 @@ +package org.aspectj.apache.bcel.util; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.IOException; +import java.io.InputStream; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.aspectj.apache.bcel.classfile.ClassParser; +import org.aspectj.apache.bcel.classfile.JavaClass; + +/** + * The repository maintains information about which classes have been loaded. + * + * It loads its data from the ClassLoader implementation passed into its constructor. + * + * @see org.aspectj.apache.bcel.Repository + * + * @version $Id: NonCachingClassLoaderRepository.java,v 1.6 2009/09/09 19:56:20 aclement Exp $ + * @author M. Dahm + * @author David Dixon-Peugh + * + */ +public class NonCachingClassLoaderRepository implements Repository { + private static java.lang.ClassLoader bootClassLoader = null; + + private final ClassLoaderReference loaderRef; + private final Map loadedClasses = new SoftHashMap(); + + public static class SoftHashMap extends AbstractMap { + private Map map; + private ReferenceQueue rq = new ReferenceQueue(); + + public SoftHashMap(Map map) { + this.map = map; + } + + public SoftHashMap() { + this(new HashMap()); + } + + public SoftHashMap(Map map, boolean b) { + this(map); + } + + class SpecialValue extends SoftReference { + private final Object key; + + SpecialValue(Object k, Object v) { + super(v, rq); + this.key = k; + } + } + + private void processQueue() { + SpecialValue sv = null; + while ((sv = (SpecialValue) rq.poll()) != null) { + map.remove(sv.key); + } + } + + @Override + public Object get(Object key) { + SpecialValue value = map.get(key); + if (value == null) + return null; + if (value.get() == null) { + // it got GC'd + map.remove(value.key); + return null; + } else { + return value.get(); + } + } + + @Override + public Object put(Object k, Object v) { + processQueue(); + return map.put(k, new SpecialValue(k, v)); + } + + @Override + public Set entrySet() { + return map.entrySet(); + } + + @Override + public void clear() { + processQueue(); + Set keys = map.keySet(); + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + Object name = iterator.next(); + map.remove(name); + } + } + + @Override + public int size() { + processQueue(); + return map.size(); + } + + @Override + public Object remove(Object k) { + processQueue(); + SpecialValue value = map.remove(k); + if (value == null) + return null; + if (value.get() != null) { + return value.get(); + } + return null; + } + } + + public NonCachingClassLoaderRepository(java.lang.ClassLoader loader) { + this.loaderRef = new DefaultClassLoaderReference((loader != null) ? loader : getBootClassLoader()); + } + + public NonCachingClassLoaderRepository(ClassLoaderReference loaderRef) { + this.loaderRef = loaderRef; + } + + private static synchronized java.lang.ClassLoader getBootClassLoader() { + if (bootClassLoader == null) { + bootClassLoader = new URLClassLoader(new URL[0]); + } + return bootClassLoader; + } + + /** + * Store a new JavaClass into this Repository. + */ + public void storeClass(JavaClass clazz) { + synchronized (loadedClasses) { + loadedClasses.put(clazz.getClassName(), clazz); + } + clazz.setRepository(this); + } + + /** + * Remove class from repository + */ + public void removeClass(JavaClass clazz) { + synchronized (loadedClasses) { + loadedClasses.remove(clazz.getClassName()); + } + } + + /** + * Find an already defined JavaClass. + */ + public JavaClass findClass(String className) { + synchronized (loadedClasses) { + if (loadedClasses.containsKey(className)) { + return loadedClasses.get(className); + } else { + return null; + } + } + } + + /** + * Clear all entries from cache. + */ + public void clear() { + synchronized (loadedClasses) { + loadedClasses.clear(); + } + } + + /** + * Lookup a JavaClass object from the Class Name provided. + */ + public JavaClass loadClass(String className) throws ClassNotFoundException { + + JavaClass javaClass = findClass(className); + if (javaClass != null) { + return javaClass; + } + + javaClass = loadJavaClass(className); + storeClass(javaClass); + + return javaClass; + } + + public JavaClass loadClass(Class clazz) throws ClassNotFoundException { + return loadClass(clazz.getName()); + } + + private JavaClass loadJavaClass(String className) throws ClassNotFoundException { + String classFile = className.replace('.', '/'); + try { + InputStream is = loaderRef.getClassLoader().getResourceAsStream(classFile + ".class"); + + if (is == null) { + throw new ClassNotFoundException(className + " not found."); + } + + ClassParser parser = new ClassParser(is, className); + return parser.parse(); + } catch (IOException e) { + throw new ClassNotFoundException(e.toString()); + } + } + +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/Repository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/Repository.java new file mode 100644 index 000000000..eea889e61 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/Repository.java @@ -0,0 +1,98 @@ +package org.aspectj.apache.bcel.util; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import org.aspectj.apache.bcel.classfile.JavaClass; + +/** + * Abstract definition of a class repository. Instances may be used to load classes from different sources and may be used in the + * Repository.setRepository method. + * + * @see org.aspectj.apache.bcel.Repository + * @version $Id: Repository.java,v 1.5 2009/09/09 19:56:20 aclement Exp $ + * @author M. Dahm + * @author David Dixon-Peugh + */ +public interface Repository { + /** + * Store the provided class under "clazz.getClassName()" + */ + public void storeClass(JavaClass clazz); + + /** + * Remove class from repository + */ + public void removeClass(JavaClass clazz); + + /** + * Find the class with the name provided, if the class isn't there, return NULL. + */ + public JavaClass findClass(String className); + + /** + * Find the class with the name provided, if the class isn't there, make an attempt to load it. + */ + public JavaClass loadClass(String className) throws java.lang.ClassNotFoundException; + + /** + * Find the JavaClass instance for the given run-time class object + */ + public JavaClass loadClass(Class clazz) throws java.lang.ClassNotFoundException; + + /** + * Clear all entries from cache. + */ + public void clear(); +} diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/SyntheticRepository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/SyntheticRepository.java new file mode 100644 index 000000000..ea0e49216 --- /dev/null +++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/SyntheticRepository.java @@ -0,0 +1,195 @@ +package org.aspectj.apache.bcel.util; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.WeakHashMap; + +import org.aspectj.apache.bcel.classfile.ClassParser; +import org.aspectj.apache.bcel.classfile.JavaClass; + +/** + * This repository is used in situations where a Class is created outside the realm of a ClassLoader. Classes are loaded from the + * file systems using the paths specified in the given class path. By default, this is the value returned by + * ClassPath.getClassPath().
+ * It is designed to be used as a singleton, however it can also be used with custom classpaths. + * + * /** Abstract definition of a class repository. Instances may be used to load classes from different sources and may be used in + * the Repository.setRepository method. + * + * @see org.aspectj.apache.bcel.Repository + * + * @version $Id: SyntheticRepository.java,v 1.8 2009/09/09 19:56:20 aclement Exp $ + * @author M. Dahm + * @author David Dixon-Peugh + */ +public class SyntheticRepository implements Repository { + private static final String DEFAULT_PATH = ClassPath.getClassPath(); + + private static HashMap _instances = new HashMap(); // CLASSPATH + // X + // REPOSITORY + + private ClassPath _path = null; + private WeakHashMap _loadedClasses = new WeakHashMap(); // CLASSNAME X JAVACLASS + + private SyntheticRepository(ClassPath path) { + _path = path; + } + + public static SyntheticRepository getInstance() { + return getInstance(ClassPath.getSystemClassPath()); + } + + public static SyntheticRepository getInstance(ClassPath classPath) { + SyntheticRepository rep = _instances.get(classPath); + + if (rep == null) { + rep = new SyntheticRepository(classPath); + _instances.put(classPath, rep); + } + + return rep; + } + + /** + * Store a new JavaClass instance into this Repository. + */ + public void storeClass(JavaClass clazz) { + _loadedClasses.put(clazz.getClassName(), clazz); + clazz.setRepository(this); + } + + /** + * Remove class from repository + */ + public void removeClass(JavaClass clazz) { + _loadedClasses.remove(clazz.getClassName()); + } + + /** + * Find an already defined (cached) JavaClass object by name. + */ + public JavaClass findClass(String className) { + return _loadedClasses.get(className); + } + + /** + * Load a JavaClass object for the given class name using the CLASSPATH environment variable. + */ + public JavaClass loadClass(String className) throws ClassNotFoundException { + if (className == null || className.equals("")) { + throw new IllegalArgumentException("Invalid class name " + className); + } + + className = className.replace('/', '.'); // Just in case, canonical form + + try { + return loadClass(_path.getInputStream(className), className); + } catch (IOException e) { + throw new ClassNotFoundException("Exception while looking for class " + className + ": " + e.toString()); + } + } + + /** + * Try to find class source via getResourceAsStream(). + * + * @see Class + * @return JavaClass object for given runtime class + */ + public JavaClass loadClass(Class clazz) throws ClassNotFoundException { + String className = clazz.getName(); + String name = className; + int i = name.lastIndexOf('.'); + + if (i > 0) { + name = name.substring(i + 1); + } + + return loadClass(clazz.getResourceAsStream(name + ".class"), className); + } + + private JavaClass loadClass(InputStream is, String className) throws ClassNotFoundException { + JavaClass clazz = findClass(className); + + if (clazz != null) { + return clazz; + } + + try { + if (is != null) { + ClassParser parser = new ClassParser(is, className); + clazz = parser.parse(); + + storeClass(clazz); + + return clazz; + } + } catch (IOException e) { + throw new ClassNotFoundException("Exception while looking for class " + className + ": " + e.toString()); + } + + throw new ClassNotFoundException("SyntheticRepository could not load " + className); + } + + /** + * Clear all entries from cache. + */ + public void clear() { + _loadedClasses.clear(); + } +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/Constants.java b/bcel-builder/src/org/aspectj/apache/bcel/Constants.java deleted file mode 100644 index c75496527..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/Constants.java +++ /dev/null @@ -1,685 +0,0 @@ -package org.aspectj.apache.bcel; - -import org.aspectj.apache.bcel.generic.Type; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Constants for the project, mostly defined in the JVM specification. - * - * @author M. Dahm - * @author Andy Clement - */ -public interface Constants { - // Major and minor version of the code - public final static short MAJOR_1_1 = 45; - public final static short MINOR_1_1 = 3; - public final static short MAJOR_1_2 = 46; - public final static short MINOR_1_2 = 0; - public final static short MAJOR_1_3 = 47; - public final static short MINOR_1_3 = 0; - public final static short MAJOR_1_4 = 48; - public final static short MINOR_1_4 = 0; - public final static short MAJOR_1_5 = 49; - public final static short MINOR_1_5 = 0; - public final static short MAJOR_1_6 = 50; - public final static short MINOR_1_6 = 0; - public final static short MAJOR_1_7 = 51; - public final static short MINOR_1_7 = 0; - public final static short MAJOR_1_8 = 52; - public final static short MINOR_1_8 = 0; - public final static short MAJOR_1_9 = 53; - public final static short MINOR_1_9 = 0; - public final static short MAJOR_10 = 54; - public final static short MINOR_10 = 0; - public final static short MAJOR_11 = 55; - public final static short MINOR_11 = 0; - // Defaults - public final static short MAJOR = MAJOR_1_1; - public final static short MINOR = MINOR_1_1; - - /** Maximum value for an unsigned short */ - public final static int MAX_SHORT = 65535; // 2^16 - 1 - - /** Maximum value for an unsigned byte */ - public final static int MAX_BYTE = 255; // 2^8 - 1 - - /** Access flags for classes, fields and methods */ - public final static short ACC_PUBLIC = 0x0001; - public final static short ACC_PRIVATE = 0x0002; - public final static short ACC_PROTECTED = 0x0004; - public final static short ACC_STATIC = 0x0008; - - public final static short ACC_FINAL = 0x0010; - public final static short ACC_SYNCHRONIZED = 0x0020; - public final static short ACC_VOLATILE = 0x0040; - public final static short ACC_TRANSIENT = 0x0080; - - public final static short ACC_NATIVE = 0x0100; - public final static short ACC_INTERFACE = 0x0200; - public final static short ACC_ABSTRACT = 0x0400; - public final static short ACC_STRICT = 0x0800; - - public final static short ACC_SYNTHETIC = 0x1000; - - public final static short ACC_ANNOTATION = 0x2000; - public final static short ACC_ENUM = 0x4000; - public final static int ACC_MODULE = 0x8000; - public final static short ACC_BRIDGE = 0x0040; - public final static short ACC_VARARGS = 0x0080; - - // Module related - // Indicates that any module which depends on the current module, - // implicitly declares a dependence on the module indicated by this entry. - public final static int MODULE_ACC_TRANSITIVE = 0x0020; - // Indicates that this dependence is mandatory in the static phase, i.e., at - // compile time, but is optional in the dynamic phase, i.e., at run time. - public final static int MODULE_ACC_STATIC_PHASE = 0x0040; - // Indicates that this dependence was not explicitly or implicitly declared - // in the source of the module declaration. - public final static int MODULE_ACC_SYNTHETIC = 0x1000; - // Indicates that this dependence was implicitly declared in the source of - // the module declaration - public final static int MODULE_ACC_MANDATED = 0x8000; - - // Applies to classes compiled by new compilers only - public final static short ACC_SUPER = 0x0020; - - public final static short MAX_ACC_FLAG = ACC_STRICT; - - public final static String[] ACCESS_NAMES = { "public", "private", "protected", "static", "final", "synchronized", "volatile", - "transient", "native", "interface", "abstract", "strictfp" }; - - /** Tags in constant pool to denote type of constant */ - public final static byte CONSTANT_Utf8 = 1; - public final static byte CONSTANT_Integer = 3; - public final static byte CONSTANT_Float = 4; - public final static byte CONSTANT_Long = 5; - public final static byte CONSTANT_Double = 6; - public final static byte CONSTANT_Class = 7; - public final static byte CONSTANT_Fieldref = 9; - public final static byte CONSTANT_String = 8; - public final static byte CONSTANT_Methodref = 10; - public final static byte CONSTANT_InterfaceMethodref = 11; - public final static byte CONSTANT_NameAndType = 12; - - public final static byte CONSTANT_MethodHandle = 15; - public final static byte CONSTANT_MethodType = 16; - public final static byte CONSTANT_Dynamic = 17; - public final static byte CONSTANT_InvokeDynamic = 18; - - public final static byte CONSTANT_Module = 19; - public final static byte CONSTANT_Package = 20; - - - public final static String[] CONSTANT_NAMES = { "", "CONSTANT_Utf8", "", "CONSTANT_Integer", "CONSTANT_Float", "CONSTANT_Long", - "CONSTANT_Double", "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", "CONSTANT_Methodref", - "CONSTANT_InterfaceMethodref", "CONSTANT_NameAndType","","","CONSTANT_MethodHandle","CONSTANT_MethodType","","CONSTANT_InvokeDynamic", - // J9: - "CONSTANT_Module", "CONSTANT_Package"}; - - /** - * The name of the static initializer, also called "class initialization method" or "interface initialization - * method". This is "<clinit>". - */ - public final static String STATIC_INITIALIZER_NAME = ""; - - /** - * The name of every constructor method in a class, also called "instance initialization method". This is - * "<init>". - */ - public final static String CONSTRUCTOR_NAME = ""; - - /** The names of the interfaces implemented by arrays */ - public final static String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = { "java.lang.Cloneable", "java.io.Serializable" }; - - /** - * Limitations of the Java Virtual Machine. See The Java Virtual Machine Specification, Second Edition, page 152, chapter 4.10. - */ - public static final int MAX_CP_ENTRIES = 65535; - public static final int MAX_CODE_SIZE = 65536; // bytes - - /** - * Java VM opcodes. - */ - public static final short NOP = 0; - public static final short ACONST_NULL = 1; - public static final short ICONST_M1 = 2; - public static final short ICONST_0 = 3; - public static final short ICONST_1 = 4; - public static final short ICONST_2 = 5; - public static final short ICONST_3 = 6; - public static final short ICONST_4 = 7; - public static final short ICONST_5 = 8; - public static final short LCONST_0 = 9; - public static final short LCONST_1 = 10; - public static final short FCONST_0 = 11; - public static final short FCONST_1 = 12; - public static final short FCONST_2 = 13; - public static final short DCONST_0 = 14; - public static final short DCONST_1 = 15; - public static final short BIPUSH = 16; - public static final short SIPUSH = 17; - public static final short LDC = 18; - public static final short LDC_W = 19; - public static final short LDC2_W = 20; - public static final short ILOAD = 21; - public static final short LLOAD = 22; - public static final short FLOAD = 23; - public static final short DLOAD = 24; - public static final short ALOAD = 25; - public static final short ILOAD_0 = 26; - public static final short ILOAD_1 = 27; - public static final short ILOAD_2 = 28; - public static final short ILOAD_3 = 29; - public static final short LLOAD_0 = 30; - public static final short LLOAD_1 = 31; - public static final short LLOAD_2 = 32; - public static final short LLOAD_3 = 33; - public static final short FLOAD_0 = 34; - public static final short FLOAD_1 = 35; - public static final short FLOAD_2 = 36; - public static final short FLOAD_3 = 37; - public static final short DLOAD_0 = 38; - public static final short DLOAD_1 = 39; - public static final short DLOAD_2 = 40; - public static final short DLOAD_3 = 41; - public static final short ALOAD_0 = 42; - public static final short ALOAD_1 = 43; - public static final short ALOAD_2 = 44; - public static final short ALOAD_3 = 45; - public static final short IALOAD = 46; - public static final short LALOAD = 47; - public static final short FALOAD = 48; - public static final short DALOAD = 49; - public static final short AALOAD = 50; - public static final short BALOAD = 51; - public static final short CALOAD = 52; - public static final short SALOAD = 53; - public static final short ISTORE = 54; - public static final short LSTORE = 55; - public static final short FSTORE = 56; - public static final short DSTORE = 57; - public static final short ASTORE = 58; - public static final short ISTORE_0 = 59; - public static final short ISTORE_1 = 60; - public static final short ISTORE_2 = 61; - public static final short ISTORE_3 = 62; - public static final short LSTORE_0 = 63; - public static final short LSTORE_1 = 64; - public static final short LSTORE_2 = 65; - public static final short LSTORE_3 = 66; - public static final short FSTORE_0 = 67; - public static final short FSTORE_1 = 68; - public static final short FSTORE_2 = 69; - public static final short FSTORE_3 = 70; - public static final short DSTORE_0 = 71; - public static final short DSTORE_1 = 72; - public static final short DSTORE_2 = 73; - public static final short DSTORE_3 = 74; - public static final short ASTORE_0 = 75; - public static final short ASTORE_1 = 76; - public static final short ASTORE_2 = 77; - public static final short ASTORE_3 = 78; - public static final short IASTORE = 79; - public static final short LASTORE = 80; - public static final short FASTORE = 81; - public static final short DASTORE = 82; - public static final short AASTORE = 83; - public static final short BASTORE = 84; - public static final short CASTORE = 85; - public static final short SASTORE = 86; - public static final short POP = 87; - public static final short POP2 = 88; - public static final short DUP = 89; - public static final short DUP_X1 = 90; - public static final short DUP_X2 = 91; - public static final short DUP2 = 92; - public static final short DUP2_X1 = 93; - public static final short DUP2_X2 = 94; - public static final short SWAP = 95; - public static final short IADD = 96; - public static final short LADD = 97; - public static final short FADD = 98; - public static final short DADD = 99; - public static final short ISUB = 100; - public static final short LSUB = 101; - public static final short FSUB = 102; - public static final short DSUB = 103; - public static final short IMUL = 104; - public static final short LMUL = 105; - public static final short FMUL = 106; - public static final short DMUL = 107; - public static final short IDIV = 108; - public static final short LDIV = 109; - public static final short FDIV = 110; - public static final short DDIV = 111; - public static final short IREM = 112; - public static final short LREM = 113; - public static final short FREM = 114; - public static final short DREM = 115; - public static final short INEG = 116; - public static final short LNEG = 117; - public static final short FNEG = 118; - public static final short DNEG = 119; - public static final short ISHL = 120; - public static final short LSHL = 121; - public static final short ISHR = 122; - public static final short LSHR = 123; - public static final short IUSHR = 124; - public static final short LUSHR = 125; - public static final short IAND = 126; - public static final short LAND = 127; - public static final short IOR = 128; - public static final short LOR = 129; - public static final short IXOR = 130; - public static final short LXOR = 131; - public static final short IINC = 132; - public static final short I2L = 133; - public static final short I2F = 134; - public static final short I2D = 135; - public static final short L2I = 136; - public static final short L2F = 137; - public static final short L2D = 138; - public static final short F2I = 139; - public static final short F2L = 140; - public static final short F2D = 141; - public static final short D2I = 142; - public static final short D2L = 143; - public static final short D2F = 144; - public static final short I2B = 145; - public static final short INT2BYTE = 145; // Old notion - public static final short I2C = 146; - public static final short INT2CHAR = 146; // Old notion - public static final short I2S = 147; - public static final short INT2SHORT = 147; // Old notion - public static final short LCMP = 148; - public static final short FCMPL = 149; - public static final short FCMPG = 150; - public static final short DCMPL = 151; - public static final short DCMPG = 152; - public static final short IFEQ = 153; - public static final short IFNE = 154; - public static final short IFLT = 155; - public static final short IFGE = 156; - public static final short IFGT = 157; - public static final short IFLE = 158; - public static final short IF_ICMPEQ = 159; - public static final short IF_ICMPNE = 160; - public static final short IF_ICMPLT = 161; - public static final short IF_ICMPGE = 162; - public static final short IF_ICMPGT = 163; - public static final short IF_ICMPLE = 164; - public static final short IF_ACMPEQ = 165; - public static final short IF_ACMPNE = 166; - public static final short GOTO = 167; - public static final short JSR = 168; - public static final short RET = 169; - public static final short TABLESWITCH = 170; - public static final short LOOKUPSWITCH = 171; - public static final short IRETURN = 172; - public static final short LRETURN = 173; - public static final short FRETURN = 174; - public static final short DRETURN = 175; - public static final short ARETURN = 176; - public static final short RETURN = 177; - public static final short GETSTATIC = 178; - public static final short PUTSTATIC = 179; - public static final short GETFIELD = 180; - public static final short PUTFIELD = 181; - public static final short INVOKEVIRTUAL = 182; - public static final short INVOKESPECIAL = 183; - public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 - public static final short INVOKESTATIC = 184; - public static final short INVOKEINTERFACE = 185; - public static final short INVOKEDYNAMIC = 186; - public static final short NEW = 187; - public static final short NEWARRAY = 188; - public static final short ANEWARRAY = 189; - public static final short ARRAYLENGTH = 190; - public static final short ATHROW = 191; - public static final short CHECKCAST = 192; - public static final short INSTANCEOF = 193; - public static final short MONITORENTER = 194; - public static final short MONITOREXIT = 195; - public static final short WIDE = 196; - public static final short MULTIANEWARRAY = 197; - public static final short IFNULL = 198; - public static final short IFNONNULL = 199; - public static final short GOTO_W = 200; - public static final short JSR_W = 201; - - /** - * Non-legal opcodes, may be used by JVM internally. - */ - public static final short BREAKPOINT = 202; - public static final short LDC_QUICK = 203; - public static final short LDC_W_QUICK = 204; - public static final short LDC2_W_QUICK = 205; - public static final short GETFIELD_QUICK = 206; - public static final short PUTFIELD_QUICK = 207; - public static final short GETFIELD2_QUICK = 208; - public static final short PUTFIELD2_QUICK = 209; - public static final short GETSTATIC_QUICK = 210; - public static final short PUTSTATIC_QUICK = 211; - public static final short GETSTATIC2_QUICK = 212; - public static final short PUTSTATIC2_QUICK = 213; - public static final short INVOKEVIRTUAL_QUICK = 214; - public static final short INVOKENONVIRTUAL_QUICK = 215; - public static final short INVOKESUPER_QUICK = 216; - public static final short INVOKESTATIC_QUICK = 217; - public static final short INVOKEINTERFACE_QUICK = 218; - public static final short INVOKEVIRTUALOBJECT_QUICK = 219; - public static final short NEW_QUICK = 221; - public static final short ANEWARRAY_QUICK = 222; - public static final short MULTIANEWARRAY_QUICK = 223; - public static final short CHECKCAST_QUICK = 224; - public static final short INSTANCEOF_QUICK = 225; - public static final short INVOKEVIRTUAL_QUICK_W = 226; - public static final short GETFIELD_QUICK_W = 227; - public static final short PUTFIELD_QUICK_W = 228; - public static final short IMPDEP1 = 254; - public static final short IMPDEP2 = 255; - - /** - * For internal purposes only. - */ - public static final short PUSH = 4711; - public static final short SWITCH = 4712; - - /** - * Illegal codes - */ - public static final short UNDEFINED = '/' - '0'; // -1; - public static final short UNPREDICTABLE = '.' - '0';// -2; - public static final short RESERVED = -3; - public static final String ILLEGAL_OPCODE = ""; - public static final String ILLEGAL_TYPE = ""; - - public static final byte T_BOOLEAN = 4; - public static final byte T_CHAR = 5; - public static final byte T_FLOAT = 6; - public static final byte T_DOUBLE = 7; - public static final byte T_BYTE = 8; - public static final byte T_SHORT = 9; - public static final byte T_INT = 10; - public static final byte T_LONG = 11; - - public static final byte T_VOID = 12; // Non-standard - public static final byte T_ARRAY = 13; - public static final byte T_OBJECT = 14; - public static final byte T_REFERENCE = 14; // Deprecated - public static final byte T_UNKNOWN = 15; - public static final byte T_ADDRESS = 16; - - /** - * The primitive type names corresponding to the T_XX constants, e.g., TYPE_NAMES[T_INT] = "int" - */ - public static final String[] TYPE_NAMES = { ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "boolean", "char", "float", - "double", "byte", "short", "int", "long", "void", "array", "object", "unknown" // Non-standard - }; - - /** - * The primitive class names corresponding to the T_XX constants, e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" - */ - public static final String[] CLASS_TYPE_NAMES = { ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "java.lang.Boolean", - "java.lang.Character", "java.lang.Float", "java.lang.Double", "java.lang.Byte", "java.lang.Short", "java.lang.Integer", - "java.lang.Long", "java.lang.Void", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE }; - - /** - * The signature characters corresponding to primitive types, e.g., SHORT_TYPE_NAMES[T_INT] = "I" - */ - public static final String[] SHORT_TYPE_NAMES = { ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "Z", "C", "F", "D", - "B", "S", "I", "J", "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE }; - - public static int PUSH_INST = 0x0001; - public static int CONSTANT_INST = 0x0002; - public static long LOADCLASS_INST = 0x0004; - public static int CP_INST = 0x0008; - public static int INDEXED = 0x0010; - public static int LOAD_INST = 0x0020; // load instruction - public static int LV_INST = 0x0040; // local variable instruction - public static int POP_INST = 0x0080; - public static int STORE_INST = 0x0100; - public static long STACK_INST = 0x0200; - public static long BRANCH_INSTRUCTION = 0x0400; - public static long TARGETER_INSTRUCTION = 0x0800; - public static long NEGATABLE = 0x1000; - public static long IF_INST = 0x2000; - public static long JSR_INSTRUCTION = 0x4000; - public static long RET_INST = 0x8000; - public static long EXCEPTION_THROWER = 0x10000; - - public static final byte[] iLen = new byte[256]; - public static final byte UNDEFINED_LENGTH = 'X' - '0'; - public static final byte VARIABLE_LENGTH = 'V' - '0'; - public static final byte[] stackEntriesProduced = new byte[256]; - public static final Type[] types = new Type[256]; - public static final long[] instFlags = new long[256]; - - public static final Class[][] instExcs = new Class[256][]; - - static final Object _unused = ConstantsInitializer.initialize(); - - /** - * How the byte code operands are to be interpreted. - */ - public static final short[][] TYPE_OF_OPERANDS = { {}/* 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 */, { T_BYTE }/* bipush */, - { T_SHORT }/* sipush */, { T_BYTE }/* ldc */, { T_SHORT }/* ldc_w */, { T_SHORT }/* ldc2_w */, { T_BYTE }/* iload */, - { T_BYTE }/* lload */, { T_BYTE }/* fload */, { T_BYTE }/* dload */, { T_BYTE }/* aload */, {}/* iload_0 */, - {}/* iload_1 */, {}/* iload_2 */, {}/* iload_3 */, {}/* lload_0 */, {}/* lload_1 */, {}/* lload_2 */, {}/* lload_3 */, - {}/* fload_0 */, {}/* fload_1 */, {}/* fload_2 */, {}/* fload_3 */, {}/* dload_0 */, {}/* dload_1 */, {}/* dload_2 */, - {}/* dload_3 */, {}/* aload_0 */, {}/* aload_1 */, {}/* aload_2 */, {}/* aload_3 */, {}/* iaload */, {}/* laload */, - {}/* faload */, {}/* daload */, {}/* aaload */, {}/* baload */, {}/* caload */, {}/* saload */, { T_BYTE }/* istore */, - { T_BYTE }/* lstore */, { T_BYTE }/* fstore */, { T_BYTE }/* dstore */, { T_BYTE }/* astore */, {}/* istore_0 */, - {}/* istore_1 */, {}/* istore_2 */, {}/* istore_3 */, {}/* lstore_0 */, {}/* lstore_1 */, {}/* lstore_2 */, {}/* lstore_3 */, - {}/* fstore_0 */, {}/* fstore_1 */, {}/* fstore_2 */, {}/* fstore_3 */, {}/* dstore_0 */, {}/* dstore_1 */, {}/* dstore_2 */, - {}/* dstore_3 */, {}/* astore_0 */, {}/* astore_1 */, {}/* astore_2 */, {}/* astore_3 */, {}/* 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 */, { T_BYTE, T_BYTE }/* iinc */, {}/* i2l */, - {}/* i2f */, {}/* i2d */, {}/* l2i */, {}/* l2f */, {}/* l2d */, {}/* f2i */, {}/* f2l */, {}/* f2d */, {}/* d2i */, {}/* d2l */, - {}/* d2f */, {}/* i2b */, {}/* i2c */, {}/* i2s */, {}/* lcmp */, {}/* fcmpl */, {}/* fcmpg */, {}/* dcmpl */, - {}/* dcmpg */, { T_SHORT }/* ifeq */, { T_SHORT }/* ifne */, { T_SHORT }/* iflt */, { T_SHORT }/* ifge */, - { T_SHORT }/* ifgt */, { T_SHORT }/* ifle */, { T_SHORT }/* if_icmpeq */, { T_SHORT }/* if_icmpne */, - { T_SHORT }/* if_icmplt */, { T_SHORT }/* if_icmpge */, { T_SHORT }/* if_icmpgt */, { T_SHORT }/* if_icmple */, - { T_SHORT }/* if_acmpeq */, { T_SHORT }/* if_acmpne */, { T_SHORT }/* goto */, { T_SHORT }/* jsr */, - { T_BYTE }/* ret */, {}/* tableswitch */, {}/* lookupswitch */, {}/* ireturn */, {}/* lreturn */, {}/* freturn */, - {}/* dreturn */, {}/* areturn */, {}/* return */, { T_SHORT }/* getstatic */, { T_SHORT }/* putstatic */, - { T_SHORT }/* getfield */, { T_SHORT }/* putfield */, { T_SHORT }/* invokevirtual */, - { T_SHORT }/* invokespecial */, { T_SHORT }/* invokestatic */, { T_SHORT, T_BYTE, T_BYTE }/* invokeinterface */, {}, - { T_SHORT }/* new */, { T_BYTE }/* newarray */, { T_SHORT }/* anewarray */, {}/* arraylength */, {}/* athrow */, - { T_SHORT }/* checkcast */, { T_SHORT }/* instanceof */, {}/* monitorenter */, {}/* monitorexit */, { T_BYTE }/* wide */, - { T_SHORT, T_BYTE }/* multianewarray */, { T_SHORT }/* ifnull */, { T_SHORT }/* ifnonnull */, { T_INT }/* goto_w */, - { T_INT }/* jsr_w */, {}/* breakpoint */, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}/* impdep1 */, {} /* impdep2 */ - }; - - /** - * Names of opcodes. - */ - public static final String[] OPCODE_NAMES = { "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", - "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload", "lload", "fload", "dload", "aload", "iload_0", "iload_1", - "iload_2", "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0", "fload_1", "fload_2", "fload_3", - "dload_0", "dload_1", "dload_2", "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload", "laload", "faload", - "daload", "aaload", "baload", "caload", "saload", "istore", "lstore", "fstore", "dstore", "astore", "istore_0", - "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2", - "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3", "astore_0", "astore_1", "astore_2", "astore_3", "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", "iinc", "i2l", "i2f", "i2d", - "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f", "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg", "dcmpl", - "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", - "if_icmpgt", "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret", "tableswitch", "lookupswitch", "ireturn", - "lreturn", "freturn", "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield", "putfield", - "invokevirtual", "invokespecial", "invokestatic", "invokeinterface", "invokedynamic", "new", "newarray", "anewarray", - "arraylength", "athrow", "checkcast", "instanceof", "monitorenter", "monitorexit", "wide", "multianewarray", "ifnull", - "ifnonnull", "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, "impdep1", "impdep2" }; - - /** - * Number of words consumed on operand stack by instructions. - */ - public static final int[] CONSUME_STACK = { 0/* nop */, 0/* aconst_null */, 0/* iconst_m1 */, 0/* iconst_0 */, 0/* iconst_1 */, - 0/* iconst_2 */, 0/* iconst_3 */, 0/* iconst_4 */, 0/* iconst_5 */, 0/* lconst_0 */, 0/* lconst_1 */, 0/* fconst_0 */, - 0/* fconst_1 */, 0/* fconst_2 */, 0/* dconst_0 */, 0/* dconst_1 */, 0/* bipush */, 0/* sipush */, 0/* ldc */, - 0/* ldc_w */, 0/* ldc2_w */, 0/* iload */, 0/* lload */, 0/* fload */, 0/* dload */, 0/* aload */, 0/* iload_0 */, 0/* iload_1 */, - 0/* iload_2 */, 0/* iload_3 */, 0/* lload_0 */, 0/* lload_1 */, 0/* lload_2 */, 0/* lload_3 */, 0/* fload_0 */, - 0/* fload_1 */, 0/* fload_2 */, 0/* fload_3 */, 0/* dload_0 */, 0/* dload_1 */, 0/* dload_2 */, 0/* dload_3 */, - 0/* aload_0 */, 0/* aload_1 */, 0/* aload_2 */, 0/* aload_3 */, 2/* iaload */, 2/* laload */, 2/* faload */, - 2/* daload */, 2/* aaload */, 2/* baload */, 2/* caload */, 2/* saload */, 1/* istore */, 2/* lstore */, - 1/* fstore */, 2/* dstore */, 1/* astore */, 1/* istore_0 */, 1/* istore_1 */, 1/* istore_2 */, 1/* istore_3 */, - 2/* lstore_0 */, 2/* lstore_1 */, 2/* lstore_2 */, 2/* lstore_3 */, 1/* fstore_0 */, 1/* fstore_1 */, 1/* fstore_2 */, - 1/* fstore_3 */, 2/* dstore_0 */, 2/* dstore_1 */, 2/* dstore_2 */, 2/* dstore_3 */, 1/* astore_0 */, 1/* astore_1 */, - 1/* astore_2 */, 1/* astore_3 */, 3/* iastore */, 4/* lastore */, 3/* fastore */, 4/* dastore */, 3/* aastore */, - 3/* bastore */, 3/* castore */, 3/* sastore */, 1/* pop */, 2/* pop2 */, 1/* dup */, 2/* dup_x1 */, 3/* dup_x2 */, - 2/* dup2 */, 3/* dup2_x1 */, 4/* dup2_x2 */, 2/* swap */, 2/* iadd */, 4/* ladd */, 2/* fadd */, 4/* dadd */, 2/* isub */, - 4/* lsub */, 2/* fsub */, 4/* dsub */, 2/* imul */, 4/* lmul */, 2/* fmul */, 4/* dmul */, 2/* idiv */, 4/* ldiv */, 2/* fdiv */, - 4/* ddiv */, 2/* irem */, 4/* lrem */, 2/* frem */, 4/* drem */, 1/* ineg */, 2/* lneg */, 1/* fneg */, 2/* dneg */, 2/* ishl */, - 3/* lshl */, 2/* ishr */, 3/* lshr */, 2/* iushr */, 3/* lushr */, 2/* iand */, 4/* land */, 2/* ior */, 4/* lor */, 2/* ixor */, - 4/* lxor */, 0/* iinc */, 1/* i2l */, 1/* i2f */, 1/* i2d */, 2/* l2i */, 2/* l2f */, 2/* l2d */, 1/* f2i */, 1/* f2l */, - 1/* f2d */, 2/* d2i */, 2/* d2l */, 2/* d2f */, 1/* i2b */, 1/* i2c */, 1/* i2s */, 4/* lcmp */, 2/* fcmpl */, - 2/* fcmpg */, 4/* dcmpl */, 4/* dcmpg */, 1/* ifeq */, 1/* ifne */, 1/* iflt */, 1/* ifge */, 1/* ifgt */, 1/* ifle */, - 2/* if_icmpeq */, 2/* if_icmpne */, 2/* if_icmplt */, 2 /* if_icmpge */, 2/* if_icmpgt */, 2/* if_icmple */, 2/* if_acmpeq */, - 2/* if_acmpne */, 0/* goto */, 0/* jsr */, 0/* ret */, 1/* tableswitch */, 1/* lookupswitch */, 1/* ireturn */, - 2/* lreturn */, 1/* freturn */, 2/* dreturn */, 1/* areturn */, 0/* return */, 0/* getstatic */, - UNPREDICTABLE/* putstatic */, 1/* getfield */, UNPREDICTABLE/* putfield */, UNPREDICTABLE/* invokevirtual */, - UNPREDICTABLE/* invokespecial */, UNPREDICTABLE/* invokestatic */, UNPREDICTABLE/* invokeinterface */, UNDEFINED, - 0/* new */, 1/* newarray */, 1/* anewarray */, 1/* arraylength */, 1/* athrow */, 1/* checkcast */, 1/* instanceof */, - 1/* monitorenter */, 1/* monitorexit */, 0/* wide */, UNPREDICTABLE/* multianewarray */, 1/* ifnull */, - 1/* ifnonnull */, 0/* goto_w */, 0/* jsr_w */, 0/* breakpoint */, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNPREDICTABLE/* impdep1 */, UNPREDICTABLE /* impdep2 */ - }; - - // Attributes and their corresponding names. - public static final byte ATTR_UNKNOWN = -1; - public static final byte ATTR_SOURCE_FILE = 0; - public static final byte ATTR_CONSTANT_VALUE = 1; - public static final byte ATTR_CODE = 2; - public static final byte ATTR_EXCEPTIONS = 3; - public static final byte ATTR_LINE_NUMBER_TABLE = 4; - public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; - public static final byte ATTR_INNER_CLASSES = 6; - public static final byte ATTR_SYNTHETIC = 7; - public static final byte ATTR_DEPRECATED = 8; - public static final byte ATTR_PMG = 9; - public static final byte ATTR_SIGNATURE = 10; - public static final byte ATTR_STACK_MAP = 11; - public static final byte ATTR_RUNTIME_VISIBLE_ANNOTATIONS = 12; - public static final byte ATTR_RUNTIME_INVISIBLE_ANNOTATIONS = 13; - public static final byte ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = 14; - public static final byte ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = 15; - public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE = 16; - public static final byte ATTR_ENCLOSING_METHOD = 17; - public static final byte ATTR_ANNOTATION_DEFAULT = 18; - public static final byte ATTR_BOOTSTRAPMETHODS = 19; - public static final byte ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = 20; - public static final byte ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = 21; - public static final byte ATTR_METHOD_PARAMETERS = 22; - - // J9: - public static final byte ATTR_MODULE = 23; - public static final byte ATTR_MODULE_PACKAGES = 24; - public static final byte ATTR_MODULE_MAIN_CLASS = 25; - - // J11: - public static final byte ATTR_NEST_HOST = 26; - public static final byte ATTR_NEST_MEMBERS = 27; - - public static final short KNOWN_ATTRIBUTES = 28; - - public static final String[] ATTRIBUTE_NAMES = { - "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", - "InnerClasses", "Synthetic", "Deprecated", "PMGClass", "Signature", "StackMap", - "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations", - "RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod", - "AnnotationDefault","BootstrapMethods", "RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", - "MethodParameters", "Module", "ModulePackages", "ModuleMainClass", "NestHost", "NestMembers" - }; - - /** - * Constants used in the StackMap attribute. - */ - public static final byte ITEM_Bogus = 0; - public static final byte ITEM_Integer = 1; - public static final byte ITEM_Float = 2; - public static final byte ITEM_Double = 3; - public static final byte ITEM_Long = 4; - public static final byte ITEM_Null = 5; - public static final byte ITEM_InitObject = 6; - public static final byte ITEM_Object = 7; - public static final byte ITEM_NewObject = 8; - - public static final String[] ITEM_NAMES = { "Bogus", "Integer", "Float", "Double", "Long", "Null", "InitObject", "Object", - "NewObject" }; -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/ConstantsInitializer.java b/bcel-builder/src/org/aspectj/apache/bcel/ConstantsInitializer.java deleted file mode 100644 index b9bc0d49f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/ConstantsInitializer.java +++ /dev/null @@ -1,396 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel; - -import org.aspectj.apache.bcel.generic.Type; - -public class ConstantsInitializer { - - public static Object initialize() { - Constants.types[Constants.ILOAD] = Type.INT; - Constants.types[Constants.ISTORE] = Type.INT; - Constants.types[Constants.ILOAD_0] = Type.INT; - Constants.types[Constants.ISTORE_0] = Type.INT; - Constants.types[Constants.ILOAD_1] = Type.INT; - Constants.types[Constants.ISTORE_1] = Type.INT; - Constants.types[Constants.ILOAD_2] = Type.INT; - Constants.types[Constants.ISTORE_2] = Type.INT; - Constants.types[Constants.ILOAD_3] = Type.INT; - Constants.types[Constants.ISTORE_3] = Type.INT; - Constants.types[Constants.LLOAD] = Type.LONG; - Constants.types[Constants.LSTORE] = Type.LONG; - Constants.types[Constants.LLOAD_0] = Type.LONG; - Constants.types[Constants.LSTORE_0] = Type.LONG; - Constants.types[Constants.LLOAD_1] = Type.LONG; - Constants.types[Constants.LSTORE_1] = Type.LONG; - Constants.types[Constants.LLOAD_2] = Type.LONG; - Constants.types[Constants.LSTORE_2] = Type.LONG; - Constants.types[Constants.LLOAD_3] = Type.LONG; - Constants.types[Constants.LSTORE_3] = Type.LONG; - Constants.types[Constants.DLOAD] = Type.DOUBLE; - Constants.types[Constants.DSTORE] = Type.DOUBLE; - Constants.types[Constants.DLOAD_0] = Type.DOUBLE; - Constants.types[Constants.DSTORE_0] = Type.DOUBLE; - Constants.types[Constants.DLOAD_1] = Type.DOUBLE; - Constants.types[Constants.DSTORE_1] = Type.DOUBLE; - Constants.types[Constants.DLOAD_2] = Type.DOUBLE; - Constants.types[Constants.DSTORE_2] = Type.DOUBLE; - Constants.types[Constants.DLOAD_3] = Type.DOUBLE; - Constants.types[Constants.DSTORE_3] = Type.DOUBLE; - Constants.types[Constants.FLOAD] = Type.FLOAT; - Constants.types[Constants.FSTORE] = Type.FLOAT; - Constants.types[Constants.FLOAD_0] = Type.FLOAT; - Constants.types[Constants.FSTORE_0] = Type.FLOAT; - Constants.types[Constants.FLOAD_1] = Type.FLOAT; - Constants.types[Constants.FSTORE_1] = Type.FLOAT; - Constants.types[Constants.FLOAD_2] = Type.FLOAT; - Constants.types[Constants.FSTORE_2] = Type.FLOAT; - Constants.types[Constants.FLOAD_3] = Type.FLOAT; - Constants.types[Constants.FSTORE_3] = Type.FLOAT; - Constants.types[Constants.ALOAD] = Type.OBJECT; - Constants.types[Constants.ASTORE] = Type.OBJECT; - Constants.types[Constants.ALOAD_0] = Type.OBJECT; - Constants.types[Constants.ASTORE_0] = Type.OBJECT; - Constants.types[Constants.ALOAD_1] = Type.OBJECT; - Constants.types[Constants.ASTORE_1] = Type.OBJECT; - Constants.types[Constants.ALOAD_2] = Type.OBJECT; - Constants.types[Constants.ASTORE_2] = Type.OBJECT; - Constants.types[Constants.ALOAD_3] = Type.OBJECT; - Constants.types[Constants.ASTORE_3] = Type.OBJECT; - - // INSTRUCTION_FLAGS - set for all - Constants.instFlags[Constants.NOP] = 0; - Constants.instFlags[Constants.ACONST_NULL] = Constants.PUSH_INST; - Constants.instFlags[Constants.ICONST_M1] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.ICONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.ICONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.ICONST_2] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.ICONST_3] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.ICONST_4] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.ICONST_5] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.LCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.LCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.FCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.FCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.FCONST_2] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.DCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.DCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST; - - Constants.instFlags[Constants.BIPUSH] = Constants.PUSH_INST | Constants.CONSTANT_INST; - Constants.instFlags[Constants.SIPUSH] = Constants.PUSH_INST | Constants.CONSTANT_INST; - - Constants.instFlags[Constants.LDC] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST - | Constants.INDEXED; - - Constants.instFlags[Constants.LDC_W] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST - | Constants.INDEXED; - - Constants.instFlags[Constants.LDC2_W] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST - | Constants.INDEXED; - - // the next five could be 'wide' prefixed and so have longer lengths - Constants.instFlags[Constants.ILOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; - Constants.instFlags[Constants.LLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; - Constants.instFlags[Constants.FLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; - Constants.instFlags[Constants.DLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; - Constants.instFlags[Constants.ALOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; - for (int ii = Constants.ILOAD_0; ii <= Constants.ALOAD_3; ii++) { - Constants.instFlags[ii] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST; - } - - // the next five could be 'wide' prefixed and so have longer lengths - Constants.instFlags[Constants.ISTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; - Constants.instFlags[Constants.LSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; - Constants.instFlags[Constants.FSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; - Constants.instFlags[Constants.DSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; - Constants.instFlags[Constants.ASTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; - for (int ii = Constants.ISTORE_0; ii <= Constants.ASTORE_3; ii++) { - Constants.instFlags[ii] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST; - } - - Constants.instFlags[Constants.IDIV] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.IDIV] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; - Constants.instFlags[Constants.IREM] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.IREM] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; - Constants.instFlags[Constants.LDIV] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.LDIV] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; - Constants.instFlags[Constants.LREM] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.LREM] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; - - Constants.instFlags[Constants.ARRAYLENGTH] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.ARRAYLENGTH] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; - Constants.instFlags[Constants.ATHROW] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.ATHROW] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.THROWABLE }; - - Constants.instFlags[Constants.AALOAD] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.AALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.IALOAD] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.IALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.BALOAD] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.BALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.FALOAD] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.FALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.DALOAD] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.DALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.CALOAD] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.CALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.LALOAD] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.LALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.SALOAD] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.SALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - - Constants.instFlags[Constants.AASTORE] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.AASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.IASTORE] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.IASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.BASTORE] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.BASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.FASTORE] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.FASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.DASTORE] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.DASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.CASTORE] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.CASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.LASTORE] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.LASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - Constants.instFlags[Constants.SASTORE] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.SASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - - // stack instructions - Constants.instFlags[Constants.DUP] = Constants.PUSH_INST | Constants.STACK_INST; - Constants.instFlags[Constants.DUP_X1] = Constants.STACK_INST; // TODO fixme - aren't these two push/stack producers? - // (although peculiar ones...) - Constants.instFlags[Constants.DUP_X2] = Constants.STACK_INST; - Constants.instFlags[Constants.DUP2] = Constants.PUSH_INST | Constants.STACK_INST; - Constants.instFlags[Constants.DUP2_X1] = Constants.STACK_INST; // TODO fixme - aren't these two push/stack producers? - // (although peculiar ones...) - Constants.instFlags[Constants.DUP2_X2] = Constants.STACK_INST; - Constants.instFlags[Constants.POP] = Constants.STACK_INST | Constants.POP_INST; - Constants.instFlags[Constants.POP2] = Constants.STACK_INST | Constants.POP_INST; - Constants.instFlags[Constants.SWAP] = Constants.STACK_INST; - - Constants.instFlags[Constants.MONITORENTER] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.MONITORENTER] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; - Constants.instFlags[Constants.MONITOREXIT] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.MONITOREXIT] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; - - // branching instructions - Constants.instFlags[Constants.GOTO] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION; - Constants.instFlags[Constants.GOTO_W] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION; - Constants.instFlags[Constants.JSR] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.JSR_INSTRUCTION; - Constants.instFlags[Constants.JSR_W] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.JSR_INSTRUCTION; - - Constants.instFlags[Constants.IFGT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE - | Constants.IF_INST; - Constants.instFlags[Constants.IFLE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE - | Constants.IF_INST; - Constants.instFlags[Constants.IFNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE - | Constants.IF_INST; - Constants.instFlags[Constants.IFEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE - | Constants.IF_INST; - Constants.instFlags[Constants.IFGE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE - | Constants.IF_INST; - Constants.instFlags[Constants.IFLT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE - | Constants.IF_INST; - Constants.instFlags[Constants.IFNULL] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE - | Constants.IF_INST; - Constants.instFlags[Constants.IFNONNULL] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - Constants.instFlags[Constants.IF_ACMPEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - Constants.instFlags[Constants.IF_ACMPNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - Constants.instFlags[Constants.IF_ICMPEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - Constants.instFlags[Constants.IF_ICMPGE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - Constants.instFlags[Constants.IF_ICMPGT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - Constants.instFlags[Constants.IF_ICMPLE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - Constants.instFlags[Constants.IF_ICMPLT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - Constants.instFlags[Constants.IF_ICMPNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION - | Constants.NEGATABLE | Constants.IF_INST; - - Constants.instFlags[Constants.LOOKUPSWITCH] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION; - Constants.instFlags[Constants.TABLESWITCH] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION; - - // fixme these class arrays should be constants - Constants.instFlags[Constants.ARETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.ARETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; - Constants.instFlags[Constants.DRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.DRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; - Constants.instFlags[Constants.FRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.FRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; - Constants.instFlags[Constants.IRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.IRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; - Constants.instFlags[Constants.LRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.LRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; - Constants.instFlags[Constants.RETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.RETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; - - Constants.instFlags[Constants.NEW] = Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER | Constants.CP_INST - | Constants.INDEXED; - Constants.instExcs[Constants.NEW] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_FOR_ALLOCATIONS; - Constants.instFlags[Constants.NEWARRAY] = Constants.EXCEPTION_THROWER; - Constants.instExcs[Constants.NEWARRAY] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION }; - - Constants.types[Constants.IINC] = Type.INT; - Constants.instFlags[Constants.IINC] = Constants.LV_INST | Constants.INDEXED; - Constants.instFlags[Constants.RET] = Constants.INDEXED; - - Constants.instFlags[Constants.ANEWARRAY] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER - | Constants.INDEXED; - Constants.instExcs[Constants.ANEWARRAY] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY; - Constants.instFlags[Constants.CHECKCAST] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER - | Constants.INDEXED; - Constants.instExcs[Constants.CHECKCAST] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_CHECKCAST; - Constants.instFlags[Constants.INSTANCEOF] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER - | Constants.INDEXED; - Constants.instExcs[Constants.INSTANCEOF] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION; - Constants.instFlags[Constants.MULTIANEWARRAY] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER - | Constants.INDEXED; - Constants.instExcs[Constants.MULTIANEWARRAY] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY; // fixme i - // think - // this - // is a - // stackproducer, old - // bcel says no... - - Constants.instFlags[Constants.GETFIELD] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST - | Constants.INDEXED; - Constants.instExcs[Constants.GETFIELD] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD; - Constants.instFlags[Constants.GETSTATIC] = Constants.PUSH_INST | Constants.EXCEPTION_THROWER | Constants.LOADCLASS_INST - | Constants.CP_INST | Constants.INDEXED; - Constants.instExcs[Constants.GETSTATIC] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC; - Constants.instFlags[Constants.PUTFIELD] = Constants.POP_INST | Constants.EXCEPTION_THROWER | Constants.LOADCLASS_INST - | Constants.CP_INST | Constants.INDEXED; - Constants.instExcs[Constants.PUTFIELD] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD; - Constants.instFlags[Constants.PUTSTATIC] = Constants.EXCEPTION_THROWER | Constants.POP_INST | Constants.CP_INST - | Constants.LOADCLASS_INST | Constants.INDEXED; - Constants.instExcs[Constants.PUTSTATIC] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC; - - Constants.instFlags[Constants.INVOKEINTERFACE] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST - | Constants.INDEXED; - Constants.instExcs[Constants.INVOKEINTERFACE] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKEINTERFACE; - Constants.instFlags[Constants.INVOKESPECIAL] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST - | Constants.INDEXED; - Constants.instExcs[Constants.INVOKESPECIAL] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL; - Constants.instFlags[Constants.INVOKESTATIC] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST - | Constants.INDEXED; - Constants.instExcs[Constants.INVOKESTATIC] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESTATIC; - Constants.instFlags[Constants.INVOKEVIRTUAL] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST - | Constants.INDEXED; - Constants.instExcs[Constants.INVOKEVIRTUAL] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL; - - Constants.instFlags[Constants.INVOKEDYNAMIC] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST - | Constants.INDEXED; - // TBD - // Constants.instExcs[Constants.INVOKEDYNAMIC] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL; - - //@formatter:off - char[] lengths = // . = varies in length, / = undefined - ("1111111111111111" + // nop > dconst_1 - "2323322222111111" + // bipush > lload_1 - "1111111111111111" + // lload_2 > laload - "1111112222211111" + // faload > lstore_0 - "1111111111111111" + // lstore_1 > iastore - "1111111111111111" + // lastore > swap - "1111111111111111" + // iadd > ddiv - "1111111111111111" + // irem > land - "1111311111111111" + // ior > d2l - "1111111113333333" + // d2f > if_icmpeq - "3333333332..1111" + // if_icmpne > dreturn - "1133333335532311" + // areturn > athrow - "3311.433551/////").toCharArray(); // checkcast > - //@formatter:on - int count = 0; - for (; count < lengths.length; count++) { - Constants.iLen[count] = (byte) (lengths[count] - 48); - } - while (count < 256) { - Constants.iLen[count] = Constants.UNDEFINED; - count++; - } - Constants.iLen[Constants.BREAKPOINT] = 1; - Constants.iLen[Constants.IMPDEP1] = 1; - Constants.iLen[Constants.IMPDEP2] = 1; - - char[] producesOnStack = ("0111111112211122" + // nop > dconst_1 - "1111212121111122" + // bipush > lload_1 - "2211112222111112" + // lload_2 > laload - "1211110000000000" + // faload > lstore_0 - "0000000000000000" + // lstore_1 > iastore - "0000000002344562" + // lastore > swap - "1212121212121212" + // iadd > ddiv - "1212121212121212" + // irem > land - "1212021211212212" + // ior > d2l - "1111111110000000" + // d2f > if_icmpeq - "0000000010000000" + // if_icmpne > dreturn - "00.0.0.....11111" + // areturn > athrow - "11000100010/").toCharArray(); // checkcast > - count = 0; - for (; count < producesOnStack.length; count++) { - Constants.stackEntriesProduced[count] = (byte) (producesOnStack[count] - 48); - } - while (count < 256) { - Constants.iLen[count] = Constants.UNDEFINED; - count++; - } - return null; - } -} \ No newline at end of file diff --git a/bcel-builder/src/org/aspectj/apache/bcel/ExceptionConstants.java b/bcel-builder/src/org/aspectj/apache/bcel/ExceptionConstants.java deleted file mode 100644 index cf3d81308..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/ExceptionConstants.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.aspectj.apache.bcel; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Exception constants. - * - * @version $Id: ExceptionConstants.java,v 1.5 2009/09/14 20:29:10 aclement Exp $ - * @author E. Haase - */ -@SuppressWarnings("rawtypes") -public interface ExceptionConstants { - /** - * The mother of all exceptions - */ - public static final Class THROWABLE = Throwable.class; - - /** - * Super class of any run-time exception - */ - public static final Class RUNTIME_EXCEPTION = RuntimeException.class; - - /** - * Super class of any linking exception (aka Linkage Error) - */ - public static final Class LINKING_EXCEPTION = LinkageError.class; - - /** - * Linking Exceptions - */ - public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; - public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; - public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; - public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; - public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; - public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; - public static final Class INSTANTIATION_ERROR = InstantiationError.class; - public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; - public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; - public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; - public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; - public static final Class VERIFY_ERROR = VerifyError.class; - - /* UnsupportedClassVersionError is new in JDK 1.2 */ - // public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; - /** - * Run-Time Exceptions - */ - public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; - public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; - public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; - public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; - public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; - public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; - - /** - * Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual Machine Specification - */ - public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, - ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR }; // Chapter 5.1 - public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_MULTIANEWARRAY = { NO_CLASS_DEF_FOUND_ERROR, - CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, - NEGATIVE_ARRAY_SIZE_EXCEPTION, ILLEGAL_ACCESS_ERROR }; - public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, - VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, - NEGATIVE_ARRAY_SIZE_EXCEPTION }; // Chapter 5.1 - public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_CHECKCAST = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, - VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, CLASS_CAST_EXCEPTION }; // Chapter - // 5.1 - public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_FOR_ALLOCATIONS = { NO_CLASS_DEF_FOUND_ERROR, - CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, - INSTANTIATION_ERROR, ILLEGAL_ACCESS_ERROR }; - - public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, - NO_SUCH_METHOD_ERROR }; // Chapter 5.2 - - public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, - NO_SUCH_METHOD_ERROR, INCOMPATIBLE_CLASS_CHANGE_ERROR, NULL_POINTER_EXCEPTION }; - - public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, - NO_SUCH_METHOD_ERROR, INCOMPATIBLE_CLASS_CHANGE_ERROR }; - - public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKEINTERFACE = { INCOMPATIBLE_CLASS_CHANGE_ERROR, - ILLEGAL_ACCESS_ERROR, ABSTRACT_METHOD_ERROR, UNSATISFIED_LINK_ERROR }; - public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL = { INCOMPATIBLE_CLASS_CHANGE_ERROR, - NULL_POINTER_EXCEPTION, ABSTRACT_METHOD_ERROR, UNSATISFIED_LINK_ERROR }; -// public static final Class[] EXCS_INVOKEDYNAMIC = { BOOTSTRAP_METHOD_ERROR}; - - public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESTATIC = { INCOMPATIBLE_CLASS_CHANGE_ERROR, - UNSATISFIED_LINK_ERROR }; - - public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) - public static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; - // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) - - public static final Class[] EXCS_ARRAY_EXCEPTION = { NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION }; - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/Repository.java b/bcel-builder/src/org/aspectj/apache/bcel/Repository.java deleted file mode 100644 index 073355b5b..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/Repository.java +++ /dev/null @@ -1,260 +0,0 @@ -package org.aspectj.apache.bcel; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.IOException; - -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.ClassPath; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -/** - * The repository maintains informations about class interdependencies, e.g., whether a class is a sub-class of another. Delegates - * actual class loading to SyntheticRepository with current class path by default. - * - * @see org.aspectj.apache.bcel.util.Repository - * @see org.aspectj.apache.bcel.util.SyntheticRepository - * - * @version $Id: Repository.java,v 1.6 2009/09/09 22:18:20 aclement Exp $ - * @author M. Dahm - */ -public abstract class Repository { - private static org.aspectj.apache.bcel.util.Repository _repository = null; - - /** - * @return currently used repository instance - */ - public static org.aspectj.apache.bcel.util.Repository getRepository() { - if (_repository == null) { - _repository = SyntheticRepository.getInstance(); - } - return _repository; - } - - /** - * Set repository instance to be used for class loading - */ - public static void setRepository(org.aspectj.apache.bcel.util.Repository rep) { - _repository = rep; - } - - /** - * Lookup class somewhere found on your CLASSPATH, or whereever the repository instance looks for it. - * - * @return class object for given fully qualified class name, or null if the class could not be found or parsed correctly - */ - public static JavaClass lookupClass(String class_name) { - try { - JavaClass clazz = getRepository().findClass(class_name); - - if (clazz != null) { - return clazz; - } - - return getRepository().loadClass(class_name); - } catch (ClassNotFoundException ex) { - return null; - } - } - - // /** - // * Try to find class source via getResourceAsStream(). - // * - // * @see Class - // * @return JavaClass object for given runtime class - // */ - // public static JavaClass lookupClass(Class clazz) { - // try { - // return getRepository().loadClass(clazz); - // } catch (ClassNotFoundException ex) { - // return null; - // } - // } - - /** - * @return class file object for given Java class. - */ - public static ClassPath.ClassFile lookupClassFile(String class_name) { - try { - return ClassPath.getSystemClassPath().getClassFile(class_name); - } catch (IOException e) { - return null; - } - } - - /** - * Clear the repository. - */ - public static void clearCache() { - getRepository().clear(); - } - - /** - * Add clazz to repository if there isn't an equally named class already in there. - * - * @return old entry in repository - */ - public static JavaClass addClass(JavaClass clazz) { - JavaClass old = getRepository().findClass(clazz.getClassName()); - getRepository().storeClass(clazz); - return old; - } - - /** - * Remove class with given (fully qualified) name from repository. - */ - public static void removeClass(String clazz) { - getRepository().removeClass(getRepository().findClass(clazz)); - } - - // /** - // * Remove given class from repository. - // */ - // public static void removeClass(JavaClass clazz) { - // getRepository().removeClass(clazz); - // } - - // /** - // * @return list of super classes of clazz in ascending order, i.e., Object is always the last element - // */ - // public static JavaClass[] getSuperClasses(JavaClass clazz) { - // return clazz.getSuperClasses(); - // } - // - // /** - // * @return list of super classes of clazz in ascending order, i.e., Object is always the last element. return "null", if class - // * cannot be found. - // */ - // public static JavaClass[] getSuperClasses(String class_name) { - // JavaClass jc = lookupClass(class_name); - // return jc == null ? null : getSuperClasses(jc); - // } - // - // /** - // * @return all interfaces implemented by class and its super classes and the interfaces that those interfaces extend, and so - // on. - // * (Some people call this a transitive hull). - // */ - // public static JavaClass[] getInterfaces(JavaClass clazz) { - // return clazz.getAllInterfaces(); - // } - - // /** - // * @return all interfaces implemented by class and its super classes and the interfaces that extend those interfaces, and so - // on - // */ - // public static JavaClass[] getInterfaces(String class_name) { - // return getInterfaces(lookupClass(class_name)); - // } - - /** - * Equivalent to runtime "instanceof" operator. - * - * @return true, if clazz is an instance of super_class - */ - public static boolean instanceOf(JavaClass clazz, JavaClass super_class) { - return clazz.instanceOf(super_class); - } - - /** - * @return true, if clazz is an instance of super_class - */ - public static boolean instanceOf(String clazz, String super_class) { - return instanceOf(lookupClass(clazz), lookupClass(super_class)); - } - - // /** - // * @return true, if clazz is an instance of super_class - // */ - // public static boolean instanceOf(JavaClass clazz, String super_class) { - // return instanceOf(clazz, lookupClass(super_class)); - // } - - // /** - // * @return true, if clazz is an instance of super_class - // */ - // public static boolean instanceOf(String clazz, JavaClass super_class) { - // return instanceOf(lookupClass(clazz), super_class); - // } - - /** - * @return true, if clazz is an implementation of interface inter - */ - public static boolean implementationOf(JavaClass clazz, JavaClass inter) { - return clazz.implementationOf(inter); - } - - /** - * @return true, if clazz is an implementation of interface inter - */ - public static boolean implementationOf(String clazz, String inter) { - return implementationOf(lookupClass(clazz), lookupClass(inter)); - } - - // - // /** - // * @return true, if clazz is an implementation of interface inter - // */ - // public static boolean implementationOf(JavaClass clazz, String inter) { - // return implementationOf(clazz, lookupClass(inter)); - // } - - // /** - // * @return true, if clazz is an implementation of interface inter - // */ - // public static boolean implementationOf(String clazz, JavaClass inter) { - // return implementationOf(lookupClass(clazz), inter); - // } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/AnnotationDefault.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/AnnotationDefault.java deleted file mode 100644 index bd5a7251f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/AnnotationDefault.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.annotation.ElementValue; - -/** - * This attribute is attached to a method and indicates the default - * value for an annotation element. - */ -public class AnnotationDefault extends Attribute { - - private ElementValue value; - - public AnnotationDefault(int nameIndex, int len, DataInputStream dis, ConstantPool cpool) throws IOException { - this(nameIndex, len, ElementValue.readElementValue(dis,cpool), cpool); - } - - private AnnotationDefault(int nameIndex, int len, ElementValue value, ConstantPool cpool) { - super(Constants.ATTR_ANNOTATION_DEFAULT, nameIndex, len, cpool); - this.value = value; - } - - public Attribute copy(ConstantPool constant_pool) { - throw new RuntimeException("Not implemented yet!"); - // is this next line sufficient? - // return (EnclosingMethod)clone(); - } - - public final ElementValue getElementValue() { return value; } - - public final void dump(DataOutputStream dos) throws IOException { - super.dump(dos); - value.dump(dos); - } - - public void accept(ClassVisitor v) { - v.visitAnnotationDefault(this); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java deleted file mode 100644 index daeb59a38..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.Serializable; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; - -/** - * Abstract super class for Attribute objects. Currently the ConstantValue, SourceFile, Code, - * Exceptiontable, LineNumberTable, LocalVariableTable, InnerClasses and Synthetic - * attributes are supported. The Unknown attribute stands for non-standard-attributes. - * - * @version $Id: Attribute.java,v 1.9 2009/12/09 18:01:31 aclement Exp $ - * @author M. Dahm - * @see ConstantValue - * @see SourceFile - * @see Code - * @see Unknown - * @see ExceptionTable - * @see LineNumberTable - * @see LocalVariableTable - * @see InnerClasses - * @see Synthetic - * @see Deprecated - * @see Signature - */ -public abstract class Attribute implements Cloneable, Node, Serializable { - public final static Attribute[] NoAttributes = new Attribute[0]; - - protected byte tag; // Tag to distinguish subclasses - protected int nameIndex; - protected int length; - protected ConstantPool cpool; - - protected Attribute(byte tag, int nameIndex, int length, ConstantPool cpool) { - this.tag = tag; - this.nameIndex = nameIndex; - this.length = length; - this.cpool = cpool; - } - - public void dump(DataOutputStream file) throws IOException { - file.writeShort(nameIndex); - file.writeInt(length); - } - - // OPTIMIZE how about just reading them in and storing them until we need to decode what they really are? - public static final Attribute readAttribute(DataInputStream file, ConstantPool cpool) throws IOException { - byte tag = Constants.ATTR_UNKNOWN; - int idx = file.readUnsignedShort(); - String name = cpool.getConstantUtf8(idx).getValue(); - int len = file.readInt(); - - // Compare strings to find known attribute - for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++) { - if (name.equals(Constants.ATTRIBUTE_NAMES[i])) { - tag = i; - break; - } - } - switch (tag) { - case Constants.ATTR_UNKNOWN: - return new Unknown(idx, len, file, cpool); - case Constants.ATTR_CONSTANT_VALUE: - return new ConstantValue(idx, len, file, cpool); - case Constants.ATTR_SOURCE_FILE: - return new SourceFile(idx, len, file, cpool); - case Constants.ATTR_CODE: - return new Code(idx, len, file, cpool); - case Constants.ATTR_EXCEPTIONS: - return new ExceptionTable(idx, len, file, cpool); - case Constants.ATTR_LINE_NUMBER_TABLE: - return new LineNumberTable(idx, len, file, cpool); - case Constants.ATTR_LOCAL_VARIABLE_TABLE: - return new LocalVariableTable(idx, len, file, cpool); - case Constants.ATTR_INNER_CLASSES: - return new InnerClasses(idx, len, file, cpool); - case Constants.ATTR_SYNTHETIC: - return new Synthetic(idx, len, file, cpool); - case Constants.ATTR_DEPRECATED: - return new Deprecated(idx, len, file, cpool); - case Constants.ATTR_SIGNATURE: - return new Signature(idx, len, file, cpool); - case Constants.ATTR_STACK_MAP: - return new StackMap(idx, len, file, cpool); - case Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS: - return new RuntimeVisAnnos(idx, len, file, cpool); - case Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS: - return new RuntimeInvisAnnos(idx, len, file, cpool); - case Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: - return new RuntimeVisParamAnnos(idx, len, file, cpool); - case Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: - return new RuntimeInvisParamAnnos(idx, len, file, cpool); - case Constants.ATTR_ANNOTATION_DEFAULT: - return new AnnotationDefault(idx, len, file, cpool); - case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE: - return new LocalVariableTypeTable(idx, len, file, cpool); - case Constants.ATTR_ENCLOSING_METHOD: - return new EnclosingMethod(idx, len, file, cpool); - case Constants.ATTR_BOOTSTRAPMETHODS: - return new BootstrapMethods(idx,len,file,cpool); - case Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS: - return new RuntimeVisTypeAnnos(idx, len, file, cpool); - case Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: - return new RuntimeInvisTypeAnnos(idx, len, file, cpool); - case Constants.ATTR_METHOD_PARAMETERS: - return new MethodParameters(idx, len, file, cpool); - case Constants.ATTR_MODULE: - return new Module(idx, len, file, cpool); - case Constants.ATTR_MODULE_PACKAGES: - return new ModulePackages(idx, len, file, cpool); - case Constants.ATTR_MODULE_MAIN_CLASS: - return new ModuleMainClass(idx, len, file, cpool); - case Constants.ATTR_NEST_HOST: - return new NestHost(idx, len, file, cpool); - case Constants.ATTR_NEST_MEMBERS: - return new NestMembers(idx, len, file, cpool); - default: - throw new IllegalStateException(); - } - } - - public String getName() { - return cpool.getConstantUtf8(nameIndex).getValue(); - } - - public final int getLength() { - return length; - } - - public final int getNameIndex() { - return nameIndex; - } - - public final byte getTag() { - return tag; - } - - public final ConstantPool getConstantPool() { - return cpool; - } - - @Override - public String toString() { - return Constants.ATTRIBUTE_NAMES[tag]; - } - - @Override - public abstract void accept(ClassVisitor v); - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/AttributeUtils.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/AttributeUtils.java deleted file mode 100644 index 45d1597a7..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/AttributeUtils.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -public class AttributeUtils { - - public static Attribute[] readAttributes(DataInputStream dataInputstream, ConstantPool cpool) { - try { - int length = dataInputstream.readUnsignedShort(); - if (length == 0) { - return Attribute.NoAttributes; - } - Attribute[] attrs = new Attribute[length]; - for (int i = 0; i < length; i++) { - attrs[i] = Attribute.readAttribute(dataInputstream, cpool); - } - return attrs; - } catch (IOException e) { - throw new ClassFormatException("IOException whilst reading set of attributes: " + e.toString()); - } - } - - /** Write (serialize) a set of attributes into a specified output stream */ - public static void writeAttributes(Attribute[] attributes, DataOutputStream file) throws IOException { - if (attributes == null) { - file.writeShort(0); - } else { - file.writeShort(attributes.length); - for (int i = 0; i < attributes.length; i++) { - attributes[i].dump(file); - } - } - } - - public static Signature getSignatureAttribute(Attribute[] attributes) { - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].tag == Constants.ATTR_SIGNATURE) { - return (Signature) attributes[i]; - } - } - return null; - } - - public static Code getCodeAttribute(Attribute[] attributes) { - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].tag == Constants.ATTR_CODE) { - return (Code) attributes[i]; - } - } - return null; - } - - public static ExceptionTable getExceptionTableAttribute(Attribute[] attributes) { - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].tag == Constants.ATTR_EXCEPTIONS) { - return (ExceptionTable) attributes[i]; - } - } - return null; - } - - public static ConstantValue getConstantValueAttribute(Attribute[] attributes) { - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) { - return (ConstantValue) attributes[i]; - } - } - return null; - } - - public static void accept(Attribute[] attributes, ClassVisitor visitor) { - for (int i = 0; i < attributes.length; i++) { - attributes[i].accept(visitor); - } - } - - public static boolean hasSyntheticAttribute(Attribute[] attributes) { - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].tag == Constants.ATTR_SYNTHETIC) { - return true; - } - } - return false; - } - - public static SourceFile getSourceFileAttribute(Attribute[] attributes) { - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].tag == Constants.ATTR_SOURCE_FILE) { - return (SourceFile) attributes[i]; - } - } - return null; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/BootstrapMethods.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/BootstrapMethods.java deleted file mode 100644 index f708c0cab..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/BootstrapMethods.java +++ /dev/null @@ -1,268 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * Represents the BootstrapMethods attribute in Java 7 classes. - * - * @author Andy Clement - */ -public final class BootstrapMethods extends Attribute { - - // if 'isInPackedState' then this data needs unpacking - private boolean isInPackedState = false; - private byte[] data; // discarded once unpacked - - private int numBootstrapMethods; - private BootstrapMethod[] bootstrapMethods; - - public BootstrapMethods(BootstrapMethods c) { - this(c.getNameIndex(), c.getLength(), c.getBootstrapMethods(), c.getConstantPool()); - } - - public BootstrapMethods(int nameIndex, int length, BootstrapMethod[] lineNumberTable, ConstantPool constantPool) { - super(Constants.ATTR_BOOTSTRAPMETHODS, nameIndex, length, constantPool); - setBootstrapMethods(lineNumberTable); - isInPackedState = false; - } - - public final void setBootstrapMethods(BootstrapMethod[] bootstrapMethods) { - this.data = null; - this.isInPackedState = false; - this.bootstrapMethods = bootstrapMethods; - this.numBootstrapMethods = bootstrapMethods==null?0:bootstrapMethods.length; - } - - BootstrapMethods(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, (BootstrapMethod[])null, constant_pool); - data = new byte[length]; - file.readFully(data); - isInPackedState = true; - } - - public static class BootstrapMethod { - private int bootstrapMethodRef; - private int[] bootstrapArguments; - - BootstrapMethod(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), readBootstrapArguments(file)); - } - - private static int[] readBootstrapArguments(DataInputStream dis) throws IOException { - int numBootstrapMethods = dis.readUnsignedShort(); - int[] bootstrapArguments = new int[numBootstrapMethods]; - for (int i=0;i 72) { - line.append('\n'); - buf.append(line); - line.setLength(0); - } - } - - buf.append(line); - - return buf.toString(); - } - - - /** - * @return deep copy of this attribute - */ - // @Override - // public Attribute copy(ConstantPool constant_pool) { - // unpack(); - // LineNumberTable newTable = (LineNumberTable) clone(); - // newTable.table = new LineNumber[tableLength]; - // for (int i = 0; i < tableLength; i++) { - // newTable.table[i] = table[i].copy(); - // } - // newTable.cpool = constant_pool; - // return newTable; - // } - public final int getNumBootstrapMethods () { - unpack(); - return bootstrapMethods.length; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassFormatException.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassFormatException.java deleted file mode 100644 index a958329e5..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassFormatException.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Thrown when the BCEL attempts to read a class file and determines - * that the file is malformed or otherwise cannot be interpreted as a - * class file. - * - * @version $Id: ClassFormatException.java,v 1.3 2008/05/28 23:53:02 aclement Exp $ - * @author M. Dahm - */ -public class ClassFormatException extends RuntimeException { - public ClassFormatException() { super(); } - public ClassFormatException(String s) { super(s); } -} - diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java deleted file mode 100644 index 54882beee..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java +++ /dev/null @@ -1,249 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.aspectj.apache.bcel.Constants; - -/** - * Wrapper class that parses a given Java .class file. The method parse returns a - * JavaClass object on success. When an I/O error or an - * inconsistency occurs an appropiate exception is propagated back to - * the caller. - * - * The structure and the names comply, except for a few conveniences, - * exactly with the - * JVM specification 1.0. See this paper for - * further details about the structure of a bytecode file. - * - * @version $Id: ClassParser.java,v 1.6 2008/05/30 17:29:14 aclement Exp $ - * @author M. Dahm - */ -public final class ClassParser { - private DataInputStream file; - private String filename; - private int classnameIndex; - private int superclassnameIndex; - private int major, minor; - private int accessflags; - private int[] interfaceIndices; - private ConstantPool cpool; - private Field[] fields; - private Method[] methods; - private Attribute[] attributes; - - private static final int BUFSIZE = 8192; - - /** Parse class from the given stream */ - public ClassParser(InputStream file, String filename) { - this.filename = filename; - if (file instanceof DataInputStream) this.file = (DataInputStream)file; - else this.file = new DataInputStream(new BufferedInputStream(file,BUFSIZE)); - } - - public ClassParser(ByteArrayInputStream baos, String filename) { - this.filename = filename; - this.file = new DataInputStream(baos); - } - - /** Parse class from given .class file */ - public ClassParser(String file_name) throws IOException { - this.filename = file_name; - file = new DataInputStream(new BufferedInputStream(new FileInputStream(file_name),BUFSIZE)); - } - - /** - * Parse the given Java class file and return an object that represents - * the contained data, i.e., constants, methods, fields and commands. - * A ClassFormatException is raised, if the file is not a valid - * .class file. (This does not include verification of the byte code as it - * is performed by the java interpreter). - */ - public JavaClass parse() throws IOException, ClassFormatException { - /****************** Read headers ********************************/ - // Check magic tag of class file - readID(); - - // Get compiler version - readVersion(); - - /****************** Read constant pool and related **************/ - // Read constant pool entries - readConstantPool(); - - // Get class information - readClassInfo(); - - // Get interface information, i.e., implemented interfaces - readInterfaces(); - - /****************** Read class fields and methods ***************/ - // Read class fields, i.e., the variables of the class - readFields(); - - // Read class methods, i.e., the functions in the class - readMethods(); - - // Read class attributes - readAttributes(); - - // Read everything of interest, so close the file - file.close(); - - // Return the information we have gathered in a new object - JavaClass jc= new JavaClass(classnameIndex, superclassnameIndex, - filename, major, minor, accessflags, - cpool, interfaceIndices, fields, - methods, attributes); - return jc; - } - - /** Read information about the attributes of the class */ - private final void readAttributes() { - attributes = AttributeUtils.readAttributes(file,cpool); - } - - /** Read information about the class and its super class */ - private final void readClassInfo() throws IOException { - accessflags = file.readUnsignedShort(); - - /* Interfaces are implicitely abstract, the flag should be set - * according to the JVM specification */ - if((accessflags & Constants.ACC_INTERFACE) != 0) - accessflags |= Constants.ACC_ABSTRACT; - - // don't police it like this... leave higher level verification code to check it. -// if(((access_flags & Constants.ACC_ABSTRACT) != 0) && -// ((access_flags & Constants.ACC_FINAL) != 0 )) -// throw new ClassFormatException("Class can't be both final and abstract"); - - classnameIndex = file.readUnsignedShort(); - superclassnameIndex = file.readUnsignedShort(); - } - - private final void readConstantPool() throws IOException { - try { - cpool = new ConstantPool(file); - } catch (ClassFormatException cfe) { - // add some context if we can - cfe.printStackTrace(); - if (filename!=null) { - String newmessage = "File: '"+filename+"': "+cfe.getMessage(); - throw new ClassFormatException(newmessage); // this loses the old stack trace but I dont think that matters! - } - throw cfe; - } - } - - /** Read information about the fields of the class */ - private final void readFields() throws IOException, ClassFormatException { - int fieldCount = file.readUnsignedShort(); - if (fieldCount == 0) { - fields = Field.NoFields; - } else { - fields = new Field[fieldCount]; - for(int i=0; i < fieldCount; i++) - fields[i] = new Field(file, cpool); - } - } - - /** Check whether the header of the file is ok. Of course, this has - * to be the first action on successive file reads */ - private final void readID() throws IOException { - int magic = 0xCAFEBABE; - if (file.readInt() != magic) - throw new ClassFormatException(filename + " is not a Java .class file"); - } - - private static final int[] NO_INTERFACES = new int[0]; - - /** Read information about the interfaces implemented by this class */ - private final void readInterfaces() throws IOException { - int interfacesCount = file.readUnsignedShort(); - if (interfacesCount==0) { - interfaceIndices = NO_INTERFACES; - } else { - interfaceIndices = new int[interfacesCount]; - for(int i=0; i < interfacesCount; i++) - interfaceIndices[i] = file.readUnsignedShort(); - } - } - - /** Read information about the methods of the class */ - private final void readMethods() throws IOException { - int methodsCount = file.readUnsignedShort(); - if (methodsCount==0) { - methods = Method.NoMethods; - } else { - methods = new Method[methodsCount]; - for(int i=0; i < methodsCount; i++) - methods[i] = new Method(file, cpool); - } - } - - /** Read major and minor version of compiler which created the file */ - private final void readVersion() throws IOException { - minor = file.readUnsignedShort(); - major = file.readUnsignedShort(); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java deleted file mode 100644 index 5c60f818f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java +++ /dev/null @@ -1,180 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Interface to make use of the Visitor pattern programming style. I.e. a class that implements this interface can traverse the - * contents of a Java class just by calling the `accept' method which all classes have. - * - * Implemented by wish of Boris Bokowski. - * - * @version $Id: ClassVisitor.java,v 1.4 2009/09/15 19:40:13 aclement Exp $ - * @author M. Dahm - */ -public interface ClassVisitor { - public void visitCode(Code obj); - - public void visitCodeException(CodeException obj); - - public void visitConstantClass(ConstantClass obj); - - public void visitConstantDouble(ConstantDouble obj); - - public void visitConstantFieldref(ConstantFieldref obj); - - public void visitConstantFloat(ConstantFloat obj); - - public void visitConstantInteger(ConstantInteger obj); - - public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj); - - public void visitConstantLong(ConstantLong obj); - - public void visitConstantMethodref(ConstantMethodref obj); - - public void visitConstantMethodHandle(ConstantMethodHandle obj); - - public void visitConstantNameAndType(ConstantNameAndType obj); - - public void visitConstantMethodType(ConstantMethodType obj); - - public void visitConstantInvokeDynamic(ConstantInvokeDynamic obj); - - public void visitConstantDynamic(ConstantDynamic obj); - - public void visitConstantPool(ConstantPool obj); - - public void visitConstantString(ConstantString obj); - - public void visitConstantModule(ConstantModule obj); - - public void visitConstantPackage(ConstantPackage obj); - - public void visitConstantUtf8(ConstantUtf8 obj); - - public void visitConstantValue(ConstantValue obj); - - public void visitDeprecated(Deprecated obj); - - public void visitExceptionTable(ExceptionTable obj); - - public void visitField(Field obj); - - public void visitInnerClass(InnerClass obj); - - public void visitInnerClasses(InnerClasses obj); - - public void visitJavaClass(JavaClass obj); - - public void visitLineNumber(LineNumber obj); - - public void visitLineNumberTable(LineNumberTable obj); - - public void visitLocalVariable(LocalVariable obj); - - public void visitLocalVariableTable(LocalVariableTable obj); - - public void visitMethod(Method obj); - - public void visitSignature(Signature obj); - - public void visitSourceFile(SourceFile obj); - - public void visitSynthetic(Synthetic obj); - - public void visitBootstrapMethods(BootstrapMethods obj); - - public void visitUnknown(Unknown obj); - - public void visitStackMap(StackMap obj); - - public void visitStackMapEntry(StackMapEntry obj); - - public void visitEnclosingMethod(EnclosingMethod obj); - - public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos obj); - - public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos obj); - - public void visitRuntimeVisibleParameterAnnotations(RuntimeVisParamAnnos obj); - - public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisParamAnnos obj); - - public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos obj); - - public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos obj); - - public void visitAnnotationDefault(AnnotationDefault obj); - - public void visitLocalVariableTypeTable(LocalVariableTypeTable obj); - - public void visitMethodParameters(MethodParameters methodParameters); - - // J9: - public void visitModule(Module module); - public void visitModulePackages(ModulePackages modulePackage); - public void visitModuleMainClass(ModuleMainClass moduleMainClass); - - // J11: - public void visitNestHost(NestHost nestHost); - public void visitNestMembers(NestMembers nestMembers); -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java deleted file mode 100644 index b714e6cab..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java +++ /dev/null @@ -1,388 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a chunk of Java byte code contained in a method. It is instantiated by the - * Attribute.readAttribute() method. A Code attribute contains informations about operand stack, local variables, - * byte code and the exceptions handled within this method. - * - * This attribute has attributes itself, namely LineNumberTable which is used for debugging purposes and - * LocalVariableTable which contains information about the local variables. - * - * @version $Id: Code.java,v 1.9 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - * @see Attribute - * @see CodeException - * @see LineNumberTable - * @see LocalVariableTable - */ -public final class Code extends Attribute { - private int maxStack; // Maximum size of stack used by this method - private int maxLocals; // Number of local variables - private byte[] code; // Actual byte code - private CodeException[] exceptionTable; - private Attribute[] attributes; - private static final CodeException[] NO_EXCEPTIONS = new CodeException[] {}; - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical - * copy. - */ - public Code(Code c) { - this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), c.getCode(), c.getExceptionTable(), c - .getAttributes(), c.getConstantPool()); - } - - Code(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - // Initialize with some default values which will be overwritten later - this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), (byte[]) null, (CodeException[]) null, - (Attribute[]) null, constant_pool); - - int len = file.readInt(); - code = new byte[len]; // Read byte code - file.readFully(code); - - /* - * Read exception table that contains all regions where an exception handler is active, i.e., a try { ... } catch() block. - */ - len = file.readUnsignedShort(); - if (len == 0) { - exceptionTable = NO_EXCEPTIONS; - } else { - exceptionTable = new CodeException[len]; - for (int i = 0; i < len; i++) { - exceptionTable[i] = new CodeException(file); - } - } - - // Read all attributes, eg: LineNumberTable, LocalVariableTable - attributes = AttributeUtils.readAttributes(file, constant_pool); - - /* - * Adjust length, because of setAttributes in this(), s.b. length is incorrect, because it didn't take the internal - * attributes into account yet! Very subtle bug, fixed in 3.1.1. - */ - this.length = length; - } - - /** - * @param name_index Index pointing to the name Code - * @param length Content length in bytes - * @param max_stack Maximum size of stack - * @param max_locals Number of local variables - * @param code Actual byte code - * @param exception_table Table of handled exceptions - * @param attributes Attributes of code: LineNumber or LocalVariable - * @param constant_pool Array of constants - */ - public Code(int name_index, int length, int max_stack, int max_locals, byte[] code, CodeException[] exception_table, - Attribute[] attributes, ConstantPool constant_pool) { - super(Constants.ATTR_CODE, name_index, length, constant_pool); - - this.maxStack = max_stack; - this.maxLocals = max_locals; - - setCode(code); - setExceptionTable(exception_table); - setAttributes(attributes); // Overwrites length! - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitCode(this); - } - - /** - * Dump code attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - - file.writeShort(maxStack); - file.writeShort(maxLocals); - file.writeInt(code.length); - file.write(code, 0, code.length); - - file.writeShort(exceptionTable.length); - for (int i = 0; i < exceptionTable.length; i++) { - exceptionTable[i].dump(file); - } - - file.writeShort(attributes.length); - for (int i = 0; i < attributes.length; i++) { - attributes[i].dump(file); - } - } - - /** - * @return Collection of code attributes. - * @see Attribute - */ - public final Attribute[] getAttributes() { - return attributes; - } - - /** - * @return LineNumberTable of Code, if it has one - */ - public LineNumberTable getLineNumberTable() { - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].tag == Constants.ATTR_LINE_NUMBER_TABLE) { - return (LineNumberTable) attributes[i]; - } - } - return null; - } - - /** - * @return LocalVariableTable of Code, if it has one - */ - public LocalVariableTable getLocalVariableTable() { - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].tag == Constants.ATTR_LOCAL_VARIABLE_TABLE) { - return (LocalVariableTable) attributes[i]; - } - } - return null; - } - - /** - * @return Actual byte code of the method. - */ - public final byte[] getCode() { - return code; - } - - /** - * @return Table of handled exceptions. - * @see CodeException - */ - public final CodeException[] getExceptionTable() { - return exceptionTable; - } - - /** - * @return Number of local variables. - */ - public final int getMaxLocals() { - return maxLocals; - } - - /** - * @return Maximum size of stack used by this method. - */ - - public final int getMaxStack() { - return maxStack; - } - - /** - * @return the internal length of this code attribute (minus the first 6 bytes) and excluding all its attributes - */ - private final int getInternalLength() { - return 2 /* max_stack */+ 2 /* max_locals */+ 4 /* code length */ - + (code == null ? 0 : code.length) /* byte-code */ - + 2 /* exception-table length */ - + 8 * (exceptionTable == null ? 0 : exceptionTable.length) /* exception table */ - + 2 /* attributes count */; - } - - /** - * @return the full size of this code attribute, minus its first 6 bytes, including the size of all its contained attributes - */ - private final int calculateLength() { - int len = 0; - if (attributes != null) { - for (int i = 0; i < attributes.length; i++) { - len += attributes[i].length + 6 /* attribute header size */; - } - } - return len + getInternalLength(); - } - - /** - * @param attributes. - */ - public final void setAttributes(Attribute[] attributes) { - this.attributes = attributes; - length = calculateLength(); // Adjust length - } - - /** - * @param code byte code - */ - public final void setCode(byte[] code) { - this.code = code; - } - - /** - * @param exception_table exception table - */ - public final void setExceptionTable(CodeException[] exception_table) { - this.exceptionTable = exception_table; - } - - /** - * @param max_locals maximum number of local variables - */ - public final void setMaxLocals(int max_locals) { - this.maxLocals = max_locals; - } - - /** - * @param max_stack maximum stack size - */ - public final void setMaxStack(int max_stack) { - this.maxStack = max_stack; - } - - /** - * @return String representation of code chunk. - */ - public final String toString(boolean verbose) { - StringBuffer buf; - - buf = new StringBuffer("Code(max_stack = " + maxStack + ", max_locals = " + maxLocals + ", code_length = " + code.length - + ")\n" + Utility.codeToString(code, cpool, 0, -1, verbose)); - - if (exceptionTable.length > 0) { - buf.append("\nException handler(s) = \n" + "From\tTo\tHandler\tType\n"); - - for (int i = 0; i < exceptionTable.length; i++) { - buf.append(exceptionTable[i].toString(cpool, verbose) + "\n"); - } - } - - if (attributes.length > 0) { - buf.append("\nAttribute(s) = \n"); - - for (int i = 0; i < attributes.length; i++) { - buf.append(attributes[i].toString() + "\n"); - } - } - - return buf.toString(); - } - - /** - * @return String representation of code chunk. - */ - @Override - public final String toString() { - return toString(true); - } - - // /** - // * @return deep copy of this attribute - // */ - // public Attribute copy(ConstantPool constant_pool) { - // Code c = (Code)clone(); - // c.code = (byte[])code.clone(); - // c.cpool = constant_pool; - // - // c.exceptionTable = new CodeException[exceptionTable.length]; - // for(int i=0; i < exceptionTable.length; i++) - // c.exceptionTable[i] = exceptionTable[i].copy(); - // - // c.attributes = new Attribute[attributes.length]; - // for(int i=0; i < attributes.length; i++) - // c.attributes[i] = attributes[i].copy(constant_pool); - // - // return c; - // } - - /** - * Returns the same as toString(true) except that the attribute information isn't included (line numbers). Can be used to check - * whether two pieces of code are equivalent. - */ - public String getCodeString() { - StringBuffer codeString = new StringBuffer(); - codeString.append("Code(max_stack = ").append(maxStack); - codeString.append(", max_locals = ").append(maxLocals); - codeString.append(", code_length = ").append(code.length).append(")\n"); - codeString.append(Utility.codeToString(code, cpool, 0, -1, true)); - if (exceptionTable.length > 0) { - codeString.append("\n").append("Exception entries = ").append(exceptionTable.length).append("\n"); - for (int i = 0; i < exceptionTable.length; i++) { - CodeException exc = exceptionTable[i]; - int type = exc.getCatchType(); - String name = "finally"; - if (type != 0) { - name = this.cpool.getConstantString(type, Constants.CONSTANT_Class); - } - codeString.append(name).append("["); - codeString.append(exc.getStartPC()).append(">").append(exc.getEndPC()).append("]\n"); - } - } - return codeString.toString(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/CodeException.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/CodeException.java deleted file mode 100644 index 72b4d539e..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/CodeException.java +++ /dev/null @@ -1,196 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.Constants; -import java.io.*; - -/** - * This class represents an entry in the exception table of the Code - * attribute and is used only there. It contains a range in which a - * particular exception handler is active. - * - * @version $Id: CodeException.java,v 1.3 2008/05/28 23:53:02 aclement Exp $ - * @author M. Dahm - * @see Code - */ -public final class CodeException implements Cloneable, Constants, Node, Serializable { - private int start_pc; // Range in the code the exception handler is - private int end_pc; // active. start_pc is inclusive, end_pc exclusive - private int handler_pc; /* Starting address of exception handler, i.e., - * an offset from start of code. - */ - private int catch_type; /* If this is zero the handler catches any - * exception, otherwise it points to the - * exception class which is to be caught. - */ - - public CodeException(CodeException c) { - this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); - } - - CodeException(DataInputStream file) throws IOException { - start_pc = file.readUnsignedShort(); - end_pc = file.readUnsignedShort(); - handler_pc = file.readUnsignedShort(); - catch_type = file.readUnsignedShort(); - } - - public CodeException(int start_pc, int end_pc, int handler_pc, int catch_type) { - this.start_pc = start_pc; - this.end_pc = end_pc; - this.handler_pc = handler_pc; - this.catch_type = catch_type; - } - - public void accept(ClassVisitor v) { - v.visitCodeException(this); - } - - public final void dump(DataOutputStream file) throws IOException { - file.writeShort(start_pc); - file.writeShort(end_pc); - file.writeShort(handler_pc); - file.writeShort(catch_type); - } - - /** - * @return 0, if the handler catches any exception, otherwise it points to - * the exception class which is to be caught. - */ - public final int getCatchType() { return catch_type; } - - /** - * @return Exclusive end index of the region where the handler is active. - */ - public final int getEndPC() { return end_pc; } - - /** - * @return Starting address of exception handler, relative to the code. - */ - public final int getHandlerPC() { return handler_pc; } - - /** - * @return Inclusive start index of the region where the handler is active. - */ - public final int getStartPC() { return start_pc; } - - /** - * @param catch_type. - */ - public final void setCatchType(int catch_type) { - this.catch_type = catch_type; - } - - /** - * @param end_pc end of handled block - */ - public final void setEndPC(int end_pc) { - this.end_pc = end_pc; - } - - /** - * @param handler_pc where the actual code is - */ - public final void setHandlerPC(int handler_pc) { - this.handler_pc = handler_pc; - } - - /** - * @param start_pc start of handled block - */ - public final void setStartPC(int start_pc) { - this.start_pc = start_pc; - } - - /** - * @return String representation. - */ - public final String toString() { - return "CodeException(start_pc = " + start_pc + - ", end_pc = " + end_pc + - ", handler_pc = " + handler_pc + ", catch_type = " + catch_type + ")"; - } - - /** - * @return String representation. - */ - public final String toString(ConstantPool cp, boolean verbose) { - String str; - - if(catch_type == 0) - str = "(0)"; - else - str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false) + - (verbose? "(" + catch_type + ")" : ""); - - return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; - } - - public final String toString(ConstantPool cp) { - return toString(cp, true); - } - - /** - * @return deep copy of this object - */ - public CodeException copy() { - try { - return (CodeException)clone(); - } catch(CloneNotSupportedException e) {} - - return null; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java deleted file mode 100644 index d391b75ea..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java +++ /dev/null @@ -1,149 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * Abstract superclass for classes to represent the different constant types in the constant pool of a class file. The classes keep - * closely to the JVM specification. - * - * @version $Id: Constant.java,v 1.5 2009/09/10 15:35:04 aclement Exp $ - * @author M. Dahm - */ -public abstract class Constant implements Cloneable, Node { - - protected byte tag; - - Constant(byte tag) { - this.tag = tag; - } - - public final byte getTag() { - return tag; - } - - @Override - public String toString() { - return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]"; - } - - public abstract void accept(ClassVisitor v); - - public abstract void dump(DataOutputStream dataOutputStream) throws IOException; - - public abstract Object getValue(); - - public Constant copy() { - try { - return (Constant) super.clone(); - } catch (CloneNotSupportedException e) { - } - - return null; - } - - @Override - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } - - static final Constant readConstant(DataInputStream dis) throws IOException, ClassFormatException { - byte b = dis.readByte(); - switch (b) { - case Constants.CONSTANT_Class: - return new ConstantClass(dis); - case Constants.CONSTANT_NameAndType: - return new ConstantNameAndType(dis); - case Constants.CONSTANT_Utf8: - return new ConstantUtf8(dis); - case Constants.CONSTANT_Fieldref: - return new ConstantFieldref(dis); - case Constants.CONSTANT_Methodref: - return new ConstantMethodref(dis); - case Constants.CONSTANT_InterfaceMethodref: - return new ConstantInterfaceMethodref(dis); - case Constants.CONSTANT_String: - return new ConstantString(dis); - case Constants.CONSTANT_Integer: - return new ConstantInteger(dis); - case Constants.CONSTANT_Float: - return new ConstantFloat(dis); - case Constants.CONSTANT_Long: - return new ConstantLong(dis); - case Constants.CONSTANT_Double: - return new ConstantDouble(dis); - case Constants.CONSTANT_MethodHandle: - return new ConstantMethodHandle(dis); - case Constants.CONSTANT_MethodType: - return new ConstantMethodType(dis); - case Constants.CONSTANT_InvokeDynamic: - return new ConstantInvokeDynamic(dis); - case Constants.CONSTANT_Module: - return new ConstantModule(dis); - case Constants.CONSTANT_Package: - return new ConstantPackage(dis); - case Constants.CONSTANT_Dynamic: - return new ConstantDynamic(dis); - default: - throw new ClassFormatException("Invalid byte tag in constant pool: " + b); - } - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantCP.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantCP.java deleted file mode 100644 index a476c4d15..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantCP.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * Abstract super class for Fieldref and Methodref constants. - * - * @version $Id: ConstantCP.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @see ConstantFieldref - * @see ConstantMethodref - * @see ConstantInterfaceMethodref - */ -public abstract class ConstantCP extends Constant { - - protected int classIndex, nameAndTypeIndex; - - ConstantCP(byte tag, DataInputStream file) throws IOException { - this(tag, file.readUnsignedShort(), file.readUnsignedShort()); - } - - protected ConstantCP(byte tag, int classIndex, int nameAndTypeIndex) { - super(tag); - this.classIndex = classIndex; - this.nameAndTypeIndex = nameAndTypeIndex; - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(classIndex); - file.writeShort(nameAndTypeIndex); - } - - public final int getClassIndex() { - return classIndex; - } - - public final int getNameAndTypeIndex() { - return nameAndTypeIndex; - } - - public String getClass(ConstantPool cp) { - return cp.constantToString(classIndex, Constants.CONSTANT_Class); - } - - @Override - public final String toString() { - return super.toString() + "(classIndex = " + classIndex + ", nameAndTypeIndex = " + nameAndTypeIndex + ")"; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantClass.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantClass.java deleted file mode 100644 index 883f3b25f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantClass.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to a (external) class. - * - * @version $Id: ConstantClass.java,v 1.6 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @author Andy Clement - */ -public final class ConstantClass extends Constant { - private int nameIndex; - - ConstantClass(DataInputStream file) throws IOException { - super(Constants.CONSTANT_Class); - this.nameIndex = file.readUnsignedShort(); - } - - public ConstantClass(int nameIndex) { - super(Constants.CONSTANT_Class); - this.nameIndex = nameIndex; - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantClass(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(nameIndex); - } - - public final int getNameIndex() { - return nameIndex; - } - - @Override - public Integer getValue() { - return nameIndex; - } - - public String getClassname(ConstantPool cpool) { - return cpool.getConstantUtf8(nameIndex).getValue(); - } - - @Override - public final String toString() { - return super.toString() + "(name_index = " + nameIndex + ")"; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantDouble.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantDouble.java deleted file mode 100644 index 813aec72a..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantDouble.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to a Double object. - * - * @version $Id: ConstantDouble.java,v 1.6 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @author Andy Clement - */ -public final class ConstantDouble extends Constant implements SimpleConstant { - private double value; - - public ConstantDouble(double value) { - super(Constants.CONSTANT_Double); - this.value = value; - } - - ConstantDouble(DataInputStream file) throws IOException { - this(file.readDouble()); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantDouble(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeDouble(value); - } - - @Override - public final String toString() { - return super.toString() + "(bytes = " + value + ")"; - } - - @Override - public Double getValue() { - return value; - } - - public String getStringValue() { - return Double.toString(value); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantDynamic.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantDynamic.java deleted file mode 100644 index 40100f83b..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantDynamic.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to the name and signature of a field or method. - * - * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.10 - * - * @author Andy Clement - * @see Constant - */ -public final class ConstantDynamic extends Constant { - private final int bootstrapMethodAttrIndex; - private final int nameAndTypeIndex; - - ConstantDynamic(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort()); - } - - public ConstantDynamic(int readUnsignedShort, int nameAndTypeIndex) { - super(Constants.CONSTANT_InvokeDynamic); - this.bootstrapMethodAttrIndex = readUnsignedShort; - this.nameAndTypeIndex = nameAndTypeIndex; - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(bootstrapMethodAttrIndex); - file.writeShort(nameAndTypeIndex); - } - - public final int getNameAndTypeIndex() { - return nameAndTypeIndex; - } - - public final int getBootstrapMethodAttrIndex() { - return bootstrapMethodAttrIndex; - } - - @Override - public final String toString() { - return super.toString() + "(bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex + ",nameAndTypeIndex=" + nameAndTypeIndex + ")"; - } - - @Override - public String getValue() { - return toString(); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantDynamic(this); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantFieldref.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantFieldref.java deleted file mode 100644 index 056f3e3fd..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantFieldref.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a constant pool reference to a field. - * - * @version $Id: ConstantFieldref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - */ -public final class ConstantFieldref extends ConstantCP { - - ConstantFieldref(DataInputStream file) throws IOException { - super(Constants.CONSTANT_Fieldref, file); - } - - public ConstantFieldref(int class_index, int name_and_type_index) { - super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantFieldref(this); - } - - @Override - public String getValue() { - return toString(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantFloat.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantFloat.java deleted file mode 100644 index 985c28125..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantFloat.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to a float object. - * - * @version $Id: ConstantFloat.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @see Constant - */ -public final class ConstantFloat extends Constant implements SimpleConstant { - private float floatValue; - - public ConstantFloat(float floatValue) { - super(Constants.CONSTANT_Float); - this.floatValue = floatValue; - } - - ConstantFloat(DataInputStream file) throws IOException { - this(file.readFloat()); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantFloat(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeFloat(floatValue); - } - - @Override - public final Float getValue() { - return floatValue; - } - - public final String getStringValue() { - return Float.toString(floatValue); - } - - @Override - public final String toString() { - return super.toString() + "(bytes = " + floatValue + ")"; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInteger.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInteger.java deleted file mode 100644 index 415706eed..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInteger.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to an int object. - * - * @version $Id: ConstantInteger.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @see Constant - */ -public final class ConstantInteger extends Constant implements SimpleConstant { - private int intValue; - - public ConstantInteger(int intValue) { - super(Constants.CONSTANT_Integer); - this.intValue = intValue; - } - - ConstantInteger(DataInputStream file) throws IOException { - this(file.readInt()); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantInteger(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeInt(intValue); - } - - @Override - public final String toString() { - return super.toString() + "(bytes = " + intValue + ")"; - } - - @Override - public Integer getValue() { - return intValue; - } - - public int getIntValue() { - return intValue; - } - - public String getStringValue() { - return Integer.toString(intValue); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java deleted file mode 100644 index b973c726e..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a constant pool reference to an interface method. - * - * @version $Id: ConstantInterfaceMethodref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - */ -public final class ConstantInterfaceMethodref extends ConstantCP { - - ConstantInterfaceMethodref(DataInputStream file) throws IOException { - super(Constants.CONSTANT_InterfaceMethodref, file); - } - - public ConstantInterfaceMethodref(int classIndex, int nameAndTypeIndex) { - super(Constants.CONSTANT_InterfaceMethodref, classIndex, nameAndTypeIndex); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantInterfaceMethodref(this); - } - - @Override - public String getValue() { - return toString(); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java deleted file mode 100644 index 0d263aa65..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to the name and signature of a field or method. - * - * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.10 - * - * @author Andy Clement - * @see Constant - */ -public final class ConstantInvokeDynamic extends Constant { - private final int bootstrapMethodAttrIndex; - private final int nameAndTypeIndex; - - ConstantInvokeDynamic(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort()); - } - - public ConstantInvokeDynamic(int readUnsignedShort, int nameAndTypeIndex) { - super(Constants.CONSTANT_InvokeDynamic); - this.bootstrapMethodAttrIndex = readUnsignedShort; - this.nameAndTypeIndex = nameAndTypeIndex; - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(bootstrapMethodAttrIndex); - file.writeShort(nameAndTypeIndex); - } -// -// public final byte getReferenceKind() { -// return bootstrapMethodAttrIndex; -// } -// -// public final String getName(ConstantPool cp) { -// return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); -// } -// -// public final int getSignatureIndex() { -// return referenceIndex; -// } -// -// public final String getSignature(ConstantPool cp) { -// return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); -// } - - public final int getNameAndTypeIndex() { - return nameAndTypeIndex; - } - - public final int getBootstrapMethodAttrIndex() { - return bootstrapMethodAttrIndex; - } - - @Override - public final String toString() { - return super.toString() + "(bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex + ",nameAndTypeIndex=" + nameAndTypeIndex + ")"; - } - - @Override - public String getValue() { - return toString(); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantInvokeDynamic(this); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantLong.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantLong.java deleted file mode 100644 index 1d56b98a3..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantLong.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to a long object. - * - * @version $Id: ConstantLong.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @see Constant - */ -public final class ConstantLong extends Constant implements SimpleConstant { - private long longValue; - - public ConstantLong(long longValue) { - super(Constants.CONSTANT_Long); - this.longValue = longValue; - } - - ConstantLong(DataInputStream file) throws IOException { - this(file.readLong()); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantLong(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeLong(longValue); - } - - @Override - public final Long getValue() { - return longValue; - } - - public final String getStringValue() { - return Long.toString(longValue); - } - - @Override - public final String toString() { - return super.toString() + "(longValue = " + longValue + ")"; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java deleted file mode 100644 index 712a13f4c..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to the name and signature of a field or method. - * - * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.8 - * - * @author Andy Clement - * @see Constant - */ -public final class ConstantMethodHandle extends Constant { - private byte referenceKind; - private int referenceIndex; - - ConstantMethodHandle(DataInputStream file) throws IOException { - this(file.readByte(), file.readUnsignedShort()); - } - - public ConstantMethodHandle(byte referenceKind, int referenceIndex) { - super(Constants.CONSTANT_MethodHandle); - this.referenceKind = referenceKind; - this.referenceIndex = referenceIndex; - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeByte(referenceKind); - file.writeShort(referenceIndex); - } - - public final byte getReferenceKind() { - return referenceKind; - } - - public final int getReferenceIndex() { - return referenceIndex; - } - - @Override - public final String toString() { - return super.toString() + "(referenceKind=" + referenceKind + ",referenceIndex=" + referenceIndex + ")"; - } - - @Override - public String getValue() { - return toString(); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantMethodHandle(this); - } - - public static String kindToString(byte kind) { - switch (kind) { - case 1: return "getfield"; - case 2: return "getstatic"; - case 3: return "putfield"; - case 4: return "putstatic"; - case 5: return "invokevirtual"; - case 6: return "invokestatic"; - case 7: return "invokespecial"; - case 8: return "newinvokespecial"; - case 9: return "invokeinterface"; - default: - return "nyi"; - } - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodType.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodType.java deleted file mode 100644 index 867e7eb0a..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodType.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to the name and signature of a field or method. - * - * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.9 - * - * @author Andy Clement - * @see Constant - */ -public final class ConstantMethodType extends Constant { - private int descriptorIndex; - - ConstantMethodType(DataInputStream file) throws IOException { - this(file.readUnsignedShort()); - } - - public ConstantMethodType(int descriptorIndex) { - super(Constants.CONSTANT_MethodType); - this.descriptorIndex = descriptorIndex; - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(descriptorIndex); - } - - public final int getDescriptorIndex() { - return descriptorIndex; - } - -// public final String getName(ConstantPool cp) { -// return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); -// } -// -// public final int getSignatureIndex() { -// return referenceIndex; -// } -// -// public final String getSignature(ConstantPool cp) { -// return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); -// } - - @Override - public final String toString() { - return super.toString() + "(descriptorIndex=" + descriptorIndex + ")"; - } - - @Override - public String getValue() { - return toString(); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantMethodType(this); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodref.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodref.java deleted file mode 100644 index 29b37c5d7..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantMethodref.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a constant pool reference to a method. - * - * @version $Id: ConstantMethodref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - */ -public final class ConstantMethodref extends ConstantCP { - - ConstantMethodref(DataInputStream file) throws IOException { - super(Constants.CONSTANT_Methodref, file); - } - - public ConstantMethodref(int class_index, int name_and_type_index) { - super(Constants.CONSTANT_Methodref, class_index, name_and_type_index); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantMethodref(this); - } - - @Override - public String getValue() { - return toString(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java deleted file mode 100644 index efe4d3a1b..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java +++ /dev/null @@ -1,111 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2017 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * Represents a module. - * - * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.11 - * - * @author Andy Clement - */ -public final class ConstantModule extends Constant { - - private int nameIndex; - - ConstantModule(DataInputStream file) throws IOException { - this(file.readUnsignedShort()); - } - - public ConstantModule(int nameIndex) { - super(Constants.CONSTANT_Module); - this.nameIndex = nameIndex; - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantModule(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(nameIndex); - } - - @Override - public Integer getValue() { - return nameIndex; - } - - public final int getNameIndex() { - return nameIndex; - } - - @Override - public final String toString() { - return super.toString() + "(name_index = " + nameIndex + ")"; - } - - public String getModuleName(ConstantPool cpool) { - Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); - return ((ConstantUtf8) c).getValue(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java deleted file mode 100644 index 8af80fab2..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to the name and signature of a field or method. - * - * @version $Id: ConstantNameAndType.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @see Constant - */ -public final class ConstantNameAndType extends Constant { - private int name_index; // Name of field/method - private int signature_index; // and its signature. - - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantNameAndType(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort()); - } - - /** - * @param name_index Name of field/method - * @param signature_index and its signature - */ - public ConstantNameAndType(int name_index, int signature_index) { - super(Constants.CONSTANT_NameAndType); - this.name_index = name_index; - this.signature_index = signature_index; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitConstantNameAndType(this); - } - - /** - * Dump name and signature index to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(name_index); - file.writeShort(signature_index); - } - - /** - * @return Name index in constant pool of field/method name. - */ - public final int getNameIndex() { - return name_index; - } - - /** - * @return name - */ - public final String getName(ConstantPool cp) { - return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); - } - - /** - * @return Index in constant pool of field/method signature. - */ - public final int getSignatureIndex() { - return signature_index; - } - - /** - * @return signature - */ - public final String getSignature(ConstantPool cp) { - return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); - } - - @Override - public final String toString() { - return super.toString() + "(name_index = " + name_index + ", signature_index = " + signature_index + ")"; - } - - @Override - public String getValue() { - return toString(); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantObject.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantObject.java deleted file mode 100644 index 70e9b1d0d..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantObject.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * This interface denotes those constants that have a "natural" value, such as ConstantLong, ConstantString, etc.. - * - * @version $Id: ConstantObject.java,v 1.4 2009/09/10 03:59:33 aclement Exp $ - * @author M. Dahm - * @see Constant - */ -public interface ConstantObject { - public abstract Object getConstantValue(ConstantPool cp); -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java deleted file mode 100644 index 70f22c749..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java +++ /dev/null @@ -1,111 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2017 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * Represents a module. - * - * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.12 - * - * @author Andy Clement - */ -public final class ConstantPackage extends Constant { - - private int nameIndex; - - ConstantPackage(DataInputStream file) throws IOException { - this(file.readUnsignedShort()); - } - - public ConstantPackage(int nameIndex) { - super(Constants.CONSTANT_Package); - this.nameIndex = nameIndex; - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantPackage(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(nameIndex); - } - - @Override - public Integer getValue() { - return nameIndex; - } - - public final int getNameIndex() { - return nameIndex; - } - - @Override - public final String toString() { - return super.toString() + "(name_index = " + nameIndex + ")"; - } - - public String getPackageName(ConstantPool cpool) { - Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); - return ((ConstantUtf8) c).getValue(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java deleted file mode 100644 index 0430e28ba..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java +++ /dev/null @@ -1,816 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.generic.ArrayType; -import org.aspectj.apache.bcel.generic.ObjectType; - -/** - * This class represents the constant pool, i.e., a table of constants, of a parsed classfile. It may contain null references, due - * to the JVM specification that skips an entry after an 8-byte constant (double, long) entry. - */ -public class ConstantPool implements Node { - private Constant[] pool; - private int poolSize; // number of entries in the pool (could be < pool.length as the array is resized in 'chunks') - - private Map utf8Cache = new HashMap(); - private Map methodCache = new HashMap(); - private Map fieldCache = new HashMap(); - - public int getSize() { - return poolSize; - } - - public ConstantPool() { - pool = new Constant[10]; - poolSize = 0; - } - - public ConstantPool(Constant[] constants) { - pool = constants; - poolSize = (constants == null ? 0 : constants.length); - } - - ConstantPool(DataInputStream file) throws IOException { - byte tag; - poolSize = file.readUnsignedShort(); - pool = new Constant[poolSize]; - // pool[0] is unused by the compiler and may be used freely by the implementation - for (int i = 1; i < poolSize; i++) { - pool[i] = Constant.readConstant(file); - tag = pool[i].getTag(); - if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) { - i++; - } - } - } - - public Constant getConstant(int index, byte tag) { - Constant c = getConstant(index); - // if (c == null) throw new ClassFormatException("Constant pool at index " + index + " is null."); - if (c.tag == tag) - return c; - throw new ClassFormatException("Expected class '" + Constants.CONSTANT_NAMES[tag] + "' at index " + index + " and found " - + c); - } - - public Constant getConstant(int index) { - try { - return pool[index]; - } catch (ArrayIndexOutOfBoundsException aioobe) { - throw new ClassFormatException("Index " + index + " into constant pool (size:" + poolSize + ") is invalid"); - } - } - - /** - * @return deep copy of this constant pool - */ - public ConstantPool copy() { - Constant[] newConstants = new Constant[poolSize]; // use the correct size - for (int i = 1; i < poolSize; i++) { - if (pool[i] != null) { - newConstants[i] = pool[i].copy(); - } - } - return new ConstantPool(newConstants); - } - - /** - * Get string from constant pool and bypass the indirection of `ConstantClass' and `ConstantString' objects. I.e. these classes - * have an index field that points to another entry of the constant pool of type `ConstantUtf8' which contains the real data. - * - * @param index Index in constant pool - * @param tag Tag of expected constant, either ConstantClass or ConstantString - * @return Contents of string reference - * @see ConstantClass - * @see ConstantString - * @throws ClassFormatException - */ - public String getConstantString(int index, byte tag) throws ClassFormatException { - Constant c = getConstant(index, tag); - int i; - /* - * This switch() is not that elegant, since the two classes have the same contents, they just differ in the name of the - * index field variable. But we want to stick to the JVM naming conventions closely though we could have solved these more - * elegantly by using the same variable name or by subclassing. - */ - // OPTIMIZE remove the difference - use the an interface and same index methods for string ref id - switch (tag) { - case Constants.CONSTANT_Class: - i = ((ConstantClass) c).getNameIndex(); - break; - case Constants.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - break; - default: - throw new RuntimeException("getConstantString called with illegal tag " + tag); - } - // Finally get the string from the constant pool - c = getConstant(i, Constants.CONSTANT_Utf8); - return ((ConstantUtf8) c).getValue(); - } - - /** - * Resolve constant to a string representation. - */ - public String constantToString(Constant c) { - String str; - int i; - - switch (c.tag) { - case Constants.CONSTANT_Class: - i = ((ConstantClass) c).getNameIndex(); - c = getConstant(i, Constants.CONSTANT_Utf8); - str = Utility.compactClassName(((ConstantUtf8) c).getValue(), false); - break; - - case Constants.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - c = getConstant(i, Constants.CONSTANT_Utf8); - str = "\"" + escape(((ConstantUtf8) c).getValue()) + "\""; - break; - - case Constants.CONSTANT_Utf8: - case Constants.CONSTANT_Double: - case Constants.CONSTANT_Float: - case Constants.CONSTANT_Long: - case Constants.CONSTANT_Integer: - str = ((SimpleConstant) c).getStringValue(); - break; - - case Constants.CONSTANT_NameAndType: - str = (constantToString(((ConstantNameAndType) c).getNameIndex(), Constants.CONSTANT_Utf8) + " " + constantToString( - ((ConstantNameAndType) c).getSignatureIndex(), Constants.CONSTANT_Utf8)); - break; - - case Constants.CONSTANT_InterfaceMethodref: - case Constants.CONSTANT_Methodref: - case Constants.CONSTANT_Fieldref: - str = (constantToString(((ConstantCP) c).getClassIndex(), Constants.CONSTANT_Class) + "." + constantToString( - ((ConstantCP) c).getNameAndTypeIndex(), Constants.CONSTANT_NameAndType)); - break; - - case Constants.CONSTANT_InvokeDynamic: - ConstantInvokeDynamic cID = ((ConstantInvokeDynamic)c); - return "#"+cID.getBootstrapMethodAttrIndex()+"."+constantToString(cID.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType); - - case Constants.CONSTANT_MethodHandle: - ConstantMethodHandle cMH = ((ConstantMethodHandle)c); - return cMH.getReferenceKind()+":"+constantToString(cMH.getReferenceIndex(),Constants.CONSTANT_Methodref); - - case Constants.CONSTANT_MethodType: - ConstantMethodType cMT = (ConstantMethodType)c; - return constantToString(cMT.getDescriptorIndex(),Constants.CONSTANT_Utf8); - - case Constants.CONSTANT_Module: - ConstantModule cM = (ConstantModule)c; - return "Module:"+constantToString(cM.getNameIndex(),Constants.CONSTANT_Utf8); - - case Constants.CONSTANT_Package: - ConstantPackage cP = (ConstantPackage)c; - return "Package:"+constantToString(cP.getNameIndex(),Constants.CONSTANT_Utf8); - - default: // Never reached - throw new RuntimeException("Unknown constant type " + c.tag); - } - - return str; - } - - private static final String escape(String str) { - int len = str.length(); - StringBuffer buf = new StringBuffer(len + 5); - char[] ch = str.toCharArray(); - - for (int i = 0; i < len; i++) { - switch (ch[i]) { - case '\n': - buf.append("\\n"); - break; - case '\r': - buf.append("\\r"); - break; - case '\t': - buf.append("\\t"); - break; - case '\b': - buf.append("\\b"); - break; - case '"': - buf.append("\\\""); - break; - default: - buf.append(ch[i]); - } - } - - return buf.toString(); - } - - public String constantToString(int index, byte tag) { - Constant c = getConstant(index, tag); - return constantToString(c); - } - - public String constantToString(int index) { - return constantToString(getConstant(index)); - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantPool(this); - } - - public Constant[] getConstantPool() { - return pool; - } // TEMPORARY, DONT LIKE PASSING THIS DATA OUT! - - public void dump(DataOutputStream file) throws IOException { - file.writeShort(poolSize); - for (int i = 1; i < poolSize; i++) - if (pool[i] != null) - pool[i].dump(file); - } - - public ConstantUtf8 getConstantUtf8(int index) { - Constant c = getConstant(index); - assert c != null; - assert c.tag == Constants.CONSTANT_Utf8; - return (ConstantUtf8) c; - } - - public ConstantModule getConstantModule(int index) { - Constant c = getConstant(index); - assert c != null; - assert c.tag == Constants.CONSTANT_Module; - return (ConstantModule)c; - } - - public ConstantPackage getConstantPackage(int index) { - Constant c = getConstant(index); - assert c != null; - assert c.tag == Constants.CONSTANT_Package; - return (ConstantPackage)c; - } - - public String getConstantString_CONSTANTClass(int index) { - ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class); - index = c.getNameIndex(); - return ((ConstantUtf8) getConstant(index, Constants.CONSTANT_Utf8)).getValue(); - } - - public int getLength() { - return poolSize; - } - - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - - for (int i = 1; i < poolSize; i++) - buf.append(i + ")" + pool[i] + "\n"); - - return buf.toString(); - } - - public int lookupInteger(int n) { - for (int i = 1; i < poolSize; i++) { - if (pool[i] instanceof ConstantInteger) { - ConstantInteger c = (ConstantInteger) pool[i]; - if (c.getValue() == n) - return i; - } - } - return -1; - } - - public int lookupUtf8(String string) { - Integer pos = utf8Cache.get(string); - if (pos != null) { - return pos; - } - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_Utf8) { - if (((ConstantUtf8) c).getValue().equals(string)) { - utf8Cache.put(string, i); - return i; - } - } - } - return -1; - } - - public int lookupClass(String classname) { - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_Class) { - int cIndex = ((ConstantClass) c).getNameIndex(); - String cName = ((ConstantUtf8) pool[cIndex]).getValue(); - if (cName.equals(classname)) - return i; - } - } - return -1; - } - - public int addUtf8(String n) { - int ret = lookupUtf8(n); - if (ret != -1) - return ret; - adjustSize(); - ret = poolSize; - pool[poolSize++] = new ConstantUtf8(n); - return ret; - } - - public int addInteger(int n) { - int ret = lookupInteger(n); - if (ret != -1) - return ret; - adjustSize(); - ret = poolSize; - pool[poolSize++] = new ConstantInteger(n); - return ret; - } - - public int addArrayClass(ArrayType type) { - return addClass(type.getSignature()); - } - - public int addClass(ObjectType type) { - return addClass(type.getClassName()); - } - - public int addClass(String classname) { - String toAdd = classname.replace('.', '/'); - int ret = lookupClass(toAdd); - if (ret != -1) - return ret; - adjustSize(); - ConstantClass c = new ConstantClass(addUtf8(toAdd)); - ret = poolSize; - pool[poolSize++] = c; - return ret; - } - - private void adjustSize() { - if (poolSize + 3 >= pool.length) { - Constant[] cs = pool; - pool = new Constant[cs.length + 8]; - System.arraycopy(cs, 0, pool, 0, cs.length); - } - if (poolSize == 0) - poolSize = 1; // someone about to do something in here! - } - - public int addFieldref(String class_name, String field_name, String signature) { - int ret = lookupFieldref(class_name, field_name, signature); - int class_index, name_and_type_index; - - if (ret != -1) - return ret; - - adjustSize(); - - class_index = addClass(class_name); - name_and_type_index = addNameAndType(field_name, signature); - ret = poolSize; - pool[poolSize++] = new ConstantFieldref(class_index, name_and_type_index); - - return ret; - } - - public int lookupFieldref(String searchClassname, String searchFieldname, String searchSignature) { - searchClassname = searchClassname.replace('.', '/'); - String k = new StringBuffer().append(searchClassname).append(searchFieldname).append(searchSignature).toString(); - Integer pos = fieldCache.get(k); - if (pos != null) - return pos.intValue(); - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_Fieldref) { - ConstantFieldref cfr = (ConstantFieldref) c; - ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; - - // check the class - int cIndex = cfr.getClassIndex(); - ConstantClass cc = (ConstantClass) pool[cIndex]; - String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); - if (!cName.equals(searchClassname)) - continue; - - // check the name and type - String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); - if (!name.equals(searchFieldname)) - continue; // not this one - String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); - if (!typeSignature.equals(searchSignature)) - continue; - fieldCache.put(k, new Integer(i)); - return i; - } - } - return -1; - } - - public int addNameAndType(String name, String signature) { - int ret = lookupNameAndType(name, signature); - if (ret != -1) - return ret; - adjustSize(); - int name_index = addUtf8(name); - int signature_index = addUtf8(signature); - ret = poolSize; - pool[poolSize++] = new ConstantNameAndType(name_index, signature_index); - return ret; - } - - public int lookupNameAndType(String searchName, String searchTypeSignature) { - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_NameAndType) { - ConstantNameAndType cnat = (ConstantNameAndType) c; - String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); - if (!name.equals(searchName)) - continue; // not this one - String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); - if (!typeSignature.equals(searchTypeSignature)) - continue; - return i; - } - } - return -1; - } - - public int addFloat(float f) { - int ret = lookupFloat(f); - if (ret != -1) - return ret; - adjustSize(); - ret = poolSize; - pool[poolSize++] = new ConstantFloat(f); - return ret; - } - - public int lookupFloat(float f) { - int bits = Float.floatToIntBits(f); - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_Float) { - ConstantFloat cf = (ConstantFloat) c; - if (Float.floatToIntBits(cf.getValue()) == bits) - return i; - } - } - return -1; - } - - public int addDouble(double d) { - int ret = lookupDouble(d); - if (ret != -1) - return ret; - adjustSize(); - ret = poolSize; - pool[poolSize] = new ConstantDouble(d); - poolSize += 2; - return ret; - } - - public int lookupDouble(double d) { - long bits = Double.doubleToLongBits(d); - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_Double) { - ConstantDouble cf = (ConstantDouble) c; - if (Double.doubleToLongBits(cf.getValue()) == bits) - return i; - } - } - return -1; - } - - public int addLong(long l) { - int ret = lookupLong(l); - if (ret != -1) - return ret; - adjustSize(); - ret = poolSize; - pool[poolSize] = new ConstantLong(l); - poolSize += 2; - return ret; - } - - public int lookupString(String s) { - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_String) { - ConstantString cs = (ConstantString) c; - ConstantUtf8 cu8 = (ConstantUtf8) pool[cs.getStringIndex()]; - if (cu8.getValue().equals(s)) - return i; - } - } - return -1; - } - - public int addString(String str) { - int ret = lookupString(str); - if (ret != -1) - return ret; - int utf8 = addUtf8(str); - adjustSize(); - ConstantString s = new ConstantString(utf8); - ret = poolSize; - pool[poolSize++] = s; - return ret; - } - - public int lookupLong(long l) { - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_Long) { - ConstantLong cf = (ConstantLong) c; - if (cf.getValue() == l) - return i; - } - } - return -1; - } - - public int addConstant(Constant c, ConstantPool cp) { - Constant[] constants = cp.getConstantPool(); - switch (c.getTag()) { - - case Constants.CONSTANT_String: { - ConstantString s = (ConstantString) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; - - return addString(u8.getValue()); - } - - case Constants.CONSTANT_Class: { - ConstantClass s = (ConstantClass) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; - - return addClass(u8.getValue()); - } - - case Constants.CONSTANT_NameAndType: { - ConstantNameAndType n = (ConstantNameAndType) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; - ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; - - return addNameAndType(u8.getValue(), u8_2.getValue()); - } - - case Constants.CONSTANT_InvokeDynamic: { - ConstantInvokeDynamic cid = (ConstantInvokeDynamic)c; - int index1 = cid.getBootstrapMethodAttrIndex(); - ConstantNameAndType cnat = (ConstantNameAndType)constants[cid.getNameAndTypeIndex()]; - ConstantUtf8 name = (ConstantUtf8) constants[cnat.getNameIndex()]; - ConstantUtf8 signature = (ConstantUtf8) constants[cnat.getSignatureIndex()]; - int index2 = addNameAndType(name.getValue(), signature.getValue()); - return addInvokeDynamic(index1,index2); - } - - case Constants.CONSTANT_MethodHandle: - ConstantMethodHandle cmh = (ConstantMethodHandle)c; - return addMethodHandle(cmh.getReferenceKind(),addConstant(constants[cmh.getReferenceIndex()],cp)); - - case Constants.CONSTANT_Utf8: - return addUtf8(((ConstantUtf8) c).getValue()); - - case Constants.CONSTANT_Double: - return addDouble(((ConstantDouble) c).getValue()); - - case Constants.CONSTANT_Float: - return addFloat(((ConstantFloat) c).getValue()); - - case Constants.CONSTANT_Long: - return addLong(((ConstantLong) c).getValue()); - - case Constants.CONSTANT_Integer: - return addInteger(((ConstantInteger) c).getValue()); - - case Constants.CONSTANT_MethodType: - ConstantMethodType cmt = (ConstantMethodType)c; - return addMethodType(addConstant(constants[cmt.getDescriptorIndex()],cp)); - - case Constants.CONSTANT_InterfaceMethodref: - case Constants.CONSTANT_Methodref: - case Constants.CONSTANT_Fieldref: { - ConstantCP m = (ConstantCP) c; - ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; - ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; - ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; - String class_name = u8.getValue().replace('/', '.'); - - u8 = (ConstantUtf8) constants[n.getNameIndex()]; - String name = u8.getValue(); - - u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; - String signature = u8.getValue(); - - switch (c.getTag()) { - case Constants.CONSTANT_InterfaceMethodref: - return addInterfaceMethodref(class_name, name, signature); - - case Constants.CONSTANT_Methodref: - return addMethodref(class_name, name, signature); // OPTIMIZE indicate it should be cached! - - case Constants.CONSTANT_Fieldref: - return addFieldref(class_name, name, signature); - - default: // Never reached - throw new RuntimeException("Unknown constant type " + c); - } - } - - default: // Never reached - throw new RuntimeException("Unknown constant type " + c); - } - } - - public int addMethodHandle(byte referenceKind, int referenceIndex) { - adjustSize(); - int ret = poolSize; - pool[poolSize++] = new ConstantMethodHandle(referenceKind, referenceIndex); - return ret; - } - - public int addMethodType(int descriptorIndex) { - adjustSize(); - int ret = poolSize; - pool[poolSize++] = new ConstantMethodType(descriptorIndex); - return ret; - } - - // OPTIMIZE should put it in the cache now - public int addMethodref(String class_name, String method_name, String signature) { - int ret, class_index, name_and_type_index; - if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - name_and_type_index = addNameAndType(method_name, signature); - class_index = addClass(class_name); - ret = poolSize; - pool[poolSize++] = new ConstantMethodref(class_index, name_and_type_index); - return ret; - } - - public int addInvokeDynamic(int bootstrapMethodIndex, int constantNameAndTypeIndex) { - adjustSize(); - int ret = poolSize; - pool[poolSize++] = new ConstantInvokeDynamic(bootstrapMethodIndex, constantNameAndTypeIndex); - return ret; - } - - public int addInterfaceMethodref(String class_name, String method_name, String signature) { - int ret = lookupInterfaceMethodref(class_name, method_name, signature); - int class_index, name_and_type_index; - - if (ret != -1) - return ret; - adjustSize(); - - class_index = addClass(class_name); - name_and_type_index = addNameAndType(method_name, signature); - ret = poolSize; - pool[poolSize++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); - return ret; - } - - public int lookupInterfaceMethodref(String searchClassname, String searchMethodName, String searchSignature) { - searchClassname = searchClassname.replace('.', '/'); - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_InterfaceMethodref) { - ConstantInterfaceMethodref cfr = (ConstantInterfaceMethodref) c; - - ConstantClass cc = (ConstantClass) pool[cfr.getClassIndex()]; - String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); - if (!cName.equals(searchClassname)) - continue; - - // check the name and type - ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; - String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); - if (!name.equals(searchMethodName)) - continue; // not this one - String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); - if (!typeSignature.equals(searchSignature)) - continue; - return i; - } - } - return -1; - } - - public int lookupMethodref(String searchClassname, String searchMethodName, String searchSignature) { - String key = new StringBuffer().append(searchClassname).append(searchMethodName).append(searchSignature).toString(); - Integer cached = methodCache.get(key); - if (cached != null) - return cached.intValue(); - searchClassname = searchClassname.replace('.', '/'); - for (int i = 1; i < poolSize; i++) { - Constant c = pool[i]; - if (c != null && c.tag == Constants.CONSTANT_Methodref) { - ConstantMethodref cfr = (ConstantMethodref) c; - ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; - - // check the class - int cIndex = cfr.getClassIndex(); - ConstantClass cc = (ConstantClass) pool[cIndex]; - String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); - if (!cName.equals(searchClassname)) - continue; - - // check the name and type - String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); - if (!name.equals(searchMethodName)) - continue; // not this one - String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); - if (!typeSignature.equals(searchSignature)) - continue; - methodCache.put(key, new Integer(i)); - return i; - } - } - return -1; - } - - public ConstantPool getFinalConstantPool() { - Constant[] cs = new Constant[poolSize]; // create it the exact size we need - System.arraycopy(pool, 0, cs, 0, poolSize); - return new ConstantPool(cs); - } - - public String getModuleName(int moduleIndex) { - return getConstantModule(moduleIndex).getModuleName(this); - } - - public String getPackageName(int packageIndex) { - return getConstantPackage(packageIndex).getPackageName(this); - } -} \ No newline at end of file diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantString.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantString.java deleted file mode 100644 index ef9da55db..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantString.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to a String object. - * - * @version $Id: ConstantString.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @see Constant - */ -public final class ConstantString extends Constant { - - private int stringIndex; - - ConstantString(DataInputStream file) throws IOException { - this(file.readUnsignedShort()); - } - - public ConstantString(int stringIndex) { - super(Constants.CONSTANT_String); - this.stringIndex = stringIndex; - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantString(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeShort(stringIndex); - } - - // OPTIMIZE fix duplication in these next two methods - /** - * @return the index of the string in the constant pool - */ - @Override - public Integer getValue() { - return stringIndex; - } - - public final int getStringIndex() { - return stringIndex; - } - - @Override - public final String toString() { - return super.toString() + "(string_index = " + stringIndex + ")"; - } - - /** - * @return the string, as dereferenced using the internal index into the supplied constant pool - */ - public String getString(ConstantPool cpool) { - Constant c = cpool.getConstant(stringIndex, Constants.CONSTANT_Utf8); - return ((ConstantUtf8) c).getValue(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantUtf8.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantUtf8.java deleted file mode 100644 index f8200db47..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantUtf8.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from the abstract Constant class and - * represents a reference to a Utf8 encoded string. - * - * @version $Id: ConstantUtf8.java,v 1.5 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @see Constant - */ -public final class ConstantUtf8 extends Constant implements SimpleConstant { - private String string; - - ConstantUtf8(DataInputStream file) throws IOException { - super(Constants.CONSTANT_Utf8); - string = file.readUTF(); - } - - public ConstantUtf8(String string) { - super(Constants.CONSTANT_Utf8); - assert string != null; - this.string = string; - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantUtf8(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - file.writeByte(tag); - file.writeUTF(string); - } - - @Override - public final String toString() { - return super.toString() + "(\"" + Utility.replace(string, "\n", "\\n") + "\")"; - } - - @Override - public String getValue() { - return string; - } - - public String getStringValue() { - return string; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantValue.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantValue.java deleted file mode 100644 index 730e8aff0..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantValue.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from Attribute and represents a constant value, i.e., a default value for initializing a class - * field. This class is instantiated by the Attribute.readAttribute() method. - * - * @version $Id: ConstantValue.java,v 1.6 2009/09/16 00:43:49 aclement Exp $ - * @author M. Dahm - * @see Attribute - */ -public final class ConstantValue extends Attribute { - private int constantvalue_index; - - ConstantValue(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, file.readUnsignedShort(), constant_pool); - } - - public ConstantValue(int name_index, int length, int constantvalue_index, ConstantPool constant_pool) { - super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); - this.constantvalue_index = constantvalue_index; - } - - @Override - public void accept(ClassVisitor v) { - v.visitConstantValue(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(constantvalue_index); - } - - public final int getConstantValueIndex() { - return constantvalue_index; - } - - @Override - public final String toString() { - Constant c = cpool.getConstant(constantvalue_index); - - String buf; - int i; - - // Print constant to string depending on its type - switch (c.getTag()) { - case Constants.CONSTANT_Long: - buf = "" + ((ConstantLong) c).getValue(); - break; - case Constants.CONSTANT_Float: - buf = "" + ((ConstantFloat) c).getValue(); - break; - case Constants.CONSTANT_Double: - buf = "" + ((ConstantDouble) c).getValue(); - break; - case Constants.CONSTANT_Integer: - buf = "" + ((ConstantInteger) c).getValue(); - break; - case Constants.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - c = cpool.getConstant(i, Constants.CONSTANT_Utf8); - buf = "\"" + Utility.convertString(((ConstantUtf8) c).getValue()) + "\""; - break; - - default: - throw new IllegalStateException("Type of ConstValue invalid: " + c); - } - - return buf; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Deprecated.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Deprecated.java deleted file mode 100644 index 21bbbcb46..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Deprecated.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from Attribute and denotes that this is a deprecated method. It is instantiated from the - * Attribute.readAttribute() method. - * - * @version $Id: Deprecated.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Attribute - */ -public final class Deprecated extends Attribute { - private byte[] bytes; - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical - * copy. - */ - public Deprecated(Deprecated c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } - - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param bytes Attribute contents - * @param constant_pool Array of constants - */ - public Deprecated(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { - super(Constants.ATTR_DEPRECATED, name_index, length, constant_pool); - this.bytes = bytes; - } - - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Deprecated(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, (byte[]) null, constant_pool); - - if (length > 0) { - bytes = new byte[length]; - file.readFully(bytes); - System.err.println("Deprecated attribute with length > 0"); - } - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitDeprecated(this); - } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - - if (length > 0) - file.write(bytes, 0, length); - } - - /** - * @return data bytes. - */ - public final byte[] getBytes() { - return bytes; - } - - /** - * @param bytes. - */ - public final void setBytes(byte[] bytes) { - this.bytes = bytes; - } - - /** - * @return attribute name - */ - @Override - public final String toString() { - return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED]; - } - - // /** - // * @return deep copy of this attribute - // */ - // public Attribute copy(ConstantPool constant_pool) { - // Deprecated c = (Deprecated)clone(); - // - // if(bytes != null) - // c.bytes = (byte[])bytes.clone(); - // - // c.cpool = constant_pool; - // return c; - // } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/EnclosingMethod.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/EnclosingMethod.java deleted file mode 100644 index 9e1554ec5..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/EnclosingMethod.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This attribute exists for local or - * anonymous classes and ... there can be only one. - */ -public class EnclosingMethod extends Attribute { - - // Pointer to the CONSTANT_Class_info structure representing the - // innermost class that encloses the declaration of the current class. - private int classIndex; - - // If the current class is not immediately enclosed by a method or - // constructor, then the value of the method_index item must be zero. - // Otherwise, the value of the method_index item must point to a - // CONSTANT_NameAndType_info structure representing the name and the - // type of a method in the class referenced by the class we point - // to in the class_index. *It is the compiler responsibility* to - // ensure that the method identified by this index is the closest - // lexically enclosing method that includes the local/anonymous class. - private int methodIndex; - - // Ctors - and code to read an attribute in. - public EnclosingMethod(int nameIndex, int len, DataInputStream dis, ConstantPool cpool) throws IOException { - this(nameIndex, len, dis.readUnsignedShort(), dis.readUnsignedShort(), cpool); - } - - private EnclosingMethod(int nameIndex, int len, int classIdx,int methodIdx, ConstantPool cpool) { - super(Constants.ATTR_ENCLOSING_METHOD, nameIndex, len, cpool); - classIndex = classIdx; - methodIndex = methodIdx; - } - - public void accept(ClassVisitor v) { - v.visitEnclosingMethod(this); - } - - public Attribute copy(ConstantPool constant_pool) { - throw new RuntimeException("Not implemented yet!"); - // is this next line sufficient? - // return (EnclosingMethod)clone(); - } - - // Accessors - public final int getEnclosingClassIndex() { return classIndex; } - public final int getEnclosingMethodIndex(){ return methodIndex;} - - public final void setEnclosingClassIndex(int idx) {classIndex = idx;} - public final void setEnclosingMethodIndex(int idx){methodIndex= idx;} - - public final ConstantClass getEnclosingClass() { - ConstantClass c = - (ConstantClass)cpool.getConstant(classIndex,Constants.CONSTANT_Class); - return c; - } - - public final ConstantNameAndType getEnclosingMethod() { - if (methodIndex == 0) return null; - ConstantNameAndType nat = - (ConstantNameAndType)cpool.getConstant(methodIndex,Constants.CONSTANT_NameAndType); - return nat; - } - - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(classIndex); - file.writeShort(methodIndex); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ExceptionTable.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ExceptionTable.java deleted file mode 100644 index ad7d43f2e..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ExceptionTable.java +++ /dev/null @@ -1,199 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents the table of exceptions that are thrown by a method. This attribute may be used once per method. The name - * of this class is ExceptionTable for historical reasons; The Java Virtual Machine Specification, Second Edition defines - * this attribute using the name Exceptions (which is inconsistent with the other classes). - * - * @version $Id: ExceptionTable.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Code - */ -public final class ExceptionTable extends Attribute { - private int number_of_exceptions; // Table of indices into - private int[] exception_index_table; // constant pool - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical - * copy. - */ - public ExceptionTable(ExceptionTable c) { - this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c.getConstantPool()); - } - - /** - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param exception_index_table Table of indices in constant pool - * @param constant_pool Array of constants - */ - public ExceptionTable(int name_index, int length, int[] exception_index_table, ConstantPool constant_pool) { - super(Constants.ATTR_EXCEPTIONS, name_index, length, constant_pool); - setExceptionIndexTable(exception_index_table); - } - - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - ExceptionTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, (int[]) null, constant_pool); - - number_of_exceptions = file.readUnsignedShort(); - exception_index_table = new int[number_of_exceptions]; - - for (int i = 0; i < number_of_exceptions; i++) - exception_index_table[i] = file.readUnsignedShort(); - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitExceptionTable(this); - } - - /** - * Dump exceptions attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(number_of_exceptions); - for (int i = 0; i < number_of_exceptions; i++) - file.writeShort(exception_index_table[i]); - } - - /** - * @return Array of indices into constant pool of thrown exceptions. - */ - public final int[] getExceptionIndexTable() { - return exception_index_table; - } - - /** - * @return Length of exception table. - */ - public final int getNumberOfExceptions() { - return number_of_exceptions; - } - - /** - * @return class names of thrown exceptions - */ - public final String[] getExceptionNames() { - String[] names = new String[number_of_exceptions]; - for (int i = 0; i < number_of_exceptions; i++) - names[i] = cpool.getConstantString(exception_index_table[i], Constants.CONSTANT_Class).replace('/', '.'); - return names; - } - - /** - * @param exception_index_table. Also redefines number_of_exceptions according to table length. - */ - public final void setExceptionIndexTable(int[] exception_index_table) { - this.exception_index_table = exception_index_table; - number_of_exceptions = (exception_index_table == null) ? 0 : exception_index_table.length; - } - - /** - * @return String representation, i.e., a list of thrown exceptions. - */ - @Override - public final String toString() { - StringBuffer buf = new StringBuffer(""); - String str; - - for (int i = 0; i < number_of_exceptions; i++) { - str = cpool.getConstantString(exception_index_table[i], Constants.CONSTANT_Class); - buf.append(Utility.compactClassName(str, false)); - - if (i < number_of_exceptions - 1) - buf.append(", "); - } - - return buf.toString(); - } - - // /** - // * @return deep copy of this attribute - // */ - // public Attribute copy(ConstantPool constant_pool) { - // ExceptionTable c = (ExceptionTable)clone(); - // c.exception_index_table = (int[])exception_index_table.clone(); - // c.cpool = constant_pool; - // return c; - // } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Field.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Field.java deleted file mode 100644 index f34464375..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Field.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataInputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.generic.Type; - -/** - * This class represents the field info structure, i.e., the representation for a variable in the class. See JVM specification for - * details. - * - * @version $Id: Field.java,v 1.6 2009/09/15 03:33:52 aclement Exp $ - * @author M. Dahm - */ -public final class Field extends FieldOrMethod { - - public static final Field[] NoFields = new Field[0]; - - private Type fieldType = null; // lazily initialized - - private Field() { - } - - public Field(Field c) { - super(c); - } - - Field(DataInputStream dis, ConstantPool cpool) throws IOException { - super(dis, cpool); - } - - public Field(int modifiers, int nameIndex, int signatureIndex, Attribute[] attributes, ConstantPool cpool) { - super(modifiers, nameIndex, signatureIndex, attributes, cpool); - } - - public void accept(ClassVisitor v) { - v.visitField(this); - } - - /** - * @return constant value associated with this field (may be null) - */ - public final ConstantValue getConstantValue() { - return AttributeUtils.getConstantValueAttribute(attributes); - } - - /** - * Return string representation close to declaration format, eg: 'public static final short MAX = 100' - */ - @Override - public final String toString() { - // Get names from constant pool - StringBuffer buf = new StringBuffer(Utility.accessToString(modifiers)); - if (buf.length() > 0) { - buf.append(" "); - } - String signature = Utility.signatureToString(getSignature()); - - buf.append(signature).append(" ").append(getName()); - - ConstantValue cv = getConstantValue(); - if (cv != null) { - buf.append(" = ").append(cv); - } - - // append all attributes that are *not* "ConstantValue" - for (Attribute a : attributes) { - if (!(a instanceof ConstantValue)) { - buf.append(" [").append(a.toString()).append("]"); - } - } - - return buf.toString(); - } - - /** return the type of the field */ - public Type getType() { - if (fieldType == null) { - fieldType = Type.getReturnType(getSignature()); - } - return fieldType; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java deleted file mode 100644 index a152b616f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java +++ /dev/null @@ -1,201 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; - -/** - * Abstract super class for fields and methods. - * - * @version $Id: FieldOrMethod.java,v 1.12 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - */ -public abstract class FieldOrMethod extends Modifiers implements Node { - protected int nameIndex; - protected int signatureIndex; - protected Attribute[] attributes; - - protected ConstantPool cpool; - private String name; // lazily initialized - private String signature; // lazily initialized - private AnnotationGen[] annotations; // lazily initialized - private String signatureAttributeString = null; - private boolean searchedForSignatureAttribute = false; - - protected FieldOrMethod() { - } - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical - * copy. - */ - protected FieldOrMethod(FieldOrMethod c) { - this(c.getModifiers(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c.getConstantPool()); - } - - protected FieldOrMethod(DataInputStream file, ConstantPool cpool) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, cpool); - attributes = AttributeUtils.readAttributes(file, cpool); - } - - protected FieldOrMethod(int accessFlags, int nameIndex, int signatureIndex, Attribute[] attributes, ConstantPool cpool) { - this.modifiers = accessFlags; - this.nameIndex = nameIndex; - this.signatureIndex = signatureIndex; - this.cpool = cpool; - this.attributes = attributes; - } - - /** - * @param attributes Collection of object attributes. - */ - public void setAttributes(Attribute[] attributes) { - this.attributes = attributes; - } - - public final void dump(DataOutputStream file) throws IOException { - file.writeShort(modifiers); - file.writeShort(nameIndex); - file.writeShort(signatureIndex); - AttributeUtils.writeAttributes(attributes, file); - } - - public final Attribute[] getAttributes() { - return attributes; - } - - public final ConstantPool getConstantPool() { - return cpool; - } - - public final int getNameIndex() { - return nameIndex; - } - - public final int getSignatureIndex() { - return signatureIndex; - } - - public final String getName() { - if (name == null) { - ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); - name = c.getValue(); - } - return name; - } - - public final String getSignature() { - if (signature == null) { - ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(signatureIndex, Constants.CONSTANT_Utf8); - signature = c.getValue(); - } - return signature; - } - - /** - * This will return the contents of a signature attribute attached to a member, or if there is none it will return the same as - * 'getSignature()'. Signature attributes are attached to members that were declared generic. - */ - public final String getDeclaredSignature() { - if (getGenericSignature() != null) - return getGenericSignature(); - return getSignature(); - } - - public AnnotationGen[] getAnnotations() { - // Ensure we have unpacked any attributes that contain annotations. - // We don't remove these annotation attributes from the attributes list, they - // remain there. - if (annotations == null) { - // Find attributes that contain annotation data - List accumulatedAnnotations = new ArrayList(); - for (int i = 0; i < attributes.length; i++) { - Attribute attribute = attributes[i]; - if (attribute instanceof RuntimeAnnos) { - RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attribute; - accumulatedAnnotations.addAll(runtimeAnnotations.getAnnotations()); - } - } - if (accumulatedAnnotations.size() == 0) { - annotations = AnnotationGen.NO_ANNOTATIONS; - } else { - annotations = accumulatedAnnotations.toArray(new AnnotationGen[] {}); - } - } - return annotations; - } - - /** - * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature may be - * (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector;' Coded for performance - - * searches for the attribute only when requested - only searches for it once. - */ - public final String getGenericSignature() { - if (!searchedForSignatureAttribute) { - Signature sig = AttributeUtils.getSignatureAttribute(attributes); - signatureAttributeString = (sig == null ? null : sig.getSignature()); - searchedForSignatureAttribute = true; - } - return signatureAttributeString; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/InnerClass.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/InnerClass.java deleted file mode 100644 index d3b1eb0a8..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/InnerClass.java +++ /dev/null @@ -1,232 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a inner class attribute, i.e., the class indices of the inner and outer classes, the name and the - * attributes of the inner class. - * - * @version $Id: InnerClass.java,v 1.4 2009/09/10 15:35:05 aclement Exp $ - * @author M. Dahm - * @see InnerClasses - */ -public final class InnerClass implements Cloneable, Node { - private int inner_class_index; - private int outer_class_index; - private int inner_name_index; - private int inner_access_flags; - - /** - * Initialize from another object. - */ - public InnerClass(InnerClass c) { - this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c.getInnerAccessFlags()); - } - - /** - * Construct object from file stream. - * - * @param file Input stream - * @throws IOException - */ - InnerClass(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort()); - } - - /** - * @param inner_class_index Class index in constant pool of inner class - * @param outer_class_index Class index in constant pool of outer class - * @param inner_name_index Name index in constant pool of inner class - * @param inner_access_flags Access flags of inner class - */ - public InnerClass(int inner_class_index, int outer_class_index, int inner_name_index, int inner_access_flags) { - this.inner_class_index = inner_class_index; - this.outer_class_index = outer_class_index; - this.inner_name_index = inner_name_index; - this.inner_access_flags = inner_access_flags; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(ClassVisitor v) { - v.visitInnerClass(this); - } - - /** - * Dump inner class attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException { - file.writeShort(inner_class_index); - file.writeShort(outer_class_index); - file.writeShort(inner_name_index); - file.writeShort(inner_access_flags); - } - - /** - * @return access flags of inner class. - */ - public final int getInnerAccessFlags() { - return inner_access_flags; - } - - /** - * @return class index of inner class. - */ - public final int getInnerClassIndex() { - return inner_class_index; - } - - /** - * @return name index of inner class. - */ - public final int getInnerNameIndex() { - return inner_name_index; - } - - /** - * @return class index of outer class. - */ - public final int getOuterClassIndex() { - return outer_class_index; - } - - /** - * @param inner_access_flags. - */ - public final void setInnerAccessFlags(int inner_access_flags) { - this.inner_access_flags = inner_access_flags; - } - - /** - * @param inner_class_index. - */ - public final void setInnerClassIndex(int inner_class_index) { - this.inner_class_index = inner_class_index; - } - - /** - * @param inner_name_index. - */ - public final void setInnerNameIndex(int inner_name_index) { - this.inner_name_index = inner_name_index; - } - - /** - * @param outer_class_index. - */ - public final void setOuterClassIndex(int outer_class_index) { - this.outer_class_index = outer_class_index; - } - - /** - * @return String representation. - */ - @Override - public final String toString() { - return "InnerClass(" + inner_class_index + ", " + outer_class_index + ", " + inner_name_index + ", " + inner_access_flags - + ")"; - } - - /** - * @return Resolved string representation - */ - public final String toString(ConstantPool constant_pool) { - String inner_class_name, outer_class_name, inner_name, access; - - inner_class_name = constant_pool.getConstantString(inner_class_index, Constants.CONSTANT_Class); - inner_class_name = Utility.compactClassName(inner_class_name); - - if (outer_class_index != 0) { - outer_class_name = constant_pool.getConstantString(outer_class_index, Constants.CONSTANT_Class); - outer_class_name = Utility.compactClassName(outer_class_name); - } else - outer_class_name = ""; - - if (inner_name_index != 0) - inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index, Constants.CONSTANT_Utf8)).getValue(); - else - inner_name = ""; - - access = Utility.accessToString(inner_access_flags, true); - access = access.equals("") ? "" : (access + " "); - - return "InnerClass:" + access + inner_class_name + "(\"" + outer_class_name + "\", \"" + inner_name + "\")"; - } - - /** - * @return deep copy of this object - */ - public InnerClass copy() { - try { - return (InnerClass) clone(); - } catch (CloneNotSupportedException e) { - } - - return null; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/InnerClasses.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/InnerClasses.java deleted file mode 100644 index 0078156ed..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/InnerClasses.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from Attribute and denotes that this class is an Inner class of another. to the source file of - * this class. It is instantiated from the Attribute.readAttribute() method. - * - * @version $Id: InnerClasses.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Attribute - */ -public final class InnerClasses extends Attribute { - private InnerClass[] inner_classes; - private int number_of_classes; - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical - * copy. - */ - public InnerClasses(InnerClasses c) { - this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool()); - } - - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param inner_classes array of inner classes attributes - * @param constant_pool Array of constants - * @param sourcefile_index Index in constant pool to CONSTANT_Utf8 - */ - public InnerClasses(int name_index, int length, InnerClass[] inner_classes, ConstantPool constant_pool) { - super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool); - setInnerClasses(inner_classes); - } - - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - InnerClasses(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, (InnerClass[]) null, constant_pool); - - number_of_classes = file.readUnsignedShort(); - inner_classes = new InnerClass[number_of_classes]; - - for (int i = 0; i < number_of_classes; i++) - inner_classes[i] = new InnerClass(file); - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitInnerClasses(this); - } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(number_of_classes); - - for (int i = 0; i < number_of_classes; i++) - inner_classes[i].dump(file); - } - - /** - * @return array of inner class "records" - */ - public final InnerClass[] getInnerClasses() { - return inner_classes; - } - - /** - * @param inner_classes. - */ - public final void setInnerClasses(InnerClass[] inner_classes) { - this.inner_classes = inner_classes; - number_of_classes = (inner_classes == null) ? 0 : inner_classes.length; - } - - /** - * @return String representation. - */ - @Override - public final String toString() { - StringBuffer buf = new StringBuffer(); - - for (int i = 0; i < number_of_classes; i++) - buf.append(inner_classes[i].toString(cpool) + "\n"); - - return buf.toString(); - } - - // /** - // * @return deep copy of this attribute - // */ - // public Attribute copy(ConstantPool constant_pool) { - // InnerClasses c = (InnerClasses)clone(); - // - // c.inner_classes = new InnerClass[number_of_classes]; - // for(int i=0; i < number_of_classes; i++) - // c.inner_classes[i] = inner_classes[i].copy(); - // - // c.cpool = constant_pool; - // return c; - // } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/JavaClass.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/JavaClass.java deleted file mode 100644 index 25c415295..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/JavaClass.java +++ /dev/null @@ -1,837 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import java.util.StringTokenizer; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; -import org.aspectj.apache.bcel.generic.Type; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -/** - * Represents a Java class, i.e., the data structures, constant pool, fields, methods and commands contained in a Java .class file. - * See JVM specification for details. - * - * The intent of this class is to represent a parsed or otherwise existing class file. Those interested in programatically - * generating classes should see the ClassGen class. - * - * @version $Id: JavaClass.java,v 1.22 2009/09/15 19:40:14 aclement Exp $ - * @see org.aspectj.apache.bcel.generic.ClassGen - * @author M. Dahm - */ -public class JavaClass extends Modifiers implements Cloneable, Node { - - private static final String[] NoInterfaceNames = new String[0]; - private static final Field[] NoFields = new Field[0]; - private static final Method[] NoMethod = new Method[0]; - private static final int[] NoInterfaceIndices = new int[0]; - private static final Attribute[] NoAttributes = new Attribute[0]; - - private String fileName; - private String packageName; - private String sourcefileName; - private int classnameIdx; - private int superclassnameIdx; - private String classname; - private String superclassname; - private int major, minor; - private ConstantPool cpool; - private int[] interfaces; - private String[] interfacenames; - private Field[] fields; - private Method[] methods; - private Attribute[] attributes; - private AnnotationGen[] annotations; - - private boolean isGeneric = false; - private boolean isAnonymous = false; - private boolean isNested = false; - private boolean computedNestedTypeStatus = false; - - // Annotations are collected from certain attributes, don't do it more than necessary! - private boolean annotationsOutOfDate = true; - - // state for dealing with generic signature string - private String signatureAttributeString = null; - private Signature signatureAttribute = null; - private boolean searchedForSignatureAttribute = false; - - /** - * In cases where we go ahead and create something, use the default SyntheticRepository, because we don't know any better. - */ - private transient org.aspectj.apache.bcel.util.Repository repository = null; - - public JavaClass(int classnameIndex, int superclassnameIndex, String filename, int major, int minor, int access_flags, - ConstantPool cpool, int[] interfaces, Field[] fields, Method[] methods, Attribute[] attributes) { - if (interfaces == null) { - interfaces = NoInterfaceIndices; - } - - this.classnameIdx = classnameIndex; - this.superclassnameIdx = superclassnameIndex; - this.fileName = filename; - this.major = major; - this.minor = minor; - this.modifiers = access_flags; - this.cpool = cpool; - this.interfaces = interfaces; - this.fields = (fields == null ? NoFields : fields); - this.methods = (methods == null ? NoMethod : methods); - this.attributes = (attributes == null ? NoAttributes : attributes); - annotationsOutOfDate = true; - - // Get source file name if available - SourceFile sfAttribute = AttributeUtils.getSourceFileAttribute(attributes); - sourcefileName = sfAttribute == null ? "" : sfAttribute.getSourceFileName(); - - /* - * According to the specification the following entries must be of type `ConstantClass' but we check that anyway via the - * `ConstPool.getConstant' method. - */ - classname = cpool.getConstantString(classnameIndex, Constants.CONSTANT_Class); - classname = Utility.compactClassName(classname, false); - - int index = classname.lastIndexOf('.'); - if (index < 0) { - packageName = ""; - } else { - packageName = classname.substring(0, index); - } - - if (superclassnameIndex > 0) { // May be zero -> class is java.lang.Object - superclassname = cpool.getConstantString(superclassnameIndex, Constants.CONSTANT_Class); - superclassname = Utility.compactClassName(superclassname, false); - } else { - superclassname = "java.lang.Object"; - } - - if (interfaces.length == 0) { - interfacenames = NoInterfaceNames; - } else { - interfacenames = new String[interfaces.length]; - for (int i = 0; i < interfaces.length; i++) { - String str = cpool.getConstantString(interfaces[i], Constants.CONSTANT_Class); - interfacenames[i] = Utility.compactClassName(str, false); - } - } - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(ClassVisitor v) { - v.visitJavaClass(this); - } - - /** - * Dump class to a file. - * - * @param file Output file - * @throws IOException - */ - public void dump(File file) throws IOException { - String parent = file.getParent(); - if (parent != null) { - File dir = new File(parent); - dir.mkdirs(); - } - dump(new DataOutputStream(new FileOutputStream(file))); - } - - /** - * Dump class to a file named file_name. - * - * @param file_name Output file name - * @exception IOException - */ - public void dump(String file_name) throws IOException { - dump(new File(file_name)); - } - - /** - * @return class in binary format - */ - public byte[] getBytes() { - ByteArrayOutputStream s = new ByteArrayOutputStream(); - DataOutputStream ds = new DataOutputStream(s); - - try { - dump(ds); - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - ds.close(); - } catch (IOException e2) { - e2.printStackTrace(); - } - } - - return s.toByteArray(); - } - - /** - * Dump Java class to output stream in binary format. - */ - public void dump(OutputStream file) throws IOException { - dump(new DataOutputStream(file)); - } - - /** - * Dump Java class to output stream in binary format. - */ - public void dump(DataOutputStream file) throws IOException { - file.writeInt(0xcafebabe); - file.writeShort(minor); - file.writeShort(major); - - cpool.dump(file); - - file.writeShort(modifiers); - file.writeShort(classnameIdx); - file.writeShort(superclassnameIdx); - - file.writeShort(interfaces.length); - for (int i = 0; i < interfaces.length; i++) { - file.writeShort(interfaces[i]); - } - - file.writeShort(fields.length); - for (int i = 0; i < fields.length; i++) { - fields[i].dump(file); - } - - file.writeShort(methods.length); - for (int i = 0; i < methods.length; i++) { - methods[i].dump(file); - } - - AttributeUtils.writeAttributes(attributes, file); - - file.close(); - } - - public Attribute[] getAttributes() { - return attributes; - } - - public AnnotationGen[] getAnnotations() { - if (annotationsOutOfDate) { - // Find attributes that contain annotation data - List accumulatedAnnotations = new ArrayList(); - for (int i = 0; i < attributes.length; i++) { - Attribute attribute = attributes[i]; - if (attribute instanceof RuntimeAnnos) { - RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attribute; - accumulatedAnnotations.addAll(runtimeAnnotations.getAnnotations()); - } - } - annotations = accumulatedAnnotations.toArray(new AnnotationGen[] {}); - annotationsOutOfDate = false; - } - return annotations; - } - - /** - * @return Class name. - */ - public String getClassName() { - return classname; - } - - /** - * @return Package name. - */ - public String getPackageName() { - return packageName; - } - - public int getClassNameIndex() { - return classnameIdx; - } - - public ConstantPool getConstantPool() { - return cpool; - } - - /** - * @return Fields, i.e., variables of the class. Like the JVM spec mandates for the classfile format, these fields are those - * specific to this class, and not those of the superclass or superinterfaces. - */ - public Field[] getFields() { - return fields; - } - - /** - * @return File name of class, aka SourceFile attribute value - */ - public String getFileName() { - return fileName; - } - - /** - * @return Names of implemented interfaces. - */ - public String[] getInterfaceNames() { - return interfacenames; - } - - /** - * @return Indices in constant pool of implemented interfaces. - */ - public int[] getInterfaceIndices() { - return interfaces; - } - - public int getMajor() { - return major; - } - - /** - * @return Methods of the class. - */ - public Method[] getMethods() { - return methods; - } - - /** - * @return A org.aspectj.apache.bcel.classfile.Method corresponding to java.lang.reflect.Method if any - */ - public Method getMethod(java.lang.reflect.Method m) { - for (int i = 0; i < methods.length; i++) { - Method method = methods[i]; - - if (m.getName().equals(method.getName()) && m.getModifiers() == method.getModifiers() - && Type.getSignature(m).equals(method.getSignature())) { - return method; - } - } - - return null; - } - - public Method getMethod(java.lang.reflect.Constructor c) { - for (int i = 0; i < methods.length; i++) { - Method method = methods[i]; - if (method.getName().equals("") && c.getModifiers() == method.getModifiers() - && Type.getSignature(c).equals(method.getSignature())) { - return method; - } - } - - return null; - } - - public Field getField(java.lang.reflect.Field field) { - String fieldName = field.getName(); - for (Field f : fields) { - if (f.getName().equals(fieldName)) { - return f; - } - } - return null; - } - - /** - * @return Minor number of class file version. - */ - public int getMinor() { - return minor; - } - - /** - * @return sbsolute path to file where this class was read from - */ - public String getSourceFileName() { - return sourcefileName; - } - - /** - * @return Superclass name. - */ - public String getSuperclassName() { - return superclassname; - } - - /** - * @return Class name index. - */ - public int getSuperclassNameIndex() { - return superclassnameIdx; - } - - /** - * @param attributes . - */ - public void setAttributes(Attribute[] attributes) { - this.attributes = attributes; - annotationsOutOfDate = true; - } - - /** - * @param class_name . - */ - public void setClassName(String class_name) { - this.classname = class_name; - } - - /** - * @param class_name_index . - */ - public void setClassNameIndex(int class_name_index) { - this.classnameIdx = class_name_index; - } - - /** - * @param constant_pool . - */ - public void setConstantPool(ConstantPool constant_pool) { - this.cpool = constant_pool; - } - - /** - * @param fields . - */ - public void setFields(Field[] fields) { - this.fields = fields; - } - - /** - * Set File name of class, aka SourceFile attribute value - */ - public void setFileName(String file_name) { - this.fileName = file_name; - } - - /** - * @param interface_names . - */ - public void setInterfaceNames(String[] interface_names) { - this.interfacenames = interface_names; - } - - /** - * @param interfaces . - */ - public void setInterfaces(int[] interfaces) { - this.interfaces = interfaces; - } - - public void setMajor(int major) { - this.major = major; - } - - public void setMethods(Method[] methods) { - this.methods = methods; - } - - public void setMinor(int minor) { - this.minor = minor; - } - - /** - * Set absolute path to file this class was read from. - */ - public void setSourceFileName(String source_file_name) { - this.sourcefileName = source_file_name; - } - - /** - * @param superclass_name . - */ - public void setSuperclassName(String superclass_name) { - this.superclassname = superclass_name; - } - - /** - * @param superclass_name_index . - */ - public void setSuperclassNameIndex(int superclass_name_index) { - this.superclassnameIdx = superclass_name_index; - } - - /** - * @return String representing class contents. - */ - @Override - public String toString() { - String access = Utility.accessToString(modifiers, true); - access = access.equals("") ? "" : access + " "; - - StringBuffer buf = new StringBuffer(access + Utility.classOrInterface(modifiers) + " " + classname + " extends " - + Utility.compactClassName(superclassname, false) + '\n'); - int size = interfaces.length; - - if (size > 0) { - buf.append("implements\t\t"); - - for (int i = 0; i < size; i++) { - buf.append(interfacenames[i]); - if (i < size - 1) { - buf.append(", "); - } - } - - buf.append('\n'); - } - - buf.append("filename\t\t" + fileName + '\n'); - buf.append("compiled from\t\t" + sourcefileName + '\n'); - buf.append("compiler version\t" + major + "." + minor + '\n'); - buf.append("access flags\t\t" + modifiers + '\n'); - buf.append("constant pool\t\t" + cpool.getLength() + " entries\n"); - buf.append("ACC_SUPER flag\t\t" + isSuper() + "\n"); - - if (attributes.length > 0) { - buf.append("\nAttribute(s):\n"); - for (int i = 0; i < attributes.length; i++) { - buf.append(indent(attributes[i])); - } - } - - if (annotations != null && annotations.length > 0) { - buf.append("\nAnnotation(s):\n"); - for (int i = 0; i < annotations.length; i++) { - buf.append(indent(annotations[i])); - } - } - - if (fields.length > 0) { - buf.append("\n" + fields.length + " fields:\n"); - for (int i = 0; i < fields.length; i++) { - buf.append("\t" + fields[i] + '\n'); - } - } - - if (methods.length > 0) { - buf.append("\n" + methods.length + " methods:\n"); - for (int i = 0; i < methods.length; i++) { - buf.append("\t" + methods[i] + '\n'); - } - } - - return buf.toString(); - } - - private static final String indent(Object obj) { - StringTokenizer tok = new StringTokenizer(obj.toString(), "\n"); - StringBuffer buf = new StringBuffer(); - - while (tok.hasMoreTokens()) { - buf.append("\t" + tok.nextToken() + "\n"); - } - - return buf.toString(); - } - - public final boolean isSuper() { - return (modifiers & Constants.ACC_SUPER) != 0; - } - - public final boolean isClass() { - return (modifiers & Constants.ACC_INTERFACE) == 0; - } - - public final boolean isAnonymous() { - computeNestedTypeStatus(); - return this.isAnonymous; - } - - public final boolean isNested() { - computeNestedTypeStatus(); - return this.isNested; - } - - private final void computeNestedTypeStatus() { - if (computedNestedTypeStatus) { - return; - } - // Attribute[] attrs = attributes.getAttributes(); - for (int i = 0; i < attributes.length; i++) { - if (attributes[i] instanceof InnerClasses) { - InnerClass[] innerClasses = ((InnerClasses) attributes[i]).getInnerClasses(); - for (int j = 0; j < innerClasses.length; j++) { - boolean innerClassAttributeRefersToMe = false; - String inner_class_name = cpool.getConstantString(innerClasses[j].getInnerClassIndex(), - Constants.CONSTANT_Class); - inner_class_name = Utility.compactClassName(inner_class_name); - if (inner_class_name.equals(getClassName())) { - innerClassAttributeRefersToMe = true; - } - if (innerClassAttributeRefersToMe) { - this.isNested = true; - if (innerClasses[j].getInnerNameIndex() == 0) { - this.isAnonymous = true; - } - } - } - } - } - this.computedNestedTypeStatus = true; - } - - // J5SUPPORT: - /** - * Returns true if this class represents an annotation, i.e. it was a 'public @interface blahblah' declaration - */ - public final boolean isAnnotation() { - return (modifiers & Constants.ACC_ANNOTATION) != 0; - } - - /** - * Returns true if this class represents an enum type - */ - public final boolean isEnum() { - return (modifiers & Constants.ACC_ENUM) != 0; - } - - /********************* New repository functionality *********************/ - - /** - * Gets the ClassRepository which holds its definition. By default this is the same as SyntheticRepository.getInstance(); - */ - public org.aspectj.apache.bcel.util.Repository getRepository() { - if (repository == null) { - repository = SyntheticRepository.getInstance(); - } - return repository; - } - - /** - * Sets the ClassRepository which loaded the JavaClass. Should be called immediately after parsing is done. - */ - public void setRepository(org.aspectj.apache.bcel.util.Repository repository) { - this.repository = repository; - } - - /** - * Equivalent to runtime "instanceof" operator. - * - * @return true if this JavaClass is derived from teh super class - */ - public final boolean instanceOf(JavaClass super_class) { - if (this.equals(super_class)) { - return true; - } - - JavaClass[] super_classes = getSuperClasses(); - - for (int i = 0; i < super_classes.length; i++) { - if (super_classes[i].equals(super_class)) { - return true; - } - } - - if (super_class.isInterface()) { - return implementationOf(super_class); - } - - return false; - } - - /** - * @return true, if clazz is an implementation of interface inter - */ - public boolean implementationOf(JavaClass inter) { - if (!inter.isInterface()) { - throw new IllegalArgumentException(inter.getClassName() + " is no interface"); - } - - if (this.equals(inter)) { - return true; - } - - Collection superInterfaces = getAllInterfaces(); - - for (JavaClass superInterface : superInterfaces) { - if (superInterface.equals(inter)) { - return true; - } - } - // for (int i = 0; i < super_interfaces.length; i++) { - // if (super_interfaces[i].equals(inter)) { - // return true; - // } - // } - - return false; - } - - /** - * @return the superclass for this JavaClass object, or null if this is java.lang.Object - */ - public JavaClass getSuperClass() { - if ("java.lang.Object".equals(getClassName())) { - return null; - } - - try { - return getRepository().loadClass(getSuperclassName()); - } catch (ClassNotFoundException e) { - System.err.println(e); - return null; - } - } - - /** - * @return list of super classes of this class in ascending order, i.e., java.lang.Object is always the last element - */ - public JavaClass[] getSuperClasses() { - JavaClass clazz = this; - List vec = new ArrayList(); - for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) { - vec.add(clazz); - } - return vec.toArray(new JavaClass[vec.size()]); - } - - /** - * Get interfaces directly implemented by this JavaClass. - */ - public JavaClass[] getInterfaces() { - String[] interfaces = getInterfaceNames(); - JavaClass[] classes = new JavaClass[interfaces.length]; - - try { - for (int i = 0; i < interfaces.length; i++) { - classes[i] = getRepository().loadClass(interfaces[i]); - } - } catch (ClassNotFoundException e) { - System.err.println(e); - return null; - } - - return classes; - } - - /** - * Get all interfaces implemented by this JavaClass (transitively). - */ - public Collection getAllInterfaces() { - Queue queue = new LinkedList(); - List interfaceList = new ArrayList(); - - queue.add(this); - - while (!queue.isEmpty()) { - JavaClass clazz = queue.remove(); - - JavaClass souper = clazz.getSuperClass(); - JavaClass[] interfaces = clazz.getInterfaces(); - - if (clazz.isInterface()) { - interfaceList.add(clazz); - } else { - if (souper != null) { - queue.add(souper); - } - } - - for (int i = 0; i < interfaces.length; i++) { - queue.add(interfaces[i]); - } - } - - return interfaceList; - // return interfaceList.toArray(new JavaClass[interfaceList.size()]); - } - - /** - * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature may be - * Ljava/util/Vector; the signature attribute will tell us e.g. "Ljava/lang/Object". We can learn the type variable names, - * their bounds, and the true superclass and superinterface types (including any parameterizations) Coded for performance - - * searches for the attribute only when requested - only searches for it once. - */ - public final String getGenericSignature() { - loadGenericSignatureInfoIfNecessary(); - return signatureAttributeString; - } - - public boolean isGeneric() { - loadGenericSignatureInfoIfNecessary(); - return isGeneric; - } - - private void loadGenericSignatureInfoIfNecessary() { - if (!searchedForSignatureAttribute) { - signatureAttribute = AttributeUtils.getSignatureAttribute(attributes); - signatureAttributeString = signatureAttribute == null ? null : signatureAttribute.getSignature(); - isGeneric = signatureAttribute != null && signatureAttributeString.charAt(0) == '<'; - searchedForSignatureAttribute = true; - } - } - - public final Signature getSignatureAttribute() { - loadGenericSignatureInfoIfNecessary(); - return signatureAttribute; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumber.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumber.java deleted file mode 100644 index 6b2a64877..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumber.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * This class represents a (PC offset, line number) pair, i.e., a line number in the source that corresponds to a relative address - * in the byte code. This is used for debugging purposes. - * - * @version $Id: LineNumber.java,v 1.6 2009/09/09 21:26:54 aclement Exp $ - * @author M. Dahm - * @author Andy Clement - * @see LineNumberTable - */ -public final class LineNumber implements Node { - private int startPC; - private int lineNumber; - - public LineNumber(LineNumber c) { - this(c.getStartPC(), c.getLineNumber()); - } - - LineNumber(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort()); - } - - public LineNumber(int startPC, int lineNumber) { - this.startPC = startPC; - this.lineNumber = lineNumber; - } - - public void accept(ClassVisitor v) { - v.visitLineNumber(this); - } - - public final void dump(DataOutputStream file) throws IOException { - file.writeShort(startPC); - file.writeShort(lineNumber); - } - - public final int getLineNumber() { - return lineNumber; - } - - public final int getStartPC() { - return startPC; - } - - // public final void setLineNumber(int line_number) { - // this.lineNumber = line_number; - // } - // - // public final void setStartPC(int start_pc) { - // this.startPC = start_pc; - // } - - @Override - public final String toString() { - return "LineNumber(" + startPC + ", " + lineNumber + ")"; - } - - public LineNumber copy() { - return new LineNumber(this); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumberTable.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumberTable.java deleted file mode 100644 index 871bfe6bf..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumberTable.java +++ /dev/null @@ -1,276 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a table of line numbers for debugging purposes. This attribute is used by the Code attribute. It - * contains pairs of PCs and line numbers. - * - * @version $Id: LineNumberTable.java,v 1.8 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Code changes: asc Feb06 Made unpacking lazy - */ -public final class LineNumberTable extends Attribute { - - // if 'isInPackedState' then this data needs unpacking - private boolean isInPackedState = false; - private byte[] data; // discarded once unpacked - - private int tableLength; - private LineNumber[] table; - - /* - * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical - * copy. - */ - public LineNumberTable(LineNumberTable c) { - this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool()); - } - - public LineNumberTable(int nameIndex, int length, LineNumber[] lineNumberTable, ConstantPool constantPool) { - super(Constants.ATTR_LINE_NUMBER_TABLE, nameIndex, length, constantPool); - setLineNumberTable(lineNumberTable); - isInPackedState = false; - } - - /** - * Construct object from file stream. - * - * @param name_index Index of name - * @param length Content length in bytes - * @param file Input stream - * @throws IOException - * @param constant_pool Array of constants - */ - LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, (LineNumber[]) null, constant_pool); - data = new byte[length]; - file.readFully(data); - isInPackedState = true; - // assert(bytesRead==length) - } - - // Unpacks the byte array into the table - private void unpack() { - if (isInPackedState) { - try { - ByteArrayInputStream bs = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bs); - tableLength = (dis.readUnsignedShort()); - table = new LineNumber[tableLength]; - for (int i = 0; i < tableLength; i++) { - table[i] = new LineNumber(dis); - } - dis.close(); - data = null; // throw it away now - } catch (IOException e) { - throw new RuntimeException("Unpacking of LineNumberTable attribute failed"); - } - isInPackedState = false; - } - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - unpack(); - v.visitLineNumberTable(this); - } - - /** - * Dump line number table attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - if (isInPackedState) { - file.write(data); - } else { - file.writeShort(tableLength); - for (int i = 0; i < tableLength; i++) { - table[i].dump(file); - } - } - } - - /** - * @return Array of (pc offset, line number) pairs. - */ - public final LineNumber[] getLineNumberTable() { - unpack(); - return table; - } - - /** - * @param line_number_table. - */ - public final void setLineNumberTable(LineNumber[] line_number_table) { - this.data = null; - this.isInPackedState = false; - this.table = line_number_table; - this.tableLength = (line_number_table == null) ? 0 : line_number_table.length; - } - - /** - * @return String representation. - */ - @Override - public final String toString() { - unpack(); - StringBuffer buf = new StringBuffer(); - StringBuffer line = new StringBuffer(); - - for (int i = 0; i < tableLength; i++) { - line.append(table[i].toString()); - - if (i < tableLength - 1) { - line.append(", "); - } - - if (line.length() > 72) { - line.append('\n'); - buf.append(line); - line.setLength(0); - } - } - - buf.append(line); - - return buf.toString(); - } - - /** - * Map byte code positions to source code lines. - * - * @param pos byte code offset - * @return corresponding line in source code - */ - public int getSourceLine(int pos) { - unpack(); - int l = 0, r = tableLength - 1; - - if (r < 0) // array is empty - return -1; - - int min_index = -1, min = -1; - - /* - * Do a binary search since the array is ordered. - */ - do { - int i = (l + r) / 2; - int j = table[i].getStartPC(); - - if (j == pos) - return table[i].getLineNumber(); - else if (pos < j) // else constrain search area - r = i - 1; - else - // pos > j - l = i + 1; - - /* - * If exact match can't be found (which is the most common case) return the line number that corresponds to the greatest - * index less than pos. - */ - if (j < pos && j > min) { - min = j; - min_index = i; - } - } while (l <= r); - - /* - * It's possible that we did not find any valid entry for the bytecode offset we were looking for. - */ - if (min_index < 0) - return -1; - - return table[min_index].getLineNumber(); - } - - /** - * @return deep copy of this attribute - */ - // @Override - // public Attribute copy(ConstantPool constant_pool) { - // unpack(); - // LineNumberTable newTable = (LineNumberTable) clone(); - // newTable.table = new LineNumber[tableLength]; - // for (int i = 0; i < tableLength; i++) { - // newTable.table[i] = table[i].copy(); - // } - // newTable.cpool = constant_pool; - // return newTable; - // } - public final int getTableLength() { - unpack(); - return tableLength; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariable.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariable.java deleted file mode 100644 index c8d5cd87f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariable.java +++ /dev/null @@ -1,267 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a local variable within a method. It contains its scope, name, signature and index on the method's frame. - * - * @version $Id: LocalVariable.java,v 1.5 2009/09/10 15:35:05 aclement Exp $ - * @author M. Dahm - * @see LocalVariableTable - */ -public final class LocalVariable implements Constants, Cloneable, Node { - - private int start_pc; // Range in which the variable is valid - private int length; - private int name_index; // Index in constant pool of variable name - private int signature_index; // Index of variable signature - private int index; /* - * Variable is `index'th local variable on this method's frame. - */ - - private ConstantPool constant_pool; - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical - * copy. - */ - public LocalVariable(LocalVariable c) { - this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(), c.getConstantPool()); - } - - /** - * Construct object from file stream. - * - * @param file Input stream - * @throws IOException - */ - LocalVariable(DataInputStream file, ConstantPool constant_pool) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file - .readUnsignedShort(), constant_pool); - } - - /** - * @param start_pc Range in which the variable - * @param length ... is valid - * @param name_index Index in constant pool of variable name - * @param signature_index Index of variable's signature - * @param index Variable is `index'th local variable on the method's frame - * @param constant_pool Array of constants - */ - public LocalVariable(int start_pc, int length, int name_index, int signature_index, int index, ConstantPool constant_pool) { - this.start_pc = start_pc; - this.length = length; - this.name_index = name_index; - this.signature_index = signature_index; - this.index = index; - this.constant_pool = constant_pool; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(ClassVisitor v) { - v.visitLocalVariable(this); - } - - /** - * Dump local variable to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException { - file.writeShort(start_pc); - file.writeShort(length); - file.writeShort(name_index); - file.writeShort(signature_index); - file.writeShort(index); - } - - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { - return constant_pool; - } - - /** - * @return Variable is valid within getStartPC() .. getStartPC()+getLength() - */ - public final int getLength() { - return length; - } - - /** - * @return Variable name. - */ - public final String getName() { - ConstantUtf8 c; - - c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8); - return c.getValue(); - } - - /** - * @return Index in constant pool of variable name. - */ - public final int getNameIndex() { - return name_index; - } - - /** - * @return Signature. - */ - public final String getSignature() { - ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(signature_index, CONSTANT_Utf8); - return c.getValue(); - } - - /** - * @return Index in constant pool of variable signature. - */ - public final int getSignatureIndex() { - return signature_index; - } - - /** - * @return index of register where variable is stored - */ - public final int getIndex() { - return index; - } - - /** - * @return Start of range where he variable is valid - */ - public final int getStartPC() { - return start_pc; - } - - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } - - /** - * @param length. - */ - public final void setLength(int length) { - this.length = length; - } - - /** - * @param name_index. - */ - public final void setNameIndex(int name_index) { - this.name_index = name_index; - } - - /** - * @param signature_index. - */ - public final void setSignatureIndex(int signature_index) { - this.signature_index = signature_index; - } - - /** - * @param index. - */ - public final void setIndex(int index) { - this.index = index; - } - - /** - * @param start_pc Specify range where the local variable is valid. - */ - public final void setStartPC(int start_pc) { - this.start_pc = start_pc; - } - - /** - * @return string representation. - */ - @Override - public final String toString() { - String name = getName(), signature = Utility.signatureToString(getSignature()); - - return "LocalVariable(start_pc = " + start_pc + ", length = " + length + ", index = " + index + ":" + signature + " " - + name + ")"; - } - - /** - * @return deep copy of this object - */ - public LocalVariable copy() { - try { - return (LocalVariable) clone(); - } catch (CloneNotSupportedException e) { - } - - return null; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariableTable.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariableTable.java deleted file mode 100644 index e6415dae6..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariableTable.java +++ /dev/null @@ -1,230 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents collection of local variables in a method. This attribute is contained in the Code attribute. - * - * @version $Id: LocalVariableTable.java,v 1.8 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Code - * @see LocalVariable Updates: Andy 14Feb06 - Made unpacking of the data lazy, depending on someone actually asking for it. - */ -public class LocalVariableTable extends Attribute { - - // if 'isInPackedState' then this data needs unpacking - private boolean isInPackedState = false; - private byte[] data; - - private int localVariableTableLength; - private LocalVariable[] localVariableTable; - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical - * copy. - */ - public LocalVariableTable(LocalVariableTable c) { - this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool()); - } - - /** - * @param name_index Index in constant pool to `LocalVariableTable' - * @param length Content length in bytes - * @param local_variable_table Table of local variables - * @param constant_pool Array of constants - */ - public LocalVariableTable(int name_index, int length, LocalVariable[] local_variable_table, ConstantPool constant_pool) { - super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); - setLocalVariableTable(local_variable_table); - } - - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - LocalVariableTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); - data = new byte[length]; - file.readFully(data); - isInPackedState = true; - // assert(bytesRead==length) - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - unpack(); - v.visitLocalVariableTable(this); - } - - /** - * Dump local variable table attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - if (isInPackedState) { - file.write(data); - } else { - file.writeShort(localVariableTableLength); - for (int i = 0; i < localVariableTableLength; i++) - localVariableTable[i].dump(file); - } - } - - /** - * @return Array of local variables of method. - */ - public final LocalVariable[] getLocalVariableTable() { - unpack(); - return localVariableTable; - } - - /** - * @return first matching variable using index - */ - public final LocalVariable getLocalVariable(int index) { - unpack(); - for (int i = 0; i < localVariableTableLength; i++) { - if (localVariableTable[i] != null && localVariableTable[i].getIndex() == index) { - return localVariableTable[i]; - } - } - return null; - } - - public final void setLocalVariableTable(LocalVariable[] local_variable_table) { - data = null; - isInPackedState = false; - this.localVariableTable = local_variable_table; - localVariableTableLength = (local_variable_table == null) ? 0 : local_variable_table.length; - } - - /** - * @return String representation. - */ - @Override - public final String toString() { - StringBuffer buf = new StringBuffer(""); - unpack(); - for (int i = 0; i < localVariableTableLength; i++) { - buf.append(localVariableTable[i].toString()); - - if (i < localVariableTableLength - 1) - buf.append('\n'); - } - - return buf.toString(); - } - - /** - * @return deep copy of this attribute - */ - // public Attribute copy(ConstantPool constant_pool) { - // unpack(); - // LocalVariableTable c = (LocalVariableTable) clone(); - // - // c.localVariableTable = new LocalVariable[localVariableTableLength]; - // for (int i = 0; i < localVariableTableLength; i++) - // c.localVariableTable[i] = localVariableTable[i].copy(); - // - // c.cpool = constant_pool; - // return c; - // } - public final int getTableLength() { - unpack(); - return localVariableTableLength; - } - - // --- - // Unpacks the byte array into the table - private void unpack() { - if (!isInPackedState) - return; - try { - ByteArrayInputStream bs = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bs); - localVariableTableLength = (dis.readUnsignedShort()); - localVariableTable = new LocalVariable[localVariableTableLength]; - for (int i = 0; i < localVariableTableLength; i++) - localVariableTable[i] = new LocalVariable(dis, cpool); - dis.close(); - data = null; // throw it away now - } catch (IOException e) { - throw new RuntimeException("Unpacking of LocalVariableTable attribute failed"); - } - isInPackedState = false; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java deleted file mode 100644 index ecd7e4383..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement initial implementation - * Heavily based on LocalVariableTable - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -// The new table is used when generic types are about... - -//LocalVariableTable_attribute { -// u2 attribute_name_index; -// u4 attribute_length; -// u2 local_variable_table_length; -// { u2 start_pc; -// u2 length; -// u2 name_index; -// u2 descriptor_index; -// u2 index; -// } local_variable_table[local_variable_table_length]; -// } - -//LocalVariableTypeTable_attribute { -// u2 attribute_name_index; -// u4 attribute_length; -// u2 local_variable_type_table_length; -// { -// u2 start_pc; -// u2 length; -// u2 name_index; -// u2 signature_index; -// u2 index; -// } local_variable_type_table[local_variable_type_table_length]; -// } -// J5TODO: Needs some testing ! -public class LocalVariableTypeTable extends Attribute { - private int local_variable_type_table_length; // Table of local - private LocalVariable[] local_variable_type_table; // variables - - public LocalVariableTypeTable(LocalVariableTypeTable c) { - this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool()); - } - - public LocalVariableTypeTable(int name_index, int length, LocalVariable[] local_variable_table, ConstantPool constant_pool) { - super(Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool); - setLocalVariableTable(local_variable_table); - } - - LocalVariableTypeTable(int nameIdx, int len, DataInputStream dis, ConstantPool cpool) throws IOException { - this(nameIdx, len, (LocalVariable[]) null, cpool); - - local_variable_type_table_length = (dis.readUnsignedShort()); - local_variable_type_table = new LocalVariable[local_variable_type_table_length]; - - for (int i = 0; i < local_variable_type_table_length; i++) - local_variable_type_table[i] = new LocalVariable(dis, cpool); - } - - @Override - public void accept(ClassVisitor v) { - v.visitLocalVariableTypeTable(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(local_variable_type_table_length); - for (int i = 0; i < local_variable_type_table_length; i++) - local_variable_type_table[i].dump(file); - } - - public final LocalVariable[] getLocalVariableTypeTable() { - return local_variable_type_table; - } - - public final LocalVariable getLocalVariable(int index) { - for (int i = 0; i < local_variable_type_table_length; i++) - if (local_variable_type_table[i].getIndex() == index) - return local_variable_type_table[i]; - - return null; - } - - public final void setLocalVariableTable(LocalVariable[] local_variable_table) { - this.local_variable_type_table = local_variable_table; - local_variable_type_table_length = (local_variable_table == null) ? 0 : local_variable_table.length; - } - - /** - * @return String representation. - */ - @Override - public final String toString() { - StringBuffer buf = new StringBuffer(""); - - for (int i = 0; i < local_variable_type_table_length; i++) { - buf.append(local_variable_type_table[i].toString()); - - if (i < local_variable_type_table_length - 1) - buf.append('\n'); - } - - return buf.toString(); - } - - // /** - // * @return deep copy of this attribute - // */ - // public Attribute copy(ConstantPool constant_pool) { - // LocalVariableTypeTable c = (LocalVariableTypeTable)clone(); - // - // c.local_variable_type_table = new LocalVariable[local_variable_type_table_length]; - // for(int i=0; i < local_variable_type_table_length; i++) - // c.local_variable_type_table[i] = local_variable_type_table[i].copy(); - // - // c.cpool = constant_pool; - // return c; - // } - - public final int getTableLength() { - return local_variable_type_table_length; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Method.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Method.java deleted file mode 100644 index 46aeac845..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Method.java +++ /dev/null @@ -1,273 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; -import org.aspectj.apache.bcel.generic.Type; - -/** - * This class represents the method info structure, i.e., the representation for a method in the class. See JVM specification for - * details. A method has access flags, a name, a signature and a number of attributes. - * - * @version $Id: Method.java,v 1.11 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - */ -public final class Method extends FieldOrMethod { - - public static final AnnotationGen[][] NO_PARAMETER_ANNOTATIONS = new AnnotationGen[][] {}; - - public static final Method[] NoMethods = new Method[0]; - - private boolean parameterAnnotationsOutOfDate = true; - private AnnotationGen[][] unpackedParameterAnnotations; - - private Method() { - parameterAnnotationsOutOfDate = true; - } - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical - * copy. - */ - public Method(Method c) { - super(c); - parameterAnnotationsOutOfDate = true; - } - - Method(DataInputStream file, ConstantPool constant_pool) throws IOException { - super(file, constant_pool); - } - - public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes, ConstantPool constant_pool) { - super(access_flags, name_index, signature_index, attributes, constant_pool); - parameterAnnotationsOutOfDate = true; - } - - public void accept(ClassVisitor v) { - v.visitMethod(this); - } - - // CUSTARD mutable or not? - @Override - public void setAttributes(Attribute[] attributes) { - parameterAnnotationsOutOfDate = true; - super.setAttributes(attributes); - } - - /** - * @return Code attribute of method, if any - */ - public final Code getCode() { - return AttributeUtils.getCodeAttribute(attributes); - } - - public final ExceptionTable getExceptionTable() { - return AttributeUtils.getExceptionTableAttribute(attributes); - } - - /** - * Return LocalVariableTable of code attribute if any (the call is forwarded to the Code attribute) - */ - public final LocalVariableTable getLocalVariableTable() { - Code code = getCode(); - if (code != null) - return code.getLocalVariableTable(); - return null; - } - - /** - * Return LineNumberTable of code attribute if any (the call is forwarded to the Code attribute) - */ - public final LineNumberTable getLineNumberTable() { - Code code = getCode(); - if (code != null) - return code.getLineNumberTable(); - return null; - } - - /** - * Return string representation close to declaration format, eg: 'public static void main(String[] args) throws IOException' - */ - @Override - public final String toString() { - ConstantUtf8 c; - String name, signature, access; // Short cuts to constant pool - StringBuffer buf; - - access = Utility.accessToString(modifiers); - - // Get name and signature from constant pool - c = (ConstantUtf8) cpool.getConstant(signatureIndex, Constants.CONSTANT_Utf8); - signature = c.getValue(); - - c = (ConstantUtf8) cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); - name = c.getValue(); - - signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable()); - buf = new StringBuffer(signature); - - for (int i = 0; i < attributes.length; i++) { - Attribute a = attributes[i]; - if (!((a instanceof Code) || (a instanceof ExceptionTable))) - buf.append(" [" + a.toString() + "]"); - } - - ExceptionTable e = getExceptionTable(); - if (e != null) { - String str = e.toString(); - if (!str.equals("")) - buf.append("\n\t\tthrows " + str); - } - - return buf.toString(); - } - - /** - * @return return type of method - */ - public Type getReturnType() { - return Type.getReturnType(getSignature()); - } - - /** - * @return array of method argument types - */ - public Type[] getArgumentTypes() { - return Type.getArgumentTypes(getSignature()); - } - - private void ensureParameterAnnotationsUnpacked() { - if (!parameterAnnotationsOutOfDate) - return; - parameterAnnotationsOutOfDate = false; - - int parameterCount = getArgumentTypes().length; - if (parameterCount == 0) { - unpackedParameterAnnotations = NO_PARAMETER_ANNOTATIONS; - return; - } - - RuntimeVisParamAnnos parameterAnnotationsVis = null; - RuntimeInvisParamAnnos parameterAnnotationsInvis = null; - - // Find attributes that contain annotation data - Attribute[] attrs = getAttributes(); - - for (int i = 0; i < attrs.length; i++) { - Attribute attribute = attrs[i]; - if (attribute instanceof RuntimeVisParamAnnos) { - parameterAnnotationsVis = (RuntimeVisParamAnnos) attribute; - } else if (attribute instanceof RuntimeInvisParamAnnos) { - parameterAnnotationsInvis = (RuntimeInvisParamAnnos) attribute; - } - } - - boolean foundSome = false; - // Build a list of annotation arrays, one per argument - if (parameterAnnotationsInvis != null || parameterAnnotationsVis != null) { - List annotationsForEachParameter = new ArrayList(); - AnnotationGen[] visibleOnes = null; - AnnotationGen[] invisibleOnes = null; - for (int i = 0; i < parameterCount; i++) { - int count = 0; - visibleOnes = new AnnotationGen[0]; - invisibleOnes = new AnnotationGen[0]; - if (parameterAnnotationsVis != null) { - visibleOnes = parameterAnnotationsVis.getAnnotationsOnParameter(i); - count += visibleOnes.length; - } - if (parameterAnnotationsInvis != null) { - invisibleOnes = parameterAnnotationsInvis.getAnnotationsOnParameter(i); - count += invisibleOnes.length; - } - - AnnotationGen[] complete = AnnotationGen.NO_ANNOTATIONS; - if (count != 0) { - complete = new AnnotationGen[visibleOnes.length + invisibleOnes.length]; - System.arraycopy(visibleOnes, 0, complete, 0, visibleOnes.length); - System.arraycopy(invisibleOnes, 0, complete, visibleOnes.length, invisibleOnes.length); - foundSome = true; - } - annotationsForEachParameter.add(complete); - } - if (foundSome) { - unpackedParameterAnnotations = annotationsForEachParameter.toArray(new AnnotationGen[][] {}); - return; - } - } - unpackedParameterAnnotations = NO_PARAMETER_ANNOTATIONS; - } - - public AnnotationGen[] getAnnotationsOnParameter(int i) { - ensureParameterAnnotationsUnpacked(); - if (unpackedParameterAnnotations == NO_PARAMETER_ANNOTATIONS) { - return AnnotationGen.NO_ANNOTATIONS; - } - return unpackedParameterAnnotations[i]; - } - - public AnnotationGen[][] getParameterAnnotations() { - ensureParameterAnnotationsUnpacked(); - return unpackedParameterAnnotations; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/MethodParameters.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/MethodParameters.java deleted file mode 100644 index 547041584..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/MethodParameters.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2013 VMware - * - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -// see http://cr.openjdk.java.net/~abuckley/8misc.pdf -public class MethodParameters extends Attribute { - - public final static int[] NO_PARAMETER_NAME_INDEXES = new int[0]; - public final static int[] NO_PARAMETER_ACCESS_FLAGS = new int[0]; - - public final static int ACCESS_FLAGS_FINAL = 0x0010; - public final static int ACCESS_FLAGS_SYNTHETIC = 0x1000; - public final static int ACCESS_FLAGS_MANDATED = 0x8000; - - // if 'isInPackedState' then this data needs unpacking - private boolean isInPackedState = false; - private byte[] data; - private int[] names; - private int[] accessFlags; - - public MethodParameters(int index, int length, DataInputStream dis, ConstantPool cpool) throws IOException { - super(Constants.ATTR_METHOD_PARAMETERS,index,length,cpool); - data = new byte[length]; - dis.readFully(data,0,length); - isInPackedState = true; - } - - private void ensureInflated() { - if (names!=null) return; - try { - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data)); - int parametersCount = dis.readUnsignedByte(); - if (parametersCount == 0) { - names = NO_PARAMETER_NAME_INDEXES; - accessFlags = NO_PARAMETER_ACCESS_FLAGS; - } else { - names = new int[parametersCount]; - accessFlags = new int[parametersCount]; - for (int i=0;i. - */ - -import org.aspectj.apache.bcel.Constants; - -/** - * Super class for all objects that have modifiers like private, final, ... I.e. - * classes, fields, and methods. - * was AccessFlags - * - * @version $Id: Modifiers.java,v 1.2 2008/05/28 23:53:01 aclement Exp $ - * @author M. Dahm - */ -public abstract class Modifiers { - - protected int modifiers; - - public Modifiers() { } - - public Modifiers(int a) { - modifiers = a; - } - - public final int getModifiers() { - return modifiers; - } - - public final void setModifiers(int modifiers) { - this.modifiers = modifiers; - } - - public final boolean isPublic() { - return (modifiers & Constants.ACC_PUBLIC) != 0; - } - - public final boolean isPrivate() { - return (modifiers & Constants.ACC_PRIVATE) != 0; - } - - public final boolean isProtected() { - return (modifiers & Constants.ACC_PROTECTED) != 0; - } - - public final boolean isStatic() { - return (modifiers & Constants.ACC_STATIC) != 0; - } - - public final boolean isFinal() { - return (modifiers & Constants.ACC_FINAL) != 0; - } - - public final boolean isSynchronized() { - return (modifiers & Constants.ACC_SYNCHRONIZED) != 0; - } - - public final boolean isVolatile() { - return (modifiers & Constants.ACC_VOLATILE) != 0; - } - - public final boolean isTransient() { - return (modifiers & Constants.ACC_TRANSIENT) != 0; - } - - public final boolean isNative() { - return (modifiers & Constants.ACC_NATIVE) != 0; - } - - public final boolean isInterface() { - return (modifiers & Constants.ACC_INTERFACE) != 0; - } - - public final boolean isAbstract() { - return (modifiers & Constants.ACC_ABSTRACT) != 0; - } - - public final boolean isStrictfp() { - return (modifiers & Constants.ACC_STRICT) != 0; - } - - public final boolean isVarargs() { - return (modifiers & Constants.ACC_VARARGS) != 0; - } - - public final boolean isBridge() { - return (modifiers & Constants.ACC_BRIDGE) != 0; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java deleted file mode 100644 index 5eef18cde..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java +++ /dev/null @@ -1,664 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2016-17 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from Attribute and represents the module - * information captured in a class file. - * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html - * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 - * - * @author Andy Clement - */ -public final class Module extends Attribute { - - private static final String[] NO_MODULE_NAMES = {}; - - private int moduleNameIndex; // u2 module_name_index - private int moduleFlags; // u2 module_flags - private int moduleVersionIndex; // u2 module_version_index - private Require[] requires; - private Export[] exports; - private Open[] opens; - private Uses[] uses; - private Provide[] provides; - - private byte[] moduleInfo; - private int ptr; - private boolean unpacked = false; - - public Module(Module module) { - super(module.getTag(), module.getNameIndex(), module.getLength(), module.getConstantPool()); - moduleInfo = module.getBytes(); - } - - public Module(int nameIndex, int length, byte[] data, ConstantPool cp) { - super(Constants.ATTR_MODULE, nameIndex, length, cp); - } - - Module(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { - this(nameIndex, length, (byte[])null, cp); - moduleInfo = new byte[length]; - stream.read(moduleInfo); - unpacked = false; - } - - public class Require { - - private final int moduleIndex; - private final int flags; - private final int versionIndex; - - public Require(int moduleIndex, int flags, int versionIndex) { - this.moduleIndex = moduleIndex; - this.flags = flags; - this.versionIndex = versionIndex; - } - - public String getModuleName() { - return cpool.getModuleName(moduleIndex); - } - - public int getFlags() { - return flags; - } - - public int getVersionIndex() { - return versionIndex; - } - - public String getVersionString() { - if (versionIndex == 0) { - return null; - } else { - return cpool.getConstantUtf8(versionIndex).getValue(); - } - } - - public String getFlagsAsString() { - StringBuilder s = new StringBuilder(); - if ((flags & Constants.MODULE_ACC_TRANSITIVE)!=0) { - s.append(" transitive"); - } - if ((flags & Constants.MODULE_ACC_STATIC_PHASE)!=0) { - s.append(" static"); - } - if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { - s.append(" synthetic"); - } - if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { - s.append(" mandated"); - } - return s.toString(); - } - - public String toString() { - return "requires"+getFlagsAsString()+" "+getModuleName()+(versionIndex==0?"":" "+getVersionString()); - } - } - - - public class Export { - - private final int packageIndex; - private final int flags; - private final int[] toModuleIndices; - - public Export(int packageIndex, int flags, int[] toModuleIndices) { - this.packageIndex = packageIndex; - this.flags = flags; - this.toModuleIndices = toModuleIndices; - } - - public int getPackageIndex() { - return packageIndex; - } - - public int getFlags() { - return flags; - } - - public int[] getToModuleIndices() { - return toModuleIndices; - } - - public String getPackage() { - return cpool.getPackageName(packageIndex); - } - - public String getFlagsAsString() { - StringBuilder s = new StringBuilder(); - if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { - s.append(" synthetic"); - } - if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { - s.append(" synthetic"); - } - return s.toString(); - } - - public String[] getToModuleNames() { - if (toModuleIndices==null) { - return NO_MODULE_NAMES; - } - String[] toModuleNames = new String[toModuleIndices.length]; - for (int i=0;i0) { - s.append(", "); - } - s.append(toModules[i]); - } - } - return s.toString().trim(); - } - } - - - public class Open { - - private final int packageIndex; - private final int flags; - private final int[] toModuleIndices; - - public Open(int packageIndex, int flags, int[] toModuleIndices) { - this.packageIndex = packageIndex; - this.flags = flags; - this.toModuleIndices = toModuleIndices; - } - - public int getPackageIndex() { - return packageIndex; - } - - public int getFlags() { - return flags; - } - - public int[] getToModuleIndices() { - return toModuleIndices; - } - - public String getPackage() { - return cpool.getPackageName(packageIndex); - } - - public String getFlagsAsString() { - StringBuilder s = new StringBuilder(); - if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { - s.append(" synthetic"); - } - if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { - s.append(" synthetic"); - } - return s.toString(); - } - - public String[] getToModuleNames() { - if (toModuleIndices==null) { - return NO_MODULE_NAMES; - } - String[] toModuleNames = new String[toModuleIndices.length]; - for (int i=0;i0) { - s.append(", "); - } - s.append(toModules[i]); - } - } - return s.toString().trim(); - } - } - - public class Provide { - private final int providedTypeIndex; - private final int[] withTypeIndices; - - public Provide(int providedTypeIndex, int[] withTypeIndices) { - this.providedTypeIndex = providedTypeIndex; - this.withTypeIndices = withTypeIndices; - } - - public String getProvidedType() { - return cpool.getConstantString_CONSTANTClass(providedTypeIndex); - } - - public int getProvidedTypeIndex() { - return providedTypeIndex; - } - - public String[] getWithTypeStrings() { - String[] result = new String[withTypeIndices.length]; - for (int i=0;i0) s.append(","); - s.append(withtypes[i].replace('/','.')); - } - return s.toString(); - } - } - - public class Uses { - private final int typeNameIndex; - - public Uses(int typeNameIndex) { - this.typeNameIndex = typeNameIndex; - } - - public String getTypeName() { - return cpool.getConstantString_CONSTANTClass(typeNameIndex); - } - - public int getTypeNameIndex() { - return typeNameIndex; - } - - public String toString() { - StringBuilder s =new StringBuilder(); - s.append("uses ").append(getTypeName().replace('/', '.')); - return s.toString().trim(); - } - } - - private final int readInt() { - return ((moduleInfo[ptr++] & 0xFF) << 24) + ((moduleInfo[ptr++] & 0xFF) << 16) - + ((moduleInfo[ptr++] & 0xFF) << 8) + (moduleInfo[ptr++] & 0xFF); - } - - private final int readUnsignedShort() { - return ((moduleInfo[ptr++] & 0xff) << 8) + (moduleInfo[ptr++] & 0xff); - } - - private final int readUnsignedShort(int offset) { - return ((moduleInfo[offset++] & 0xff) << 8) + (moduleInfo[offset] & 0xff); - } - - // Format: http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 - private void ensureUnpacked() { - if (!unpacked) { - ptr = 0; - moduleNameIndex = readUnsignedShort(); - moduleFlags = readUnsignedShort(); - moduleVersionIndex = readUnsignedShort(); - - int count = readUnsignedShort(); - requires = new Require[count]; - for (int i = 0; i < count; i++) { - requires[i] = new Require(readUnsignedShort(), readUnsignedShort(), readUnsignedShort()); - } - - count = readUnsignedShort(); - exports = new Export[count]; - for (int i = 0; i < count; i++) { - int index = readUnsignedShort(); - int flags = readUnsignedShort(); - int toCount = readUnsignedShort(); - int[] to = new int[toCount]; - for (int j = 0; j < toCount; j++) { - to[j] = readUnsignedShort(); - } - exports[i] = new Export(index, flags, to); - } - - count = readUnsignedShort(); - opens = new Open[count]; - for (int i = 0; i < count; i++) { - int index = readUnsignedShort(); - int flags = readUnsignedShort(); - int toCount = readUnsignedShort(); - int[] to = new int[toCount]; - for (int j = 0; j < toCount; j++) { - to[j] = readUnsignedShort(); - } - opens[i] = new Open(index, flags, to); - } - count = readUnsignedShort(); - uses = new Uses[count]; - for (int i = 0; i < count; i++) { - uses[i] = new Uses(readUnsignedShort()); - } - count = readUnsignedShort(); - provides = new Provide[count]; - for (int i = 0; i < count; i++) { - int index = readUnsignedShort(); - int toCount = readUnsignedShort(); - int[] to = new int[toCount]; - for (int j = 0; j < toCount; j++) { - to[j] = readUnsignedShort(); - } - provides[i] = new Provide(index, to); - } - unpacked = true; - } - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - if (!unpacked) { - file.write(moduleInfo); - } else { - - file.writeShort(moduleNameIndex); - file.writeShort(moduleFlags); - file.writeShort(moduleVersionIndex); - - file.writeShort(requires.length); - for (int i = 0; i < requires.length; i++) { - file.writeShort(requires[i].moduleIndex); - file.writeShort(requires[i].flags); - file.writeShort(requires[i].versionIndex); - } - file.writeShort(exports.length); - for (Export export : exports) { - file.writeShort(export.packageIndex); - int[] toIndices = export.toModuleIndices; - file.writeShort(toIndices.length); - for (int index : toIndices) { - file.writeShort(index); - } - } - file.writeShort(opens.length); - for (Open open : opens) { - file.writeShort(open.packageIndex); - int[] toIndices = open.toModuleIndices; - file.writeShort(toIndices.length); - for (int index : toIndices) { - file.writeShort(index); - } - } - file.writeShort(uses.length); - for (Uses use : uses) { - file.writeShort(use.getTypeNameIndex()); - } - file.writeShort(provides.length); - for (Provide provide : provides) { - file.writeShort(provide.providedTypeIndex); - int[] toIndices = provide.withTypeIndices; - file.writeShort(toIndices.length); - for (int index : toIndices) { - file.writeShort(index); - } - } - } - } - - public String toStringRequires() { - StringBuilder s = new StringBuilder(); - s.append('#').append(requires.length); - if (requires.length > 0) { - for (Require require : requires) { - s.append(' '); - s.append(require.moduleIndex).append(':').append(require.flags); - } - } - return s.toString(); - } - - public String toStringExports() { - StringBuilder s = new StringBuilder(); - s.append('#').append(exports.length); - if (exports.length > 0) { - for (Export export : exports) { - s.append(' '); - s.append(export.packageIndex).append(":["); - int[] toIndices = export.toModuleIndices; - for (int i = 0; i < toIndices.length; i++) { - if (i > 0) - s.append(','); - s.append(toIndices[i]); - } - s.append("]"); - } - } - return s.toString(); - } - - public String toStringOpens() { - StringBuilder s = new StringBuilder(); - s.append('#').append(opens.length); - if (opens.length > 0) { - for (Open open : opens) { - s.append(' '); - s.append(open.packageIndex).append(":["); - int[] toIndices = open.toModuleIndices; - for (int i = 0; i < toIndices.length; i++) { - if (i > 0) - s.append(','); - s.append(toIndices[i]); - } - s.append("]"); - } - } - return s.toString(); - } - - public String toStringUses() { - StringBuilder s = new StringBuilder(); - s.append('#').append(uses.length); - if (uses.length > 0) { - for (Uses use : uses) { - s.append(' '); - s.append(use.getTypeName()); - } - } - return s.toString(); - } - - public String toStringProvides() { - StringBuilder s = new StringBuilder(); - s.append('#').append(provides.length); - if (provides.length > 0) { - for (Provide provide : provides) { - s.append(' '); - s.append(provide.providedTypeIndex).append(":["); - int[] indices = provide.withTypeIndices; - for (int i = 0; i < indices.length; i++) { - if (i > 0) - s.append(','); - s.append(indices[i]); - } - s.append("]"); - } - } - return s.toString(); - } - - @Override - public final String toString() { - StringBuilder s = new StringBuilder(); - ensureUnpacked(); - s.append("Module("); - if (requires.length != 0) { - s.append("requires="); - s.append(toStringRequires()); - s.append(" "); - } - if (exports.length != 0) { - s.append("exports="); - s.append(toStringExports()); - s.append(" "); - } - if (opens.length != 0) { - s.append("opens="); - s.append(toStringOpens()); - s.append(" "); - } - if (uses.length != 0) { - s.append("uses="); - s.append(toStringUses()); - s.append(" "); - } - if (provides.length != 0) { - s.append("provides="); - s.append(toStringProvides()); - s.append(" "); - } - return s.toString().trim()+")"; - } - - /** - * @return deep copy of this attribute // - */ -// @Override -// public Attribute copy(ConstantPool constant_pool) { -// return (Module) clone(); -// } - - @Override - public void accept(ClassVisitor v) { - v.visitModule(this); - } - - public Require[] getRequires() { - ensureUnpacked(); - return requires; - } - - public String[] getRequiredModuleNames() { - ensureUnpacked(); - String[] results = new String[requires.length]; - for (int i=0;i. - */ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * Indicates the main class of a module. - * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26 - * - * @author Andy Clement - */ -public final class ModuleMainClass extends Attribute { - - private int mainClassIndex; - - public ModuleMainClass(ModuleMainClass c) { - this(c.getNameIndex(), c.getLength(), c.getMainClassIndex(), c.getConstantPool()); - } - - public ModuleMainClass(int nameIndex, int length, int mainClassIndex, ConstantPool cp) { - super(Constants.ATTR_MODULE_MAIN_CLASS, nameIndex, length, cp); - this.mainClassIndex = mainClassIndex; - } - - ModuleMainClass(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { - this(nameIndex, length, 0, cp); - this.mainClassIndex = stream.readUnsignedShort(); - } - - @Override - public void accept(ClassVisitor v) { - v.visitModuleMainClass(this); - } - - @Override - public final void dump(DataOutputStream stream) throws IOException { - super.dump(stream); - stream.writeShort(mainClassIndex); - } - - public final int getMainClassIndex() { - return mainClassIndex; - } - - @Override - public final String toString() { - return cpool.getConstantString_CONSTANTClass(mainClassIndex); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java deleted file mode 100644 index 37da4bc47..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java +++ /dev/null @@ -1,126 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2017 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * Indicates all the packages of a module that are exported or opened by the module attribute. - * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26 - * - * @author Andy Clement - */ -public final class ModulePackages extends Attribute { - - private static int[] NO_PACKAGES = new int[0]; - private int[] packageIndices; - - public ModulePackages(ModulePackages c) { - this(c.getNameIndex(), c.getLength(), c.getPackageIndices(), c.getConstantPool()); - } - - public ModulePackages(int nameIndex, int length, int[] packageIndices, ConstantPool cp) { - super(Constants.ATTR_MODULE_PACKAGES, nameIndex, length, cp); - setPackageIndices(packageIndices); - } - - ModulePackages(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { - this(nameIndex, length, (int[]) null, cp); - int packageIndicesCount = stream.readUnsignedShort(); - packageIndices = new int[packageIndicesCount]; - for (int i = 0; i < packageIndicesCount; i++) { - packageIndices[i] = stream.readUnsignedShort(); - } - } - - @Override - public void accept(ClassVisitor v) { - v.visitModulePackages(this); - } - - @Override - public final void dump(DataOutputStream stream) throws IOException { - super.dump(stream); - stream.writeShort(packageIndices.length); - for (int i = 0; i < packageIndices.length; i++) { - stream.writeShort(packageIndices[i]); - } - } - - public final int[] getPackageIndices() { - return packageIndices; - } - - public final void setPackageIndices(int[] packageIndices) { - if (packageIndices == null) { - this.packageIndices = NO_PACKAGES; - } else { - this.packageIndices = packageIndices; - } - } - - @Override - public final String toString() { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < packageIndices.length; i++) { - buf.append(cpool.getPackageName(packageIndices[i]) + "\n"); - } - return buf.toString(); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/NestHost.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/NestHost.java deleted file mode 100644 index 52d312659..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/NestHost.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.28 - * - * @see Attribute - */ -public final class NestHost extends Attribute { - private int hostClassIndex; - - public NestHost(NestHost c) { - this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool()); - } - - public NestHost(int nameIndex, int length, int hostClassIndex, ConstantPool cp) { - super(Constants.ATTR_NEST_MEMBERS, nameIndex, length, cp); - this.hostClassIndex = hostClassIndex; - } - - NestHost(int nameIndex, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(nameIndex, length, 0, constant_pool); - hostClassIndex = file.readUnsignedShort(); - } - - @Override - public void accept(ClassVisitor v) { - v.visitNestHost(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(hostClassIndex); - } - - public final int getHostClassIndex() { - return hostClassIndex; - } - - public final void setHostClassIndex(int hostClassIndex) { - this.hostClassIndex = hostClassIndex; - } - - public final String getHostClassName() { - ConstantClass constantClass = (ConstantClass)cpool.getConstant(hostClassIndex,Constants.CONSTANT_Class); - return constantClass.getClassname(cpool); - } - - @Override - public final String toString() { - StringBuffer buf = new StringBuffer(); - buf.append("NestHost("); - ConstantClass constantClass = (ConstantClass)cpool.getConstant(hostClassIndex,Constants.CONSTANT_Class); - buf.append(constantClass.getClassname(cpool)); - buf.append(")"); - return buf.toString(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/NestMembers.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/NestMembers.java deleted file mode 100644 index 9d273966f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/NestMembers.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.29 - * - * @see Attribute - */ -public final class NestMembers extends Attribute { - private int numberOfClasses; - private int[] classes; // CONSTANT_Class_info references - - public NestMembers(NestMembers c) { - this(c.getNameIndex(), c.getLength(), c.getClasses(), c.getConstantPool()); - } - - public NestMembers(int nameIndex, int length, int[] classes, ConstantPool cp) { - super(Constants.ATTR_NEST_MEMBERS, nameIndex, length, cp); - setClasses(classes); - } - - NestMembers(int nameIndex, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(nameIndex, length, (int[]) null, constant_pool); - numberOfClasses = file.readUnsignedShort(); - classes = new int[numberOfClasses]; - for (int i = 0; i < numberOfClasses; i++) { - classes[i] = file.readUnsignedShort(); - } - } - - @Override - public void accept(ClassVisitor v) { - v.visitNestMembers(this); - } - - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(numberOfClasses); - for (int i = 0; i < numberOfClasses; i++) { - file.writeShort(classes[i]); - } - } - - public final int[] getClasses() { - return classes; - } - - public final void setClasses(int[] inner_classes) { - this.classes = inner_classes; - numberOfClasses = (inner_classes == null) ? 0 : inner_classes.length; - } - - public final String[] getClassesNames() { - String[] result = new String[numberOfClasses]; - for (int i = 0; i < numberOfClasses; i++) { - ConstantClass constantClass = (ConstantClass)cpool.getConstant(classes[i],Constants.CONSTANT_Class); - result[i] = constantClass.getClassname(cpool); - } - return result; - } - - @Override - public final String toString() { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < numberOfClasses; i++) { - ConstantClass constantClass = (ConstantClass)cpool.getConstant(classes[i],Constants.CONSTANT_Class); - buf.append(constantClass.getClassname(cpool)).append(" "); - } - return "NestMembers("+buf.toString().trim()+")"; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Node.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Node.java deleted file mode 100644 index 5bef82979..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Node.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Denote class to have an accept method(); - * - * @version $Id: Node.java,v 1.3 2008/05/28 23:53:01 aclement Exp $ - * @author M. Dahm - */ -public interface Node { - public void accept(ClassVisitor obj); -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Signature.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Signature.java deleted file mode 100644 index b7488e9a4..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Signature.java +++ /dev/null @@ -1,310 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - * Extended by Adrian Colyer, June 2005 to support unpacking of Signature - * attribute - */ - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from Attribute and represents a reference to a GJ - * attribute. - * - * @version $Id: Signature.java,v 1.11 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Attribute - */ -public final class Signature extends Attribute { - private int signature_index; - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical - * copy. - */ - public Signature(Signature c) { - this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool()); - } - - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Signature(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, file.readUnsignedShort(), constant_pool); - } - - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param constant_pool Array of constants - * @param Signature_index Index in constant pool to CONSTANT_Utf8 - */ - public Signature(int name_index, int length, int signature_index, ConstantPool constant_pool) { - super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool); - this.signature_index = signature_index; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - System.err.println("Visiting non-standard Signature object"); - v.visitSignature(this); - } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(signature_index); - } - - /** - * @return Index in constant pool of source file name. - */ - public final int getSignatureIndex() { - return signature_index; - } - - /** - * @param Signature_index. - */ - public final void setSignatureIndex(int signature_index) { - this.signature_index = signature_index; - } - - /** - * @return GJ signature. - */ - public final String getSignature() { - ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(signature_index, Constants.CONSTANT_Utf8); - return c.getValue(); - } - - /** - * Extends ByteArrayInputStream to make 'unreading' chars possible. - */ - private static final class MyByteArrayInputStream extends ByteArrayInputStream { - MyByteArrayInputStream(String data) { - super(data.getBytes()); - } - - final int mark() { - return pos; - } - - final String getData() { - return new String(buf); - } - - final void reset(int p) { - pos = p; - } - - final void unread() { - if (pos > 0) - pos--; - } - } - - private static boolean identStart(int ch) { - return ch == 'T' || ch == 'L'; - } - - private static final void matchIdent(MyByteArrayInputStream in, StringBuffer buf) { - int ch; - - if ((ch = in.read()) == -1) - throw new RuntimeException("Illegal signature: " + in.getData() + " no ident, reaching EOF"); - - // System.out.println("return from ident:" + (char)ch); - - if (!identStart(ch)) { - StringBuffer buf2 = new StringBuffer(); - - int count = 1; - while (Character.isJavaIdentifierPart((char) ch)) { - buf2.append((char) ch); - count++; - ch = in.read(); - } - - if (ch == ':') { // Ok, formal parameter - in.skip("Ljava/lang/Object".length()); - buf.append(buf2); - - ch = in.read(); - in.unread(); - // System.out.println("so far:" + buf2 + ":next:" +(char)ch); - } else { - for (int i = 0; i < count; i++) - in.unread(); - } - - return; - } - - StringBuffer buf2 = new StringBuffer(); - ch = in.read(); - - do { - buf2.append((char) ch); - ch = in.read(); - // System.out.println("within ident:"+ (char)ch); - - } while ((ch != -1) && (Character.isJavaIdentifierPart((char) ch) || (ch == '/'))); - - buf.append(buf2.toString().replace('/', '.')); - - // System.out.println("regular return ident:"+ (char)ch + ":" + buf2); - - if (ch != -1) - in.unread(); - } - - private static final void matchGJIdent(MyByteArrayInputStream in, StringBuffer buf) { - int ch; - - matchIdent(in, buf); - - ch = in.read(); - if ((ch == '<') || ch == '(') { // Parameterized or method - // System.out.println("Enter <"); - buf.append((char) ch); - matchGJIdent(in, buf); - - while (((ch = in.read()) != '>') && (ch != ')')) { // List of parameters - if (ch == -1) - throw new RuntimeException("Illegal signature: " + in.getData() + " reaching EOF"); - - // System.out.println("Still no >"); - buf.append(", "); - in.unread(); - matchGJIdent(in, buf); // Recursive call - } - - // System.out.println("Exit >"); - - buf.append((char) ch); - } else - in.unread(); - - ch = in.read(); - if (identStart(ch)) { - in.unread(); - matchGJIdent(in, buf); - } else if (ch == ')') { - in.unread(); - return; - } else if (ch != ';') - throw new RuntimeException("Illegal signature: " + in.getData() + " read " + (char) ch); - } - - public static String translate(String s) { - // System.out.println("Sig:" + s); - StringBuffer buf = new StringBuffer(); - - matchGJIdent(new MyByteArrayInputStream(s), buf); - - return buf.toString(); - } - - public static final boolean isFormalParameterList(String s) { - return s.startsWith("<") && (s.indexOf(':') > 0); - } - - public static final boolean isActualParameterList(String s) { - return s.startsWith("L") && s.endsWith(">;"); - } - - /** - * @return String representation - */ - @Override - public final String toString() { - String s = getSignature(); - - return "Signature(" + s + ")"; - } - - // /** - // * @return deep copy of this attribute - // */ - // @Override - // public Attribute copy(ConstantPool constant_pool) { - // return (Signature) clone(); - // } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/SimpleConstant.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/SimpleConstant.java deleted file mode 100644 index 84ff40cf9..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/SimpleConstant.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.classfile; - -public interface SimpleConstant { - public String getStringValue(); -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/SourceFile.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/SourceFile.java deleted file mode 100644 index 9fd840fc0..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/SourceFile.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from Attribute and represents a reference to the source file of this class. At most one SourceFile - * attribute should appear per classfile. The intention of this class is that it is instantiated from the - * Attribute.readAttribute() method. - * - * @version $Id: SourceFile.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Attribute - */ -public final class SourceFile extends Attribute { - private int sourcefile_index; - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical - * copy. - */ - public SourceFile(SourceFile c) { - this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c.getConstantPool()); - } - - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - SourceFile(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, file.readUnsignedShort(), constant_pool); - } - - /** - * @param name_index Index in constant pool to CONSTANT_Utf8, which should represent the string "SourceFile". - * @param length Content length in bytes, the value should be 2. - * @param constant_pool The constant pool that this attribute is associated with. - * @param sourcefile_index Index in constant pool to CONSTANT_Utf8. This string will be interpreted as the name of the file from - * which this class was compiled. It will not be interpreted as indicating the name of the directory contqining the file - * or an absolute path; this information has to be supplied the consumer of this attribute - in many cases, the JVM. - */ - public SourceFile(int name_index, int length, int sourcefile_index, ConstantPool constant_pool) { - super(Constants.ATTR_SOURCE_FILE, name_index, length, constant_pool); - this.sourcefile_index = sourcefile_index; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitSourceFile(this); - } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(sourcefile_index); - } - - /** - * @return Index in constant pool of source file name. - */ - public final int getSourceFileIndex() { - return sourcefile_index; - } - - /** - * @param sourcefile_index. - */ - public final void setSourceFileIndex(int sourcefile_index) { - this.sourcefile_index = sourcefile_index; - } - - /** - * @return Source file name. - */ - public final String getSourceFileName() { - ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(sourcefile_index, Constants.CONSTANT_Utf8); - return c.getValue(); - } - - /** - * @return String representation - */ - @Override - public final String toString() { - return "SourceFile(" + getSourceFileName() + ")"; - } - - /** - * @return deep copy of this attribute // - */ - // @Override - // public Attribute copy(ConstantPool constant_pool) { - // return (SourceFile) clone(); - // } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMap.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMap.java deleted file mode 100644 index 29f9c1535..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMap.java +++ /dev/null @@ -1,190 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a stack map attribute used for preverification of Java classes for the - * Java 2 Micro Edition (J2ME). This attribute is used by the KVM and contained - * within the Code attribute of a method. See CLDC specification 5.3.1.2 - * - * @version $Id: StackMap.java,v 1.6 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Code - * @see StackMapEntry - * @see StackMapType - */ -public final class StackMap extends Attribute { - private int map_length; - private StackMapEntry[] map; // Table of stack map entries - - /* - * @param name_index Index of name - * - * @param length Content length in bytes - * - * @param map Table of stack map entries - * - * @param constant_pool Array of constants - */ - public StackMap(int name_index, int length, StackMapEntry[] map, ConstantPool constant_pool) { - super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool); - - setStackMap(map); - } - - /** - * Construct object from file stream. - * - * @param name_index Index of name - * @param length Content length in bytes - * @param file Input stream - * @throws IOException - * @param constant_pool Array of constants - */ - StackMap(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, (StackMapEntry[]) null, constant_pool); - - map_length = file.readUnsignedShort(); - map = new StackMapEntry[map_length]; - - for (int i = 0; i < map_length; i++) - map[i] = new StackMapEntry(file, constant_pool); - } - - /** - * Dump line number table attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(map_length); - for (int i = 0; i < map_length; i++) - map[i].dump(file); - } - - /** - * @return Array of stack map entries - */ - public final StackMapEntry[] getStackMap() { - return map; - } - - /** - * @param map Array of stack map entries - */ - public final void setStackMap(StackMapEntry[] map) { - this.map = map; - - map_length = (map == null) ? 0 : map.length; - } - - /** - * @return String representation. - */ - @Override - public final String toString() { - StringBuffer buf = new StringBuffer("StackMap("); - - for (int i = 0; i < map_length; i++) { - buf.append(map[i].toString()); - - if (i < map_length - 1) - buf.append(", "); - } - - buf.append(')'); - - return buf.toString(); - } - - // - // /** - // * @return deep copy of this attribute - // */ - // public Attribute copy(ConstantPool constant_pool) { - // StackMap c = (StackMap)clone(); - // - // c.map = new StackMapEntry[map_length]; - // for(int i=0; i < map_length; i++) - // c.map[i] = map[i].copy(); - // - // c.cpool = constant_pool; - // return c; - // } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitStackMap(this); - } - - public final int getMapLength() { - return map_length; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapEntry.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapEntry.java deleted file mode 100644 index 76bb2ab79..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapEntry.java +++ /dev/null @@ -1,210 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * This class represents a stack map entry recording the types of - * local variables and the the of stack items at a given byte code offset. - * See CLDC specification 5.3.1.2 - * - * @version $Id: StackMapEntry.java,v 1.5 2008/05/28 23:53:02 aclement Exp $ - * @author M. Dahm - * @see StackMap - * @see StackMapType - */ -public final class StackMapEntry implements Cloneable { - private int byte_code_offset; - private int number_of_locals; - private StackMapType[] types_of_locals; - private int number_of_stack_items; - private StackMapType[] types_of_stack_items; - private ConstantPool constant_pool; - - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - StackMapEntry(DataInputStream file, ConstantPool constant_pool) throws IOException - { - this(file.readShort(), file.readShort(), null, -1, null, constant_pool); - - types_of_locals = new StackMapType[number_of_locals]; - for(int i=0; i < number_of_locals; i++) - types_of_locals[i] = new StackMapType(file, constant_pool); - - number_of_stack_items = file.readShort(); - types_of_stack_items = new StackMapType[number_of_stack_items]; - for(int i=0; i < number_of_stack_items; i++) - types_of_stack_items[i] = new StackMapType(file, constant_pool); - } - - public StackMapEntry(int byte_code_offset, int number_of_locals, - StackMapType[] types_of_locals, - int number_of_stack_items, - StackMapType[] types_of_stack_items, - ConstantPool constant_pool) { - this.byte_code_offset = byte_code_offset; - this.number_of_locals = number_of_locals; - this.types_of_locals = types_of_locals; - this.number_of_stack_items = number_of_stack_items; - this.types_of_stack_items = types_of_stack_items; - this.constant_pool = constant_pool; - } - - /** - * Dump stack map entry - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeShort(byte_code_offset); - - file.writeShort(number_of_locals); - for(int i=0; i < number_of_locals; i++) - types_of_locals[i].dump(file); - - file.writeShort(number_of_stack_items); - for(int i=0; i < number_of_stack_items; i++) - types_of_stack_items[i].dump(file); - } - - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer("(offset=" + byte_code_offset); - - if(number_of_locals > 0) { - buf.append(", locals={"); - - for(int i=0; i < number_of_locals; i++) { - buf.append(types_of_locals[i]); - if(i < number_of_locals - 1) - buf.append(", "); - } - - buf.append("}"); - } - - if(number_of_stack_items > 0) { - buf.append(", stack items={"); - - for(int i=0; i < number_of_stack_items; i++) { - buf.append(types_of_stack_items[i]); - if(i < number_of_stack_items - 1) - buf.append(", "); - } - - buf.append("}"); - } - - buf.append(")"); - - return buf.toString(); - } - - - public void setByteCodeOffset(int b) { byte_code_offset = b; } - public int getByteCodeOffset() { return byte_code_offset; } - public void setNumberOfLocals(int n) { number_of_locals = n; } - public int getNumberOfLocals() { return number_of_locals; } - public void setTypesOfLocals(StackMapType[] t) { types_of_locals = t; } - public StackMapType[] getTypesOfLocals() { return types_of_locals; } - public void setNumberOfStackItems(int n) { number_of_stack_items = n; } - public int getNumberOfStackItems() { return number_of_stack_items; } - public void setTypesOfStackItems(StackMapType[] t) { types_of_stack_items = t; } - public StackMapType[] getTypesOfStackItems() { return types_of_stack_items; } - - /** - * @return deep copy of this object - */ - public StackMapEntry copy() { - try { - return (StackMapEntry)clone(); - } catch(CloneNotSupportedException e) {} - - return null; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(ClassVisitor v) { - v.visitStackMapEntry(this); - } - - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { return constant_pool; } - - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapType.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapType.java deleted file mode 100644 index b1116abbe..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/StackMapType.java +++ /dev/null @@ -1,172 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.Constants; -import java.io.*; - -/** - * This class represents the type of a local variable or item on stack - * used in the StackMap entries. - * - * @version $Id: StackMapType.java,v 1.3 2008/05/28 23:53:02 aclement Exp $ - * @author M. Dahm - * @see StackMapEntry - * @see StackMap - * @see Constants - */ -public final class StackMapType implements Cloneable { - private byte type; - private int index = -1; // Index to CONSTANT_Class or offset - private ConstantPool constant_pool; - - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - StackMapType(DataInputStream file, ConstantPool constant_pool) throws IOException - { - this(file.readByte(), -1, constant_pool); - - if(hasIndex()) - setIndex(file.readShort()); - - setConstantPool(constant_pool); - } - - /** - * @param type type tag as defined in the Constants interface - * @param index index to constant pool, or byte code offset - */ - public StackMapType(byte type, int index, ConstantPool constant_pool) { - setType(type); - setIndex(index); - setConstantPool(constant_pool); - } - - public void setType(byte t) { - if((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) - throw new RuntimeException("Illegal type for StackMapType: " + t); - type = t; - } - - public byte getType() { return type; } - public void setIndex(int t) { index = t; } - - /** @return index to constant pool if type == ITEM_Object, or offset - * in byte code, if type == ITEM_NewObject, and -1 otherwise - */ - public int getIndex() { return index; } - - /** - * Dump type entries to file. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(type); - if(hasIndex()) - file.writeShort(getIndex()); - } - - /** @return true, if type is either ITEM_Object or ITEM_NewObject - */ - public final boolean hasIndex() { - return ((type == Constants.ITEM_Object) || - (type == Constants.ITEM_NewObject)); - } - - private String printIndex() { - if(type == Constants.ITEM_Object) - return ", class=" + constant_pool.constantToString(index, Constants.CONSTANT_Class); - else if(type == Constants.ITEM_NewObject) - return ", offset=" + index; - else - return ""; - } - - /** - * @return String representation - */ - public final String toString() { - return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")"; - } - - /** - * @return deep copy of this object - */ - public StackMapType copy() { - try { - return (StackMapType)clone(); - } catch(CloneNotSupportedException e) {} - - return null; - } - - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { return constant_pool; } - - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Synthetic.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Synthetic.java deleted file mode 100644 index 57fe97468..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Synthetic.java +++ /dev/null @@ -1,185 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class is derived from Attribute and declares this class as `synthetic', i.e., it needs special handling. The JVM - * specification states "A class member that does not appear in the source code must be marked using a Synthetic attribute." It may - * appear in the ClassFile attribute table, a field_info table or a method_info table. This class is intended to be instantiated - * from the Attribute.readAttribute() method. - * - * @version $Id: Synthetic.java,v 1.5 2009/09/15 19:40:12 aclement Exp $ - * @author M. Dahm - * @see Attribute - */ -public final class Synthetic extends Attribute { - private byte[] bytes; - - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical - * copy. - */ - public Synthetic(Synthetic c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } - - // - // public Synthetic(ConstantPoolGen cpool) { - // super(Constants.ATTR_SYNTHETIC, cpool.addUtf8("Synthetic"), 0, cpool); - // ConstantPoolGen cpg = myGen.getConstantPool(); - // int index = ; - // Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg.getConstantPool()); - // } - - /** - * @param name_index Index in constant pool to CONSTANT_Utf8, which should represent the string "Synthetic". - * @param length Content length in bytes - should be zero. - * @param bytes Attribute contents - * @param constant_pool The constant pool this attribute is associated with. - */ - public Synthetic(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { - super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool); - this.bytes = bytes; - } - - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Synthetic(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, (byte[]) null, constant_pool); - - if (length > 0) { - bytes = new byte[length]; - file.readFully(bytes); - System.err.println("Synthetic attribute with length > 0"); - } - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitSynthetic(this); - } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - if (length > 0) - file.write(bytes, 0, length); - } - - /** - * @return data bytes. - */ - public final byte[] getBytes() { - return bytes; - } - - /** - * @param bytes. - */ - public final void setBytes(byte[] bytes) { - this.bytes = bytes; - } - - /** - * @return String representation. - */ - @Override - public final String toString() { - StringBuffer buf = new StringBuffer("Synthetic"); - - if (length > 0) - buf.append(" " + Utility.toHexString(bytes)); - - return buf.toString(); - } - - // /** - // * @return deep copy of this attribute - // */ - // public Attribute copy(ConstantPool constant_pool) { - // Synthetic c = (Synthetic)clone(); - // - // if(bytes != null) - // c.bytes = (byte[])bytes.clone(); - // - // c.cpool = constant_pool; - // return c; - // } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Unknown.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Unknown.java deleted file mode 100644 index 416d105b1..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Unknown.java +++ /dev/null @@ -1,215 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * This class represents a reference to an unknown (i.e., application-specific) attribute of a class. It is instantiated from the - * Attribute.readAttribute() method. Applications that need to read in application-specific attributes should create an AttributeReader implementation and attach it via Attribute.addAttributeReader. - * - * - * @version $Id: Unknown.java,v 1.6 2009/09/15 19:40:12 aclement Exp $ - * @see org.aspectj.apache.bcel.classfile.Attribute - * @author M. Dahm - */ -public final class Unknown extends Attribute { - private byte[] bytes; - private String name; - - // evil static - removed by Andy C - no apparent users (4 Mar 06) - // private static HashMap unknown_attributes = new HashMap(); - - /** - * @return array of unknown attributes, but just one for each kind. - */ - // static Unknown[] getUnknownAttributes() { - // Unknown[] unknowns = new Unknown[unknown_attributes.size()]; - // Iterator entries = unknown_attributes.values().iterator(); - // - // for(int i=0; entries.hasNext(); i++) - // unknowns[i] = (Unknown)entries.next(); - // - // unknown_attributes.clear(); - // return unknowns; - // } - /** - * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical - * copy. - */ - public Unknown(Unknown c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } - - /** - * Create a non-standard attribute. - * - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param bytes Attribute contents - * @param constant_pool Array of constants - */ - public Unknown(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { - super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool); - this.bytes = bytes; - - name = ((ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8)).getValue(); - // unknown_attributes.put(name, this); - } - - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Unknown(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException { - this(name_index, length, (byte[]) null, constant_pool); - - if (length > 0) { - bytes = new byte[length]; - file.readFully(bytes); - } - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. I.e., the - * hierarchy of methods, fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept(ClassVisitor v) { - v.visitUnknown(this); - } - - /** - * Dump unknown bytes to file stream. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump(DataOutputStream file) throws IOException { - super.dump(file); - if (length > 0) - file.write(bytes, 0, length); - } - - /** - * @return data bytes. - */ - public final byte[] getBytes() { - return bytes; - } - - /** - * @return name of attribute. - */ - @Override - public String getName() { - return name; - } - - /** - * @param bytes. - */ - public final void setBytes(byte[] bytes) { - this.bytes = bytes; - } - - /** - * @return String representation. - */ - @Override - public final String toString() { - if (length == 0 || bytes == null) - return "(Unknown attribute " + name + ")"; - - String hex; - if (length > 10) { - byte[] tmp = new byte[10]; - System.arraycopy(bytes, 0, tmp, 0, 10); - hex = Utility.toHexString(tmp) + "... (truncated)"; - } else - hex = Utility.toHexString(bytes); - - return "(Unknown attribute " + name + ": " + hex + ")"; - } - - /** - * @return deep copy of this attribute - */ - // @Override - // public Attribute copy(ConstantPool constant_pool) { - // Unknown c = (Unknown) clone(); - // - // if (bytes != null) - // c.bytes = bytes.clone(); - // - // c.cpool = constant_pool; - // return c; - // } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Utility.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Utility.java deleted file mode 100644 index 98f5952ae..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Utility.java +++ /dev/null @@ -1,1094 +0,0 @@ -package org.aspectj.apache.bcel.classfile; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeParamAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; -import org.aspectj.apache.bcel.generic.Type; -import org.aspectj.apache.bcel.util.ByteSequence; - -/** - * Utility functions that do not really belong to any class in particular. - * - * @version $Id: Utility.java,v 1.14 2009/09/28 16:39:46 aclement Exp $ - * @author M. Dahm - * - * modified: Andy Clement 2-mar-05 Removed unnecessary static and optimized - */ -public abstract class Utility { - - /* - * The 'WIDE' instruction is used in the byte code to allow 16-bit wide indices for local variables. This opcode precedes an - * 'ILOAD', e.g.. The opcode immediately following takes an extra byte which is combined with the following byte to form a - * 16-bit value. - */ - private static boolean wide = false; - - /** - * Convert bit field of flags into string such as 'static final'. - * - * @param access_flags Access flags - * @return String representation of flags - */ - public static final String accessToString(int access_flags) { - return accessToString(access_flags, false); - } - - /** - * Convert bit field of flags into string such as 'static final'. - * - * Special case: Classes compiled with new compilers and with the 'ACC_SUPER' flag would be said to be "synchronized". This is - * because SUN used the same value for the flags 'ACC_SUPER' and 'ACC_SYNCHRONIZED'. - * - * @param access_flags Access flags - * @param for_class access flags are for class qualifiers ? - * @return String representation of flags - */ - public static final String accessToString(int access_flags, boolean for_class) { - StringBuffer buf = new StringBuffer(); - - int p = 0; - for (int i = 0; p < Constants.MAX_ACC_FLAG; i++) { // Loop through known flags - p = pow2(i); - if ((access_flags & p) != 0) { - // Special case: see comment at top of class... - if (for_class && ((p == Constants.ACC_SUPER) || (p == Constants.ACC_INTERFACE))) { - continue; - } - buf.append(Constants.ACCESS_NAMES[i]).append(" "); - } - } - return buf.toString().trim(); - } - - /** - * @return "class" or "interface", depending on the ACC_INTERFACE flag - */ - public static final String classOrInterface(int access_flags) { - return ((access_flags & Constants.ACC_INTERFACE) != 0) ? "interface" : "class"; - } - - /** - * Disassemble a byte array of JVM byte codes starting from code line 'index' and return the disassembled string representation. - * Decode only 'num' opcodes (including their operands), use -1 if you want to decompile everything. - * - * @param code byte code array - * @param constant_pool Array of constants - * @param index offset in `code' array (number of opcodes, not bytes!) - * @param length number of opcodes to decompile, -1 for all - * @param verbose be verbose, e.g. print constant pool index - * @return String representation of byte codes - */ - public static final String codeToString(byte[] code, ConstantPool constant_pool, int index, int length, boolean verbose) { - StringBuffer buf = new StringBuffer(code.length * 20); // Should be sufficient - ByteSequence stream = new ByteSequence(code); - - try { - for (int i = 0; i < index; i++) { - // Skip `index' lines of code - codeToString(stream, constant_pool, verbose); - } - - for (int i = 0; stream.available() > 0; i++) { - if ((length < 0) || (i < length)) { - String indices = fillup(stream.getIndex() + ":", 6, true, ' '); - buf.append(indices + codeToString(stream, constant_pool, verbose) + '\n'); - } - } - } catch (IOException e) { - System.out.println(buf.toString()); - e.printStackTrace(); - throw new ClassFormatException("Byte code error: " + e); - } - - return buf.toString(); - } - - /** - * Disassemble a stream of byte codes and return the string representation. - */ - public static final String codeToString(byte[] code, ConstantPool constant_pool, int index, int length) { - return codeToString(code, constant_pool, index, length, true); - } - - public static final String codeToString(ByteSequence bytes, ConstantPool constant_pool) throws IOException { - return codeToString(bytes, constant_pool, true); - } - - /** - * Shorten long class names, java/lang/String becomes String. - * - * @param str The long class name - * @return Compacted class name - */ - public static final String compactClassName(String str) { - return compactClassName(str, true); - } - - /** - * Shorten long class name str, i.e., chop off the prefix, if the class name starts with this string and the - * flag chopit is true. Slashes / are converted to dots .. - * - * @param str The long class name - * @param prefix The prefix the get rid off - * @param chopit Flag that determines whether chopping is executed or not - * @return Compacted class name - */ - public static final String compactClassName(String str, String prefix, boolean chopit) { - str = str.replace('/', '.'); - if (chopit) { - int len = prefix.length(); - // If string starts with 'prefix' and contains no further dots - if (str.startsWith(prefix)) { - String result = str.substring(len); - if (result.indexOf('.') == -1) { - str = result; - } - } - } - return str; - } - - /** - * Shorten long class names, java/lang/String becomes java.lang.String, e.g.. If chopit is - * true the prefix java.lang is also removed. - * - * @param str The long class name - * @param chopit Flag that determines whether chopping is executed or not - * @return Compacted class name - */ - public static final String compactClassName(String str, boolean chopit) { - return compactClassName(str, "java.lang.", chopit); - } - - public static final String methodSignatureToString(String signature, String name, String access) { - return methodSignatureToString(signature, name, access, true); - } - - public static final String methodSignatureToString(String signature, String name, String access, boolean chopit) { - return methodSignatureToString(signature, name, access, chopit, null); - } - - /** - * This method converts such a string into a Java type declaration like 'void main(String[])' and throws a - * 'ClassFormatException' when the parsed type is invalid. - */ - public static final String methodSignatureToString(String signature, String name, String access, boolean chopit, - LocalVariableTable vars) throws ClassFormatException { - StringBuffer buf = new StringBuffer("("); - String type; - int index; - int var_index = (access.indexOf("static") >= 0) ? 0 : 1; - - try { // Read all declarations between for `(' and `)' - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - - index = 1; // current string position - - while (signature.charAt(index) != ')') { - ResultHolder rh = signatureToStringInternal(signature.substring(index), chopit); - String param_type = rh.getResult(); - buf.append(param_type); - - if (vars != null) { - LocalVariable l = vars.getLocalVariable(var_index); - - if (l != null) { - buf.append(" " + l.getName()); - } - } else { - buf.append(" arg" + var_index); - } - - if ("double".equals(param_type) || "long".equals(param_type)) { - var_index += 2; - } else { - var_index++; - } - - buf.append(", "); - index += rh.getConsumedChars(); - } - - index++; - - // Read return type after `)' - type = signatureToString(signature.substring(index), chopit); - - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - - if (buf.length() > 1) { - buf.setLength(buf.length() - 2); - } - - buf.append(")"); - - return access + ((access.length() > 0) ? " " : "") + // May be an empty string - type + " " + name + buf.toString(); - } - - /** - * Replace all occurences of old in str with new. - * - * @param str String to permute - * @param old String to be replaced - * @param new Replacement string - * @return new String object - */ - public static final String replace(String str, String old, String new_) { - int index, old_index; - StringBuffer buf = new StringBuffer(); - - try { - index = str.indexOf(old); - if (index != -1) { - old_index = 0; - - // While we have something to replace - while ((index = str.indexOf(old, old_index)) != -1) { - buf.append(str.substring(old_index, index)); // append prefix - buf.append(new_); // append replacement - old_index = index + old.length(); // Skip 'old'.length chars - } - - buf.append(str.substring(old_index)); // append rest of string - str = buf.toString(); - } - } catch (StringIndexOutOfBoundsException e) { - System.err.println(e); - } - - return str; - } - - /** - * Converts signature to string with all class names compacted. - * - * @param signature to convert - * @return Human readable signature - */ - public static final String signatureToString(String signature) { - return signatureToString(signature, true); - } - - public static final String signatureToString(String signature, boolean chopit) { - ResultHolder rh = signatureToStringInternal(signature, chopit); - return rh.getResult(); - } - - /** - * This method converts this string into a Java type declaration such as 'String[]' and throws a `ClassFormatException' when the - * parsed type is invalid. - */ - public static final ResultHolder signatureToStringInternal(String signature, boolean chopit) { - int processedChars = 1; // This is the default, read just one char - try { - switch (signature.charAt(0)) { - case 'B': - return ResultHolder.BYTE; - case 'C': - return ResultHolder.CHAR; - case 'D': - return ResultHolder.DOUBLE; - case 'F': - return ResultHolder.FLOAT; - case 'I': - return ResultHolder.INT; - case 'J': - return ResultHolder.LONG; - case 'L': { // Full class name - int index = signature.indexOf(';'); // Look for closing ';' - - if (index < 0) { - throw new ClassFormatException("Invalid signature: " + signature); - } - - if (signature.length() > index + 1 && signature.charAt(index + 1) == '>') { - index = index + 2; - } - - int genericStart = signature.indexOf('<'); - if (genericStart != -1) { - int genericEnd = signature.indexOf('>'); - // FIXME asc going to need a lot more work in here for generics - ResultHolder rh = signatureToStringInternal(signature.substring(genericStart + 1, genericEnd), chopit); - StringBuffer sb = new StringBuffer(); - sb.append(signature.substring(1, genericStart)); - sb.append("<").append(rh.getResult()).append(">"); - ResultHolder retval = new ResultHolder(compactClassName(sb.toString(), chopit), genericEnd + 1); - return retval; - } else { - processedChars = index + 1; // "Lblabla;" `L' and `;' are removed - ResultHolder retval = new ResultHolder(compactClassName(signature.substring(1, index), chopit), processedChars); - return retval; - } - } - - case 'S': - return ResultHolder.SHORT; - case 'Z': - return ResultHolder.BOOLEAN; - - case '[': { // Array declaration - StringBuffer brackets; - int consumedChars, n; - - brackets = new StringBuffer(); // Accumulate []'s - // Count opening brackets and look for optional size argument - for (n = 0; signature.charAt(n) == '['; n++) { - brackets.append("[]"); - } - consumedChars = n; - ResultHolder restOfIt = signatureToStringInternal(signature.substring(n), chopit); - consumedChars += restOfIt.getConsumedChars(); - brackets.insert(0, restOfIt.getResult()); - return new ResultHolder(brackets.toString(), consumedChars); - } - case 'V': - return ResultHolder.VOID; - - default: - throw new ClassFormatException("Invalid signature: `" + signature + "'"); - } - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid signature: " + e + ":" + signature); - } - } - - /** - * Return type of method signature as a byte value as defined in Constants - * - * @param signature in format described above - * @return type of method signature - * @see Constants - */ - public static final byte typeOfMethodSignature(String signature) throws ClassFormatException { - int index; - try { - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - index = signature.lastIndexOf(')') + 1; - return typeOfSignature(signature.substring(index)); - } catch (StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - /** - * Convert (signed) byte to (unsigned) short value, i.e., all negative values become positive. - */ - private static final short byteToShort(byte b) { - return (b < 0) ? (short) (256 + b) : (short) b; - } - - /** - * Convert bytes into hexidecimal string - * - * @return bytes as hexidecimal string, e.g. 00 FA 12 ... - */ - public static final String toHexString(byte[] bytes) { - StringBuffer buf = new StringBuffer(); - - for (int i = 0; i < bytes.length; i++) { - short b = byteToShort(bytes[i]); - String hex = Integer.toString(b, 0x10); - - // Just one digit, so prepend 0 - if (b < 0x10) { - buf.append('0'); - } - - buf.append(hex); - - if (i < bytes.length - 1) { - buf.append(' '); - } - } - - return buf.toString(); - } - - /** - * Return a string for an integer justified left or right and filled up with 'fill' characters if necessary. - * - * @param i integer to format - * @param length length of desired string - * @param left_justify format left or right - * @param fill fill character - * @return formatted int - */ - public static final String format(int i, int length, boolean left_justify, char fill) { - return fillup(Integer.toString(i), length, left_justify, fill); - } - - /** - * Fillup char with up to length characters with char `fill' and justify it left or right. - * - * @param str string to format - * @param length length of desired string - * @param left_justify format left or right - * @param fill fill character - * @return formatted string - */ - public static final String fillup(String str, int length, boolean left_justify, char fill) { - int len = length - str.length(); - char[] buf = new char[(len < 0) ? 0 : len]; - - for (int j = 0; j < buf.length; j++) { - buf[j] = fill; - } - - if (left_justify) { - return str + new String(buf); - } else { - return new String(buf) + str; - } - } - - /** - * Escape all occurences of newline chars '\n', quotes \", etc. - */ - public static final String convertString(String label) { - char[] ch = label.toCharArray(); - StringBuffer buf = new StringBuffer(); - - for (int i = 0; i < ch.length; i++) { - switch (ch[i]) { - case '\n': - buf.append("\\n"); - break; - case '\r': - buf.append("\\r"); - break; - case '\"': - buf.append("\\\""); - break; - case '\'': - buf.append("\\'"); - break; - case '\\': - buf.append("\\\\"); - break; - default: - buf.append(ch[i]); - break; - } - } - - return buf.toString(); - } - - /** - * Converts a list of AnnotationGen objects into a set of attributes that can be attached to the class file. - * - * @param cp The constant pool gen where we can create the necessary name refs - * @param annotations A list of AnnotationGen objects - */ - public static Collection getAnnotationAttributes(ConstantPool cp, List annotations) { - - if (annotations.size() == 0) { - return null; - } - - try { - int countVisible = 0; - int countInvisible = 0; - - // put the annotations in the right output stream - for (AnnotationGen a : annotations) { - if (a.isRuntimeVisible()) { - countVisible++; - } else { - countInvisible++; - } - } - - ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); - ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); - DataOutputStream rvaDos = new DataOutputStream(rvaBytes); - DataOutputStream riaDos = new DataOutputStream(riaBytes); - - rvaDos.writeShort(countVisible); - riaDos.writeShort(countInvisible); - - // put the annotations in the right output stream - for (AnnotationGen a : annotations) { - if (a.isRuntimeVisible()) { - a.dump(rvaDos); - } else { - a.dump(riaDos); - } - } - - rvaDos.close(); - riaDos.close(); - - byte[] rvaData = rvaBytes.toByteArray(); - byte[] riaData = riaBytes.toByteArray(); - - int rvaIndex = -1; - int riaIndex = -1; - - if (rvaData.length > 2) { - rvaIndex = cp.addUtf8("RuntimeVisibleAnnotations"); - } - if (riaData.length > 2) { - riaIndex = cp.addUtf8("RuntimeInvisibleAnnotations"); - } - - List newAttributes = new ArrayList(); - if (rvaData.length > 2) { - newAttributes.add(new RuntimeVisAnnos(rvaIndex, rvaData.length, rvaData, cp)); - } - if (riaData.length > 2) { - newAttributes.add(new RuntimeInvisAnnos(riaIndex, riaData.length, riaData, cp)); - } - - return newAttributes; - } catch (IOException e) { - System.err.println("IOException whilst processing annotations"); - e.printStackTrace(); - } - return null; - } - - /** - * Annotations against a class are stored in one of four attribute kinds: - RuntimeVisibleParameterAnnotations - - * RuntimeInvisibleParameterAnnotations - */ - // OPTIMIZE looks heavyweight? - public static Attribute[] getParameterAnnotationAttributes(ConstantPool cp, List[] vec) { - - int visCount[] = new int[vec.length]; - int totalVisCount = 0; - int invisCount[] = new int[vec.length]; - int totalInvisCount = 0; - try { - - for (int i = 0; i < vec.length; i++) { - List l = vec[i]; - if (l != null) { - for (AnnotationGen element : l) { - if (element.isRuntimeVisible()) { - visCount[i]++; - totalVisCount++; - } else { - invisCount[i]++; - totalInvisCount++; - } - } - } - } - - // Lets do the visible ones - ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); - DataOutputStream rvaDos = new DataOutputStream(rvaBytes); - rvaDos.writeByte(vec.length); // First goes number of parameters - - for (int i = 0; i < vec.length; i++) { - rvaDos.writeShort(visCount[i]); - if (visCount[i] > 0) { - List l = vec[i]; - for (AnnotationGen element : l) { - if (element.isRuntimeVisible()) { - element.dump(rvaDos); - } - } - } - } - rvaDos.close(); - - // Lets do the invisible ones - ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); - DataOutputStream riaDos = new DataOutputStream(riaBytes); - riaDos.writeByte(vec.length); // First goes number of parameters - - for (int i = 0; i < vec.length; i++) { - riaDos.writeShort(invisCount[i]); - if (invisCount[i] > 0) { - List l = vec[i]; - for (AnnotationGen element : l) { - if (!element.isRuntimeVisible()) { - element.dump(riaDos); - } - } - } - } - riaDos.close(); - - byte[] rvaData = rvaBytes.toByteArray(); - byte[] riaData = riaBytes.toByteArray(); - - int rvaIndex = -1; - int riaIndex = -1; - - if (totalVisCount > 0) { - rvaIndex = cp.addUtf8("RuntimeVisibleParameterAnnotations"); - } - if (totalInvisCount > 0) { - riaIndex = cp.addUtf8("RuntimeInvisibleParameterAnnotations"); - } - - List newAttributes = new ArrayList(); - - if (totalVisCount > 0) { - newAttributes.add(new RuntimeVisParamAnnos(rvaIndex, rvaData.length, rvaData, cp)); - } - - if (totalInvisCount > 0) { - newAttributes.add(new RuntimeInvisParamAnnos(riaIndex, riaData.length, riaData, cp)); - } - - return newAttributes.toArray(new Attribute[] {}); - } catch (IOException e) { - System.err.println("IOException whilst processing parameter annotations"); - e.printStackTrace(); - } - return null; - } - - public static class ResultHolder { - private String result; - private int consumed; - - public static final ResultHolder BYTE = new ResultHolder("byte", 1); - public static final ResultHolder CHAR = new ResultHolder("char", 1); - public static final ResultHolder DOUBLE = new ResultHolder("double", 1); - public static final ResultHolder FLOAT = new ResultHolder("float", 1); - public static final ResultHolder INT = new ResultHolder("int", 1); - public static final ResultHolder LONG = new ResultHolder("long", 1); - public static final ResultHolder SHORT = new ResultHolder("short", 1); - public static final ResultHolder BOOLEAN = new ResultHolder("boolean", 1); - public static final ResultHolder VOID = new ResultHolder("void", 1); - - public ResultHolder(String s, int c) { - result = s; - consumed = c; - } - - public String getResult() { - return result; - } - - public int getConsumedChars() { - return consumed; - } - } - - /** - * Return type of signature as a byte value as defined in Constants - * - * @param signature in format described above - * @return type of signature - * @see Constants - */ - public static final byte typeOfSignature(String signature) throws ClassFormatException { - try { - switch (signature.charAt(0)) { - case 'B': - return Constants.T_BYTE; - case 'C': - return Constants.T_CHAR; - case 'D': - return Constants.T_DOUBLE; - case 'F': - return Constants.T_FLOAT; - case 'I': - return Constants.T_INT; - case 'J': - return Constants.T_LONG; - case 'L': - return Constants.T_REFERENCE; - case '[': - return Constants.T_ARRAY; - case 'V': - return Constants.T_VOID; - case 'Z': - return Constants.T_BOOLEAN; - case 'S': - return Constants.T_SHORT; - default: - throw new ClassFormatException("Invalid method signature: " + signature); - } - } catch (StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - public static final byte typeOfSignature(char c) throws ClassFormatException { - switch (c) { - case 'B': - return Constants.T_BYTE; - case 'C': - return Constants.T_CHAR; - case 'D': - return Constants.T_DOUBLE; - case 'F': - return Constants.T_FLOAT; - case 'I': - return Constants.T_INT; - case 'J': - return Constants.T_LONG; - case 'L': - return Constants.T_REFERENCE; - case '[': - return Constants.T_ARRAY; - case 'V': - return Constants.T_VOID; - case 'Z': - return Constants.T_BOOLEAN; - case 'S': - return Constants.T_SHORT; - default: - throw new ClassFormatException("Invalid type of signature: " + c); - } - } - - /** - * Disassemble a stream of byte codes and return the string representation. - * - * @param bytes stream of bytes - * @param constant_pool Array of constants - * @param verbose be verbose, e.g. print constant pool index - * @return String representation of byte code - */ - public static final String codeToString(ByteSequence bytes, ConstantPool constant_pool, boolean verbose) throws IOException { - short opcode = (short) bytes.readUnsignedByte(); - int default_offset = 0, low, high, npairs; - int index, vindex, constant; - int[] match, jump_table; - int no_pad_bytes = 0, offset; - StringBuffer buf = new StringBuffer(Constants.OPCODE_NAMES[opcode]); - - /* - * Special case: Skip (0-3) padding bytes, i.e., the following bytes are 4-byte-aligned - */ - if ((opcode == Constants.TABLESWITCH) || (opcode == Constants.LOOKUPSWITCH)) { - int remainder = bytes.getIndex() % 4; - no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; - - for (int i = 0; i < no_pad_bytes; i++) { - byte b = bytes.readByte(); - if (b != 0) { - System.err.println("Warning: Padding byte != 0 in " + Constants.OPCODE_NAMES[opcode] + ":" + b); - } - } - - // Both cases have a field default_offset in common - default_offset = bytes.readInt(); - } - - switch (opcode) { - /* - * Table switch has variable length arguments. - */ - case Constants.TABLESWITCH: - low = bytes.readInt(); - high = bytes.readInt(); - - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - - buf.append("\tdefault = " + default_offset + ", low = " + low + ", high = " + high + "("); - - jump_table = new int[high - low + 1]; - for (int i = 0; i < jump_table.length; i++) { - jump_table[i] = offset + bytes.readInt(); - buf.append(jump_table[i]); - if (i < jump_table.length - 1) { - buf.append(", "); - } - } - buf.append(")"); - break; - - /* - * Lookup switch has variable length arguments. - */ - case Constants.LOOKUPSWITCH: { - - npairs = bytes.readInt(); - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - - match = new int[npairs]; - jump_table = new int[npairs]; - default_offset += offset; - - buf.append("\tdefault = " + default_offset + ", npairs = " + npairs + " ("); - - for (int i = 0; i < npairs; i++) { - match[i] = bytes.readInt(); - jump_table[i] = offset + bytes.readInt(); - buf.append("(" + match[i] + ", " + jump_table[i] + ")"); - if (i < npairs - 1) { - buf.append(", "); - } - } - buf.append(")"); - } - break; - - // Two address bytes + offset from start of byte stream form the jump target - case Constants.GOTO: - case Constants.IFEQ: - case Constants.IFGE: - case Constants.IFGT: - case Constants.IFLE: - case Constants.IFLT: - case Constants.JSR: - case Constants.IFNE: - case Constants.IFNONNULL: - case Constants.IFNULL: - case Constants.IF_ACMPEQ: - case Constants.IF_ACMPNE: - case Constants.IF_ICMPEQ: - case Constants.IF_ICMPGE: - case Constants.IF_ICMPGT: - case Constants.IF_ICMPLE: - case Constants.IF_ICMPLT: - case Constants.IF_ICMPNE: - buf.append("\t\t#" + ((bytes.getIndex() - 1) + bytes.readShort())); - break; - - // 32-bit wide jumps - case Constants.GOTO_W: - case Constants.JSR_W: - buf.append("\t\t#" + ((bytes.getIndex() - 1) + bytes.readInt())); - break; - - // Index byte references local variable (register) - case Constants.ALOAD: - case Constants.ASTORE: - case Constants.DLOAD: - case Constants.DSTORE: - case Constants.FLOAD: - case Constants.FSTORE: - case Constants.ILOAD: - case Constants.ISTORE: - case Constants.LLOAD: - case Constants.LSTORE: - case Constants.RET: - if (wide) { - vindex = bytes.readUnsignedShort(); - wide = false; // Clear flag - } else { - vindex = bytes.readUnsignedByte(); - } - buf.append("\t\t%" + vindex); - break; - - /* - * Remember wide byte which is used to form a 16-bit address in the following instruction. Relies on that the method is - * called again with the following opcode. - */ - case Constants.WIDE: - wide = true; - buf.append("\t(wide)"); - break; - - // Array of basic type - case Constants.NEWARRAY: - buf.append("\t\t<" + Constants.TYPE_NAMES[bytes.readByte()] + ">"); - break; - - // Access object/class fields - case Constants.GETFIELD: - case Constants.GETSTATIC: - case Constants.PUTFIELD: - case Constants.PUTSTATIC: - index = bytes.readUnsignedShort(); - buf.append("\t\t" + constant_pool.constantToString(index, Constants.CONSTANT_Fieldref) - + (verbose ? " (" + index + ")" : "")); - break; - - // Operands are references to classes in constant pool - case Constants.NEW: - case Constants.CHECKCAST: - buf.append("\t"); - case Constants.INSTANCEOF: - index = bytes.readUnsignedShort(); - buf.append("\t<" + constant_pool.constantToString(index) + ">" + (verbose ? " (" + index + ")" : "")); - break; - - // Operands are references to methods in constant pool - case Constants.INVOKESPECIAL: - case Constants.INVOKESTATIC: - case Constants.INVOKEVIRTUAL: - index = bytes.readUnsignedShort(); - buf.append("\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : "")); - break; - - case Constants.INVOKEINTERFACE: - index = bytes.readUnsignedShort(); - int nargs = bytes.readUnsignedByte(); // historical, redundant - buf.append("\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")\t" : "") + nargs + "\t" - + bytes.readUnsignedByte()); // Last byte is a reserved - // space - break; - - case Constants.INVOKEDYNAMIC://http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokedynamic - index = bytes.readUnsignedShort(); - bytes.readUnsignedShort(); // zeroes - buf.append("\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : "")); - break; - - // Operands are references to items in constant pool - case Constants.LDC_W: - case Constants.LDC2_W: - index = bytes.readUnsignedShort(); - buf.append("\t\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : "")); - break; - - case Constants.LDC: - index = bytes.readUnsignedByte(); - buf.append("\t\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : "")); - break; - - // Array of references - case Constants.ANEWARRAY: - index = bytes.readUnsignedShort(); - buf.append("\t\t<" + compactClassName(constant_pool.getConstantString(index, Constants.CONSTANT_Class), false) + ">" - + (verbose ? " (" + index + ")" : "")); - break; - - // Multidimensional array of references - case Constants.MULTIANEWARRAY: { - index = bytes.readUnsignedShort(); - int dimensions = bytes.readUnsignedByte(); - - buf.append("\t<" + compactClassName(constant_pool.getConstantString(index, Constants.CONSTANT_Class), false) + ">\t" - + dimensions + (verbose ? " (" + index + ")" : "")); - } - break; - - // Increment local variable - case Constants.IINC: - if (wide) { - vindex = bytes.readUnsignedShort(); - constant = bytes.readShort(); - wide = false; - } else { - vindex = bytes.readUnsignedByte(); - constant = bytes.readByte(); - } - buf.append("\t\t%" + vindex + "\t" + constant); - break; - - default: - if ((Constants.iLen[opcode] - 1) > 0) { - for (int i = 0; i < Constants.TYPE_OF_OPERANDS[opcode].length; i++) { - buf.append("\t\t"); - switch (Constants.TYPE_OF_OPERANDS[opcode][i]) { - case Constants.T_BYTE: - buf.append(bytes.readByte()); - break; - case Constants.T_SHORT: - buf.append(bytes.readShort()); - break; - case Constants.T_INT: - buf.append(bytes.readInt()); - break; - - default: // Never reached - System.err.println("Unreachable default case reached!"); - System.exit(-1); - } - } - } - } - return buf.toString(); - } - - // private helpers - private static final int pow2(int n) { - return 1 << n; - } - - /** - * Convert type to Java method signature, e.g. int[] f(java.lang.String x) becomes (Ljava/lang/String;)[I - * - * @param returnType what the method returns - * @param argTypes what are the argument types - * @return method signature for given type(s). - */ - public static String toMethodSignature(Type returnType, Type[] argTypes) { - StringBuffer buf = new StringBuffer("("); - int length = (argTypes == null) ? 0 : argTypes.length; - for (int i = 0; i < length; i++) { - buf.append(argTypes[i].getSignature()); - } - buf.append(')'); - buf.append(returnType.getSignature()); - return buf.toString(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java deleted file mode 100644 index 2e6024580..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.List; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ConstantUtf8; - -public class AnnotationElementValue extends ElementValue { - - private AnnotationGen a; - - public AnnotationElementValue(AnnotationGen a, ConstantPool cpool) { - super(ANNOTATION, cpool); - this.a = a; - } - - public AnnotationElementValue(int type, AnnotationGen annotation, ConstantPool cpool) { - super(type, cpool); - assert type == ANNOTATION; - this.a = annotation; - } - - public AnnotationElementValue(AnnotationElementValue value, ConstantPool cpool, boolean copyPoolEntries) { - super(ANNOTATION, cpool); - a = new AnnotationGen(value.getAnnotation(), cpool, copyPoolEntries); - } - - @Override - public void dump(DataOutputStream dos) throws IOException { - dos.writeByte(type); // u1 type of value (ANNOTATION == '@') - a.dump(dos); - } - - @Override - public String stringifyValue() { - StringBuffer sb = new StringBuffer(); - ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(a.getTypeIndex(), Constants.CONSTANT_Utf8); - sb.append(cu8.getValue()); - // haven't really tested this values section: - List pairs = a.getValues(); - if (pairs != null && pairs.size() > 0) { - sb.append("("); - for (int p = 0; p < pairs.size(); p++) { - if (p > 0) { - sb.append(","); - } - sb.append(pairs.get(p).getNameString()).append("=").append(pairs.get(p).getValue().stringifyValue()); - } - sb.append(")"); - } - return sb.toString(); - } - - public AnnotationGen getAnnotation() { - return a; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java deleted file mode 100644 index 9a0a42909..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java +++ /dev/null @@ -1,176 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004, 2013 IBM Corporation - * - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ConstantUtf8; -import org.aspectj.apache.bcel.classfile.Utility; -import org.aspectj.apache.bcel.generic.ObjectType; - -public class AnnotationGen { - public static final AnnotationGen[] NO_ANNOTATIONS = new AnnotationGen[0]; - - private int typeIndex; - private List pairs = Collections.emptyList(); - private ConstantPool cpool; - private boolean isRuntimeVisible = false; - - public AnnotationGen(AnnotationGen a, ConstantPool cpool, boolean copyPoolEntries) { - this.cpool = cpool; - if (copyPoolEntries) { - typeIndex = cpool.addUtf8(a.getTypeSignature()); - } else { - typeIndex = a.getTypeIndex(); - } - isRuntimeVisible = a.isRuntimeVisible(); - pairs = copyValues(a.getValues(), cpool, copyPoolEntries); - } - - private List copyValues(List in, ConstantPool cpool, boolean copyPoolEntries) { - List out = new ArrayList(); - for (NameValuePair nvp : in) { - out.add(new NameValuePair(nvp, cpool, copyPoolEntries)); - } - return out; - } - - private AnnotationGen(ConstantPool cpool) { - this.cpool = cpool; - } - - /** - * Retrieve an immutable version of this AnnotationGen - */ - public AnnotationGen(ObjectType type, List pairs, boolean runtimeVisible, ConstantPool cpool) { - this.cpool = cpool; - if (type != null) { - this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects - } - this.pairs = pairs; - isRuntimeVisible = runtimeVisible; - } - - public static AnnotationGen read(DataInputStream dis, ConstantPool cpool, boolean b) throws IOException { - AnnotationGen a = new AnnotationGen(cpool); - a.typeIndex = dis.readUnsignedShort(); - int elemValuePairCount = dis.readUnsignedShort(); - for (int i = 0; i < elemValuePairCount; i++) { - int nidx = dis.readUnsignedShort(); - a.addElementNameValuePair(new NameValuePair(nidx, ElementValue.readElementValue(dis, cpool), cpool)); - } - a.isRuntimeVisible(b); - return a; - } - - public void dump(DataOutputStream dos) throws IOException { - dos.writeShort(typeIndex); // u2 index of type name in cpool - dos.writeShort(pairs.size()); // u2 element_value pair count - for (int i = 0; i < pairs.size(); i++) { - NameValuePair envp = pairs.get(i); - envp.dump(dos); - } - } - - public void addElementNameValuePair(NameValuePair evp) { - if (pairs == Collections.EMPTY_LIST) { - pairs = new ArrayList(); - } - pairs.add(evp); - } - - public int getTypeIndex() { - return typeIndex; - } - - public String getTypeSignature() { - ConstantUtf8 utf8 = (ConstantUtf8) cpool.getConstant(typeIndex); - return utf8.getValue(); - } - - public String getTypeName() { - return Utility.signatureToString(getTypeSignature()); - } - - public List getValues() { - return pairs; - } - - @Override - public String toString() { - StringBuffer s = new StringBuffer(); - s.append("AnnotationGen:[" + getTypeName() + " #" + pairs.size() + " {"); - for (int i = 0; i < pairs.size(); i++) { - s.append(pairs.get(i)); - if (i + 1 < pairs.size()) - s.append(","); - } - s.append("}]"); - return s.toString(); - } - - public String toShortString() { - StringBuffer s = new StringBuffer(); - s.append("@").append(getTypeName()); - if (pairs.size()!=0) { - s.append("("); - for (int i = 0; i < pairs.size(); i++) { - s.append(pairs.get(i)); - if (i + 1 < pairs.size()) - s.append(","); - } - s.append(")"); - } - return s.toString(); - } - - private void isRuntimeVisible(boolean b) { - isRuntimeVisible = b; - } - - public boolean isRuntimeVisible() { - return isRuntimeVisible; - } - - /** - * @return true if the annotation has a value with the specified name and (toString'd) value - */ - public boolean hasNameValuePair(String name, String value) { - for (NameValuePair pair : pairs) { - if (pair.getNameString().equals(name)) { - if (pair.getValue().stringifyValue().equals(value)) { - return true; - } - } - } - return false; - } - - /** - * @return true if the annotation has a value with the specified name - */ - public boolean hasNamedValue(String name) { - for (NameValuePair pair : pairs) { - if (pair.getNameString().equals(name)) { - return true; - } - } - return false; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java deleted file mode 100644 index 3dd19af71..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.classfile.ConstantPool; - -public class ArrayElementValue extends ElementValue { - private static final ElementValue[] NO_VALUES = new ElementValue[0]; - - // J5TODO: Should we make this an array or a list? A list would be easier to modify ... - private ElementValue[] evalues = NO_VALUES; - - public ElementValue[] getElementValuesArray() { - return evalues; - } - - public int getElementValuesArraySize() { - return evalues.length; - } - - public ArrayElementValue(ConstantPool cp) { - super(ARRAY, cp); - } - - public ArrayElementValue(int type, ElementValue[] datums, ConstantPool cpool) { - super(type, cpool); - if (type != ARRAY) - throw new RuntimeException("Only element values of type array can be built with this ctor"); - this.evalues = datums; - } - - public ArrayElementValue(ArrayElementValue value, ConstantPool cpool, boolean copyPoolEntries) { - super(ARRAY, cpool); - evalues = new ElementValue[value.getElementValuesArraySize()]; - ElementValue[] in = value.getElementValuesArray(); - for (int i = 0; i < in.length; i++) { - evalues[i] = ElementValue.copy(in[i], cpool, copyPoolEntries); - } - } - - @Override - public void dump(DataOutputStream dos) throws IOException { - dos.writeByte(type); // u1 type of value (ARRAY == '[') - dos.writeShort(evalues.length); - for (int i = 0; i < evalues.length; i++) { - evalues[i].dump(dos); - } - } - - @Override - public String stringifyValue() { - StringBuffer sb = new StringBuffer(); - sb.append("["); - for (int i = 0; i < evalues.length; i++) { - ElementValue element = evalues[i]; - sb.append(element.stringifyValue()); - if ((i + 1) < evalues.length) - sb.append(","); - } - sb.append("]"); - return sb.toString(); - } - - public void addElement(ElementValue gen) { - ElementValue[] old = evalues; - evalues = new ElementValue[evalues.length + 1]; - System.arraycopy(old, 0, evalues, 0, old.length); - evalues[old.length] = gen; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java deleted file mode 100644 index a4e18b6d4..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ConstantUtf8; -import org.aspectj.apache.bcel.generic.ObjectType; - -public class ClassElementValue extends ElementValue { - - // For primitive types and string type, this points to the value entry in the cpool - // For 'class' this points to the class entry in the cpool - private int idx; - - protected ClassElementValue(int typeIdx, ConstantPool cpool) { - super(ElementValue.CLASS, cpool); - this.idx = typeIdx; - } - - public ClassElementValue(ObjectType t, ConstantPool cpool) { - super(ElementValue.CLASS, cpool); - // this.idx = cpool.addClass(t); - idx = cpool.addUtf8(t.getSignature()); - } - - /** - * Return immutable variant of this ClassElementValueGen - */ - // public ElementValueGen getElementValue() { - // return new ClassElementValueGen(type,idx,cpGen); - // } - public ClassElementValue(ClassElementValue value, ConstantPool cpool, boolean copyPoolEntries) { - super(CLASS, cpool); - if (copyPoolEntries) { - // idx = cpool.addClass(value.getClassString()); - idx = cpool.addUtf8(value.getClassString()); - } else { - idx = value.getIndex(); - - } - } - - public int getIndex() { - return idx; - } - - public String getClassString() { - ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); - return cu8.getValue(); - // ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx); - // ConstantUtf8 utf8 = (ConstantUtf8)getConstantPool().getConstant(c.getNameIndex()); - // return utf8.getBytes(); - } - - @Override - public String stringifyValue() { - return getClassString(); - } - - @Override - public void dump(DataOutputStream dos) throws IOException { - dos.writeByte(type); // u1 kind of value - dos.writeShort(idx); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java deleted file mode 100644 index 06f7c7273..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java +++ /dev/null @@ -1,135 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004, 2013 IBM, VMware - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.classfile.ConstantPool; - -public abstract class ElementValue { - - public static final int STRING = 's'; - public static final int ENUM_CONSTANT = 'e'; - public static final int CLASS = 'c'; - public static final int ANNOTATION = '@'; - public static final int ARRAY = '['; - - public static final int PRIMITIVE_INT = 'I'; - public static final int PRIMITIVE_BYTE = 'B'; - public static final int PRIMITIVE_CHAR = 'C'; - public static final int PRIMITIVE_DOUBLE = 'D'; - public static final int PRIMITIVE_FLOAT = 'F'; - public static final int PRIMITIVE_LONG = 'J'; - public static final int PRIMITIVE_SHORT = 'S'; - public static final int PRIMITIVE_BOOLEAN = 'Z'; - - protected int type; - protected ConstantPool cpool; - - protected ElementValue(int type, ConstantPool cpool) { - this.type = type; - this.cpool = cpool; - } - - public int getElementValueType() { - return type; - } - - public abstract String stringifyValue(); - - public abstract void dump(DataOutputStream dos) throws IOException; - - public static ElementValue readElementValue(DataInputStream dis, ConstantPool cpGen) throws IOException { - int type = dis.readUnsignedByte(); - switch (type) { - case 'B': // byte - return new SimpleElementValue(PRIMITIVE_BYTE, dis.readUnsignedShort(), cpGen); - case 'C': // char - return new SimpleElementValue(PRIMITIVE_CHAR, dis.readUnsignedShort(), cpGen); - case 'D': // double - return new SimpleElementValue(PRIMITIVE_DOUBLE, dis.readUnsignedShort(), cpGen); - case 'F': // float - return new SimpleElementValue(PRIMITIVE_FLOAT, dis.readUnsignedShort(), cpGen); - case 'I': // int - return new SimpleElementValue(PRIMITIVE_INT, dis.readUnsignedShort(), cpGen); - case 'J': // long - return new SimpleElementValue(PRIMITIVE_LONG, dis.readUnsignedShort(), cpGen); - case 'S': // short - return new SimpleElementValue(PRIMITIVE_SHORT, dis.readUnsignedShort(), cpGen); - case 'Z': // boolean - return new SimpleElementValue(PRIMITIVE_BOOLEAN, dis.readUnsignedShort(), cpGen); - case 's': // String - return new SimpleElementValue(STRING, dis.readUnsignedShort(), cpGen); - - case 'e': // Enum constant - return new EnumElementValue(dis.readUnsignedShort(), dis.readUnsignedShort(), cpGen); - - case 'c': // Class - return new ClassElementValue(dis.readUnsignedShort(), cpGen); - - // FIXME should this be true here? or should it be the value for the containing annotation? - case '@': // Annotation - return new AnnotationElementValue(ANNOTATION, AnnotationGen.read(dis, cpGen, true), cpGen); - - case '[': // Array - int numArrayVals = dis.readUnsignedShort(); - ElementValue[] evalues = new ElementValue[numArrayVals]; - for (int j = 0; j < numArrayVals; j++) { - evalues[j] = ElementValue.readElementValue(dis, cpGen); - } - return new ArrayElementValue(ARRAY, evalues, cpGen); - - default: - throw new RuntimeException("Unexpected element value kind in annotation: " + type); - } - } - - protected ConstantPool getConstantPool() { - return cpool; - } - - /** - * Creates an (modifiable) ElementValueGen copy of an (immutable) ElementValue - constant pool is assumed correct. - */ - public static ElementValue copy(ElementValue value, ConstantPool cpool, boolean copyPoolEntries) { - switch (value.getElementValueType()) { - case 'B': // byte - case 'C': // char - case 'D': // double - case 'F': // float - case 'I': // int - case 'J': // long - case 'S': // short - case 'Z': // boolean - case 's': // String - return new SimpleElementValue((SimpleElementValue) value, cpool, copyPoolEntries); - - case 'e': // Enum constant - return new EnumElementValue((EnumElementValue) value, cpool, copyPoolEntries); - - case '@': // Annotation - return new AnnotationElementValue((AnnotationElementValue) value, cpool, copyPoolEntries); - - case '[': // Array - return new ArrayElementValue((ArrayElementValue) value, cpool, copyPoolEntries); - - case 'c': // Class - return new ClassElementValue((ClassElementValue) value, cpool, copyPoolEntries); - - default: - throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")"); - } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java deleted file mode 100644 index a8b219774..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ConstantUtf8; -import org.aspectj.apache.bcel.generic.ObjectType; - -public class EnumElementValue extends ElementValue { - - // For enum types, these two indices point to the type and value - private int typeIdx; - private int valueIdx; - - /** - * This ctor assumes the constant pool already contains the right type and value - as indicated by typeIdx and valueIdx. This - * ctor is used for deserialization - */ - protected EnumElementValue(int typeIdx, int valueIdx, ConstantPool cpool) { - super(ElementValue.ENUM_CONSTANT, cpool); - if (type != ENUM_CONSTANT) { - throw new RuntimeException("Only element values of type enum can be built with this ctor"); - } - this.typeIdx = typeIdx; - this.valueIdx = valueIdx; - } - - // /** - // * Return immutable variant of this EnumElementValue - // */ - // public ElementValueGen getElementValue() { - // System.err.println("Duplicating value: "+getEnumTypeString()+":"+getEnumValueString()); - // return new EnumElementValueGen(type,typeIdx,valueIdx,cpGen); - // } - - public EnumElementValue(ObjectType t, String value, ConstantPool cpool) { - super(ElementValue.ENUM_CONSTANT, cpool); - typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t); - valueIdx = cpool.addUtf8(value);// was addString(value); - } - - public EnumElementValue(EnumElementValue value, ConstantPool cpool, boolean copyPoolEntries) { - super(ENUM_CONSTANT, cpool); - if (copyPoolEntries) { - typeIdx = cpool.addUtf8(value.getEnumTypeString());// was addClass(value.getEnumTypeString()); - valueIdx = cpool.addUtf8(value.getEnumValueString()); // was addString(value.getEnumValueString()); - } else { - typeIdx = value.getTypeIndex(); - valueIdx = value.getValueIndex(); - } - } - - @Override - public void dump(DataOutputStream dos) throws IOException { - dos.writeByte(type); // u1 type of value (ENUM_CONSTANT == 'e') - dos.writeShort(typeIdx); // u2 - dos.writeShort(valueIdx); // u2 - } - - /** - * return signature and value, something like Lp/Color;RED - */ - @Override - public String stringifyValue() { - StringBuffer sb = new StringBuffer(); - ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(typeIdx, Constants.CONSTANT_Utf8); - sb.append(cu8.getValue()); - cu8 = (ConstantUtf8) cpool.getConstant(valueIdx, Constants.CONSTANT_Utf8); - sb.append(cu8.getValue()); - return sb.toString(); - } - - public String toString() { - StringBuilder s = new StringBuilder("E("); - s.append(getEnumTypeString()).append(" ").append(getEnumValueString()).append(")"); - return s.toString(); - } - - // BCELBUG: Should we need to call utility.signatureToString() on the output here? - public String getEnumTypeString() { - // Constant cc = getConstantPool().getConstant(typeIdx); - // ConstantClass cu8 = (ConstantClass)getConstantPool().getConstant(typeIdx); - // return ((ConstantUtf8)getConstantPool().getConstant(cu8.getNameIndex())).getBytes(); - return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)).getValue(); - // return Utility.signatureToString(cu8.getBytes()); - } - - public String getEnumValueString() { - return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getValue(); - // ConstantString cu8 = (ConstantString)getConstantPool().getConstant(valueIdx); - // return ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); - } - - public int getValueIndex() { - return valueIdx; - } - - public int getTypeIndex() { - return typeIdx; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java deleted file mode 100644 index 99b4211ec..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.classfile.ConstantPool; - -public class NameValuePair { - private int nameIdx; - private ElementValue value; - private ConstantPool cpool; - - public NameValuePair(NameValuePair pair, ConstantPool cpool, boolean copyPoolEntries) { - this.cpool = cpool; - // J5ASSERT: - // Could assert nvp.getNameString() points to the same thing as cpool.getConstant(nvp.getNameIndex()) - // if (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes())) { - // throw new RuntimeException("envp buggered"); - // } - if (copyPoolEntries) { - nameIdx = cpool.addUtf8(pair.getNameString()); - } else { - nameIdx = pair.getNameIndex(); - } - value = ElementValue.copy(pair.getValue(), cpool, copyPoolEntries); - } - - protected NameValuePair(int idx, ElementValue value, ConstantPool cpool) { - this.nameIdx = idx; - this.value = value; - this.cpool = cpool; - } - - public NameValuePair(String name, ElementValue value, ConstantPool cpool) { - this.nameIdx = cpool.addUtf8(name); - this.value = value; - this.cpool = cpool; - } - - protected void dump(DataOutputStream dos) throws IOException { - dos.writeShort(nameIdx); // u2 name of the element - value.dump(dos); - } - - public int getNameIndex() { - return nameIdx; - } - - public final String getNameString() { - return cpool.getConstantUtf8(nameIdx).getValue(); - } - - public final ElementValue getValue() { - return value; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getNameString()).append("=").append(value.stringifyValue()); - return sb.toString(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java deleted file mode 100644 index ac145087b..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004, 2013 IBM, VMware - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -public abstract class RuntimeAnnos extends Attribute { - - private List annotations; - private boolean visible; - - // Keep just a byte stream of the data until someone actually asks for it - private boolean inflated = false; - private byte[] annotation_data; - - public RuntimeAnnos(byte attrid, boolean visible, int nameIdx, int len, ConstantPool cpool) { - super(attrid, nameIdx, len, cpool); - this.visible = visible; - annotations = new ArrayList(); - } - - public RuntimeAnnos(byte attrid, boolean visible, int nameIdx, int len, byte[] data, ConstantPool cpool) { - super(attrid, nameIdx, len, cpool); - this.visible = visible; - annotations = new ArrayList(); - annotation_data = data; - } - - public List getAnnotations() { - if (!inflated) - inflate(); - return annotations; - } - - public boolean areVisible() { - return visible; - } - - protected void readAnnotations(DataInputStream dis, ConstantPool cpool) throws IOException { - annotation_data = new byte[length]; - dis.readFully(annotation_data, 0, length); - } - - protected void writeAnnotations(DataOutputStream dos) throws IOException { - if (!inflated) { - dos.write(annotation_data, 0, length); - } else { - dos.writeShort(annotations.size()); - for (Iterator i = annotations.iterator(); i.hasNext();) { - AnnotationGen ann = i.next(); - ann.dump(dos); - } - } - } - - - private void inflate() { - try { - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data)); - int numberOfAnnotations = dis.readUnsignedShort(); - if (numberOfAnnotations > 0) { - List inflatedAnnotations = new ArrayList(); - for (int i = 0; i < numberOfAnnotations; i++) { - inflatedAnnotations.add(AnnotationGen.read(dis, getConstantPool(), visible)); - } - annotations = inflatedAnnotations; - } - dis.close(); - inflated = true; - } catch (IOException ioe) { - throw new RuntimeException("Unabled to inflate annotation data, badly formed? "); - } - } - - /** FOR TESTING ONLY: Tells you if the annotations have been inflated to an object graph */ - public boolean isInflated() { - return inflated; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java deleted file mode 100644 index a6b2e529f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004, 2013 IBM, VMware - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ClassVisitor; - -public class RuntimeInvisAnnos extends RuntimeAnnos { - - public RuntimeInvisAnnos(int nameIdx, int len, ConstantPool cpool) { - super(Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS, false, nameIdx, len, cpool); - } - - public RuntimeInvisAnnos(int nameIdx, int len, - DataInputStream dis,ConstantPool cpool) throws IOException { - this(nameIdx, len, cpool); - readAnnotations(dis,cpool); - } - - public RuntimeInvisAnnos(int nameIndex, int len, byte[] rvaData,ConstantPool cpool) { - super(Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS,false,nameIndex,len,rvaData,cpool); - } - - public void accept(ClassVisitor v) { - v.visitRuntimeInvisibleAnnotations(this); - } - - public final void dump(DataOutputStream dos) throws IOException { - super.dump(dos); - writeAnnotations(dos); - } - - public Attribute copy(ConstantPool constant_pool) { - throw new RuntimeException("Not implemented yet!"); - } -} \ No newline at end of file diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java deleted file mode 100644 index cb2eb8d7a..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004, 2013 IBM, VMware - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataInputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ClassVisitor; - -public class RuntimeInvisParamAnnos extends RuntimeParamAnnos { - - public RuntimeInvisParamAnnos(int nameIdx, int len, ConstantPool cpool) { - super(Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, false, nameIdx, len, cpool); - } - - public RuntimeInvisParamAnnos(int nameIdx, int len, - DataInputStream dis,ConstantPool cpool) throws IOException { - this(nameIdx, len, cpool); - readParameterAnnotations(dis,cpool); - } - - public RuntimeInvisParamAnnos(int nameIndex, int len, byte[] rvaData,ConstantPool cpool) { - super(Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,false,nameIndex,len,rvaData,cpool); - } - - public void accept(ClassVisitor v) { - v.visitRuntimeInvisibleParameterAnnotations(this); - } - - public Attribute copy(ConstantPool constant_pool) { - throw new RuntimeException("Not implemented yet!"); - } -} \ No newline at end of file diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java deleted file mode 100644 index 333ccbddd..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2013 VMware - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.DataInputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ClassVisitor; - -public class RuntimeInvisTypeAnnos extends RuntimeTypeAnnos { - - public RuntimeInvisTypeAnnos(int nameIdx, int len, DataInputStream dis, - ConstantPool cpool) throws IOException { - this(nameIdx, len, cpool); - readTypeAnnotations(dis, cpool); - } - - public RuntimeInvisTypeAnnos(int nameIdx, int len, ConstantPool cpool) { - super(Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, false, nameIdx, len, cpool); - } - - public void accept(ClassVisitor v) { - v.visitRuntimeInvisibleTypeAnnotations(this); - } -} \ No newline at end of file diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java deleted file mode 100644 index 517ebee62..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.annotation; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -public abstract class RuntimeParamAnnos extends Attribute { - - private List parameterAnnotations; - private boolean visible; - - - // Keep just a byte stream of the data until someone actually asks for it - private boolean inflated = false; - private byte[] annotation_data; - - - public RuntimeParamAnnos(byte attrid, boolean visible, - int nameIdx, int len, ConstantPool cpool) { - super(attrid,nameIdx,len,cpool); - this.visible = visible; - parameterAnnotations = new ArrayList(); - } - - public RuntimeParamAnnos(byte attrid,boolean visible,int nameIdx,int len,byte[] data,ConstantPool cpool) { - super(attrid,nameIdx,len,cpool); - this.visible = visible; - parameterAnnotations = new ArrayList(); - annotation_data = data; - } - - public final void dump(DataOutputStream dos) throws IOException { - super.dump(dos); - writeAnnotations(dos); - } - - public Attribute copy(ConstantPool constant_pool) { - throw new RuntimeException("Not implemented yet!"); - } - - /** Return a list of Annotation[] - each list entry contains the annotations for one parameter */ - public List /*Annotation[]*/ getParameterAnnotations() { - if (!inflated) inflate(); - return parameterAnnotations; - } - - public AnnotationGen[] getAnnotationsOnParameter(int parameterIndex) { - if (!inflated) inflate(); - // This may happen. In a ctor for a non static inner type the compiler - // may have added an extra parameter to the generated ctor (the parameter - // contains the instance of the outer class) - in this case - // it may appear that there are more parameters than there are entries - // in the parameter annotations array - if (parameterIndex>=parameterAnnotations.size()) { - return AnnotationGen.NO_ANNOTATIONS; - } - return parameterAnnotations.get(parameterIndex); - } - - public boolean areVisible() { - return visible; - } - - protected void readParameterAnnotations(DataInputStream dis,ConstantPool cpool) throws IOException { - annotation_data = new byte[length]; - dis.readFully(annotation_data,0,length); - } - - private void inflate() { - try { - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data)); - int numParameters = dis.readUnsignedByte(); - if (numParameters > 0) { - List inflatedParameterAnnotations = new ArrayList(); - for (int i=0; i(); -// annotation_data = data; -// } - - public Attribute copy(ConstantPool constant_pool) { - throw new RuntimeException("Not implemented yet!"); - } - - public TypeAnnotationGen[] getTypeAnnotations() { - ensureInflated(); - return typeAnnotations; - } - - - public boolean areVisible() { - return visible; - } - - private void ensureInflated() { - if (typeAnnotations !=null) { - return; - } - try { - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data)); - int numTypeAnnotations = dis.readUnsignedShort(); - if (numTypeAnnotations == 0) { - typeAnnotations = TypeAnnotationGen.NO_TYPE_ANNOTATIONS; - } else { - typeAnnotations = new TypeAnnotationGen[numTypeAnnotations]; - for (int i=0; i copyValues(List in, ConstantPool cpool, boolean copyPoolEntries) { -// List out = new ArrayList(); -// for (NameValuePair nvp : in) { -// out.add(new NameValuePair(nvp, cpool, copyPoolEntries)); -// } -// return out; -// } -// -// -// /** -// * Retrieve an immutable version of this AnnotationGen -// */ -// public TypeAnnotationGen(ObjectType type, List pairs, boolean runtimeVisible, ConstantPool cpool) { -// this.cpool = cpool; -// if (type != null) { -// this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects -// } -// this.pairs = pairs; -// isRuntimeVisible = runtimeVisible; -// } -// - - public int[] getTypePath() { - return typePath; - } - - public String getTypePathString() { - return toTypePathString(typePath); - } - - public static String toTypePathString(int[] typepath) { - StringBuilder sb = new StringBuilder(); - int count = 0; - sb.append("["); - while (count < typepath.length) { - if (count>0) sb.append(","); - switch (typepath[count++]) { - case TYPE_PATH_ENTRY_KIND_ARRAY: - sb.append("ARRAY"); - count++; - break; - case TYPE_PATH_ENTRY_KIND_INNER_TYPE: - sb.append("INNER_TYPE"); - count++; - break; - case TYPE_PATH_ENTRY_KIND_WILDCARD: - sb.append("WILDCARD"); - count++; - break; - case TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT: - sb.append("TYPE_ARGUMENT(").append(typepath[count++]).append(")"); - break; - } - } - sb.append("]"); - return sb.toString(); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ArrayType.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ArrayType.java deleted file mode 100644 index d9599289b..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ArrayType.java +++ /dev/null @@ -1,156 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import org.aspectj.apache.bcel.Constants; - -/** - * Denotes array type, such as int[][] - * - * @version $Id: ArrayType.java,v 1.4 2008/08/26 15:02:04 aclement Exp $ - * @author M. Dahm - */ -public final class ArrayType extends ReferenceType { - private int dimensions; - private Type basic_type; - - /** - * Convenience constructor for array type, e.g. int[] - * - * @param type array type, e.g. T_INT - */ - public ArrayType(byte type, int dimensions) { - this(BasicType.getType(type), dimensions); - } - - /** - * Convenience constructor for reference array type, e.g. Object[] - * - * @param class_name complete name of class (java.lang.String, e.g.) - */ - public ArrayType(String class_name, int dimensions) { - this(new ObjectType(class_name), dimensions); - } - - /** - * Constructor for array of given type - * - * @param type type of array (may be an array itself) - */ - public ArrayType(Type type, int dimensions) { - super(Constants.T_ARRAY, ""); - - if((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) - throw new ClassGenException("Invalid number of dimensions: " + dimensions); - - switch(type.getType()) { - case Constants.T_ARRAY: - ArrayType array = (ArrayType)type; - this.dimensions = dimensions + array.dimensions; - basic_type = array.basic_type; - break; - - case Constants.T_VOID: - throw new ClassGenException("Invalid type: void[]"); - - default: // Basic type or reference - this.dimensions = dimensions; - basic_type = type; - break; - } - - StringBuffer buf = new StringBuffer(); - for(int i=0; i < this.dimensions; i++) - buf.append('['); - - buf.append(basic_type.getSignature()); - - signature = buf.toString(); - } - - /** - * @return basic type of array, i.e., for int[][][] the basic type is int - */ - public Type getBasicType() { - return basic_type; - } - - /** - * @return element type of array, i.e., for int[][][] the element type is int[][] - */ - public Type getElementType() { - if(dimensions == 1) - return basic_type; - else - return new ArrayType(basic_type, dimensions - 1); - } - - /** @return number of dimensions of array - */ - public int getDimensions() { return dimensions; } - - /** @return a hash code value for the object. - */ - public int hashCode() { return basic_type.hashCode() ^ dimensions; } - - /** @return true if both type objects refer to the same array type. - */ - public boolean equals(Object type) { - if(type instanceof ArrayType) { - ArrayType array = (ArrayType)type; - return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); - } else - return false; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/BasicType.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/BasicType.java deleted file mode 100644 index 477fb1dff..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/BasicType.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import org.aspectj.apache.bcel.Constants; - -/** - * Denotes basic type such as int. - * - * @version $Id: BasicType.java,v 1.4 2008/08/28 00:05:57 aclement Exp $ - * @author M. Dahm - */ -public final class BasicType extends Type { - /** - * Constructor for basic types such as int, long, `void' - * - * @param type one of T_INT, T_BOOLEAN, ..., T_VOID - * @see org.aspectj.apache.bcel.Constants - */ - BasicType(byte type) { - super(type, Constants.SHORT_TYPE_NAMES[type]); - - if (type < Constants.T_BOOLEAN || type > Constants.T_VOID) { - throw new ClassGenException("Invalid type: " + type); - } - } - - public static final BasicType getType(byte type) { - switch (type) { - case Constants.T_VOID: - return VOID; - case Constants.T_BOOLEAN: - return BOOLEAN; - case Constants.T_BYTE: - return BYTE; - case Constants.T_SHORT: - return SHORT; - case Constants.T_CHAR: - return CHAR; - case Constants.T_INT: - return INT; - case Constants.T_LONG: - return LONG; - case Constants.T_DOUBLE: - return DOUBLE; - case Constants.T_FLOAT: - return FLOAT; - - default: - throw new ClassGenException("Invalid type: " + type); - } - } - - /** - * @return true if both type objects refer to the same type - */ - public boolean equals(Object type) { - return type instanceof BasicType ? ((BasicType) type).type == this.type : false; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java deleted file mode 100644 index 35d9528b8..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * BranchHandle is returned by specialized InstructionList.append() whenever a BranchInstruction is appended. This is useful when - * the target of this instruction is not known at time of creation and must be set later via setTarget(). - * - * @see InstructionHandle - * @see Instruction - * @see InstructionList - * @version $Id: BranchHandle.java,v 1.5 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public final class BranchHandle extends InstructionHandle { - private InstructionBranch bi; // An alias in fact, but saves lots of casts - - private BranchHandle(InstructionBranch i) { - super(i); - bi = i; - } - - static final BranchHandle getBranchHandle(InstructionBranch i) { - return new BranchHandle(i); - } - - /* - * Override InstructionHandle methods: delegate to branch instruction. Through this overriding all access to the private - * i_position field should be prevented. - */ - public int getPosition() { - return bi.positionOfThisInstruction; - } - - void setPosition(int pos) { - this.pos = bi.positionOfThisInstruction = pos; - } - - /** - * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length - * instructions 'setPositions()' performs multiple passes over the instruction list to calculate the correct (byte) positions - * and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition(int offset, int max_offset) { - int x = bi.updatePosition(offset, max_offset); - pos = bi.positionOfThisInstruction; - return x; - } - - /** - * Pass new target to instruction. - */ - public void setTarget(InstructionHandle ih) { - bi.setTarget(ih); - } - - /** - * Update target of instruction. - */ - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - bi.updateTarget(old_ih, new_ih); - } - - /** - * @return target of instruction. - */ - public InstructionHandle getTarget() { - return bi.getTarget(); - } - - /** - * Set new contents. Old instruction is disposed and may not be used anymore. - */ - public void setInstruction(Instruction i) { - super.setInstruction(i); - bi = (InstructionBranch) i; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGen.java deleted file mode 100644 index 4ba767d97..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGen.java +++ /dev/null @@ -1,637 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.lang.reflect.Modifier; -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.Field; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.Modifiers; -import org.aspectj.apache.bcel.classfile.SourceFile; -import org.aspectj.apache.bcel.classfile.Utility; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; - -/** - * Template class for building up a java class. May be initialized with an existing java class. - * - * @see JavaClass - * @version $Id: ClassGen.java,v 1.15 2009/09/15 19:40:14 aclement Exp $ - * @author M. Dahm - * - * Upgraded, Andy Clement 9th Mar 06 - calculates SUID - */ -public class ClassGen extends Modifiers implements Cloneable { - - private String classname; - private String superclassname; - private String filename; - private int classnameIndex = -1; - private int superclassnameIndex = -1; - private int major = Constants.MAJOR_1_1; - private int minor = Constants.MINOR_1_1; - private ConstantPool cpool; - private List fieldsList = new ArrayList(); - private List methodsList = new ArrayList(); - private List attributesList = new ArrayList(); - private List interfaceList = new ArrayList(); - private List annotationsList = new ArrayList(); - - public ClassGen(String classname, String superclassname, String filename, int modifiers, String[] interfacenames, - ConstantPool cpool) { - this.classname = classname; - this.superclassname = superclassname; - this.filename = filename; - this.modifiers = modifiers; - this.cpool = cpool; - if (filename != null) { - addAttribute(new SourceFile(cpool.addUtf8("SourceFile"), 2, cpool.addUtf8(filename), cpool)); - } - this.classnameIndex = cpool.addClass(classname); - this.superclassnameIndex = cpool.addClass(superclassname); - if (interfacenames != null) { - for (String interfacename : interfacenames) { - addInterface(interfacename); - } - } - } - - public ClassGen(String classname, String superclassname, String filename, int modifiers, String[] interfacenames) { - this(classname, superclassname, filename, modifiers, interfacenames, new ConstantPool()); - } - - public ClassGen(JavaClass clazz) { - classnameIndex = clazz.getClassNameIndex(); - superclassnameIndex = clazz.getSuperclassNameIndex(); - classname = clazz.getClassName(); - superclassname = clazz.getSuperclassName(); - filename = clazz.getSourceFileName(); - modifiers = clazz.getModifiers(); - cpool = clazz.getConstantPool().copy(); - major = clazz.getMajor(); - minor = clazz.getMinor(); - - Method[] methods = clazz.getMethods(); - Field[] fields = clazz.getFields(); - String[] interfaces = clazz.getInterfaceNames(); - - for (int i = 0; i < interfaces.length; i++) { - addInterface(interfaces[i]); - } - - // OPTIMIZE Could make unpacking lazy, done on first reference - Attribute[] attributes = clazz.getAttributes(); - for (Attribute attr : attributes) { - if (attr instanceof RuntimeVisAnnos) { - RuntimeVisAnnos rva = (RuntimeVisAnnos) attr; - List annos = rva.getAnnotations(); - for (AnnotationGen a : annos) { - annotationsList.add(new AnnotationGen(a, cpool, false)); - } - } else if (attr instanceof RuntimeInvisAnnos) { - RuntimeInvisAnnos ria = (RuntimeInvisAnnos) attr; - List annos = ria.getAnnotations(); - for (AnnotationGen anno : annos) { - annotationsList.add(new AnnotationGen(anno, cpool, false)); - } - } else { - attributesList.add(attr); - } - } - - for (int i = 0; i < methods.length; i++) { - addMethod(methods[i]); - } - - for (int i = 0; i < fields.length; i++) { - addField(fields[i]); - } - } - - /** - * @return build and return a JavaClass - */ - public JavaClass getJavaClass() { - int[] interfaces = getInterfaces(); - Field[] fields = getFields(); - Method[] methods = getMethods(); - - Collection attributes = null; - if (annotationsList.size() == 0) { - attributes = attributesList; - } else { - // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations' - attributes = new ArrayList(); - attributes.addAll(Utility.getAnnotationAttributes(cpool, annotationsList)); - attributes.addAll(attributesList); - } - - // Must be last since the above calls may still add something to it - ConstantPool cp = this.cpool.getFinalConstantPool(); - - return new JavaClass(classnameIndex, superclassnameIndex, filename, major, minor, modifiers, cp, interfaces, fields, - methods, attributes.toArray(new Attribute[attributes.size()]));// OPTIMIZE avoid toArray()? - } - - public void addInterface(String name) { - interfaceList.add(name); - } - - public void removeInterface(String name) { - interfaceList.remove(name); - } - - public int getMajor() { - return major; - } - - public void setMajor(int major) { - this.major = major; - } - - public void setMinor(int minor) { - this.minor = minor; - } - - public int getMinor() { - return minor; - } - - public void addAttribute(Attribute a) { - attributesList.add(a); - } - - public void addAnnotation(AnnotationGen a) { - annotationsList.add(a); - } - - public void addMethod(Method m) { - methodsList.add(m); - } - - /** - * Convenience method. - * - * Add an empty constructor to this class that does nothing but calling super(). - * - * @param access rights for constructor - */ - public void addEmptyConstructor(int access_flags) { - InstructionList il = new InstructionList(); - il.append(InstructionConstants.THIS); // Push `this' - il.append(new InvokeInstruction(Constants.INVOKESPECIAL, cpool.addMethodref(superclassname, "", "()V"))); - il.append(InstructionConstants.RETURN); - - MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "", classname, il, cpool); - mg.setMaxStack(1); - mg.setMaxLocals(); - addMethod(mg.getMethod()); - } - - /** - * Add a field to this class. - * - * @param f field to add - */ - public void addField(Field f) { - fieldsList.add(f); - } - - public boolean containsField(Field f) { - return fieldsList.contains(f); - } - - /** - * @return field object with given name, or null if not found - */ - public Field findsField(String name) { - for (Field field : fieldsList) { - if (field.getName().equals(name)) { - return field; - } - } - return null; - } - - /** - * @return method object with given name and signature, or null if not found - */ - public Method containsMethod(String name, String signature) { - for (Method method : methodsList) { - if (method.getName().equals(name) && method.getSignature().equals(signature)) { - return method; - } - } - return null; - } - - public void removeAttribute(Attribute a) { - attributesList.remove(a); - } - - public void removeAnnotation(AnnotationGen a) { - annotationsList.remove(a); - } - - public void removeMethod(Method m) { - methodsList.remove(m); - } - - /** - * Replace given method with new one. If the old one does not exist add the new_ method to the class anyway. - */ - public void replaceMethod(Method old, Method new_) { - if (new_ == null) - throw new ClassGenException("Replacement method must not be null"); - - int i = methodsList.indexOf(old); - - if (i < 0) - methodsList.add(new_); - else - methodsList.set(i, new_); - } - - /** - * Replace given field with new one. If the old one does not exist add the new_ field to the class anyway. - */ - public void replaceField(Field old, Field new_) { - if (new_ == null) - throw new ClassGenException("Replacement method must not be null"); - - int i = fieldsList.indexOf(old); - - if (i < 0) - fieldsList.add(new_); - else - fieldsList.set(i, new_); - } - - public void removeField(Field f) { - fieldsList.remove(f); - } - - public String getClassName() { - return classname; - } - - public String getSuperclassName() { - return superclassname; - } - - public String getFileName() { - return filename; - } - - public void setClassName(String name) { - classname = name.replace('/', '.'); - classnameIndex = cpool.addClass(name); - } - - public void setSuperclassName(String name) { - superclassname = name.replace('/', '.'); - superclassnameIndex = cpool.addClass(name); - } - - public Method[] getMethods() { - Method[] methods = new Method[methodsList.size()]; - methodsList.toArray(methods); - return methods; - } - - public void setMethods(Method[] methods) { - methodsList.clear(); - for (int m = 0; m < methods.length; m++) - addMethod(methods[m]); - } - - public void setFields(Field[] fs) { - fieldsList.clear(); - for (int m = 0; m < fs.length; m++) - addField(fs[m]); - } - - public void setMethodAt(Method method, int pos) { - methodsList.set(pos, method); - } - - public Method getMethodAt(int pos) { - return methodsList.get(pos); - } - - public String[] getInterfaceNames() { - int size = interfaceList.size(); - String[] interfaces = new String[size]; - - interfaceList.toArray(interfaces); - return interfaces; - } - - public int[] getInterfaces() { - int size = interfaceList.size(); - int[] interfaces = new int[size]; - - for (int i = 0; i < size; i++) - interfaces[i] = cpool.addClass(interfaceList.get(i)); - - return interfaces; - } - - public Field[] getFields() { - Field[] fields = new Field[fieldsList.size()]; - fieldsList.toArray(fields); - return fields; - } - - public Collection getAttributes() { - return attributesList; - } - - // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here? - public AnnotationGen[] getAnnotations() { - AnnotationGen[] annotations = new AnnotationGen[annotationsList.size()]; - annotationsList.toArray(annotations); - return annotations; - } - - public ConstantPool getConstantPool() { - return cpool; - } - - public void setConstantPool(ConstantPool constant_pool) { - cpool = constant_pool; - } - - public void setClassNameIndex(int class_name_index) { - this.classnameIndex = class_name_index; - classname = cpool.getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.'); - } - - public void setSuperclassNameIndex(int superclass_name_index) { - this.superclassnameIndex = superclass_name_index; - superclassname = cpool.getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.'); - } - - public int getSuperclassNameIndex() { - return superclassnameIndex; - } - - public int getClassNameIndex() { - return classnameIndex; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } - - public final boolean isAnnotation() { - return (modifiers & Constants.ACC_ANNOTATION) != 0; - } - - public final boolean isEnum() { - return (modifiers & Constants.ACC_ENUM) != 0; - } - - /** - * Calculate the SerialVersionUID for a class. - */ - public long getSUID() { - try { - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - - // 1. classname - dos.writeUTF(getClassName()); - - // 2. classmodifiers: ACC_PUBLIC, ACC_FINAL, ACC_INTERFACE, and ACC_ABSTRACT - int classmods = 0; - classmods |= (isPublic() ? Constants.ACC_PUBLIC : 0); - classmods |= (isFinal() ? Constants.ACC_FINAL : 0); - classmods |= (isInterface() ? Constants.ACC_INTERFACE : 0); - - if (isAbstract()) { - // if an interface then abstract is only set if it has methods - if (isInterface()) { - if (methodsList.size() > 0) - classmods |= Constants.ACC_ABSTRACT; - } else { - classmods |= Constants.ACC_ABSTRACT; - } - } - - dos.writeInt(classmods); - - // 3. ordered list of interfaces - String[] names = getInterfaceNames(); - if (names != null) { - Arrays.sort(names); - for (int i = 0; i < names.length; i++) - dos.writeUTF(names[i]); - } - - // 4. ordered list of fields (ignoring private static and private transient fields): - // (relevant modifiers are ACC_PUBLIC, ACC_PRIVATE, - // ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, - // ACC_TRANSIENT) - List relevantFields = new ArrayList(); - for (Field field : fieldsList) { - if (!(field.isPrivate() && field.isStatic()) && !(field.isPrivate() && field.isTransient())) { - relevantFields.add(field); - } - } - Collections.sort(relevantFields, new FieldComparator()); - int relevantFlags = Constants.ACC_PUBLIC | Constants.ACC_PRIVATE | Constants.ACC_PROTECTED | Constants.ACC_STATIC - | Constants.ACC_FINAL | Constants.ACC_VOLATILE | Constants.ACC_TRANSIENT; - for (Field f : relevantFields) { - dos.writeUTF(f.getName()); - dos.writeInt(relevantFlags & f.getModifiers()); - dos.writeUTF(f.getType().getSignature()); - } - - // some up front method processing: discover clinit, init and ordinary methods of interest: - List relevantMethods = new ArrayList(); - List relevantCtors = new ArrayList(); - boolean hasClinit = false; - for (Method m : methodsList) { - boolean couldBeInitializer = m.getName().charAt(0) == '<'; - if (couldBeInitializer && m.getName().equals("")) { - hasClinit = true; - } else if (couldBeInitializer && m.getName().equals("")) { - if (!m.isPrivate()) - relevantCtors.add(m); - } else { - if (!m.isPrivate()) - relevantMethods.add(m); - } - } - Collections.sort(relevantCtors, new ConstructorComparator()); - Collections.sort(relevantMethods, new MethodComparator()); - - // 5. If a class initializer exists, write out the following: - // 1. The name of the method, . - // 2. The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer. - // 3. The descriptor of the method, ()V. - if (hasClinit) { - dos.writeUTF(""); - dos.writeInt(Modifier.STATIC); - dos.writeUTF("()V"); - } - - // for methods and constructors: - // ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, - // ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT - relevantFlags = Constants.ACC_PUBLIC | Constants.ACC_PRIVATE | Constants.ACC_PROTECTED | Constants.ACC_STATIC - | Constants.ACC_FINAL | Constants.ACC_SYNCHRONIZED | Constants.ACC_NATIVE | Constants.ACC_ABSTRACT - | Constants.ACC_STRICT; - - // 6. sorted non-private constructors - for (Method ctor : relevantCtors) { - dos.writeUTF(ctor.getName()); // - dos.writeInt(relevantFlags & ctor.getModifiers()); - dos.writeUTF(ctor.getSignature().replace('/', '.')); - } - - // 7. sorted non-private methods - for (Method m : relevantMethods) { - dos.writeUTF(m.getName()); - dos.writeInt(relevantFlags & m.getModifiers()); - dos.writeUTF(m.getSignature().replace('/', '.')); - } - dos.flush(); - dos.close(); - byte[] bs = baos.toByteArray(); - MessageDigest md = MessageDigest.getInstance("SHA"); - byte[] result = md.digest(bs); - - long suid = 0L; - int pos = result.length > 8 ? 7 : result.length - 1; // use the bytes we have - while (pos >= 0) { - suid = suid << 8 | ((long) result[pos--] & 0xff); - } - - // if it was definetly 8 everytime... - // long suid = ((long)(sha[0]&0xff) | (long)(sha[1]&0xff) << 8 | - // (long)(sha[2]&0xff) << 16 | (long)(sha[3]&0xff) << 24 | - // (long)(sha[4]&0xff) << 32 | (long)(sha[5]&0xff) << 40 | - // (long)(sha[6]&0xff) << 48 | (long)(sha[7]&0xff) << 56); - return suid; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("Unable to calculate suid for " + getClassName() + ": " + e.toString()); - } - } - - private static class FieldComparator implements Comparator { - public int compare(Field f0, Field f1) { - return f0.getName().compareTo(f1.getName()); - } - } - - private static class ConstructorComparator implements Comparator { - public int compare(Method m0, Method m1) { - // can ignore the name... - return (m0).getSignature().compareTo(m1.getSignature()); - } - } - - private static class MethodComparator implements Comparator { - public int compare(Method m0, Method m1) { - int result = m0.getName().compareTo(m1.getName()); - if (result == 0) { - result = m0.getSignature().compareTo(m1.getSignature()); - } - return result; - } - } - - public boolean hasAttribute(String attributeName) { - for (Attribute attr : attributesList) { - if (attr.getName().equals(attributeName)) { - return true; - } - } - return false; - } - - public Attribute getAttribute(String attributeName) { - for (Attribute attr : attributesList) { - if (attr.getName().equals(attributeName)) { - return attr; - } - } - return null; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGenException.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGenException.java deleted file mode 100644 index b981dc8dc..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGenException.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared - * in the throws clause every time. - * - * @version $Id: ClassGenException.java,v 1.3 2008/05/28 23:52:57 aclement Exp $ - * @author M. Dahm - */ -public class ClassGenException extends RuntimeException { - public ClassGenException() { super(); } - public ClassGenException(String s) { super(s); } -} - diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/CodeExceptionGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/CodeExceptionGen.java deleted file mode 100644 index 01b839207..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/CodeExceptionGen.java +++ /dev/null @@ -1,202 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.classfile.CodeException; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -/** - * This class represents an exception handler, i.e., specifies the region where - * a handler is active and an instruction where the actual handling is done. - * pool as parameters. Opposed to the JVM specification the end of the handled - * region is set to be inclusive, i.e. all instructions between start and end - * are protected including the start and end instructions (handles) themselves. - * The end of the region is automatically mapped to be exclusive when calling - * getCodeException(), i.e., there is no difference semantically. - * - * @version $Id: CodeExceptionGen.java,v 1.5 2008/05/28 23:52:56 aclement Exp $ - * @author M. Dahm - * @see MethodGen - * @see CodeException - * @see InstructionHandle - */ -public final class CodeExceptionGen - implements InstructionTargeter, Cloneable, java.io.Serializable { - private InstructionHandle start_pc; - private InstructionHandle end_pc; - private InstructionHandle handler_pc; - private ObjectType catch_type; - - /** - * Add an exception handler, i.e., specify region where a handler is active and an - * instruction where the actual handling is done. - * - * @param start_pc Start of handled region (inclusive) - * @param end_pc End of handled region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type which exception is handled, null for ANY - */ - public CodeExceptionGen(InstructionHandle start_pc, InstructionHandle end_pc, - InstructionHandle handler_pc, ObjectType catch_type) { - setStartPC(start_pc); - setEndPC(end_pc); - setHandlerPC(handler_pc); - this.catch_type = catch_type; - } - - /** - * Get CodeException object.
- * - * This relies on that the instruction list has already been dumped - * to byte code or or that the `setPositions' methods has been - * called for the instruction list. - * - * @param cp constant pool - */ - public CodeException getCodeException(ConstantPool cp) { - return new CodeException(start_pc.getPosition(), - end_pc.getPosition() + end_pc.getInstruction().getLength(), - handler_pc.getPosition(), - (catch_type == null)? 0 : cp.addClass(catch_type)); - } - - /* Set start of handler - * @param start_pc Start of handled region (inclusive) - */ - public void setStartPC(InstructionHandle start_pc) { - InstructionBranch.notifyTarget(this.start_pc, start_pc, this); - this.start_pc = start_pc; - } - - /* Set end of handler - * @param end_pc End of handled region (inclusive) - */ - public void setEndPC(InstructionHandle end_pc) { - InstructionBranch.notifyTarget(this.end_pc, end_pc, this); - this.end_pc = end_pc; - } - - /* Set handler code - * @param handler_pc Start of handler - */ - public void setHandlerPC(InstructionHandle handler_pc) { - InstructionBranch.notifyTarget(this.handler_pc, handler_pc, this); - this.handler_pc = handler_pc; - } - - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if(start_pc == old_ih) { - targeted = true; - setStartPC(new_ih); - } - - if(end_pc == old_ih) { - targeted = true; - setEndPC(new_ih); - } - - if(handler_pc == old_ih) { - targeted = true; - setHandlerPC(new_ih); - } - - if(!targeted) - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", " + - end_pc + ", " + handler_pc + "}"); - } - - /** - * @return true, if ih is target of this handler - */ - public boolean containsTarget(InstructionHandle ih) { - return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); - } - - /** Sets the type of the Exception to catch. Set 'null' for ANY. */ - public void setCatchType(ObjectType catch_type) { this.catch_type = catch_type; } - /** Gets the type of the Exception to catch, 'null' for ANY. */ - public ObjectType getCatchType() { return catch_type; } - - /** @return start of handled region (inclusive) - */ - public InstructionHandle getStartPC() { return start_pc; } - - /** @return end of handled region (inclusive) - */ - public InstructionHandle getEndPC() { return end_pc; } - - /** @return start of handler - */ - public InstructionHandle getHandlerPC() { return handler_pc; } - - public String toString() { - return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; - } - - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java deleted file mode 100644 index 6a12a8c80..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java +++ /dev/null @@ -1,245 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.util.Iterator; -import java.util.List; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.Constant; -import org.aspectj.apache.bcel.classfile.ConstantDouble; -import org.aspectj.apache.bcel.classfile.ConstantFloat; -import org.aspectj.apache.bcel.classfile.ConstantInteger; -import org.aspectj.apache.bcel.classfile.ConstantLong; -import org.aspectj.apache.bcel.classfile.ConstantObject; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ConstantString; -import org.aspectj.apache.bcel.classfile.ConstantValue; -import org.aspectj.apache.bcel.classfile.Field; -import org.aspectj.apache.bcel.classfile.Utility; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; - -/** - * Template class for building up a field. The only extraordinary thing one can do is to add a constant value attribute to a field - * (which must of course be compatible with the declared type). - * - * @version $Id: FieldGen.java,v 1.11 2011/10/03 22:41:24 aclement Exp $ - * @author M. Dahm - * @see Field - */ -public class FieldGen extends FieldGenOrMethodGen { - private Object value = null; - - /** - * Declare a field. If it is static (isStatic() == true) and has a basic type like int or String it may have an initial value - * associated with it as defined by setInitValue(). - * - * @param modifiers access qualifiers - * @param type field type - * @param name field name - * @param cpool constant pool - */ - public FieldGen(int modifiers, Type type, String name, ConstantPool cpool) { - setModifiers(modifiers); - setType(type); - setName(name); - setConstantPool(cpool); - } - - /** - * Instantiate from existing field. - * - * @param field Field object - * @param cp constant pool (must contain the same entries as the field's constant pool) - */ - public FieldGen(Field field, ConstantPool cp) { - this(field.getModifiers(), Type.getType(field.getSignature()), field.getName(), cp); - - Attribute[] attrs = field.getAttributes(); - - for (int i = 0; i < attrs.length; i++) { - if (attrs[i] instanceof ConstantValue) { - setValue(((ConstantValue) attrs[i]).getConstantValueIndex()); - } else if (attrs[i] instanceof RuntimeAnnos) { - RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attrs[i]; - List l = runtimeAnnotations.getAnnotations(); - for (Iterator it = l.iterator(); it.hasNext();) { - AnnotationGen element = it.next(); - addAnnotation(new AnnotationGen(element, cp, false)); - } - } else { - addAttribute(attrs[i]); - } - } - } - - public void setValue(int index) { - ConstantPool cp = this.cp; - Constant c = cp.getConstant(index); - if (c instanceof ConstantInteger) { - value = ((ConstantInteger) c).getIntValue(); - } else if (c instanceof ConstantFloat) { - value = ((ConstantFloat) c).getValue(); - } else if (c instanceof ConstantDouble) { - value = ((ConstantDouble) c).getValue(); - } else if (c instanceof ConstantLong) { - value = ((ConstantLong) c).getValue(); - } else if (c instanceof ConstantString) { - value = ((ConstantString)c).getString(cp); - } else { - value = ((ConstantObject) c).getConstantValue(cp); - } - } - - public void setValue(String constantString) { - value = constantString; - } - - public void wipeValue() { - value = null; - } - - private void checkType(Type atype) { - if (type == null) - throw new ClassGenException("You haven't defined the type of the field yet"); - - if (!isFinal()) - throw new ClassGenException("Only final fields may have an initial value!"); - - if (!type.equals(atype)) - throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype); - } - - /** - * Get field object after having set up all necessary values. - */ - public Field getField() { - String signature = getSignature(); - int nameIndex = cp.addUtf8(name); - int signatureIndex = cp.addUtf8(signature); - - if (value != null) { - checkType(type); - int index = addConstant(); - addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), 2, index, cp)); - } - - addAnnotationsAsAttribute(cp); - - return new Field(modifiers, nameIndex, signatureIndex, getAttributesImmutable(), cp); - } - - private int addConstant() { - switch (type.getType()) { - case Constants.T_INT: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_BOOLEAN: - case Constants.T_SHORT: - return cp.addInteger(((Integer) value).intValue()); - - case Constants.T_FLOAT: - return cp.addFloat(((Float) value).floatValue()); - - case Constants.T_DOUBLE: - return cp.addDouble(((Double) value).doubleValue()); - - case Constants.T_LONG: - return cp.addLong(((Long) value).longValue()); - - case Constants.T_REFERENCE: - return cp.addString(((String) value)); - - default: - throw new RuntimeException("Oops: Unhandled : " + type.getType()); - } - } - - @Override - public String getSignature() { - return type.getSignature(); - } - - public String getInitialValue() { - return (value == null ? null : value.toString()); - } - - public void setInitialStringValue(String value) { - this.value = value; - } - - /** - * Return string representation close to declaration format, `public static final short MAX = 100', e.g.. - */ - @Override - public final String toString() { - String access = Utility.accessToString(modifiers); - access = access.equals("") ? "" : (access + " "); - String signature = type.toString(); - String name = getName(); - - StringBuffer buf = new StringBuffer(access).append(signature).append(" ").append(name); - String value = getInitialValue(); - - if (value != null) { - buf.append(" = ").append(value); - } - // TODO: Add attributes and annotations to the string - return buf.toString(); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java deleted file mode 100644 index ff8b6f42c..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.Modifiers; -import org.aspectj.apache.bcel.classfile.Utility; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; - -/** - * Super class for FieldGen and MethodGen objects, since they have some methods in common! - * - * @version $Id: FieldGenOrMethodGen.java,v 1.8 2009/09/15 19:40:14 aclement Exp $ - * @author M. Dahm - */ -public abstract class FieldGenOrMethodGen extends Modifiers { - - protected String name; - protected Type type; - protected ConstantPool cp; - private ArrayList attributeList = new ArrayList(); - protected ArrayList annotationList = new ArrayList(); - - protected FieldGenOrMethodGen() { - } - - public void setType(Type type) { - this.type = type; - } - - public Type getType() { - return type; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ConstantPool getConstantPool() { - return cp; - } - - public void setConstantPool(ConstantPool cp) { - this.cp = cp; - } - - public void addAttribute(Attribute a) { - attributeList.add(a); - } - - public void removeAttribute(Attribute a) { - attributeList.remove(a); - } - - public void removeAttributes() { - attributeList.clear(); - } - - public List getAnnotations() { - return annotationList; - } - - public void addAnnotation(AnnotationGen ag) { - annotationList.add(ag); - } - - public void removeAnnotation(AnnotationGen ag) { - annotationList.remove(ag); - } - - public void removeAnnotations() { - annotationList.clear(); - } - - public List getAttributes() { - return attributeList; - } - - public Attribute[] getAttributesImmutable() { - Attribute[] attributes = new Attribute[attributeList.size()]; - attributeList.toArray(attributes); - return attributes; - } - - protected void addAnnotationsAsAttribute(ConstantPool cp) { - Collection attrs = Utility.getAnnotationAttributes(cp, annotationList); - if (attrs != null) { - for (Attribute attr : attrs) { - addAttribute(attr); - } - } - } - - public abstract String getSignature(); - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java deleted file mode 100644 index 54983e7c9..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.classfile.ConstantPool; - -/** - * Super class for the GET/PUTxxx family of instructions. - * - * @version $Id: FieldInstruction.java,v 1.7 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public class FieldInstruction extends FieldOrMethod { - - public FieldInstruction(short opcode, int index) { - super(opcode, index); - } - - public String toString(ConstantPool cp) { - return org.aspectj.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " - + cp.constantToString(index, org.aspectj.apache.bcel.Constants.CONSTANT_Fieldref); - } - - /** - * @return size of field (1 or 2) - */ - protected int getFieldSize(ConstantPool cpg) { - return Type.getTypeSize(getSignature(cpg)); - } - - public Type getType(ConstantPool cpg) { - return getFieldType(cpg); - } - - public Type getFieldType(ConstantPool cpg) { - return Type.getType(getSignature(cpg)); - } - - public String getFieldName(ConstantPool cpg) { - return getName(cpg); - } - - public int produceStack(ConstantPool cpg) { - if (!isStackProducer()) { - return 0; - } - - return getFieldSize(cpg); // SAME FOR GETFIELD/GETSTATIC - } - - public int consumeStack(ConstantPool cpg) { - if (!isStackConsumer()) { - return 0; - } - if (opcode == GETFIELD) { - return 1; - } - return getFieldSize(cpg) + (opcode == PUTFIELD ? 1 : 0); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java deleted file mode 100644 index 44b263ffb..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import org.aspectj.apache.bcel.classfile.Constant; -import org.aspectj.apache.bcel.classfile.ConstantCP; -import org.aspectj.apache.bcel.classfile.ConstantNameAndType; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ConstantUtf8; - -/** - * Super class for InvokeInstruction and FieldInstruction, since they have some methods in common! - * - * @version $Id: FieldOrMethod.java,v 1.8 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public abstract class FieldOrMethod extends InstructionCP { - - protected String signature; - protected String name; - private String classname; - - protected FieldOrMethod(short opcode, int index) { - super(opcode, index); - } - - /** - * @return signature of referenced method/field. - */ - public String getSignature(ConstantPool cp) { - if (signature == null) { - Constant c = cp.getConstant(index); - ConstantCP cmr = (ConstantCP) c; - ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); - signature = ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getValue(); - } - return signature; - } - - /** - * @return name of referenced method/field. - */ - public String getName(ConstantPool cp) { - if (name == null) { - ConstantCP cmr = (ConstantCP) cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); - name = ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getValue(); - } - return name; - } - - /** - * @return name of the referenced class/interface - */ - public String getClassName(ConstantPool cp) { - if (classname == null) { - ConstantCP cmr = (ConstantCP) cp.getConstant(index); - String str = cp.getConstantString(cmr.getClassIndex(), CONSTANT_Class); - if (str.charAt(0) == '[') { - classname = str; - } else { - classname = str.replace('/', '.'); - } - } - return classname; - } - - /** - * @return type of the referenced class/interface - */ - public ObjectType getClassType(ConstantPool cpg) { - return new ObjectType(getClassName(cpg)); - } - - /** - * @return type of the referenced class/interface - */ - @Override - public ObjectType getLoadClassType(ConstantPool cpg) { - return getClassType(cpg); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java deleted file mode 100644 index d70e20308..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * IINC - Increment local variable by constant - * - * @version $Id: IINC.java,v 1.5 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public class IINC extends InstructionLV { - private int c; - - public IINC(int n, int c, boolean w) { - super(Constants.IINC, n); - this.c = c; - // this.wide = w;//((n > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE)); - } - - private boolean wide() { - return ((lvar > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE)); - } - - public void dump(DataOutputStream out) throws IOException { - if (wide()) { - out.writeByte(WIDE); - out.writeByte(opcode); - out.writeShort(lvar); - out.writeShort(c); - } else { - out.writeByte(opcode); - out.writeByte(lvar); - out.writeByte(c); - } - } - - public int getLength() { - if (wide()) { - return 6; - } else { - return 3; // includes wide byte - } - } - - public String toString(boolean verbose) { - return super.toString(verbose) + " " + c; - } - - public final int getIncrement() { - return c; - } - - public boolean equals(Object other) { - if (!(other instanceof IINC)) { - return false; - } - IINC o = (IINC) other; - return /* o.opcode == opcode && */o.lvar == lvar && o.c == c; - } - - public int hashCode() { - return opcode * 37 + lvar * (c + 17); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java deleted file mode 100644 index b545f4d37..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -/** - * INVOKEINTERFACE - Invoke interface method - * - *
- * Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
- * 
- * - * @version $Id: INVOKEINTERFACE.java,v 1.4 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public final class INVOKEINTERFACE extends InvokeInstruction { - private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2 - - public INVOKEINTERFACE(int index, int nargs, int zerobyte) { - super(Constants.INVOKEINTERFACE, index); - - if (nargs < 1) { - throw new ClassGenException("Number of arguments must be > 0 " + nargs); - } - - this.nargs = nargs; - } - - /** - * Dump instruction as byte code to stream out. - * - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - out.writeByte(nargs); - out.writeByte(0); - } - - /** - * The count argument according to the Java Language Specification, Second Edition. - */ - public int getCount() { - return nargs; - } - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - return super.toString(cp) + " " + nargs; - } - - public int consumeStack(ConstantPool cpg) { // nargs is given in byte-code - return nargs; // nargs includes this reference - } - - public boolean equals(Object other) { - if (!(other instanceof INVOKEINTERFACE)) { - return false; - } - INVOKEINTERFACE o = (INVOKEINTERFACE) other; - return o.opcode == opcode && o.index == index && o.nargs == nargs; - } - - public int hashCode() { - return opcode * 37 + index * (nargs + 17); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstVisitor.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstVisitor.java deleted file mode 100644 index 424ff4a66..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstVisitor.java +++ /dev/null @@ -1,247 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Interface implementing the Visitor pattern programming style. - * I.e., a class that implements this interface can handle all types of - * instructions with the properly typed methods just by calling the accept() - * method. - * - * @version $Id: InstVisitor.java,v 1.2 2008/05/28 23:52:59 aclement Exp $ - * @author M. Dahm - */ -public interface InstVisitor { - public void visitStackInstruction(Instruction obj); - public void visitLocalVariableInstruction(InstructionLV obj); - public void visitBranchInstruction(InstructionBranch obj); - public void visitLoadClass(Instruction obj); - public void visitFieldInstruction(Instruction obj); - public void visitIfInstruction(Instruction obj); - public void visitConversionInstruction(Instruction obj); - public void visitPopInstruction(Instruction obj); - public void visitStoreInstruction(Instruction obj); - public void visitTypedInstruction(Instruction obj); - public void visitSelect(InstructionSelect obj); - public void visitJsrInstruction(InstructionBranch obj); - public void visitGotoInstruction(Instruction obj); - public void visitUnconditionalBranch(Instruction obj); - public void visitPushInstruction(Instruction obj); - public void visitArithmeticInstruction(Instruction obj); - public void visitCPInstruction(Instruction obj); - public void visitInvokeInstruction(InvokeInstruction obj); - public void visitArrayInstruction(Instruction obj); - public void visitAllocationInstruction(Instruction obj); - public void visitReturnInstruction(Instruction obj); - public void visitFieldOrMethod(Instruction obj); - public void visitConstantPushInstruction(Instruction obj); - public void visitExceptionThrower(Instruction obj); - public void visitLoadInstruction(Instruction obj); - public void visitVariableLengthInstruction(Instruction obj); - public void visitStackProducer(Instruction obj); - public void visitStackConsumer(Instruction obj); - public void visitACONST_NULL(Instruction obj); - public void visitGETSTATIC(FieldInstruction obj); - public void visitIF_ICMPLT(Instruction obj); - public void visitMONITOREXIT(Instruction obj); - public void visitIFLT(Instruction obj); - public void visitLSTORE(Instruction obj); - public void visitPOP2(Instruction obj); - public void visitBASTORE(Instruction obj); - public void visitISTORE(Instruction obj); - public void visitCHECKCAST(Instruction obj); - public void visitFCMPG(Instruction obj); - public void visitI2F(Instruction obj); - public void visitATHROW(Instruction obj); - public void visitDCMPL(Instruction obj); - public void visitARRAYLENGTH(Instruction obj); - public void visitDUP(Instruction obj); - public void visitINVOKESTATIC(InvokeInstruction obj); - public void visitLCONST(Instruction obj); - public void visitDREM(Instruction obj); - public void visitIFGE(Instruction obj); - public void visitCALOAD(Instruction obj); - public void visitLASTORE(Instruction obj); - public void visitI2D(Instruction obj); - public void visitDADD(Instruction obj); - public void visitINVOKESPECIAL(InvokeInstruction obj); - public void visitIAND(Instruction obj); - public void visitPUTFIELD(FieldInstruction obj); - public void visitILOAD(Instruction obj); - public void visitDLOAD(Instruction obj); - public void visitDCONST(Instruction obj); - public void visitNEW(Instruction obj); - public void visitIFNULL(Instruction obj); - public void visitLSUB(Instruction obj); - public void visitL2I(Instruction obj); - public void visitISHR(Instruction obj); - public void visitTABLESWITCH(TABLESWITCH obj); - public void visitIINC(IINC obj); - public void visitDRETURN(Instruction obj); - public void visitFSTORE(Instruction obj); - public void visitDASTORE(Instruction obj); - public void visitIALOAD(Instruction obj); - public void visitDDIV(Instruction obj); - public void visitIF_ICMPGE(Instruction obj); - public void visitLAND(Instruction obj); - public void visitIDIV(Instruction obj); - public void visitLOR(Instruction obj); - public void visitCASTORE(Instruction obj); - public void visitFREM(Instruction obj); - public void visitLDC(Instruction obj); - public void visitBIPUSH(Instruction obj); - public void visitDSTORE(Instruction obj); - public void visitF2L(Instruction obj); - public void visitFMUL(Instruction obj); - public void visitLLOAD(Instruction obj); - public void visitJSR(InstructionBranch obj); - public void visitFSUB(Instruction obj); - public void visitSASTORE(Instruction obj); - public void visitALOAD(Instruction obj); - public void visitDUP2_X2(Instruction obj); - public void visitRETURN(Instruction obj); - public void visitDALOAD(Instruction obj); - public void visitSIPUSH(Instruction obj); - public void visitDSUB(Instruction obj); - public void visitL2F(Instruction obj); - public void visitIF_ICMPGT(Instruction obj); - public void visitF2D(Instruction obj); - public void visitI2L(Instruction obj); - public void visitIF_ACMPNE(Instruction obj); - public void visitPOP(Instruction obj); - public void visitI2S(Instruction obj); - public void visitIFEQ(Instruction obj); - public void visitSWAP(Instruction obj); - public void visitIOR(Instruction obj); - public void visitIREM(Instruction obj); - public void visitIASTORE(Instruction obj); - public void visitNEWARRAY(Instruction obj); - public void visitINVOKEINTERFACE(INVOKEINTERFACE obj); - public void visitINEG(Instruction obj); - public void visitLCMP(Instruction obj); - public void visitJSR_W(InstructionBranch obj); - public void visitMULTIANEWARRAY(MULTIANEWARRAY obj); - public void visitDUP_X2(Instruction obj); - public void visitSALOAD(Instruction obj); - public void visitIFNONNULL(Instruction obj); - public void visitDMUL(Instruction obj); - public void visitIFNE(Instruction obj); - public void visitIF_ICMPLE(Instruction obj); - public void visitLDC2_W(Instruction obj); - public void visitGETFIELD(FieldInstruction obj); - public void visitLADD(Instruction obj); - public void visitNOP(Instruction obj); - public void visitFALOAD(Instruction obj); - public void visitINSTANCEOF(Instruction obj); - public void visitIFLE(Instruction obj); - public void visitLXOR(Instruction obj); - public void visitLRETURN(Instruction obj); - public void visitFCONST(Instruction obj); - public void visitIUSHR(Instruction obj); - public void visitBALOAD(Instruction obj); - public void visitDUP2(Instruction obj); - public void visitIF_ACMPEQ(Instruction obj); - public void visitIMPDEP1(Instruction obj); - public void visitMONITORENTER(Instruction obj); - public void visitLSHL(Instruction obj); - public void visitDCMPG(Instruction obj); - public void visitD2L(Instruction obj); - public void visitIMPDEP2(Instruction obj); - public void visitL2D(Instruction obj); - public void visitRET(RET obj); - public void visitIFGT(Instruction obj); - public void visitIXOR(Instruction obj); - public void visitINVOKEVIRTUAL(InvokeInstruction obj); - public void visitFASTORE(Instruction obj); - public void visitIRETURN(Instruction obj); - public void visitIF_ICMPNE(Instruction obj); - public void visitFLOAD(Instruction obj); - public void visitLDIV(Instruction obj); - public void visitPUTSTATIC(FieldInstruction obj); - public void visitAALOAD(Instruction obj); - public void visitD2I(Instruction obj); - public void visitIF_ICMPEQ(Instruction obj); - public void visitAASTORE(Instruction obj); - public void visitARETURN(Instruction obj); - public void visitDUP2_X1(Instruction obj); - public void visitFNEG(Instruction obj); - public void visitGOTO_W(Instruction obj); - public void visitD2F(Instruction obj); - public void visitGOTO(Instruction obj); - public void visitISUB(Instruction obj); - public void visitF2I(Instruction obj); - public void visitDNEG(Instruction obj); - public void visitICONST(Instruction obj); - public void visitFDIV(Instruction obj); - public void visitI2B(Instruction obj); - public void visitLNEG(Instruction obj); - public void visitLREM(Instruction obj); - public void visitIMUL(Instruction obj); - public void visitIADD(Instruction obj); - public void visitLSHR(Instruction obj); - public void visitLOOKUPSWITCH(LOOKUPSWITCH obj); - public void visitDUP_X1(Instruction obj); - public void visitFCMPL(Instruction obj); - public void visitI2C(Instruction obj); - public void visitLMUL(Instruction obj); - public void visitLUSHR(Instruction obj); - public void visitISHL(Instruction obj); - public void visitLALOAD(Instruction obj); - public void visitASTORE(Instruction obj); - public void visitANEWARRAY(Instruction obj); - public void visitFRETURN(Instruction obj); - public void visitFADD(Instruction obj); - public void visitBREAKPOINT(Instruction obj); -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java deleted file mode 100644 index 113be06ee..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java +++ /dev/null @@ -1,454 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.Serializable; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.util.ByteSequence; - -/** - * Abstract super class for all Java byte codes. - * - * @version $Id: Instruction.java,v 1.10 2011/04/05 15:15:33 aclement Exp $ - * @author M. Dahm - */ -public class Instruction implements Cloneable, Serializable, Constants { - public short opcode = -1; - - public Instruction(short opcode) { - this.opcode = opcode; - } - - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - } - - public String getName() { - return Constants.OPCODE_NAMES[opcode]; - } - - /** - * Use with caution, since 'BranchInstruction's have a 'target' reference which is not copied correctly (only basic types are). - * This also applies for 'Select' instructions with their multiple branch targets. - * - * @return (shallow) copy of an instruction - */ - // GET RID OF THIS - make it throw an exception and track the callers - final public Instruction copy() { - // if overridden correctly can just return 'this' here - if (InstructionConstants.INSTRUCTIONS[opcode] != null) { // immutable instructions do not need copying - return this; - } else { - Instruction i = null; - try {// OPTIMIZE is clone the right thing to do here? it is horrible - i = (Instruction) clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - } - return i; - } - } - - /** - * Read an instruction bytecode from an input stream and return the appropriate object. - * - * @param file file to read from - * @return instruction object being read - */ - public static final Instruction readInstruction(ByteSequence bytes) throws IOException { - boolean wide = false; - short opcode = (short) bytes.readUnsignedByte(); - - if (opcode == Constants.WIDE) { - wide = true; - opcode = (short) bytes.readUnsignedByte(); - } - - Instruction constantInstruction = InstructionConstants.INSTRUCTIONS[opcode]; - - if (constantInstruction != null) { - return constantInstruction; - } - - Instruction obj = null; - try { - switch (opcode) { - case Constants.BIPUSH: - obj = new InstructionByte(Constants.BIPUSH, bytes.readByte()); - break; - case Constants.SIPUSH: - obj = new InstructionShort(Constants.SIPUSH, bytes.readShort()); - break; - case Constants.LDC: - obj = new InstructionCP(Constants.LDC, bytes.readUnsignedByte()); - break; - case Constants.LDC_W: - case Constants.LDC2_W: - obj = new InstructionCP(opcode, bytes.readUnsignedShort()); - break; - case Constants.ILOAD: - case Constants.LLOAD: - case Constants.FLOAD: - case Constants.DLOAD: - case Constants.ALOAD: - case Constants.ISTORE: - case Constants.LSTORE: - case Constants.FSTORE: - case Constants.DSTORE: - case Constants.ASTORE: - obj = new InstructionLV(opcode, wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte()); - break; - case Constants.IINC: - obj = new IINC(wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte(), wide ? bytes.readShort() - : bytes.readByte(), wide); - break; - case Constants.IFNULL: - case Constants.IFNONNULL: - case Constants.IFEQ: - case Constants.IFNE: - case Constants.IFLT: - case Constants.IFGE: - case Constants.IFGT: - case Constants.IFLE: - case Constants.IF_ICMPEQ: - case Constants.IF_ICMPNE: - case Constants.IF_ICMPLT: - case Constants.IF_ICMPGE: - case Constants.IF_ICMPGT: - case Constants.IF_ICMPLE: - case Constants.IF_ACMPEQ: - case Constants.IF_ACMPNE: - case Constants.GOTO: - case Constants.JSR: - obj = new InstructionBranch(opcode, bytes.readShort()); - break; - case Constants.GOTO_W: - case Constants.JSR_W: - obj = new InstructionBranch(opcode, bytes.readInt()); - break; - case Constants.TABLESWITCH: - obj = new TABLESWITCH(bytes); - break; - case Constants.LOOKUPSWITCH: - obj = new LOOKUPSWITCH(bytes); - break; - case Constants.RET: - obj = new RET(wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte(), wide); - break; - case Constants.NEW: - obj = new InstructionCP(Constants.NEW, bytes.readUnsignedShort()); - break; - case Constants.GETSTATIC: - case Constants.PUTSTATIC: - case Constants.GETFIELD: - case Constants.PUTFIELD: - obj = new FieldInstruction(opcode, bytes.readUnsignedShort()); - break; - case Constants.INVOKEVIRTUAL: - case Constants.INVOKESPECIAL: - case Constants.INVOKESTATIC: - obj = new InvokeInstruction(opcode, bytes.readUnsignedShort()); - break; - case Constants.INVOKEINTERFACE: - obj = new INVOKEINTERFACE(bytes.readUnsignedShort(), bytes.readUnsignedByte(), bytes.readByte()); - break; - case Constants.INVOKEDYNAMIC: - obj = new InvokeDynamic(bytes.readUnsignedShort(),bytes.readUnsignedShort()); - break; - case Constants.NEWARRAY: - obj = new InstructionByte(Constants.NEWARRAY, bytes.readByte()); - break; - case Constants.ANEWARRAY: - case Constants.CHECKCAST: - obj = new InstructionCP(opcode, bytes.readUnsignedShort()); - break; - case Constants.INSTANCEOF: - obj = new InstructionCP(Constants.INSTANCEOF, bytes.readUnsignedShort()); - break; - case Constants.MULTIANEWARRAY: - obj = new MULTIANEWARRAY(bytes.readUnsignedShort(), bytes.readByte()); - break; - default: - throw new ClassGenException("Illegal opcode detected"); - } - } catch (ClassGenException e) { - throw e; - } catch (Exception e) { - throw new ClassGenException(e.toString()); - } - - return obj; - } - - /** - * @return Number of words consumed from stack by this instruction, or Constants.UNPREDICTABLE, if this can not be computed - * statically - */ - public int consumeStack(ConstantPool cpg) { - return Constants.CONSUME_STACK[opcode]; - } - - /** - * @return Number of words produced onto stack by this instruction, or Constants.UNPREDICTABLE, if this can not be computed - * statically - */ - public int produceStack(ConstantPool cpg) { - return Constants.stackEntriesProduced[opcode]; - } - - public short getOpcode() { - return opcode; - } - - public int getLength() { - // if it is zero, it should have been provided by an overriding implementation of getLength() - int len = Constants.iLen[opcode]; - assert len != 0; - // if (len == 0) { - // throw new IllegalStateException("Length not right for " + getName().toUpperCase()); - // } - return len; - } - - /** Some instructions may be reused, so don't do anything by default */ - void dispose() { - } - - @Override - public boolean equals(Object other) { - if (this.getClass() != Instruction.class) { - throw new RuntimeException("NO WAY " + this.getClass()); - } - if (!(other instanceof Instruction)) { - return false; - } - return ((Instruction) other).opcode == opcode; - - // IMPLEMENT EQUALS AND HASHCODE IN THE SUBTYPES! - - // Instruction i1 = this; - // Instruction i2 = (Instruction) that; - // if (i1.opcode == i2.opcode) { - // if (i1.isConstantInstruction()) { - // return i1.getValue().equals(i2.getValue()); - // } else if (i1.isIndexedInstruction()) { - // return i1.getIndex() == i2.getIndex(); - // } else if (i1.opcode == Constants.NEWARRAY) { - // return ((InstructionByte) i1).getTypecode() == ((InstructionByte) i2).getTypecode(); - // } else { - // return true; - // } - // } - // - // return false; - } - - @Override - public int hashCode() { - if (this.getClass() != Instruction.class) { - throw new RuntimeException("NO WAY " + this.getClass()); - } - return opcode * 37; - // int result = 17 + opcode * 37; - // if (isConstantInstruction()) { - // result = 37 * getValue().hashCode() + result; - // } else if (isIndexedInstruction()) { - // result = 37 * getIndex() + result; - // } else if (opcode == Constants.NEWARRAY) { - // result = 37 * ((InstructionByte) this).getTypecode() + result; - // } - // return result; - } - - public Type getType() { - return getType(null); - } - - public Type getType(ConstantPool cp) { - // if (types[opcode]==null) throw new RuntimeException(getName()+" is not a typed instruction"); - Type t = Constants.types[opcode]; - if (t != null) { - return t; - } - throw new RuntimeException("Do not know type for instruction " + getName() + "(" + opcode + ")"); - } - - public Number getValue() { - assert (instFlags[opcode] & CONSTANT_INST) == 0; - // if ((instFlags[opcode] & CONSTANT_INST) == 0) { - // throw new RuntimeException(getName() + " is not a constant instruction"); - // } - switch (opcode) { - case ICONST_M1: - case ICONST_0: - case ICONST_1: - case ICONST_2: - case ICONST_3: - case ICONST_4: - case ICONST_5: - return new Integer(opcode - ICONST_0); - default: - throw new IllegalStateException("Not implemented yet for " + getName()); - } - } - - public int getIndex() { - return -1; - } - - public void setIndex(int i) { - throw new IllegalStateException("Shouldnt be asking " + getName().toUpperCase()); - } - - public Object getValue(ConstantPool cpg) { - throw new IllegalStateException("Shouldnt be asking " + getName().toUpperCase()); - } - - public boolean isLoadInstruction() { - return (Constants.instFlags[opcode] & LOAD_INST) != 0; - } - - // remove these from here, leave them in the InstructionLV - public boolean isASTORE() { - return false; - } - - public boolean isALOAD() { - return false; - } - - public boolean isStoreInstruction() { - return (Constants.instFlags[opcode] & STORE_INST) != 0; - } - - // public boolean containsTarget(InstructionHandle ih) { - // throw new IllegalStateException("Dont ask!!"); - // } - - public boolean isJsrInstruction() { - return (Constants.instFlags[opcode] & JSR_INSTRUCTION) != 0; - } - - public boolean isConstantInstruction() { - return (Constants.instFlags[opcode] & CONSTANT_INST) != 0; - } - - public boolean isConstantPoolInstruction() { - return (Constants.instFlags[opcode] & CP_INST) != 0; - } - - public boolean isStackProducer() { - return Constants.stackEntriesProduced[opcode] != 0; - } - - public boolean isStackConsumer() { - return Constants.CONSUME_STACK[opcode] != 0; - } - - public boolean isIndexedInstruction() { - return (Constants.instFlags[opcode] & INDEXED) != 0; - } - - public boolean isArrayCreationInstruction() { - return opcode == NEWARRAY || opcode == ANEWARRAY || opcode == MULTIANEWARRAY; - } - - public ObjectType getLoadClassType(ConstantPool cpg) { - assert (Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0; - // if ((Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0) { - // throw new IllegalStateException("This opcode " + opcode + " does not have the property " - // + Long.toHexString(Constants.LOADCLASS_INST)); - // } - Type t = getType(cpg); - if (t instanceof ArrayType) { - t = ((ArrayType) t).getBasicType(); - } - return t instanceof ObjectType ? (ObjectType) t : null; - } - - public boolean isReturnInstruction() { - return (Constants.instFlags[opcode] & RET_INST) != 0; - } - - // public boolean isGoto() { - // return opcode == GOTO || opcode == GOTO_W; - // } - - public boolean isLocalVariableInstruction() { - return (Constants.instFlags[opcode] & LV_INST) != 0; - } - - /** - * Long output format: 'name of opcode' "[" 'opcode number' "]" "(" 'length of instruction' ")" - */ - public String toString(boolean verbose) { - if (verbose) { - StringBuffer sb = new StringBuffer(); - sb.append(getName()).append("[").append(opcode).append("](size").append(Constants.iLen[opcode]).append(")"); - return sb.toString(); - } else { - return getName(); - } - } - - @Override - public String toString() { - return toString(true); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java deleted file mode 100644 index 53fed8e52..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java +++ /dev/null @@ -1,338 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.generic; - -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -/** - * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch instructions may have a variable length, namely - * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH. A branch instruction may be talking in terms of absolute destination (targetIndex) or - * about an instruction it doesnt yet know the position if (targetInstruction). targetInstruction (if set) overrides targetIndex - * - * @see InstructionList - * @version $Id: InstructionBranch.java,v 1.6 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public class InstructionBranch extends Instruction implements InstructionTargeter { - private static final int UNSET = -1; - - protected int targetIndex = UNSET; // Branch target relative to this - // instruction - protected InstructionHandle targetInstruction; // Target object in - // instruction list - protected int positionOfThisInstruction; // for calculating relative branch - - // destinations! - - public InstructionBranch(short opcode, InstructionHandle target) { - super(opcode); - setTarget(target); - } - - public InstructionBranch(short opcode, int index) { - super(opcode); - this.targetIndex = index; - } - - public InstructionBranch(short opcode) { - super(opcode); - } - - public void dump(DataOutputStream out) throws IOException { - int target = getTargetOffset(); - - if (Math.abs(target) >= 32767 && opcode != GOTO_W && opcode != JSR_W) { - throw new ClassGenException("Branch target offset too large for short. Instruction: " + getName().toUpperCase() + "(" - + opcode + ")"); - } - - out.writeByte(opcode); - - switch (opcode) { - - case GOTO_W: - case JSR_W: - out.writeInt(target); - break; - - case IF_ACMPEQ: - case IF_ACMPNE: - case IF_ICMPEQ: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - case IF_ICMPLT: - case IF_ICMPNE: - case IFEQ: - case IFLE: - case IFLT: - case IFGT: - case IFNE: - case IFGE: - case IFNULL: - case IFNONNULL: - case GOTO: - case JSR: - out.writeShort(target); - break; - - default: - throw new IllegalStateException("Don't know how to write out " + getName().toUpperCase()); - } - - } - - protected int getTargetOffset() { - if (targetInstruction == null && targetIndex == UNSET) { - throw new ClassGenException("Target of " + super.toString(true) + " is unknown"); - } - - if (targetInstruction == null) { - return targetIndex; - } else { - return targetInstruction.getPosition() - positionOfThisInstruction; - } - } - - /** - * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length - * instructions `setPositions' performs multiple passes over the instruction list to calculate the correct (byte) positions and - * offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition(int offset, int max_offset) { - int i = getTargetOffset(); - - positionOfThisInstruction += offset; - - if (Math.abs(i) >= 32767 - max_offset && opcode != JSR_W && opcode != GOTO_W) { - // Try and promote it to wide if we can - if (opcode == JSR || opcode == GOTO) { - if (opcode == JSR) { - opcode = JSR_W; - } else { - opcode = GOTO_W; - } - return 2; // instruction jump destination grows from a short to a long - } else { - throw new IllegalStateException("Unable to pack method, jump (with opcode=" + opcode + ") is too far: " - + Math.abs(i)); - } - } - - return 0; - } - - /** - * Long output format: - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - String s = super.toString(verbose); - String t = "null"; - - if (verbose) { - if (targetInstruction != null) { - if (targetInstruction.getInstruction() == this) { - t = ""; - } else if (targetInstruction.getInstruction() == null) { - t = ""; - } else { - t = targetInstruction.getInstruction().toString(false); - } - } - } else { - if (targetInstruction != null) { - targetIndex = getTargetOffset(); - t = "" + (targetIndex + positionOfThisInstruction); - } - } - - return s + " -> " + t; - } - - /** - * @return target offset in byte code - */ - public final int getIndex() { - return targetIndex; - } - - /** - * @return target of branch instruction - */ - public InstructionHandle getTarget() { - return targetInstruction; - } - - /** - * Set branch target - * - * @param target branch target - */ - public void setTarget(InstructionHandle target) { - notifyTarget(this.targetInstruction, target, this); - this.targetInstruction = target; - } - - /** - * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen - */ - static final void notifyTarget(InstructionHandle oldHandle, InstructionHandle newHandle, InstructionTargeter t) { - if (oldHandle != null) { - oldHandle.removeTargeter(t); - } - if (newHandle != null) { - newHandle.addTargeter(t); - } - } - - /** - * Update the target destination for this instruction. If an oldHandle is provided it is checked to verify that is where the - * target currently points to before changing it. - * - * @param oldHandle old target - * @param newHandle new target - */ - public void updateTarget(InstructionHandle oldHandle, InstructionHandle newHandle) { - if (targetInstruction == oldHandle) { - setTarget(newHandle); - } else { - throw new ClassGenException("Not targeting " + oldHandle + ", but " + targetInstruction); - } - } - - /** - * @return true, if ih is target of this instruction - */ - public boolean containsTarget(InstructionHandle ih) { - return targetInstruction == ih; - } - - /** - * Inform target that it's not targeted anymore. - */ - void dispose() { - setTarget(null); - targetIndex = -1; - positionOfThisInstruction = -1; - } - - public Type getType(ConstantPool cp) { - if ((Constants.instFlags[opcode] & Constants.JSR_INSTRUCTION) != 0) { - return new ReturnaddressType(physicalSuccessor()); - } - return super.getType(cp); - } - - /** - * Returns an InstructionHandle to the physical successor of this JsrInstruction. For this method to work, this - * JsrInstruction object must not be shared between multiple InstructionHandle objects! Formally, there must not be - * InstructionHandle objects i, j where i != j and i.getInstruction() == this == j.getInstruction(). - * - * @return an InstructionHandle to the "next" instruction that will be executed when RETurned from a subroutine. - */ - public InstructionHandle physicalSuccessor() { - InstructionHandle ih = this.targetInstruction; - - // Rewind! - while (ih.getPrev() != null) { - ih = ih.getPrev(); - } - - // Find the handle for "this" JsrInstruction object. - while (ih.getInstruction() != this) { - ih = ih.getNext(); - } - - InstructionHandle toThis = ih; - - while (ih != null) { - ih = ih.getNext(); - if (ih != null && ih.getInstruction() == this) { - throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction."); - } - } - - // Return the physical successor - return toThis.getNext(); - } - - public boolean isIfInstruction() { - return (Constants.instFlags[opcode] & Constants.IF_INST) != 0; - } - - /** - * Only equal if they are the same branch instruction - otherwise too risky as the targets may only temporarily be pointing at - * the same destination. - */ - public boolean equals(Object other) { - return this == other; - } - - public int hashCode() { - int result = 17; - result = opcode * 37 + result; - return result; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java deleted file mode 100644 index 5ba8a9abe..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.generic; - -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Instruction that needs one byte - */ -public class InstructionByte extends Instruction { - private final byte theByte; - - public InstructionByte(short opcode, byte b) { - super(opcode); - this.theByte = b; - } - - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeByte(theByte); - } - - public String toString(boolean verbose) { - return super.toString(verbose) + " " + theByte; - } - - /** - * For supporting NEWARRAY - * - * @return typecode of the array - */ - public final byte getTypecode() { - return theByte; - } - - /** - * For supporting NEWARRAY - * - * @return type of the array - */ - public final Type getType() { - return new ArrayType(BasicType.getType(theByte), 1); - } - - public boolean equals(Object other) { - if (!(other instanceof InstructionByte)) { - return false; - } - InstructionByte o = (InstructionByte) other; - return o.opcode == opcode && o.theByte == theByte; - } - - public int hashCode() { - return opcode * 37 + theByte; - } -} \ No newline at end of file diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCLV.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCLV.java deleted file mode 100644 index 85ae588e5..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCLV.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/** - * A small subclass of the local variable accessing instruction class InstructionLV - this subclass does - * not allow the index to be altered. - */ -public class InstructionCLV extends InstructionLV { - - public InstructionCLV(short opcode) { - super(opcode); - } - - public InstructionCLV(short opcode,int localVariableIndex) { - super(opcode,localVariableIndex); - } - - public void setIndex(int localVariableIndex) { - if (localVariableIndex!=getIndex()) { - throw new ClassGenException("Do not attempt to modify the index to '"+localVariableIndex+"' for this constant instruction: "+this); - } - } - - public boolean canSetIndex() { - return false; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java deleted file mode 100644 index 09222d6a4..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Constant; -import org.aspectj.apache.bcel.classfile.ConstantClass; -import org.aspectj.apache.bcel.classfile.ConstantDouble; -import org.aspectj.apache.bcel.classfile.ConstantFloat; -import org.aspectj.apache.bcel.classfile.ConstantInteger; -import org.aspectj.apache.bcel.classfile.ConstantLong; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ConstantString; -import org.aspectj.apache.bcel.classfile.ConstantUtf8; - -/** - * Class for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc. - * - * @version $Id: InstructionCP.java,v 1.6 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public class InstructionCP extends Instruction { - protected int index; - - public InstructionCP(short opcode, int index) { - super(opcode); - this.index = index; - } - - @Override - public void dump(DataOutputStream out) throws IOException { - if (opcode == LDC_W && index < 256) { - out.writeByte(LDC); - out.writeByte(index); - } else { - out.writeByte(opcode); - if (Constants.iLen[opcode] == 2) { - if (index > 255) { - throw new IllegalStateException(); - } - out.writeByte(index); - } else { - out.writeShort(index); - } - } - } - - @Override - public int getLength() { - if (opcode == LDC_W && index < 256) { - return 2; - } else { - return super.getLength(); - } - } - - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" "("<length of instruction>")" "<"< constant pool - * index>">" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - @Override - public String toString(boolean verbose) { - return super.toString(verbose) + " " + index; - } - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - Constant c = cp.getConstant(index); - String str = cp.constantToString(c); - - if (c instanceof ConstantClass) { - str = str.replace('.', '/'); - } - - return org.aspectj.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + str; - } - - /** - * @return index in constant pool referred by this instruction. - */ - @Override - public final int getIndex() { - return index; - } - - @Override - public void setIndex(int index) { - this.index = index; - if (this.index > 255 && opcode == LDC) { - // promote it - opcode = LDC_W; - } - } - - @Override - public Type getType(ConstantPool cpg) { - switch (cpg.getConstant(index).getTag()) { - case CONSTANT_String: - return Type.STRING; - case CONSTANT_Float: - return Type.FLOAT; - case CONSTANT_Integer: - return Type.INT; - case CONSTANT_Long: - return Type.LONG; - case CONSTANT_Double: - return Type.DOUBLE; - case CONSTANT_Class: - String name = cpg.getConstantString_CONSTANTClass(index); - // ConstantPool cp = cpg.getConstantPool(); - // String name = cp.getConstantString(index, CONSTANT_Class); - if (!name.startsWith("[")) { - StringBuffer sb = new StringBuffer(); - sb.append("L").append(name).append(";"); - return Type.getType(sb.toString()); - } else { - return Type.getType(name); - } - default: - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } - - @Override - public Object getValue(ConstantPool constantPool) { - Constant constant = constantPool.getConstant(index); - - switch (constant.getTag()) { - case Constants.CONSTANT_String: - int i = ((ConstantString) constant).getStringIndex(); - constant = constantPool.getConstant(i); - return ((ConstantUtf8) constant).getValue(); - - case Constants.CONSTANT_Float: - return ((ConstantFloat) constant).getValue(); - - case Constants.CONSTANT_Integer: - return ((ConstantInteger) constant).getValue(); - - case Constants.CONSTANT_Long: - return ((ConstantLong) constant).getValue(); - - case Constants.CONSTANT_Double: - return ((ConstantDouble) constant).getValue(); - default: - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } - - public boolean equals(Object other) { - if (!(other instanceof InstructionCP)) { - return false; - } - InstructionCP o = (InstructionCP) other; - return o.opcode == opcode && o.index == index; - } - - public int hashCode() { - return opcode * 37 + index; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionConstants.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionConstants.java deleted file mode 100644 index e6f884793..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionConstants.java +++ /dev/null @@ -1,379 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.Constants; - -/** - * This interface contains shareable instruction objects. - * - * In order to save memory you can use some instructions multiply, - * since they have an immutable state and are directly derived from - * Instruction. I.e. they have no instance fields that could be - * changed. Since some of these instructions like ICONST_0 occur - * very frequently this can save a lot of time and space. This - * feature is an adaptation of the FlyWeight design pattern, we - * just use an array instead of a factory. - * - * The Instructions can also accessed directly under their names, so - * it's possible to write il.append(Instruction.ICONST_0); - * - * @version $Id: InstructionConstants.java,v 1.4 2008/08/13 18:18:22 aclement Exp $ - * @author M. Dahm - */ -public interface InstructionConstants { - /** Predefined instruction objects - */ - public static final Instruction NOP = new Instruction(Constants.NOP); - public static final Instruction ACONST_NULL = new Instruction(Constants.ACONST_NULL); - public static final Instruction ICONST_M1 = new Instruction(Constants.ICONST_M1); - public static final Instruction ICONST_0 = new Instruction(Constants.ICONST_0); - public static final Instruction ICONST_1 = new Instruction(Constants.ICONST_1); - public static final Instruction ICONST_2 = new Instruction(Constants.ICONST_2); - public static final Instruction ICONST_3 = new Instruction(Constants.ICONST_3); - public static final Instruction ICONST_4 = new Instruction(Constants.ICONST_4); - public static final Instruction ICONST_5 = new Instruction(Constants.ICONST_5); - public static final Instruction LCONST_0 = new Instruction(Constants.LCONST_0); - public static final Instruction LCONST_1 = new Instruction(Constants.LCONST_1); - public static final Instruction FCONST_0 = new Instruction(Constants.FCONST_0); - public static final Instruction FCONST_1 = new Instruction(Constants.FCONST_1); - public static final Instruction FCONST_2 = new Instruction(Constants.FCONST_2); - public static final Instruction DCONST_0 = new Instruction(Constants.DCONST_0); - public static final Instruction DCONST_1 = new Instruction(Constants.DCONST_1); - public static final Instruction IALOAD = new Instruction(Constants.IALOAD); - public static final Instruction LALOAD = new Instruction(Constants.LALOAD); - public static final Instruction FALOAD = new Instruction(Constants.FALOAD); - public static final Instruction DALOAD = new Instruction(Constants.DALOAD); - public static final Instruction AALOAD = new Instruction(Constants.AALOAD); - public static final Instruction BALOAD = new Instruction(Constants.BALOAD); - public static final Instruction CALOAD = new Instruction(Constants.CALOAD); - public static final Instruction SALOAD = new Instruction(Constants.SALOAD); - public static final Instruction IASTORE = new Instruction(Constants.IASTORE); - public static final Instruction LASTORE = new Instruction(Constants.LASTORE); - public static final Instruction FASTORE = new Instruction(Constants.FASTORE); - public static final Instruction DASTORE = new Instruction(Constants.DASTORE); - public static final Instruction AASTORE = new Instruction(Constants.AASTORE); - public static final Instruction BASTORE = new Instruction(Constants.BASTORE); - public static final Instruction CASTORE = new Instruction(Constants.CASTORE); - public static final Instruction SASTORE = new Instruction(Constants.SASTORE); - public static final Instruction POP = new Instruction(Constants.POP); - public static final Instruction POP2 = new Instruction(Constants.POP2); - public static final Instruction DUP = new Instruction(Constants.DUP); - public static final Instruction DUP_X1 = new Instruction(Constants.DUP_X1); - public static final Instruction DUP_X2 = new Instruction(Constants.DUP_X2); - public static final Instruction DUP2 = new Instruction(Constants.DUP2); - public static final Instruction DUP2_X1 = new Instruction(Constants.DUP2_X1); - public static final Instruction DUP2_X2 = new Instruction(Constants.DUP2_X2); - public static final Instruction SWAP = new Instruction(Constants.SWAP); - public static final Instruction IADD = new Instruction(Constants.IADD); - public static final Instruction LADD = new Instruction(Constants.LADD); - public static final Instruction FADD = new Instruction(Constants.FADD); - public static final Instruction DADD = new Instruction(Constants.DADD); - public static final Instruction ISUB = new Instruction(Constants.ISUB); - public static final Instruction LSUB = new Instruction(Constants.LSUB); - public static final Instruction FSUB = new Instruction(Constants.FSUB); - public static final Instruction DSUB = new Instruction(Constants.DSUB); - public static final Instruction IMUL = new Instruction(Constants.IMUL); - public static final Instruction LMUL = new Instruction(Constants.LMUL); - public static final Instruction FMUL = new Instruction(Constants.FMUL); - public static final Instruction DMUL = new Instruction(Constants.DMUL); - public static final Instruction IDIV = new Instruction(Constants.IDIV); - public static final Instruction LDIV = new Instruction(Constants.LDIV); - public static final Instruction FDIV = new Instruction(Constants.FDIV); - public static final Instruction DDIV = new Instruction(Constants.DDIV); - public static final Instruction IREM = new Instruction(Constants.IREM); - public static final Instruction LREM = new Instruction(Constants.LREM); - public static final Instruction FREM = new Instruction(Constants.FREM); - public static final Instruction DREM = new Instruction(Constants.DREM); - public static final Instruction INEG = new Instruction(Constants.INEG); - public static final Instruction LNEG = new Instruction(Constants.LNEG); - public static final Instruction FNEG = new Instruction(Constants.FNEG); - public static final Instruction DNEG = new Instruction(Constants.DNEG); - public static final Instruction ISHL = new Instruction(Constants.ISHL); - public static final Instruction LSHL = new Instruction(Constants.LSHL); - public static final Instruction ISHR = new Instruction(Constants.ISHR); - public static final Instruction LSHR = new Instruction(Constants.LSHR); - public static final Instruction IUSHR = new Instruction(Constants.IUSHR); - public static final Instruction LUSHR = new Instruction(Constants.LUSHR); - public static final Instruction IAND = new Instruction(Constants.IAND); - public static final Instruction LAND = new Instruction(Constants.LAND); - public static final Instruction IOR = new Instruction(Constants.IOR); - public static final Instruction LOR = new Instruction(Constants.LOR); - public static final Instruction IXOR = new Instruction(Constants.IXOR); - public static final Instruction LXOR = new Instruction(Constants.LXOR); - public static final Instruction I2L = new Instruction(Constants.I2L); - public static final Instruction I2F = new Instruction(Constants.I2F); - public static final Instruction I2D = new Instruction(Constants.I2D); - public static final Instruction L2I = new Instruction(Constants.L2I); - public static final Instruction L2F = new Instruction(Constants.L2F); - public static final Instruction L2D = new Instruction(Constants.L2D); - public static final Instruction F2I = new Instruction(Constants.F2I); - public static final Instruction F2L = new Instruction(Constants.F2L); - public static final Instruction F2D = new Instruction(Constants.F2D); - public static final Instruction D2I = new Instruction(Constants.D2I); - public static final Instruction D2L = new Instruction(Constants.D2L); - public static final Instruction D2F = new Instruction(Constants.D2F); - public static final Instruction I2B = new Instruction(Constants.I2B); - public static final Instruction I2C = new Instruction(Constants.I2C); - public static final Instruction I2S = new Instruction(Constants.I2S); - public static final Instruction LCMP = new Instruction(Constants.LCMP); - public static final Instruction FCMPL = new Instruction(Constants.FCMPL); - public static final Instruction FCMPG = new Instruction(Constants.FCMPG); - public static final Instruction DCMPL = new Instruction(Constants.DCMPL); - public static final Instruction DCMPG = new Instruction(Constants.DCMPG); - public static final Instruction IRETURN = new Instruction(Constants.IRETURN); - public static final Instruction LRETURN = new Instruction(Constants.LRETURN); - public static final Instruction FRETURN = new Instruction(Constants.FRETURN); - public static final Instruction DRETURN = new Instruction(Constants.DRETURN); - public static final Instruction ARETURN = new Instruction(Constants.ARETURN); - public static final Instruction RETURN = new Instruction(Constants.RETURN); - public static final Instruction ARRAYLENGTH = new Instruction(Constants.ARRAYLENGTH); - public static final Instruction ATHROW = new Instruction(Constants.ATHROW); - public static final Instruction MONITORENTER = new Instruction(Constants.MONITORENTER); - public static final Instruction MONITOREXIT = new Instruction(Constants.MONITOREXIT); - public static final Instruction IMPDEP1 = new Instruction(Constants.IMPDEP1); - public static final Instruction IMPDEP2 = new Instruction(Constants.IMPDEP2); - - // You can use these constants in multiple places safely, any attempt to change the index - // for these constants will cause an exception - public static final InstructionLV THIS = new InstructionCLV(Constants.ALOAD,0); - public static final InstructionLV ALOAD_0 = new InstructionCLV(Constants.ALOAD_0); - public static final InstructionLV ALOAD_1 = new InstructionCLV(Constants.ALOAD_1); - public static final InstructionLV ALOAD_2 = new InstructionCLV(Constants.ALOAD_2); - public static final InstructionLV ALOAD_3 = new InstructionCLV(Constants.ALOAD_3); - public static final InstructionLV ILOAD_0 = new InstructionCLV(Constants.ILOAD_0); - public static final InstructionLV ILOAD_1 = new InstructionCLV(Constants.ILOAD_1); - public static final InstructionLV ILOAD_2 = new InstructionCLV(Constants.ILOAD_2); - public static final InstructionLV ILOAD_3 = new InstructionCLV(Constants.ILOAD_3); - public static final InstructionLV DLOAD_0 = new InstructionCLV(Constants.DLOAD_0); - public static final InstructionLV DLOAD_1 = new InstructionCLV(Constants.DLOAD_1); - public static final InstructionLV DLOAD_2 = new InstructionCLV(Constants.DLOAD_2); - public static final InstructionLV DLOAD_3 = new InstructionCLV(Constants.DLOAD_3); - public static final InstructionLV FLOAD_0 = new InstructionCLV(Constants.FLOAD_0); - public static final InstructionLV FLOAD_1 = new InstructionCLV(Constants.FLOAD_1); - public static final InstructionLV FLOAD_2 = new InstructionCLV(Constants.FLOAD_2); - public static final InstructionLV FLOAD_3 = new InstructionCLV(Constants.FLOAD_3); - public static final InstructionLV LLOAD_0 = new InstructionCLV(Constants.LLOAD_0); - public static final InstructionLV LLOAD_1 = new InstructionCLV(Constants.LLOAD_1); - public static final InstructionLV LLOAD_2 = new InstructionCLV(Constants.LLOAD_2); - public static final InstructionLV LLOAD_3 = new InstructionCLV(Constants.LLOAD_3); - public static final InstructionLV ASTORE_0 = new InstructionCLV(Constants.ASTORE_0); - public static final InstructionLV ASTORE_1 = new InstructionCLV(Constants.ASTORE_1); - public static final InstructionLV ASTORE_2 = new InstructionCLV(Constants.ASTORE_2); - public static final InstructionLV ASTORE_3 = new InstructionCLV(Constants.ASTORE_3); - public static final InstructionLV ISTORE_0 = new InstructionCLV(Constants.ISTORE_0); - public static final InstructionLV ISTORE_1 = new InstructionCLV(Constants.ISTORE_1); - public static final InstructionLV ISTORE_2 = new InstructionCLV(Constants.ISTORE_2); - public static final InstructionLV ISTORE_3 = new InstructionCLV(Constants.ISTORE_3); - public static final InstructionLV LSTORE_0 = new InstructionCLV(Constants.LSTORE_0); - public static final InstructionLV LSTORE_1 = new InstructionCLV(Constants.LSTORE_1); - public static final InstructionLV LSTORE_2 = new InstructionCLV(Constants.LSTORE_2); - public static final InstructionLV LSTORE_3 = new InstructionCLV(Constants.LSTORE_3); - public static final InstructionLV FSTORE_0 = new InstructionCLV(Constants.FSTORE_0); - public static final InstructionLV FSTORE_1 = new InstructionCLV(Constants.FSTORE_1); - public static final InstructionLV FSTORE_2 = new InstructionCLV(Constants.FSTORE_2); - public static final InstructionLV FSTORE_3 = new InstructionCLV(Constants.FSTORE_3); - public static final InstructionLV DSTORE_0 = new InstructionCLV(Constants.DSTORE_0); - public static final InstructionLV DSTORE_1 = new InstructionCLV(Constants.DSTORE_1); - public static final InstructionLV DSTORE_2 = new InstructionCLV(Constants.DSTORE_2); - public static final InstructionLV DSTORE_3 = new InstructionCLV(Constants.DSTORE_3); - - - /** Get object via its opcode, for immutable instructions like - * branch instructions entries are set to null. - */ - public static final Instruction[] INSTRUCTIONS = new Instruction[256]; - - /** Interfaces may have no static initializers, so we simulate this - * with an inner class. - */ - static final Clinit bla = new Clinit(); - - static class Clinit { - Clinit() { - INSTRUCTIONS[Constants.NOP] = NOP; - INSTRUCTIONS[Constants.ACONST_NULL] = ACONST_NULL; - INSTRUCTIONS[Constants.ICONST_M1] = ICONST_M1; - INSTRUCTIONS[Constants.ICONST_0] = ICONST_0; - INSTRUCTIONS[Constants.ICONST_1] = ICONST_1; - INSTRUCTIONS[Constants.ICONST_2] = ICONST_2; - INSTRUCTIONS[Constants.ICONST_3] = ICONST_3; - INSTRUCTIONS[Constants.ICONST_4] = ICONST_4; - INSTRUCTIONS[Constants.ICONST_5] = ICONST_5; - INSTRUCTIONS[Constants.LCONST_0] = LCONST_0; - INSTRUCTIONS[Constants.LCONST_1] = LCONST_1; - INSTRUCTIONS[Constants.FCONST_0] = FCONST_0; - INSTRUCTIONS[Constants.FCONST_1] = FCONST_1; - INSTRUCTIONS[Constants.FCONST_2] = FCONST_2; - INSTRUCTIONS[Constants.DCONST_0] = DCONST_0; - INSTRUCTIONS[Constants.DCONST_1] = DCONST_1; - INSTRUCTIONS[Constants.IALOAD] = IALOAD; - INSTRUCTIONS[Constants.LALOAD] = LALOAD; - INSTRUCTIONS[Constants.FALOAD] = FALOAD; - INSTRUCTIONS[Constants.DALOAD] = DALOAD; - INSTRUCTIONS[Constants.AALOAD] = AALOAD; - INSTRUCTIONS[Constants.BALOAD] = BALOAD; - INSTRUCTIONS[Constants.CALOAD] = CALOAD; - INSTRUCTIONS[Constants.SALOAD] = SALOAD; - INSTRUCTIONS[Constants.IASTORE] = IASTORE; - INSTRUCTIONS[Constants.LASTORE] = LASTORE; - INSTRUCTIONS[Constants.FASTORE] = FASTORE; - INSTRUCTIONS[Constants.DASTORE] = DASTORE; - INSTRUCTIONS[Constants.AASTORE] = AASTORE; - INSTRUCTIONS[Constants.BASTORE] = BASTORE; - INSTRUCTIONS[Constants.CASTORE] = CASTORE; - INSTRUCTIONS[Constants.SASTORE] = SASTORE; - INSTRUCTIONS[Constants.POP] = POP; - INSTRUCTIONS[Constants.POP2] = POP2; - INSTRUCTIONS[Constants.DUP] = DUP; - INSTRUCTIONS[Constants.DUP_X1] = DUP_X1; - INSTRUCTIONS[Constants.DUP_X2] = DUP_X2; - INSTRUCTIONS[Constants.DUP2] = DUP2; - INSTRUCTIONS[Constants.DUP2_X1] = DUP2_X1; - INSTRUCTIONS[Constants.DUP2_X2] = DUP2_X2; - INSTRUCTIONS[Constants.SWAP] = SWAP; - INSTRUCTIONS[Constants.IADD] = IADD; - INSTRUCTIONS[Constants.LADD] = LADD; - INSTRUCTIONS[Constants.FADD] = FADD; - INSTRUCTIONS[Constants.DADD] = DADD; - INSTRUCTIONS[Constants.ISUB] = ISUB; - INSTRUCTIONS[Constants.LSUB] = LSUB; - INSTRUCTIONS[Constants.FSUB] = FSUB; - INSTRUCTIONS[Constants.DSUB] = DSUB; - INSTRUCTIONS[Constants.IMUL] = IMUL; - INSTRUCTIONS[Constants.LMUL] = LMUL; - INSTRUCTIONS[Constants.FMUL] = FMUL; - INSTRUCTIONS[Constants.DMUL] = DMUL; - INSTRUCTIONS[Constants.IDIV] = IDIV; - INSTRUCTIONS[Constants.LDIV] = LDIV; - INSTRUCTIONS[Constants.FDIV] = FDIV; - INSTRUCTIONS[Constants.DDIV] = DDIV; - INSTRUCTIONS[Constants.IREM] = IREM; - INSTRUCTIONS[Constants.LREM] = LREM; - INSTRUCTIONS[Constants.FREM] = FREM; - INSTRUCTIONS[Constants.DREM] = DREM; - INSTRUCTIONS[Constants.INEG] = INEG; - INSTRUCTIONS[Constants.LNEG] = LNEG; - INSTRUCTIONS[Constants.FNEG] = FNEG; - INSTRUCTIONS[Constants.DNEG] = DNEG; - INSTRUCTIONS[Constants.ISHL] = ISHL; - INSTRUCTIONS[Constants.LSHL] = LSHL; - INSTRUCTIONS[Constants.ISHR] = ISHR; - INSTRUCTIONS[Constants.LSHR] = LSHR; - INSTRUCTIONS[Constants.IUSHR] = IUSHR; - INSTRUCTIONS[Constants.LUSHR] = LUSHR; - INSTRUCTIONS[Constants.IAND] = IAND; - INSTRUCTIONS[Constants.LAND] = LAND; - INSTRUCTIONS[Constants.IOR] = IOR; - INSTRUCTIONS[Constants.LOR] = LOR; - INSTRUCTIONS[Constants.IXOR] = IXOR; - INSTRUCTIONS[Constants.LXOR] = LXOR; - INSTRUCTIONS[Constants.I2L] = I2L; - INSTRUCTIONS[Constants.I2F] = I2F; - INSTRUCTIONS[Constants.I2D] = I2D; - INSTRUCTIONS[Constants.L2I] = L2I; - INSTRUCTIONS[Constants.L2F] = L2F; - INSTRUCTIONS[Constants.L2D] = L2D; - INSTRUCTIONS[Constants.F2I] = F2I; - INSTRUCTIONS[Constants.F2L] = F2L; - INSTRUCTIONS[Constants.F2D] = F2D; - INSTRUCTIONS[Constants.D2I] = D2I; - INSTRUCTIONS[Constants.D2L] = D2L; - INSTRUCTIONS[Constants.D2F] = D2F; - INSTRUCTIONS[Constants.I2B] = I2B; - INSTRUCTIONS[Constants.I2C] = I2C; - INSTRUCTIONS[Constants.I2S] = I2S; - INSTRUCTIONS[Constants.LCMP] = LCMP; - INSTRUCTIONS[Constants.FCMPL] = FCMPL; - INSTRUCTIONS[Constants.FCMPG] = FCMPG; - INSTRUCTIONS[Constants.DCMPL] = DCMPL; - INSTRUCTIONS[Constants.DCMPG] = DCMPG; - INSTRUCTIONS[Constants.IRETURN] = IRETURN; - INSTRUCTIONS[Constants.LRETURN] = LRETURN; - INSTRUCTIONS[Constants.FRETURN] = FRETURN; - INSTRUCTIONS[Constants.DRETURN] = DRETURN; - INSTRUCTIONS[Constants.ARETURN] = ARETURN; - INSTRUCTIONS[Constants.RETURN] = RETURN; - INSTRUCTIONS[Constants.ARRAYLENGTH] = ARRAYLENGTH; - INSTRUCTIONS[Constants.ATHROW] = ATHROW; - INSTRUCTIONS[Constants.MONITORENTER] = MONITORENTER; - INSTRUCTIONS[Constants.MONITOREXIT] = MONITOREXIT; - INSTRUCTIONS[Constants.IMPDEP1] = IMPDEP1; - INSTRUCTIONS[Constants.IMPDEP2] = IMPDEP2; - - INSTRUCTIONS[Constants.ALOAD_0] = ALOAD_0;INSTRUCTIONS[Constants.ALOAD_1] = ALOAD_1; - INSTRUCTIONS[Constants.ALOAD_2] = ALOAD_2;INSTRUCTIONS[Constants.ALOAD_3] = ALOAD_3; - INSTRUCTIONS[Constants.LLOAD_0] = LLOAD_0;INSTRUCTIONS[Constants.LLOAD_1] = LLOAD_1; - INSTRUCTIONS[Constants.LLOAD_2] = LLOAD_2;INSTRUCTIONS[Constants.LLOAD_3] = LLOAD_3; - INSTRUCTIONS[Constants.DLOAD_0] = DLOAD_0;INSTRUCTIONS[Constants.DLOAD_1] = DLOAD_1; - INSTRUCTIONS[Constants.DLOAD_2] = DLOAD_2;INSTRUCTIONS[Constants.DLOAD_3] = DLOAD_3; - INSTRUCTIONS[Constants.FLOAD_0] = FLOAD_0;INSTRUCTIONS[Constants.FLOAD_1] = FLOAD_1; - INSTRUCTIONS[Constants.FLOAD_2] = FLOAD_2;INSTRUCTIONS[Constants.FLOAD_3] = FLOAD_3; - INSTRUCTIONS[Constants.ILOAD_0] = ILOAD_0;INSTRUCTIONS[Constants.ILOAD_1] = ILOAD_1; - INSTRUCTIONS[Constants.ILOAD_2] = ILOAD_2;INSTRUCTIONS[Constants.ILOAD_3] = ILOAD_3; - - INSTRUCTIONS[Constants.ASTORE_0] = ASTORE_0;INSTRUCTIONS[Constants.ASTORE_1] = ASTORE_1; - INSTRUCTIONS[Constants.ASTORE_2] = ASTORE_2;INSTRUCTIONS[Constants.ASTORE_3] = ASTORE_3; - INSTRUCTIONS[Constants.LSTORE_0] = LSTORE_0;INSTRUCTIONS[Constants.LSTORE_1] = LSTORE_1; - INSTRUCTIONS[Constants.LSTORE_2] = LSTORE_2;INSTRUCTIONS[Constants.LSTORE_3] = LSTORE_3; - INSTRUCTIONS[Constants.DSTORE_0] = DSTORE_0;INSTRUCTIONS[Constants.DSTORE_1] = DSTORE_1; - INSTRUCTIONS[Constants.DSTORE_2] = DSTORE_2;INSTRUCTIONS[Constants.DSTORE_3] = DSTORE_3; - INSTRUCTIONS[Constants.FSTORE_0] = FSTORE_0;INSTRUCTIONS[Constants.FSTORE_1] = FSTORE_1; - INSTRUCTIONS[Constants.FSTORE_2] = FSTORE_2;INSTRUCTIONS[Constants.FSTORE_3] = FSTORE_3; - INSTRUCTIONS[Constants.ISTORE_0] = ISTORE_0;INSTRUCTIONS[Constants.ISTORE_1] = ISTORE_1; - INSTRUCTIONS[Constants.ISTORE_2] = ISTORE_2;INSTRUCTIONS[Constants.ISTORE_3] = ISTORE_3; - } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java deleted file mode 100644 index 4e1e6c8a8..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java +++ /dev/null @@ -1,771 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.Utility; - -/** - * Instances of this class may be used, e.g., to generate typed versions of instructions. Its main purpose is to be used as the byte - * code generating backend of a compiler. You can subclass it to add your own create methods. - * - * @version $Id: InstructionFactory.java,v 1.7 2010/08/23 20:44:10 aclement Exp $ - * @author M. Dahm - * @see Constants - */ -public class InstructionFactory implements InstructionConstants { - protected ClassGen cg; - protected ConstantPool cp; - - public InstructionFactory(ClassGen cg, ConstantPool cp) { - this.cg = cg; - this.cp = cp; - } - - public InstructionFactory(ClassGen cg) { - this(cg, cg.getConstantPool()); - } - - public InstructionFactory(ConstantPool cp) { - this(null, cp); - } - - public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind) { - return createInvoke(class_name, name, ret_type, arg_types, kind, false); - } - - /** - * Create an invoke instruction. - * - * @param class_name name of the called class - * @param name name of the called method - * @param ret_type return type of method - * @param arg_types argument types of method - * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL - * @param isInterface for an invokestatic on an interface allows us to tell this method the target is an interface - * @see Constants - */ - public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind, boolean isInterface) { - - String signature = Utility.toMethodSignature(ret_type, arg_types); - - int index; - if (kind == Constants.INVOKEINTERFACE || isInterface) { - index = cp.addInterfaceMethodref(class_name, name, signature); - } else if (kind == Constants.INVOKEDYNAMIC){ - throw new IllegalStateException("NYI"); - } else { - index = cp.addMethodref(class_name, name, signature); - } - - switch (kind) { - case Constants.INVOKESPECIAL: - return new InvokeInstruction(Constants.INVOKESPECIAL, index); - case Constants.INVOKEVIRTUAL: - return new InvokeInstruction(Constants.INVOKEVIRTUAL, index); - case Constants.INVOKESTATIC: - return new InvokeInstruction(Constants.INVOKESTATIC, index); - case Constants.INVOKEINTERFACE: - int nargs = 0; - for (int i = 0; i < arg_types.length; i++) { - nargs += arg_types[i].getSize(); - } - return new INVOKEINTERFACE(index, nargs + 1, 0); - default: - throw new RuntimeException("Oops: Unknown invoke kind:" + kind); - } - } - - public InvokeInstruction createInvoke(String class_name, String name, String signature, short kind) { - int index; - if (kind == Constants.INVOKEINTERFACE) { - index = cp.addInterfaceMethodref(class_name, name, signature); - } else if (kind == Constants.INVOKEDYNAMIC){ - throw new IllegalStateException("NYI"); - } else { - index = cp.addMethodref(class_name, name, signature); - } - - switch (kind) { - case Constants.INVOKESPECIAL: - return new InvokeInstruction(Constants.INVOKESPECIAL, index); - case Constants.INVOKEVIRTUAL: - return new InvokeInstruction(Constants.INVOKEVIRTUAL, index); - case Constants.INVOKESTATIC: - return new InvokeInstruction(Constants.INVOKESTATIC, index); - case Constants.INVOKEINTERFACE: - Type[] argumentTypes = Type.getArgumentTypes(signature); - int nargs = 0; - for (int i = 0; i < argumentTypes.length; i++) {// Count size of arguments - nargs += argumentTypes[i].getSize(); - } - return new INVOKEINTERFACE(index, nargs + 1, 0); - default: - throw new RuntimeException("Oops: Unknown invoke kind:" + kind); - } - } - - public static Instruction createALOAD(int n) { - if (n < 4) { - return new InstructionLV((short) (Constants.ALOAD_0 + n)); - } - return new InstructionLV(Constants.ALOAD, n); - } - - public static Instruction createASTORE(int n) { - if (n < 4) { - return new InstructionLV((short) (Constants.ASTORE_0 + n)); - } - return new InstructionLV(Constants.ASTORE, n); - } - - /** - * Uses PUSH to push a constant value onto the stack. - * - * @param value must be of type Number, Boolean, Character or String - */ - // OPTIMIZE callers should use the PUSH methods where possible if they know the types - public Instruction createConstant(Object value) { - Instruction instruction; - - if (value instanceof Number) { - instruction = InstructionFactory.PUSH(cp, (Number) value); - } else if (value instanceof String) { - instruction = InstructionFactory.PUSH(cp, (String) value); - } else if (value instanceof Boolean) { - instruction = InstructionFactory.PUSH(cp, (Boolean) value); - } else if (value instanceof Character) { - instruction = InstructionFactory.PUSH(cp, (Character) value); - } else if (value instanceof ObjectType) { - instruction = InstructionFactory.PUSH(cp, (ObjectType) value); - } else { - throw new ClassGenException("Illegal type: " + value.getClass()); - } - - return instruction; - } - - /** - * Create a field instruction. - * - * @param class_name name of the accessed class - * @param name name of the referenced field - * @param type type of field - * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC - * @see Constants - */ - public FieldInstruction createFieldAccess(String class_name, String name, Type type, short kind) { - int index; - String signature = type.getSignature(); - - index = cp.addFieldref(class_name, name, signature); - - switch (kind) { - case Constants.GETFIELD: - return new FieldInstruction(Constants.GETFIELD, index); - case Constants.PUTFIELD: - return new FieldInstruction(Constants.PUTFIELD, index); - case Constants.GETSTATIC: - return new FieldInstruction(Constants.GETSTATIC, index); - case Constants.PUTSTATIC: - return new FieldInstruction(Constants.PUTSTATIC, index); - - default: - throw new RuntimeException("Oops: Unknown getfield kind:" + kind); - } - } - - /** - * Create reference to `this' - */ - public static Instruction createThis() { - return new InstructionLV(Constants.ALOAD, 0); - } - - /** - * Create typed return - */ - public static Instruction createReturn(Type type) { - switch (type.getType()) { - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return ARETURN; - case Constants.T_INT: - case Constants.T_SHORT: - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - return IRETURN; - case Constants.T_FLOAT: - return FRETURN; - case Constants.T_DOUBLE: - return DRETURN; - case Constants.T_LONG: - return LRETURN; - case Constants.T_VOID: - return RETURN; - - default: - throw new RuntimeException("Invalid type: " + type); - } - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static Instruction createPop(int size) { - return (size == 2) ? POP2 : POP; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static Instruction createDup(int size) { - return (size == 2) ? DUP2 : DUP; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static Instruction createDup_2(int size) { - return (size == 2) ? DUP2_X2 : DUP_X2; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static Instruction createDup_1(int size) { - return (size == 2) ? DUP2_X1 : DUP_X1; - } - - /** - * @param index index of local variable - */ - public static InstructionLV createStore(Type type, int index) { - switch (type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - return new InstructionLV(Constants.ISTORE, index); - case Constants.T_FLOAT: - return new InstructionLV(Constants.FSTORE, index); - case Constants.T_DOUBLE: - return new InstructionLV(Constants.DSTORE, index); - case Constants.T_LONG: - return new InstructionLV(Constants.LSTORE, index); - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return new InstructionLV(Constants.ASTORE, index); - default: - throw new RuntimeException("Invalid type " + type); - } - } - - /** - * @param index index of local variable - */ - public static InstructionLV createLoad(Type type, int index) { - switch (type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - return new InstructionLV(Constants.ILOAD, index); - case Constants.T_FLOAT: - return new InstructionLV(Constants.FLOAD, index); - case Constants.T_DOUBLE: - return new InstructionLV(Constants.DLOAD, index); - case Constants.T_LONG: - return new InstructionLV(Constants.LLOAD, index); - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return new InstructionLV(Constants.ALOAD, index); - default: - throw new RuntimeException("Invalid type " + type); - } - } - - /** - * @param type type of elements of array, i.e., array.getElementType() - */ - public static Instruction createArrayLoad(Type type) { - switch (type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_BYTE: - return BALOAD; - case Constants.T_CHAR: - return CALOAD; - case Constants.T_SHORT: - return SALOAD; - case Constants.T_INT: - return IALOAD; - case Constants.T_FLOAT: - return FALOAD; - case Constants.T_DOUBLE: - return DALOAD; - case Constants.T_LONG: - return LALOAD; - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return AALOAD; - default: - throw new RuntimeException("Invalid type " + type); - } - } - - /** - * @param type type of elements of array, i.e., array.getElementType() - */ - public static Instruction createArrayStore(Type type) { - switch (type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_BYTE: - return BASTORE; - case Constants.T_CHAR: - return CASTORE; - case Constants.T_SHORT: - return SASTORE; - case Constants.T_INT: - return IASTORE; - case Constants.T_FLOAT: - return FASTORE; - case Constants.T_DOUBLE: - return DASTORE; - case Constants.T_LONG: - return LASTORE; - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return AASTORE; - default: - throw new RuntimeException("Invalid type " + type); - } - } - - private static final char[] shortNames = { 'C', 'F', 'D', 'B', 'S', 'I', 'L' }; - - /** - * Create conversion operation for two stack operands, this may be an I2C, instruction, e.g., if the operands are basic types - * and CHECKCAST if they are reference types. - */ - public Instruction createCast(Type src_type, Type dest_type) { - if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { - byte dest = dest_type.getType(); - byte src = src_type.getType(); - - if (dest == Constants.T_LONG && (src == Constants.T_CHAR || src == Constants.T_BYTE || src == Constants.T_SHORT)) { - src = Constants.T_INT; - } - - if (src == Constants.T_DOUBLE) { - switch (dest) { - case Constants.T_FLOAT: - return InstructionConstants.D2F; - case Constants.T_INT: - return InstructionConstants.D2I; - case Constants.T_LONG: - return InstructionConstants.D2L; - } - } else if (src == Constants.T_FLOAT) { - switch (dest) { - case Constants.T_DOUBLE: - return InstructionConstants.F2D; - case Constants.T_INT: - return InstructionConstants.F2I; - case Constants.T_LONG: - return InstructionConstants.F2L; - } - } else if (src == Constants.T_INT) { - switch (dest) { - case Constants.T_BYTE: - return InstructionConstants.I2B; - case Constants.T_CHAR: - return InstructionConstants.I2C; - case Constants.T_DOUBLE: - return InstructionConstants.I2D; - case Constants.T_FLOAT: - return InstructionConstants.I2F; - case Constants.T_LONG: - return InstructionConstants.I2L; - case Constants.T_SHORT: - return InstructionConstants.I2S; - } - } else if (src == Constants.T_LONG) { - switch (dest) { - case Constants.T_DOUBLE: - return InstructionConstants.L2D; - case Constants.T_FLOAT: - return InstructionConstants.L2F; - case Constants.T_INT: - return InstructionConstants.L2I; - } - } - - // String name = "org.aspectj.apache.bcel.generic." + short_names[src - Constants.T_CHAR] + - // "2" + short_names[dest - Constants.T_CHAR]; - - // Instruction i = null; - // try { - // i = (Instruction)java.lang.Class.forName(name).newInstance(); - // } catch(Exception e) { - // throw new RuntimeException("Could not find instruction: " + name); - // } - - return null; - // return i; - } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { - if (dest_type instanceof ArrayType) { - return new InstructionCP(Constants.CHECKCAST, cp.addArrayClass((ArrayType) dest_type)); - } else { - return new InstructionCP(Constants.CHECKCAST, cp.addClass(((ObjectType) dest_type).getClassName())); - } - } else { - throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); - } - } - - public FieldInstruction createGetField(String class_name, String name, Type t) { - return new FieldInstruction(Constants.GETFIELD, cp.addFieldref(class_name, name, t.getSignature())); - } - - public FieldInstruction createGetStatic(String class_name, String name, Type t) { - return new FieldInstruction(Constants.GETSTATIC, cp.addFieldref(class_name, name, t.getSignature())); - } - - public FieldInstruction createPutField(String class_name, String name, Type t) { - return new FieldInstruction(Constants.PUTFIELD, cp.addFieldref(class_name, name, t.getSignature())); - } - - public FieldInstruction createPutStatic(String class_name, String name, Type t) { - return new FieldInstruction(Constants.PUTSTATIC, cp.addFieldref(class_name, name, t.getSignature())); - } - - public Instruction createCheckCast(ReferenceType t) { - if (t instanceof ArrayType) { - return new InstructionCP(Constants.CHECKCAST, cp.addArrayClass((ArrayType) t)); - } else { - return new InstructionCP(Constants.CHECKCAST, cp.addClass((ObjectType) t)); - } - } - - public Instruction createInstanceOf(ReferenceType t) { - if (t instanceof ArrayType) { - return new InstructionCP(Constants.INSTANCEOF, cp.addArrayClass((ArrayType) t)); - } else { - return new InstructionCP(Constants.INSTANCEOF, cp.addClass((ObjectType) t)); - } - } - - public Instruction createNew(ObjectType t) { - return new InstructionCP(Constants.NEW, cp.addClass(t)); - } - - public Instruction createNew(String s) { - return createNew(new ObjectType(s)); - } - - /** - * Create new array of given size and type. - * - * @return an instruction that creates the corresponding array at runtime, i.e. is an AllocationInstruction - */ - public Instruction createNewArray(Type t, short dim) { - if (dim == 1) { - if (t instanceof ObjectType) { - return new InstructionCP(Constants.ANEWARRAY, cp.addClass((ObjectType) t)); - } else if (t instanceof ArrayType) { - return new InstructionCP(Constants.ANEWARRAY, cp.addArrayClass((ArrayType) t)); - } else { - return new InstructionByte(Constants.NEWARRAY, ((BasicType) t).getType()); - } - } else { - ArrayType at; - - if (t instanceof ArrayType) { - at = (ArrayType) t; - } else { - at = new ArrayType(t, dim); - } - - return new MULTIANEWARRAY(cp.addArrayClass(at), dim); - } - } - - /** - * Create "null" value for reference types, 0 for basic types like int - */ - public static Instruction createNull(Type type) { - switch (type.getType()) { - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return ACONST_NULL; - case Constants.T_INT: - case Constants.T_SHORT: - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - return ICONST_0; - case Constants.T_FLOAT: - return FCONST_0; - case Constants.T_DOUBLE: - return DCONST_0; - case Constants.T_LONG: - return LCONST_0; - case Constants.T_VOID: - return NOP; - - default: - throw new RuntimeException("Invalid type: " + type); - } - } - - /** - * Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH. For those you should use the SWITCH compound - * instruction. - */ - public static InstructionBranch createBranchInstruction(short opcode, InstructionHandle target) { - switch (opcode) { - case Constants.IFEQ: - return new InstructionBranch(Constants.IFEQ, target); - case Constants.IFNE: - return new InstructionBranch(Constants.IFNE, target); - case Constants.IFLT: - return new InstructionBranch(Constants.IFLT, target); - case Constants.IFGE: - return new InstructionBranch(Constants.IFGE, target); - case Constants.IFGT: - return new InstructionBranch(Constants.IFGT, target); - case Constants.IFLE: - return new InstructionBranch(Constants.IFLE, target); - case Constants.IF_ICMPEQ: - return new InstructionBranch(Constants.IF_ICMPEQ, target); - case Constants.IF_ICMPNE: - return new InstructionBranch(Constants.IF_ICMPNE, target); - case Constants.IF_ICMPLT: - return new InstructionBranch(Constants.IF_ICMPLT, target); - case Constants.IF_ICMPGE: - return new InstructionBranch(Constants.IF_ICMPGE, target); - case Constants.IF_ICMPGT: - return new InstructionBranch(Constants.IF_ICMPGT, target); - case Constants.IF_ICMPLE: - return new InstructionBranch(Constants.IF_ICMPLE, target); - case Constants.IF_ACMPEQ: - return new InstructionBranch(Constants.IF_ACMPEQ, target); - case Constants.IF_ACMPNE: - return new InstructionBranch(Constants.IF_ACMPNE, target); - case Constants.GOTO: - return new InstructionBranch(Constants.GOTO, target); - case Constants.JSR: - return new InstructionBranch(Constants.JSR, target); - case Constants.IFNULL: - return new InstructionBranch(Constants.IFNULL, target); - case Constants.IFNONNULL: - return new InstructionBranch(Constants.IFNONNULL, target); - case Constants.GOTO_W: - return new InstructionBranch(Constants.GOTO_W, target); - case Constants.JSR_W: - return new InstructionBranch(Constants.JSR_W, target); - default: - throw new RuntimeException("Invalid opcode: " + opcode); - } - } - - public void setClassGen(ClassGen c) { - cg = c; - } - - public ClassGen getClassGen() { - return cg; - } - - public void setConstantPool(ConstantPool c) { - cp = c; - } - - public ConstantPool getConstantPool() { - return cp; - } - - /** - * Returns the right instruction for putting whatever you want onto the stack - */ - public static Instruction PUSH(ConstantPool cp, int value) { - Instruction instruction = null; - if ((value >= -1) && (value <= 5)) { - return INSTRUCTIONS[Constants.ICONST_0 + value]; - } else if ((value >= -128) && (value <= 127)) { - instruction = new InstructionByte(Constants.BIPUSH, (byte) value); - } else if ((value >= -32768) && (value <= 32767)) { - instruction = new InstructionShort(Constants.SIPUSH, (short) value); - } else // If everything fails create a Constant pool entry - { - int pos = cp.addInteger(value); - if (pos <= Constants.MAX_BYTE) { - instruction = new InstructionCP(Constants.LDC, pos); - } else { - instruction = new InstructionCP(Constants.LDC_W, pos); - } - } - return instruction; - } - - public static Instruction PUSH(ConstantPool cp, ObjectType t) { - return new InstructionCP(Constants.LDC_W, cp.addClass(t)); - } - - public static Instruction PUSH(ConstantPool cp, boolean value) { - return INSTRUCTIONS[Constants.ICONST_0 + (value ? 1 : 0)]; - } - - public static Instruction PUSH(ConstantPool cp, float value) { - Instruction instruction = null; - if (value == 0.0) { - instruction = FCONST_0; - } else if (value == 1.0) { - instruction = FCONST_1; - } else if (value == 2.0) { - instruction = FCONST_2; - } else { - // Create a Constant pool entry - int i = cp.addFloat(value); - instruction = new InstructionCP(i <= Constants.MAX_BYTE ? Constants.LDC : Constants.LDC_W, i); - } - return instruction; - } - - public static Instruction PUSH(ConstantPool cp, long value) { - Instruction instruction = null; - if (value == 0) { - instruction = LCONST_0; - } else if (value == 1) { - instruction = LCONST_1; - } else { - instruction = new InstructionCP(Constants.LDC2_W, cp.addLong(value)); - } - return instruction; - } - - public static Instruction PUSH(ConstantPool cp, double value) { - Instruction instruction = null; - if (value == 0.0) { - instruction = DCONST_0; - } else if (value == 1.0) { - instruction = DCONST_1; - } else { - // Create a Constant pool entry - instruction = new InstructionCP(Constants.LDC2_W, cp.addDouble(value)); - } - return instruction; - } - - public static Instruction PUSH(ConstantPool cp, String value) { - Instruction instruction = null; - if (value == null) { - instruction = ACONST_NULL; - } else { - int i = cp.addString(value); - instruction = new InstructionCP(i <= Constants.MAX_BYTE ? Constants.LDC : Constants.LDC_W, i); - } - return instruction; - } - - public static Instruction PUSH(ConstantPool cp, Number value) { - Instruction instruction = null; - if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) { - instruction = PUSH(cp, value.intValue()); - } else if (value instanceof Double) { - instruction = PUSH(cp, value.doubleValue()); - } else if (value instanceof Float) { - instruction = PUSH(cp, value.floatValue()); - } else if (value instanceof Long) { - instruction = PUSH(cp, value.longValue()); - } else { - throw new ClassGenException("What's this: " + value); - } - return instruction; - } - - public static Instruction PUSH(ConstantPool cp, Character value) { - return PUSH(cp, value.charValue()); - } - - public static Instruction PUSH(ConstantPool cp, Boolean value) { - return PUSH(cp, value.booleanValue()); - } - - /** - * Return a list that will load the Class object - on 1.5 or later use the class variant of ldc, whilst on earlier JVMs use the - * regular Class.forName. - */ - public InstructionList PUSHCLASS(ConstantPool cp, String className) { - InstructionList iList = new InstructionList(); - int classIndex = cp.addClass(className); - if (cg != null && cg.getMajor() >= Constants.MAJOR_1_5) { - if (classIndex <= Constants.MAX_BYTE) { - iList.append(new InstructionCP(Instruction.LDC, classIndex)); - } else { - iList.append(new InstructionCP(Instruction.LDC_W, classIndex)); - } - } else { - className = className.replace('/', '.'); - iList.append(InstructionFactory.PUSH(cp, className)); - iList.append(this.createInvoke("java.lang.Class", "forName", ObjectType.CLASS, Type.STRINGARRAY1, - Constants.INVOKESTATIC)); - } - return iList; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java deleted file mode 100644 index 2f2691df1..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java +++ /dev/null @@ -1,189 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.aspectj.apache.bcel.classfile.Utility; - -/** - * Instances of this class give users a handle to the instructions contained in an InstructionList. Instruction objects may be used - * more than once within a list, this is useful because it saves memory and may be much faster. - * - * Within an InstructionList an InstructionHandle object is wrapped around all instructions, i.e., it implements a cell in a - * doubly-linked list. From the outside only the next and the previous instruction (handle) are accessible. One can traverse the - * list via an Enumeration returned by InstructionList.elements(). - * - * @version $Id: InstructionHandle.java,v 1.9 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - * @see Instruction - * @see BranchHandle - * @see InstructionList - */ -public class InstructionHandle implements java.io.Serializable { - InstructionHandle next, prev; // Will be set from the outside - Instruction instruction; - protected int pos = -1; // byte code offset of instruction - private Set targeters = Collections.emptySet(); - - protected InstructionHandle(Instruction i) { - setInstruction(i); - } - - static final InstructionHandle getInstructionHandle(Instruction i) { - return new InstructionHandle(i); - } - - public final InstructionHandle getNext() { - return next; - } - - public final InstructionHandle getPrev() { - return prev; - } - - public final Instruction getInstruction() { - return instruction; - } - - /** - * Replace current instruction contained in this handle. Old instruction is disposed using Instruction.dispose(). - */ - public void setInstruction(Instruction i) { // Overridden in BranchHandle - if (instruction != null) { - instruction.dispose(); - } - instruction = i; - } - - /** - * @return the position, i.e., the byte code offset of the contained instruction. This is accurate only after - * InstructionList.setPositions() has been called. - */ - public int getPosition() { - return pos; - } - - /** - * Set the position, i.e., the byte code offset of the contained instruction. - */ - void setPosition(int pos) { - this.pos = pos; - } - - /** - * Delete contents, i.e., remove user access and make handle reusable. - */ - // OPTIMIZE get rid of this? why do we need it - void dispose() { - next = prev = null; - instruction.dispose(); - instruction = null; - pos = -1; - removeAllTargeters(); - } - - /** - * Remove all targeters, if any. - */ - public void removeAllTargeters() { - targeters.clear(); - } - - /** - * Denote this handle isn't referenced anymore by t. - */ - public void removeTargeter(InstructionTargeter t) { - targeters.remove(t); - } - - /** - * Denote this handle is being referenced by t. - */ - public void addTargeter(InstructionTargeter t) { - if (targeters == Collections.EMPTY_SET) { - targeters = new HashSet(); - } - targeters.add(t); - } - - public boolean hasTargeters() { - return !targeters.isEmpty(); - } - - public Set getTargeters() { - return targeters; - } - - public Set getTargetersCopy() { - Set copy = new HashSet(); - copy.addAll(targeters); - return copy; - } - - /** - * @return a (verbose) string representation of the contained instruction. - */ - public String toString(boolean verbose) { - return Utility.format(pos, 4, false, ' ') + ": " + instruction.toString(verbose); - } - - public String toString() { - return toString(true); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java deleted file mode 100644 index 73c278016..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java +++ /dev/null @@ -1,278 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; - -/** - * Abstract super class for instructions dealing with local variables. - * - * @version $Id: InstructionLV.java,v 1.5 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public class InstructionLV extends Instruction { - protected int lvar = -1; - - public InstructionLV(short opcode, int lvar) { - super(opcode); - this.lvar = lvar; - } - - public InstructionLV(short opcode) { - super(opcode); - } - - public void dump(DataOutputStream out) throws IOException { - if (lvar == -1) { - out.writeByte(opcode); - } else { - if (lvar < 4) { - if (opcode == ALOAD) { - out.writeByte(ALOAD_0 + lvar); - } else if (opcode == ASTORE) { - out.writeByte(ASTORE_0 + lvar); - } else if (opcode == ILOAD) { - out.writeByte(ILOAD_0 + lvar); - } else if (opcode == ISTORE) { - out.writeByte(ISTORE_0 + lvar); - } else if (opcode == DLOAD) { - out.writeByte(DLOAD_0 + lvar); - } else if (opcode == DSTORE) { - out.writeByte(DSTORE_0 + lvar); - } else if (opcode == FLOAD) { - out.writeByte(FLOAD_0 + lvar); - } else if (opcode == FSTORE) { - out.writeByte(FSTORE_0 + lvar); - } else if (opcode == LLOAD) { - out.writeByte(LLOAD_0 + lvar); - } else if (opcode == LSTORE) { - out.writeByte(LSTORE_0 + lvar); - } else { - if (wide()) { - out.writeByte(Constants.WIDE); - } - out.writeByte(opcode); - if (wide()) { - out.writeShort(lvar); - } else { - out.writeByte(lvar); - } - } - } else { - if (wide()) { - out.writeByte(Constants.WIDE); - } - out.writeByte(opcode); - if (wide()) { - out.writeShort(lvar); - } else { - out.writeByte(lvar); - } - } - } - } - - /** - * Long output format: - * - * 'name of opcode' "[" 'opcode number' "]" "(" 'length of instruction' ")" "<" 'local variable index' ">" - */ - public String toString(boolean verbose) { - if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3 || opcode >= Constants.ISTORE_0 - && opcode <= Constants.ASTORE_3) { - return super.toString(verbose); - } else { - return super.toString(verbose) + (lvar != -1 && lvar < 4 ? "_" : " ") + lvar; - } - } - - public boolean isALOAD() { - return opcode == ALOAD || opcode >= ALOAD_0 && opcode <= ALOAD_3; - } - - public boolean isASTORE() { - return opcode == ASTORE || opcode >= ASTORE_0 && opcode <= ASTORE_3; - } - - public int getBaseOpcode() { - if (opcode >= ILOAD && opcode <= ALOAD || opcode >= ISTORE && opcode <= ASTORE) { - // not an optimized instruction - return opcode; - } - if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) { - int ret = opcode - ILOAD_0; - ret = ret - ret % 4; - ret = ret / 4; - return ret + ILOAD; - } - int ret = opcode - ISTORE_0; - ret = ret - ret % 4; - ret = ret / 4; - return ret + ISTORE; - } - - /** - * @return local variable index referred by this instruction. - */ - // optimize! - public final int getIndex() { - if (lvar != -1) { - return lvar; - } - if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) { - return (opcode - Constants.ILOAD_0) % 4; - } else if (opcode >= Constants.ISTORE_0 && opcode <= Constants.ASTORE_3) { - return (opcode - Constants.ISTORE_0) % 4; - } - return -1; - } - - public void setIndex(int i) { - // Switching the index for a load/store without a current index specified (ie. an aload_1 or istore_2) - // means we need to should adjust to a normal aload/istore opcode - if (getIndex() != i) { - if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) { - opcode = (short) (ILOAD + (opcode - ILOAD_0) / 4); - } else if (opcode >= Constants.ISTORE_0 && opcode <= Constants.ASTORE_3) { - opcode = (short) (ISTORE + (opcode - ISTORE_0) / 4); - } - this.lvar = i; - } - } - - public boolean canSetIndex() { - return true; - } - - public InstructionLV setIndexAndCopyIfNecessary(int newIndex) { - if (canSetIndex()) { - setIndex(newIndex); - return this; - } else { - if (getIndex() == newIndex) { - return this; - } - InstructionLV newInstruction = null; - int baseOpCode = getBaseOpcode(); - if (newIndex < 4) { - if (isStoreInstruction()) { - newInstruction = (InstructionLV) InstructionConstants.INSTRUCTIONS[(baseOpCode - Constants.ISTORE) * 4 - + Constants.ISTORE_0 + newIndex]; - } else { - newInstruction = (InstructionLV) InstructionConstants.INSTRUCTIONS[(baseOpCode - Constants.ILOAD) * 4 - + Constants.ILOAD_0 + newIndex]; - } - } else { - newInstruction = new InstructionLV((short) baseOpCode, newIndex); - } - // if (getBaseOpcode()!=newInstruction.getBaseOpcode() || newInstruction.getIndex()!=newIndex) { - // throw new - // RuntimeException("New Instruction created does not appear to be valid: originalBaseOpcode="+getBaseOpcode()+ - // " newBaseOpcode="+newInstruction.getBaseOpcode()); - // } - return newInstruction; - } - } - - public int getLength() { - int size = Constants.iLen[opcode]; - if (lvar == -1) { - return size; - } else { - if (lvar < 4) { - if (opcode == ALOAD || opcode == ASTORE) { - return 1; - } else if (opcode == ILOAD || opcode == ISTORE) { - return 1; - } else if (opcode == DLOAD || opcode == DSTORE) { - return 1; - } else if (opcode == FLOAD || opcode == FSTORE) { - return 1; - } else if (opcode == LLOAD || opcode == LSTORE) { - return 1; - } else { - if (wide()) { - return size + 2; - } - return size; - } - } else { - if (wide()) { - return size + 2; - } - return size; - } - } - } - - private final boolean wide() { - return lvar > Constants.MAX_BYTE; - } - - public boolean equals(Object other) { - if (!(other instanceof InstructionLV)) { - return false; - } - InstructionLV o = (InstructionLV) other; - return o.opcode == opcode && o.lvar == lvar; - } - - public int hashCode() { - return opcode * 37 + lvar; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java deleted file mode 100644 index b08a2b77c..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java +++ /dev/null @@ -1,1287 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Set; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Constant; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.util.ByteSequence; - -/** - * This class is a container for a list of Instruction objects. Instructions can be appended, - * inserted, moved, deleted, etc.. Instructions are being wrapped into InstructionHandles - * objects that are returned upon append/insert operations. They give the user (read only) access to the list structure, such that - * it can be traversed and manipulated in a controlled way. - * - * A list is finally dumped to a byte code array with getByteCode. - * - * @version $Id: InstructionList.java,v 1.12 2011/09/02 22:33:04 aclement Exp $ - * @author M. Dahm - * @author Abraham Nevado - * @see Instruction - * @see InstructionHandle - * @see BranchHandle - */ -public class InstructionList implements Serializable { - private InstructionHandle start = null, end = null; - private int length = 0; - private int[] positions; // byte code offsets corresponding to instructions - - public InstructionList() { - } - - public InstructionList(Instruction i) { - append(i); - } - - public boolean isEmpty() { - return start == null; - } // && end == null - - public static InstructionHandle findHandle(InstructionHandle[] ihs, int[] pos, int count, int target) { - return findHandle(ihs, pos, count, target, false); - } - - /** - * Find the target instruction (handle) that corresponds to the given target position (byte code offset). - * - * @param ihs array of instruction handles, i.e. il.getInstructionHandles() - * @param pos array of positions corresponding to ihs, i.e. il.getInstructionPositions() - * @param count length of arrays - * @param target target position to search for - * @return target position's instruction handle if available - */ - public static InstructionHandle findHandle(InstructionHandle[] ihs, int[] pos, int count, int target, - boolean returnClosestIfNoExactMatch) { - int l = 0, r = count - 1; - // Do a binary search since the pos array is ordered - int i, j; - do { - i = (l + r) / 2; - j = pos[i]; - if (j == target) { - return ihs[i]; // found it - } else if (target < j) { - r = i - 1; // else constrain search area - } else { - l = i + 1; // target > j - } - } while (l <= r); - - if (returnClosestIfNoExactMatch) { - i = (l + r) / 2; - if (i < 0) { - i = 0; - } - return ihs[i]; - } - return null; - } - - /** - * Get instruction handle for instruction at byte code position pos. This only works properly, if the list is freshly - * initialized from a byte array or setPositions() has been called before this method. - * - * @param pos byte code position to search for - * @return target position's instruction handle if available - */ - public InstructionHandle findHandle(int pos) { - InstructionHandle[] ihs = getInstructionHandles(); - return findHandle(ihs, positions, length, pos); - } - - public InstructionHandle[] getInstructionsAsArray() { - return getInstructionHandles(); - } - - public InstructionHandle findHandle(int pos, InstructionHandle[] instructionArray) { - return findHandle(instructionArray, positions, length, pos); - } - - public InstructionHandle findHandle(int pos, InstructionHandle[] instructionArray, boolean useClosestApproximationIfNoExactFound) { - return findHandle(instructionArray, positions, length, pos, useClosestApproximationIfNoExactFound); - } - - /** - * Initialize instruction list from byte array. - * - * @param code byte array containing the instructions - */ - public InstructionList(byte[] code) { - ByteSequence bytes = new ByteSequence(code); - InstructionHandle[] ihs = new InstructionHandle[code.length]; - int[] pos = new int[code.length]; // Can't be more than that - int count = 0; // Contains actual length - - /* - * Pass 1: Create an object for each byte code and append them to the list. - */ - try { - while (bytes.available() > 0) { - // Remember byte offset and associate it with the instruction - int off = bytes.getIndex(); - pos[count] = off; - - /* - * Read one instruction from the byte stream, the byte position is set accordingly. - */ - Instruction i = Instruction.readInstruction(bytes); - InstructionHandle ih; - if (i instanceof InstructionBranch) { - ih = append((InstructionBranch) i); - } else { - ih = append(i); - } - - ih.setPosition(off); - ihs[count] = ih; - - count++; - } - } catch (IOException e) { - throw new ClassGenException(e.toString()); - } - - positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, positions, 0, count); - - /* - * Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles. - */ - // OPTIMIZE better way of doing this? keep little map from earlier from pos -> instruction handle? - for (int i = 0; i < count; i++) { - if (ihs[i] instanceof BranchHandle) { - InstructionBranch bi = (InstructionBranch) ihs[i].instruction; - int target = bi.positionOfThisInstruction + bi.getIndex(); /* - * Byte code position: relative -> absolute. - */ - // Search for target position - InstructionHandle ih = findHandle(ihs, pos, count, target); - - if (ih == null) { - throw new ClassGenException("Couldn't find target for branch: " + bi); - } - - bi.setTarget(ih); // Update target - - // If it is a Select instruction, update all branch targets - if (bi instanceof InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionSelect s = (InstructionSelect) bi; - int[] indices = s.getIndices(); - - for (int j = 0; j < indices.length; j++) { - target = bi.positionOfThisInstruction + indices[j]; - ih = findHandle(ihs, pos, count, target); - - if (ih == null) { - throw new ClassGenException("Couldn't find target for switch: " + bi); - } - - s.setTarget(j, ih); // Update target - } - } - } - } - } - - /** - * Append another list after instruction (handle) ih contained in this list. Consumes argument list, i.e., it becomes empty. - * - * @param appendTo where to append the instruction list - * @param appendee Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(InstructionHandle appendTo, InstructionList appendee) { - assert appendee != null; - - if (appendee.isEmpty()) { - return appendTo; - } - - InstructionHandle next = appendTo.next; - InstructionHandle ret = appendee.start; - - appendTo.next = appendee.start; - appendee.start.prev = appendTo; - - appendee.end.next = next; - - if (next != null) { - next.prev = appendee.end; - } else { - end = appendee.end; // Update end ... - } - - length += appendee.length; // Update length - - appendee.clear(); - - return ret; - } - - /** - * Append another list after instruction i contained in this list. Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(Instruction i, InstructionList il) { - InstructionHandle ih; - - if ((ih = findInstruction2(i)) == null) { - throw new ClassGenException("Instruction " + i + " is not contained in this list."); - } - - return append(ih, il); - } - - /** - * Append another list to this one. Consumes argument list, i.e., it becomes empty. - * - * @param il list to append to end of this list - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(InstructionList il) { - assert il != null; - - if (il.isEmpty()) { - return null; - } - - if (isEmpty()) { - start = il.start; - end = il.end; - length = il.length; - - il.clear(); - - return start; - } else { - return append(end, il); // was end.instruction - } - } - - /** - * Append an instruction to the end of this list. - * - * @param ih instruction to append - */ - private void append(InstructionHandle ih) { - if (isEmpty()) { - start = end = ih; - ih.next = ih.prev = null; - } else { - end.next = ih; - ih.prev = end; - ih.next = null; - end = ih; - } - - length++; // Update length - } - - /** - * Append an instruction to the end of this list. - * - * @param i instruction to append - * @return instruction handle of the appended instruction - */ - public InstructionHandle append(Instruction i) { - InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - append(ih); - - return ih; - } - - public InstructionHandle appendDUP() { - InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.DUP); - append(ih); - return ih; - } - - public InstructionHandle appendNOP() { - InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.NOP); - append(ih); - return ih; - } - - public InstructionHandle appendPOP() { - InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.POP); - append(ih); - return ih; - } - - /** - * Append a branch instruction to the end of this list. - * - * @param i branch instruction to append - * @return branch instruction handle of the appended instruction - */ - public BranchHandle append(InstructionBranch i) { - BranchHandle ih = BranchHandle.getBranchHandle(i); - append(ih); - - return ih; - } - - /** - * Append a single instruction j after another instruction i, which must be in this list of course! - * - * @param i Instruction in list - * @param j Instruction to append after i in list - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(Instruction i, Instruction j) { - return append(i, new InstructionList(j)); - } - - /** - * Append an instruction after instruction (handle) ih contained in this list. - * - * @param ih where to append the instruction list - * @param i Instruction to append - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(InstructionHandle ih, Instruction i) { - return append(ih, new InstructionList(i)); - } - - /** - * Append an instruction after instruction (handle) ih contained in this list. - * - * @param ih where to append the instruction list - * @param i Instruction to append - * @return instruction handle pointing to the first appended instruction - */ - public BranchHandle append(InstructionHandle ih, InstructionBranch i) { - BranchHandle bh = BranchHandle.getBranchHandle(i); - InstructionList il = new InstructionList(); - il.append(bh); - - append(ih, il); - - return bh; - } - - /** - * Insert another list before Instruction handle ih contained in this list. Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to insert - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionHandle ih, InstructionList il) { - if (il == null) { - throw new ClassGenException("Inserting null InstructionList"); - } - - if (il.isEmpty()) { - return ih; - } - - InstructionHandle prev = ih.prev, ret = il.start; - - ih.prev = il.end; - il.end.next = ih; - - il.start.prev = prev; - - if (prev != null) { - prev.next = il.start; - } else { - start = il.start; // Update start ... - } - - length += il.length; // Update length - - il.clear(); - - return ret; - } - - /** - * Insert another list. - * - * @param il list to insert before start of this list - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionList il) { - if (isEmpty()) { - append(il); // Code is identical for this case - return start; - } else { - return insert(start, il); - } - } - - /** - * Insert an instruction at start of this list. - * - * @param ih instruction to insert - */ - private void insert(InstructionHandle ih) { - if (isEmpty()) { - start = end = ih; - ih.next = ih.prev = null; - } else { - start.prev = ih; - ih.next = start; - ih.prev = null; - start = ih; - } - - length++; - } - - /** - * Insert another list before Instruction i contained in this list. Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to insert - * @return instruction handle pointing to the first inserted instruction, i.e., il.getStart() - */ - public InstructionHandle insert(Instruction i, InstructionList il) { - InstructionHandle ih; - - if ((ih = findInstruction1(i)) == null) { - throw new ClassGenException("Instruction " + i + " is not contained in this list."); - } - - return insert(ih, il); - } - - /** - * Insert an instruction at start of this list. - * - * @param i instruction to insert - * @return instruction handle of the inserted instruction - */ - public InstructionHandle insert(Instruction i) { - InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - insert(ih); - - return ih; - } - - /** - * Insert a branch instruction at start of this list. - * - * @param i branch instruction to insert - * @return branch instruction handle of the appended instruction - */ - public BranchHandle insert(InstructionBranch i) { - BranchHandle ih = BranchHandle.getBranchHandle(i); - insert(ih); - return ih; - } - - /** - * Insert a single instruction j before another instruction i, which must be in this list of course! - * - * @param i Instruction in list - * @param j Instruction to insert before i in list - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(Instruction i, Instruction j) { - return insert(i, new InstructionList(j)); - } - - /** - * Insert an instruction before instruction (handle) ih contained in this list. - * - * @param ih where to insert to the instruction list - * @param i Instruction to insert - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionHandle ih, Instruction i) { - return insert(ih, new InstructionList(i)); - } - - /** - * Insert an instruction before instruction (handle) ih contained in this list. - * - * @param ih where to insert to the instruction list - * @param i Instruction to insert - * @return instruction handle of the first inserted instruction - */ - public BranchHandle insert(InstructionHandle ih, InstructionBranch i) { - BranchHandle bh = BranchHandle.getBranchHandle(i); - InstructionList il = new InstructionList(); - il.append(bh); - - insert(ih, il); - - return bh; - } - - /** - * Take all instructions (handles) from "start" to "end" and append them after the new location "target". Of course, "end" must - * be after "start" and target must not be located withing this range. If you want to move something to the start of the list - * use null as value for target.
- * Any instruction targeters pointing to handles within the block, keep their targets. - * - * @param start of moved block - * @param end of moved block - * @param target of moved block - */ - public void move(InstructionHandle start, InstructionHandle end, InstructionHandle target) { - // Step 1: Check constraints - - if (start == null || end == null) { - throw new ClassGenException("Invalid null handle: From " + start + " to " + end); - } - - if (target == start || target == end) { - throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target); - } - - for (InstructionHandle ih = start; ih != end.next; ih = ih.next) { - if (ih == null) { - throw new ClassGenException("Invalid range: From " + start + " to " + end); - } else if (ih == target) { - throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target); - } - } - - // Step 2: Temporarily remove the given instructions from the list - - InstructionHandle prev = start.prev, next = end.next; - - if (prev != null) { - prev.next = next; - } else { - this.start = next; - } - - if (next != null) { - next.prev = prev; - } else { - this.end = prev; - } - - start.prev = end.next = null; - - // Step 3: append after target - - if (target == null) { // append to start of list - end.next = this.start; - this.start = start; - } else { - next = target.next; - - target.next = start; - start.prev = target; - end.next = next; - - if (next != null) { - next.prev = end; - } - } - } - - /** - * Move a single instruction (handle) to a new location. - * - * @param ih moved instruction - * @param target new location of moved instruction - */ - public void move(InstructionHandle ih, InstructionHandle target) { - move(ih, ih, target); - } - - /** - * Remove from instruction 'prev' to instruction 'next' both contained in this list. - * - * If careAboutLostTargeters is true then this method will throw a TargetLostException when one of the removed instruction - * handles is still being targeted. - * - * @param prev where to start deleting (predecessor, exclusive) - * @param next where to end deleting (successor, exclusive) - */ - private void remove(InstructionHandle prev, InstructionHandle next, boolean careAboutLostTargeters) throws TargetLostException { - InstructionHandle first, last; // First and last deleted instruction - - if (prev == null && next == null) { // singleton list - first = last = start; - start = end = null; - } else { - if (prev == null) { // At start of list - first = start; - start = next; - } else { - first = prev.next; - prev.next = next; - } - if (next == null) { // At end of list - last = end; - end = prev; - } else { - last = next.prev; - next.prev = prev; - } - } - - first.prev = null; // Completely separated from rest of list - last.next = null; - - if (!careAboutLostTargeters) { - return; - } - - ArrayList target_vec = new ArrayList(); - - for (InstructionHandle ih = first; ih != null; ih = ih.next) { - ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets - } - - StringBuffer buf = new StringBuffer("{ "); - for (InstructionHandle ih = first; ih != null; ih = next) { - next = ih.next; - length--; - - Set targeters = ih.getTargeters(); - boolean isOK = false; - Iterator tIter = targeters.iterator(); - while (tIter.hasNext()) { - InstructionTargeter instructionTargeter = tIter.next(); - if (instructionTargeter.getClass().getName().endsWith("ShadowRange") - || instructionTargeter.getClass().getName().endsWith("ExceptionRange") - || instructionTargeter.getClass().getName().endsWith("LineNumberTag")) { - isOK = true; - } else { - System.out.println(instructionTargeter.getClass()); - } - } - if (!isOK) { - target_vec.add(ih); - buf.append(ih.toString(true) + " "); - ih.next = ih.prev = null; - } else { - ih.dispose(); - } - - // if (ih.hasTargeters()) { // Still got targeters? - // InstructionTargeter[] targeters = ih.getTargeters(); - // boolean isOK = false; - // for (int i = 0; i < targeters.length; i++) { - // InstructionTargeter instructionTargeter = targeters[i]; - // if (instructionTargeter.getClass().getName().endsWith("ShadowRange") - // || instructionTargeter.getClass().getName().endsWith("ExceptionRange") - // || instructionTargeter.getClass().getName().endsWith("LineNumberTag")) { - // isOK = true; - // } else { - // System.out.println(instructionTargeter.getClass()); - // } - // } - // if (!isOK) { - // target_vec.add(ih); - // buf.append(ih.toString(true) + " "); - // ih.next = ih.prev = null; - // } else { - // ih.dispose(); - // } - // } else { - // ih.dispose(); - // } - } - - buf.append("}"); - - if (!target_vec.isEmpty()) { - InstructionHandle[] targeted = new InstructionHandle[target_vec.size()]; - target_vec.toArray(targeted); - throw new TargetLostException(targeted, buf.toString()); - } - } - - /** - * Remove instruction from this list. The corresponding Instruction handles must not be reused! - * - * @param ih instruction (handle) to remove - */ - public void delete(InstructionHandle ih) throws TargetLostException { - remove(ih.prev, ih.next, false); - } - - /** - * Remove instruction from this list. The corresponding Instruction handles must not be reused! - * - * @param i instruction to remove - */ - // public void delete(Instruction i) throws TargetLostException { - // InstructionHandle ih; - // - // if((ih = findInstruction1(i)) == null) - // throw new ClassGenException("Instruction " + i + - // " is not contained in this list."); - // delete(ih); - // } - /** - * Remove instructions from instruction `from' to instruction `to' contained in this list. The user must ensure that `from' is - * an instruction before `to', or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from where to start deleting (inclusive) - * @param to where to end deleting (inclusive) - */ - public void delete(InstructionHandle from, InstructionHandle to) throws TargetLostException { - remove(from.prev, to.next, false); - } - - /** - * Remove instructions from instruction `from' to instruction `to' contained in this list. The user must ensure that `from' is - * an instruction before `to', or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from where to start deleting (inclusive) - * @param to where to end deleting (inclusive) - */ - public void delete(Instruction from, Instruction to) throws TargetLostException { - InstructionHandle from_ih, to_ih; - - if ((from_ih = findInstruction1(from)) == null) { - throw new ClassGenException("Instruction " + from + " is not contained in this list."); - } - - if ((to_ih = findInstruction2(to)) == null) { - throw new ClassGenException("Instruction " + to + " is not contained in this list."); - } - delete(from_ih, to_ih); - } - - /** - * Search for given Instruction reference, start at beginning of list. - * - * @param i instruction to search for - * @return instruction found on success, null otherwise - */ - private InstructionHandle findInstruction1(Instruction i) { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - if (ih.instruction == i) { - return ih; - } - } - - return null; - } - - /** - * Search for given Instruction reference, start at end of list - * - * @param i instruction to search for - * @return instruction found on success, null otherwise - */ - private InstructionHandle findInstruction2(Instruction i) { - for (InstructionHandle ih = end; ih != null; ih = ih.prev) { - if (ih.instruction == i) { - return ih; - } - } - - return null; - } - - public boolean contains(InstructionHandle i) { - if (i == null) { - return false; - } - - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - if (ih == i) { - return true; - } - } - - return false; - } - - public boolean contains(Instruction i) { - return findInstruction1(i) != null; - } - - public void setPositions() { - setPositions(false); - } - - /** - * Give all instructions their position number (offset in byte stream), i.e., make the list ready to be dumped. - * - * @param check Perform sanity checks, e.g. if all targeted instructions really belong to this list - */ - public void setPositions(boolean check) { - int maxAdditionalBytes = 0; - int index = 0, count = 0; - int[] pos = new int[length]; - - // Pass 0: Sanity checks - if (check) { - checkInstructionList(); - } - - // Pass 1: Set position numbers and sum up the maximum number of bytes an - // instruction may be shifted. - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - ih.setPosition(index); - pos[count++] = index; - - /* - * Get an estimate about how many additional bytes may be added, because BranchInstructions may have variable length - * depending on the target offset (short vs. int) or alignment issues (TABLESWITCH and LOOKUPSWITCH). - */ - switch (i.opcode) { - case Constants.JSR: - case Constants.GOTO: - maxAdditionalBytes += 2; - break; - - case Constants.TABLESWITCH: - case Constants.LOOKUPSWITCH: - maxAdditionalBytes += 3; - break; - } - index += i.getLength(); - } - - // OPTIMIZE positions will only move around if there have been expanding instructions - // if (max_additional_bytes==0...) { - // - // } - - /* - * Pass 2: Expand the variable-length (Branch)Instructions depending on the target offset (short or int) and ensure that - * branch targets are within this list. - */ - boolean nonZeroOffset = false; - int offset = 0; - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - if (ih instanceof BranchHandle) { - offset += ((BranchHandle) ih).updatePosition(offset, maxAdditionalBytes); - if (offset != 0) { - nonZeroOffset = true; - } - } - } - if (nonZeroOffset) { - /* - * Pass 3: Update position numbers (which may have changed due to the preceding expansions), like pass 1. - */ - index = count = 0; - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - ih.setPosition(index); - pos[count++] = index; - index += i.getLength(); - } - } - - positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, positions, 0, count); - } - - private void checkInstructionList() { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - - if (i instanceof InstructionBranch) { // target instruction within list? - Instruction inst = ((InstructionBranch) i).getTarget().instruction; - if (!contains(inst)) { - throw new ClassGenException("Branch target of " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst - + " not in instruction list"); - } - - if (i instanceof InstructionSelect) { - InstructionHandle[] targets = ((InstructionSelect) i).getTargets(); - - for (int j = 0; j < targets.length; j++) { - inst = targets[j].instruction; - if (!contains(inst)) { - throw new ClassGenException("Branch target of " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst - + " not in instruction list"); - } - } - } - - if (!(ih instanceof BranchHandle)) { - throw new ClassGenException("Branch instruction " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst - + " not contained in BranchHandle."); - } - - } - } - } - - /** - * When everything is finished, use this method to convert the instruction list into an array of bytes. - * - * @return the byte code ready to be dumped - */ - public byte[] getByteCode() { - // Update position indices of instructions - setPositions(); - - ByteArrayOutputStream b = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(b); - - try { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - i.dump(out); // Traverse list - } - } catch (IOException e) { - System.err.println(e); - return null; - } - byte[] byteCode = b.toByteArray(); - if (byteCode.length > Constants.MAX_CODE_SIZE) { - throw new ClassGenException("Code size too big: " + byteCode.length); - } - - return byteCode; - } - - /** - * @return an array of instructions without target information for branch instructions. - */ - public Instruction[] getInstructions() { - ByteSequence bytes = new ByteSequence(getByteCode()); - ArrayList instructions = new ArrayList(); - - try { - while (bytes.available() > 0) { - instructions.add(Instruction.readInstruction(bytes)); - } - } catch (IOException e) { - throw new ClassGenException(e.toString()); - } - - Instruction[] result = new Instruction[instructions.size()]; - instructions.toArray(result); - return result; - } - - @Override - public String toString() { - return toString(true); - } - - /** - * @param verbose toggle output format - * @return String containing all instructions in this list. - */ - public String toString(boolean verbose) { - StringBuffer buf = new StringBuffer(); - - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - buf.append(ih.toString(verbose) + "\n"); - } - - return buf.toString(); - } - - /** - * @return Enumeration that lists all instructions (handles) - */ - public Iterator iterator() { - return new Iterator() { - private InstructionHandle ih = start; - - public Object next() { - InstructionHandle i = ih; - ih = ih.next; - return i; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public boolean hasNext() { - return ih != null; - } - }; - } - - /** - * @return array containing all instructions (handles) - */ - public InstructionHandle[] getInstructionHandles() { - InstructionHandle[] ihs = new InstructionHandle[length]; - InstructionHandle ih = start; - - for (int i = 0; i < length; i++) { - ihs[i] = ih; - ih = ih.next; - } - - return ihs; - } - - /** - * Get positions (offsets) of all instructions in the list. This relies on that the list has been freshly created from an byte - * code array, or that setPositions() has been called. Otherwise this may be inaccurate. - * - * @return array containing all instruction's offset in byte code - */ - public int[] getInstructionPositions() { - return positions; - } - - /** - * @return complete, i.e., deep copy of this list - */ - public InstructionList copy() { - HashMap map = new HashMap(); - InstructionList il = new InstructionList(); - - /* - * Pass 1: Make copies of all instructions, append them to the new list and associate old instruction references with the - * new ones, i.e., a 1:1 mapping. - */ - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - Instruction c = i.copy(); // Use clone for shallow copy - - if (c instanceof InstructionBranch) { - map.put(ih, il.append((InstructionBranch) c)); - } else { - map.put(ih, il.append(c)); - } - } - - /* - * Pass 2: Update branch targets. - */ - InstructionHandle ih = start; - InstructionHandle ch = il.start; - - while (ih != null) { - Instruction i = ih.instruction; - Instruction c = ch.instruction; - - if (i instanceof InstructionBranch) { - InstructionBranch bi = (InstructionBranch) i; - InstructionBranch bc = (InstructionBranch) c; - InstructionHandle itarget = bi.getTarget(); // old target - - // New target is in hash map - bc.setTarget(map.get(itarget)); - - if (bi instanceof InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionHandle[] itargets = ((InstructionSelect) bi).getTargets(); - InstructionHandle[] ctargets = ((InstructionSelect) bc).getTargets(); - - for (int j = 0; j < itargets.length; j++) { // Update all targets - ctargets[j] = map.get(itargets[j]); - } - } - } - - ih = ih.next; - ch = ch.next; - } - - return il; - } - - /** - * Replace all references to the old constant pool with references to the new constant pool - */ - public void replaceConstantPool(ConstantPool old_cp, ConstantPool new_cp) { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - if (i.isConstantPoolInstruction()) { - InstructionCP ci = (InstructionCP) i; - Constant c = old_cp.getConstant(ci.getIndex()); - ci.setIndex(new_cp.addConstant(c, old_cp)); - } - } - } - - private void clear() { - start = end = null; - length = 0; - } - - /** - * Delete contents of list. Provides better memory utilization, because the system then may reuse the instruction handles. This - * method is typically called right after MethodGen.getMethod(). - */ - public void dispose() { - // Traverse in reverse order, because ih.next is overwritten - for (InstructionHandle ih = end; ih != null; ih = ih.prev) { - /* - * Causes BranchInstructions to release target and targeters, because it calls dispose() on the contained instruction. - */ - ih.dispose(); - } - - clear(); - } - - /** - * @return start of list - */ - public InstructionHandle getStart() { - return start; - } - - /** - * @return end of list - */ - public InstructionHandle getEnd() { - return end; - } - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int getLength() { - return length; - } - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int size() { - return length; - } - - /** - * Redirect all references from old_target to new_target, i.e., update targets of branch instructions. - * - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - */ - public void redirectBranches(InstructionHandle old_target, InstructionHandle new_target) { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.getInstruction(); - - if (i instanceof InstructionBranch) { - InstructionBranch b = (InstructionBranch) i; - InstructionHandle target = b.getTarget(); - - if (target == old_target) { - b.setTarget(new_target); - } - - if (b instanceof InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionHandle[] targets = ((InstructionSelect) b).getTargets(); - - for (int j = 0; j < targets.length; j++) { - if (targets[j] == old_target) { - ((InstructionSelect) b).setTarget(j, new_target); - } - } - } - } - } - } - - /** - * Redirect all references of local variables from old_target to new_target. - * - * @param lg array of local variables - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - * @see MethodGen - */ - public void redirectLocalVariables(LocalVariableGen[] lg, InstructionHandle old_target, InstructionHandle new_target) { - for (int i = 0; i < lg.length; i++) { - InstructionHandle start = lg[i].getStart(); - InstructionHandle end = lg[i].getEnd(); - - if (start == old_target) { - lg[i].setStart(new_target); - } - if (end == old_target) { - lg[i].setEnd(new_target); - } - } - } - - /** - * Redirect all references of exception handlers from old_target to new_target. - * - * @param exceptions array of exception handlers - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - * @see MethodGen - */ - public void redirectExceptionHandlers(CodeExceptionGen[] exceptions, InstructionHandle old_target, InstructionHandle new_target) { - for (int i = 0; i < exceptions.length; i++) { - if (exceptions[i].getStartPC() == old_target) { - exceptions[i].setStartPC(new_target); - } - - if (exceptions[i].getEndPC() == old_target) { - exceptions[i].setEndPC(new_target); - } - - if (exceptions[i].getHandlerPC() == old_target) { - exceptions[i].setHandlerPC(new_target); - } - } - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java deleted file mode 100644 index b4e00c027..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java +++ /dev/null @@ -1,291 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.util.ByteSequence; - -/** - * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions. - * - * @version $Id: InstructionSelect.java,v 1.4 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - * @see LOOKUPSWITCH - * @see TABLESWITCH - * @see InstructionList - */ -public abstract class InstructionSelect extends InstructionBranch { - protected int[] match; // matches, i.e., case 1: ... - protected int[] indices; // target offsets - protected InstructionHandle[] targets; // target objects in instruction list - protected int fixedLength; // fixed length defined by subclasses - protected int matchLength; // number of cases - protected int padding = 0; // number of pad bytes for alignment - - protected short length; - - /** - * (Match, target) pairs for switch. `Match' and `targets' must have the same length of course. - * - * @param match array of matching values - * @param targets instruction targets - * @param target default instruction target - */ - InstructionSelect(short opcode, int[] match, InstructionHandle[] targets, InstructionHandle target) { - super(opcode, target); - - this.targets = targets; - for (int i = 0; i < targets.length; i++) { - notifyTarget(null, targets[i], this); - } - - this.match = match; - - if ((matchLength = match.length) != targets.length) { - throw new ClassGenException("Match and target array have not the same length"); - } - - indices = new int[matchLength]; - } - - protected int getTargetOffset(InstructionHandle target) { - if (target == null) { - throw new ClassGenException("Target of " + super.toString(true) + " is invalid null handle"); - } - - int t = target.getPosition(); - - if (t < 0) { - throw new ClassGenException("Invalid branch target position offset for " + super.toString(true) + ":" + t + ":" - + target); - } - - return t - positionOfThisInstruction; - } - - /** - * Since this is a variable length instruction, it may shift the following instructions which then need to update their - * position. - * - * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length - * instructions `setPositions' performs multiple passes over the instruction list to calculate the correct (byte) positions and - * offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition(int offset, int max_offset) { - positionOfThisInstruction += offset; // Additional offset caused by - // preceding SWITCHs, GOTOs, - // etc. - - short old_length = length; - - /* - * Alignment on 4-byte-boundary, + 1, because of tag byte. - */ - padding = (4 - (positionOfThisInstruction + 1) % 4) % 4; - length = (short) (fixedLength + padding); // Update length - - return length - old_length; - } - - /** - * Dump instruction as byte code to stream out. - * - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - - for (int i = 0; i < padding; i++) { - out.writeByte(0); - } - - targetIndex = getTargetOffset(); // Write default target offset - out.writeInt(targetIndex); - } - - public InstructionSelect(short opcode, ByteSequence bytes) throws IOException { - super(opcode); - padding = (4 - bytes.getIndex() % 4) % 4; // Compute number of pad bytes - - for (int i = 0; i < padding; i++) { - bytes.readByte(); - } - - // Default branch target common for both cases (TABLESWITCH, - // LOOKUPSWITCH) - targetIndex = bytes.readInt(); - } - - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - StringBuffer buf = new StringBuffer(super.toString(verbose)); - - if (verbose) { - for (int i = 0; i < matchLength; i++) { - String s = "null"; - - if (targets[i] != null) { - s = targets[i].getInstruction().toString(); - } - - buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})"); - } - } else { - buf.append(" ..."); - } - - return buf.toString(); - } - - /** - * Set branch target for `i'th case - */ - public void setTarget(int i, InstructionHandle target) { - notifyTarget(targets[i], target, this); - targets[i] = target; - } - - /** - * @param old_ih old target - * @param new_ih new target - */ - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if (targetInstruction == old_ih) { - targeted = true; - setTarget(new_ih); - } - - for (int i = 0; i < targets.length; i++) { - if (targets[i] == old_ih) { - targeted = true; - setTarget(i, new_ih); - } - } - - if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih); - } - } - - /** - * @return true, if ih is target of this instruction - */ - public boolean containsTarget(InstructionHandle ih) { - if (targetInstruction == ih) { - return true; - } - - for (int i = 0; i < targets.length; i++) { - if (targets[i] == ih) { - return true; - } - } - - return false; - } - - /** - * Inform targets that they're not targeted anymore. - */ - void dispose() { - super.dispose(); - - for (int i = 0; i < targets.length; i++) { - targets[i].removeTargeter(this); - } - } - - /** - * @return array of match indices - */ - public int[] getMatchs() { - return match; - } - - /** - * @return array of match target offsets - */ - public int[] getIndices() { - return indices; - } - - public boolean equals(Object other) { - return this == other; - } - - public int hashCode() { - return opcode * 37; - } - - /** - * @return array of match targets - */ - public InstructionHandle[] getTargets() { - return targets; - } - - public int getLength() { - return length; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java deleted file mode 100644 index 99054cbff..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Instruction that needs one short - */ -public class InstructionShort extends Instruction { - private final short value; - - public InstructionShort(short opcode, short value) { - super(opcode); - this.value = value; - } - - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeShort(value); - } - - public String toString(boolean verbose) { - return super.toString(verbose) + " " + value; - } - - public boolean equals(Object other) { - if (!(other instanceof InstructionShort)) { - return false; - } - InstructionShort o = (InstructionShort) other; - return o.opcode == opcode && o.value == value; - } - - public int hashCode() { - return opcode * 37 + value; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionTargeter.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionTargeter.java deleted file mode 100644 index 950ed3fa9..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionTargeter.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Denote that a class targets InstructionHandles within an InstructionList. Namely - * the following implementers: - * - * @see BranchHandle - * @see LocalVariableGen - * @see CodeExceptionGen - * @version $Id: InstructionTargeter.java,v 1.3 2008/05/28 23:52:57 aclement Exp $ - * @author M. Dahm - */ -public interface InstructionTargeter { - public boolean containsTarget(InstructionHandle ih); - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih); -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeDynamic.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeDynamic.java deleted file mode 100644 index b3c7ba85a..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeDynamic.java +++ /dev/null @@ -1,129 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -package org.aspectj.apache.bcel.generic; - -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantInvokeDynamic; -import org.aspectj.apache.bcel.classfile.ConstantNameAndType; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -/** - * INVOKEDYNAMIC - * - * @author Andy Clement - */ -public final class InvokeDynamic extends InvokeInstruction { - - public InvokeDynamic(int index, int zeroes) { - super(Constants.INVOKEDYNAMIC, index); - } - - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - out.writeShort(0); - } - - public String toString(ConstantPool cp) { - return super.toString(cp) + " " + index; - } - - public boolean equals(Object other) { - if (!(other instanceof InvokeDynamic)) { - return false; - } - InvokeDynamic o = (InvokeDynamic) other; - return o.opcode == opcode && o.index == index; - } - - public int hashCode() { - return opcode * 37 + index; - } - - public Type getReturnType(ConstantPool cp) { - return Type.getReturnType(getSignature(cp)); - } - - public Type[] getArgumentTypes(ConstantPool cp) { - return Type.getArgumentTypes(getSignature(cp)); - } - - public String getSignature(ConstantPool cp) { - if (signature == null) { - ConstantInvokeDynamic cid = (ConstantInvokeDynamic)cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex()); - signature = cp.getConstantUtf8(cnat.getSignatureIndex()).getValue(); - } - return signature; - } - - @Override - public String getName(ConstantPool cp) { - if (name == null) { - ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex()); - name = cp.getConstantUtf8(cnat.getNameIndex()).getValue(); - } - return name; - } - - public String getClassName(ConstantPool cp) { - throw new IllegalStateException("there is no classname for invokedynamic"); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java deleted file mode 100644 index 89cd43474..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java +++ /dev/null @@ -1,137 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.util.StringTokenizer; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Constant; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -/** - * Super class for the INVOKExxx family of instructions. - * - * @version $Id: InvokeInstruction.java,v 1.6 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public class InvokeInstruction extends FieldOrMethod { - - /** - * @param index to constant pool - */ - public InvokeInstruction(short opcode, int index) { - super(opcode, index); - } - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - Constant c = cp.getConstant(index); - StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); - - return Constants.OPCODE_NAMES[opcode] + " " + tok.nextToken().replace('.', '/') + tok.nextToken(); - } - - /** - * Also works for instructions whose stack effect depends on the constant pool entry they reference. - * - * @return Number of words consumed from stack by this instruction - */ - public int consumeStack(ConstantPool cpg) { - String signature = getSignature(cpg); - int sum = Type.getArgumentSizes(signature); - if (opcode != Constants.INVOKESTATIC) { - sum += 1; - } - return sum; - } - - /** - * Also works for instructions whose stack effect depends on the constant pool entry they reference. - * - * @return Number of words produced onto stack by this instruction - */ - public int produceStack(ConstantPool cpg) { - return getReturnType(cpg).getSize(); - } - - /** - * @return return type of referenced method. - */ - public Type getType(ConstantPool cpg) { - return getReturnType(cpg); - } - - /** - * @return name of referenced method. - */ - public String getMethodName(ConstantPool cpg) { - return getName(cpg); - } - - /** - * @return return type of referenced method. - */ - public Type getReturnType(ConstantPool cpg) { - return Type.getReturnType(getSignature(cpg)); - } - - /** - * @return argument types of referenced method. - */ - public Type[] getArgumentTypes(ConstantPool cpg) { - return Type.getArgumentTypes(getSignature(cpg)); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java deleted file mode 100644 index c8ebcba4c..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.util.ByteSequence; - -/** - * LOOKUPSWITCH - Switch with unordered set of values - * - * @version $Id: LOOKUPSWITCH.java,v 1.5 2011/04/05 15:15:33 aclement Exp $ - * @author M. Dahm - */ -public class LOOKUPSWITCH extends InstructionSelect { - - public LOOKUPSWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target) { - super(LOOKUPSWITCH, match, targets, target); - // Alignment remainer assumed 0 here, until dump time - length = (short) (9 + matchLength * 8); - fixedLength = length; - } - - /** - * Dump instruction as byte code to stream out. - * - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - out.writeInt(matchLength); // npairs - - for (int i = 0; i < matchLength; i++) { - out.writeInt(match[i]); // match-offset pairs - out.writeInt(indices[i] = getTargetOffset(targets[i])); - } - } - - /** - * Read needed data (e.g. index) from file. - */ - public LOOKUPSWITCH(ByteSequence bytes) throws IOException { - super(Constants.LOOKUPSWITCH, bytes); // reads padding - - matchLength = bytes.readInt(); - fixedLength = (short) (9 + matchLength * 8); - length = (short) (fixedLength + padding); - - match = new int[matchLength]; - indices = new int[matchLength]; - targets = new InstructionHandle[matchLength]; - - for (int i = 0; i < matchLength; i++) { - match[i] = bytes.readInt(); - indices[i] = bytes.readInt(); - } - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberGen.java deleted file mode 100644 index 237720c7b..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberGen.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.classfile.LineNumber; - -/** - * This class represents a line number within a method, i.e., give an instruction - * a line number corresponding to the source code line. - * - * @version $Id: LineNumberGen.java,v 1.5 2008/05/28 23:53:00 aclement Exp $ - * @author M. Dahm - * @see LineNumber - * @see MethodGen - */ -public class LineNumberGen - implements InstructionTargeter, Cloneable, java.io.Serializable -{ - private InstructionHandle ih; - private int src_line; - - /** - * Create a line number. - * - * @param ih instruction handle to reference - */ - public LineNumberGen(InstructionHandle ih, int src_line) { - setInstruction(ih); - setSourceLine(src_line); - } - - /** - * @return true, if ih is target of this line number - */ - public boolean containsTarget(InstructionHandle ih) { - return this.ih == ih; - } - - /** - * @param old_ih old target - * @param new_ih new target - */ - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - if(old_ih != ih) - throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); - else - setInstruction(new_ih); - } - - /** - * Get LineNumber attribute . - * - * This relies on that the instruction list has already been dumped to byte code or - * or that the `setPositions' methods has been called for the instruction list. - */ - public LineNumber getLineNumber() { - return new LineNumber(ih.getPosition(), src_line); - } - - public void setInstruction(InstructionHandle ih) { - InstructionBranch.notifyTarget(this.ih, ih, this); - - this.ih = ih; - } - - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } - - public InstructionHandle getInstruction() { return ih; } - public void setSourceLine(int src_line) { this.src_line = src_line; } - public int getSourceLine() { return src_line; } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java deleted file mode 100644 index fe1d56c27..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * PARC initial implementation - * Andy Clement pushed down into bcel module - * ******************************************************************/ - - -package org.aspectj.apache.bcel.generic; - -/** - * we don't actually target instructions, but instructions target us. - */ -public class LineNumberTag extends Tag { - - private final int lineNumber; - - public LineNumberTag(int lineNumber) { - this.lineNumber = lineNumber; - } - - public int getLineNumber() { - return lineNumber; - } - - public String toString() { - return "line " + lineNumber; - } - - public boolean equals(Object other) { - if (!(other instanceof LineNumberTag)) return false; - return lineNumber == ((LineNumberTag)other).lineNumber; - } - - public int hashCode() { - return lineNumber; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableGen.java deleted file mode 100644 index b701e7274..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableGen.java +++ /dev/null @@ -1,220 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.LocalVariable; - -/** - * This class represents a local variable within a method. It contains its scope, name and type. The generated LocalVariable object - * can be obtained with getLocalVariable which needs the instruction list and the constant pool as parameters. - * - * @version $Id: LocalVariableGen.java,v 1.7 2008/08/28 00:04:23 aclement Exp $ - * @author M. Dahm - * @see LocalVariable - * @see MethodGen - */ -public class LocalVariableGen implements InstructionTargeter, Cloneable, java.io.Serializable { - private int index; - private String name; - private Type type; - private InstructionHandle start, end; - - /** - * Generate a local variable that with index `index'. Note that double and long variables need two indexs. Index indices have to - * be provided by the user. - * - * @param index index of local variable - * @param name its name - * @param type its type - * @param start from where the instruction is valid (null means from the start) - * @param end until where the instruction is valid (null means to the end) - */ - public LocalVariableGen(int index, String name, Type type, InstructionHandle start, InstructionHandle end) { - if (index < 0 || index > Constants.MAX_SHORT) { - throw new ClassGenException("Invalid index index: " + index); - } - - this.name = name; - this.type = type; - this.index = index; - setStart(start); - setEnd(end); - } - - /** - * Get LocalVariable object. - * - * This relies on that the instruction list has already been dumped to byte code or or that the `setPositions' methods has been - * called for the instruction list. - * - * Note that for local variables whose scope end at the last instruction of the method's code, the JVM specification is - * ambiguous: both a start_pc+length ending at the last instruction and start_pc+length ending at first index beyond the end of - * the code are valid. - * - * @param il instruction list (byte code) which this variable belongs to - * @param cp constant pool - */ - public LocalVariable getLocalVariable(ConstantPool cp) { - int start_pc = start.getPosition(); - int length = end.getPosition() - start_pc; - - if (length > 0) { - length += end.getInstruction().getLength(); - } - - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(type.getSignature()); - - return new LocalVariable(start_pc, length, name_index, signature_index, index, cp); - } - - public void setIndex(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setType(Type type) { - this.type = type; - } - - public Type getType() { - return type; - } - - public InstructionHandle getStart() { - return start; - } - - public InstructionHandle getEnd() { - return end; - } - - public void setStart(InstructionHandle start) { - InstructionBranch.notifyTarget(this.start, start, this); - this.start = start; - } - - public void setEnd(InstructionHandle end) { - InstructionBranch.notifyTarget(this.end, end, this); - this.end = end; - } - - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if (start == old_ih) { - targeted = true; - setStart(new_ih); - } - - if (end == old_ih) { - targeted = true; - setEnd(new_ih); - } - - if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + end + "}"); - } - } - - /** - * @return true, if ih is target of this variable - */ - public boolean containsTarget(InstructionHandle ih) { - return start == ih || end == ih; - } - - /** - * We consider to local variables to be equal, if the use the same index and are valid in the same range. - */ - public boolean equals(Object o) { - if (!(o instanceof LocalVariableGen)) { - return false; - } - - LocalVariableGen l = (LocalVariableGen) o; - return l.index == index && l.start == start && l.end == end; - } - - public String toString() { - return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; - } - - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java deleted file mode 100644 index 7a4fab4e9..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * PARC initial implementation - * Andy Clement pushed down into bcel module - * ******************************************************************/ - -package org.aspectj.apache.bcel.generic; - -public final class LocalVariableTag extends Tag { - private final String signature; - private String name; - private int slot; - private final int startPosition; - private boolean remapped = false; - - private int hashCode = 0; - private Type type; // not always known, in which case signature has to be used - - // AMC - pr101047, two local vars with the same name can share the same slot, but must in that case - // have different start positions. - public LocalVariableTag(String signature, String name, int slot, int startPosition) { - this.signature = signature; - this.name = name; - this.slot = slot; - this.startPosition = startPosition; - } - - public LocalVariableTag(Type type, String signature, String name, int slot, int startPosition) { - this.type = type; - this.signature = signature; - this.name = name; - this.slot = slot; - this.startPosition = startPosition; - } - - public String getName() { - return name; - } - - public int getSlot() { - return slot; - } - - public String getType() { - return signature; - } - - public Type getRealType() { - return type; - } - - public void updateSlot(int newSlot) { - this.slot = newSlot; - this.remapped = true; - this.hashCode = 0; - } - - public void setName(String name) { - this.name = name; - this.hashCode = 0; - } - - public boolean isRemapped() { - return this.remapped; - } - - public String toString() { - return "local " + slot + ": " + signature + " " + name; - } - - public boolean equals(Object other) { - if (!(other instanceof LocalVariableTag)) { - return false; - } - LocalVariableTag o = (LocalVariableTag) other; - return o.slot == slot && o.startPosition == startPosition && o.signature.equals(signature) && o.name.equals(name); - } - - public int hashCode() { - if (hashCode == 0) { - int ret = signature.hashCode(); - ret = 37 * ret + name.hashCode(); - ret = 37 * ret + slot; - ret = 37 * ret + startPosition; - hashCode = ret; - } - return hashCode; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java deleted file mode 100644 index 94a213a25..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.ExceptionConstants; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -/** - * MULTIANEWARRAY - Create new mutidimensional array of references - * - *
- * Stack: ..., count1, [count2, ...] -> ..., arrayref
- * 
- * - * @version $Id: MULTIANEWARRAY.java,v 1.4 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public class MULTIANEWARRAY extends InstructionCP { - private short dimensions; - - public MULTIANEWARRAY(int index, short dimensions) { - super(Constants.MULTIANEWARRAY, index); - this.dimensions = dimensions; - } - - /** - * Dump instruction as byte code to stream out. - * - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - out.writeByte(dimensions); - } - - /** - * Read needed data (i.e., no. dimension) from file. - */ - // protected void initFromFile(ByteSequence bytes, boolean wide) - // throws IOException - // { - // super.initFromFile(bytes, wide); - // dimensions = bytes.readByte(); - // // length = 4; - // } - - /** - * @return number of dimensions to be created - */ - public final short getDimensions() { - return dimensions; - } - - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + index + " " + dimensions; - } - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - return super.toString(cp) + " " + dimensions; - } - - /** - * Also works for instructions whose stack effect depends on the constant pool entry they reference. - * - * @return Number of words consumed from stack by this instruction - */ - public int consumeStack(ConstantPool cpg) { - return dimensions; - } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - - return cs; - } - - public ObjectType getLoadClassType(ConstantPool cpg) { - Type t = getType(cpg); - - if (t instanceof ArrayType) { - t = ((ArrayType) t).getBasicType(); - } - - return (t instanceof ObjectType) ? (ObjectType) t : null; - } - - // /** - // * Call corresponding visitor method(s). The order is: - // * Call visitor methods of implemented interfaces first, then - // * call methods according to the class hierarchy in descending order, - // * i.e., the most specific visitXXX() call comes last. - // * - // * @param v Visitor object - // */ - // public void accept(Visitor v) { - // v.visitLoadClass(this); - // v.visitAllocationInstruction(this); - // v.visitExceptionThrower(this); - // v.visitTypedInstruction(this); - // v.visitCPInstruction(this); - // v.visitMULTIANEWARRAY(this); - // } - - public boolean equals(Object other) { - if (!(other instanceof MULTIANEWARRAY)) { - return false; - } - MULTIANEWARRAY o = (MULTIANEWARRAY) other; - return o.opcode == opcode && o.index == index && o.dimensions == dimensions; - } - - public int hashCode() { - return opcode * 37 + index * (dimensions + 17); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java deleted file mode 100644 index 3938beb35..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java +++ /dev/null @@ -1,1169 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Stack; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.Code; -import org.aspectj.apache.bcel.classfile.CodeException; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.ExceptionTable; -import org.aspectj.apache.bcel.classfile.LineNumber; -import org.aspectj.apache.bcel.classfile.LineNumberTable; -import org.aspectj.apache.bcel.classfile.LocalVariable; -import org.aspectj.apache.bcel.classfile.LocalVariableTable; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.Utility; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeParamAnnos; - -/** - * Template class for building up a method. This is done by defining exception handlers, adding thrown exceptions, local variables - * and attributes, whereas the 'LocalVariableTable' and 'LineNumberTable' attributes will be set automatically for the code. Use - * stripAttributes() if you don't like this. - * - * While generating code it may be necessary to insert NOP operations. You can use the `removeNOPs' method to get rid off them. The - * resulting method object can be obtained via the `getMethod()' method. - * - * @version $Id: MethodGen.java,v 1.17 2011/05/19 23:23:46 aclement Exp $ - * @author M. Dahm - * @author Patrick C. Beard [setMaxStack()] - * @see InstructionList - * @see Method - */ -public class MethodGen extends FieldGenOrMethodGen { - private String classname; - private Type[] parameterTypes; - private String[] parameterNames; - private int maxLocals; - private int maxStack; - private InstructionList il; - - // Indicates whether to produce code attributes for LineNumberTable and LocalVariableTable, like javac -O - private boolean stripAttributes; - - private int highestLineNumber = 0; - - private ArrayList localVariablesList = new ArrayList(); - private ArrayList lineNumbersList = new ArrayList(); - private ArrayList exceptionsList = new ArrayList(); - private ArrayList exceptionsThrown = new ArrayList(); - private ArrayList codeAttributesList = new ArrayList(); - private List[] param_annotations; // Array of lists containing AnnotationGen objects - private boolean hasParameterAnnotations = false; - private boolean haveUnpackedParameterAnnotations = false; - - /** - * Declare method. If the method is non-static the constructor automatically declares a local variable `$this' in slot 0. The - * actual code is contained in the `il' parameter, which may further manipulated by the user. But he must take care not to - * remove any instruction (handles) that are still referenced from this object. - * - * For example one may not add a local variable and later remove the instructions it refers to without causing havoc. It is safe - * however if you remove that local variable, too. - * - * @param access_flags access qualifiers - * @param return_type method type - * @param arg_types argument types - * @param arg_names argument names (if this is null, default names will be provided for them) - * @param method_name name of method - * @param class_name class name containing this method (may be null, if you don't care) - * @param il instruction list associated with this method, may be null only for abstract or native methods - * @param cp constant pool - */ - public MethodGen(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, String method_name, - String class_name, InstructionList il, ConstantPool cp) { - - this.modifiers = access_flags; - this.type = return_type; - this.parameterTypes = arg_types; - this.parameterNames = arg_names; - this.name = method_name; - this.classname = class_name; - this.il = il; - this.cp = cp; - - // OPTIMIZE this code messes with the local variables - do we need it? - // boolean abstract_ = isAbstract() || isNative(); - // InstructionHandle start = null; - // InstructionHandle end = null; - // - // if (!abstract_) { - // start = il.getStart(); - // end = il.getEnd(); - // - // /* Add local variables, namely the implicit `this' and the arguments - // */ - // // if(!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0 - // // addLocalVariable("this", new ObjectType(class_name), start, end); - // // } - // } - - // if(arg_types != null) { - // int size = arg_types.length; - // - // for(int i=0; i < size; i++) { - // if(Type.VOID == arg_types[i]) { - // throw new ClassGenException("'void' is an illegal argument type for a method"); - // } - // } - // - // if(arg_names != null) { // Names for variables provided? - // if(size != arg_names.length) - // throw new ClassGenException("Mismatch in argument array lengths: " + - // size + " vs. " + arg_names.length); - // } else { // Give them dummy names - // // arg_names = new String[size]; - // // - // // for(int i=0; i < size; i++) - // // arg_names[i] = "arg" + i; - // // - // // setArgumentNames(arg_names); - // } - - // if(!abstract_) { - // for(int i=0; i < size; i++) { - // // addLocalVariable(arg_names[i], arg_types[i], start, end); - // } - // } - // } - } - - public int getHighestlinenumber() { - return highestLineNumber; - } - - /** - * Instantiate from existing method. - * - * @param m method - * @param class_name class name containing this method - * @param cp constant pool - */ - - public MethodGen(Method m, String class_name, ConstantPool cp) { - this(m, class_name, cp, false); - } - - // OPTIMIZE should always use tags and never anything else! - public MethodGen(Method m, String class_name, ConstantPool cp, boolean useTags) { - this(m.getModifiers(), - // OPTIMIZE implementation of getReturnType() and getArgumentTypes() on Method seems weak - m.getReturnType(), m.getArgumentTypes(), null /* may be overridden anyway */, m.getName(), class_name, ((m - .getModifiers() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0) ? new InstructionList(m.getCode() - .getCode()) : null, cp); - - Attribute[] attributes = m.getAttributes(); - for (int i = 0; i < attributes.length; i++) { - Attribute a = attributes[i]; - - if (a instanceof Code) { - Code code = (Code) a; - setMaxStack(code.getMaxStack()); - setMaxLocals(code.getMaxLocals()); - - CodeException[] ces = code.getExceptionTable(); - - InstructionHandle[] arrayOfInstructions = il.getInstructionsAsArray(); - - // process the exception table - // - - if (ces != null) { - for (CodeException ce : ces) { - int type = ce.getCatchType(); - ObjectType catchType = null; - - if (type > 0) { - String cen = m.getConstantPool().getConstantString_CONSTANTClass(type); - catchType = new ObjectType(cen); - } - - int end_pc = ce.getEndPC(); - int length = m.getCode().getCode().length; - - InstructionHandle end; - - if (length == end_pc) { // May happen, because end_pc is exclusive - end = il.getEnd(); - } else { - end = il.findHandle(end_pc, arrayOfInstructions);// il.findHandle(end_pc); - end = end.getPrev(); // Make it inclusive - } - - addExceptionHandler(il.findHandle(ce.getStartPC(), arrayOfInstructions), end, il.findHandle(ce - .getHandlerPC(), arrayOfInstructions), catchType); - } - } - - Attribute[] codeAttrs = code.getAttributes(); - for (int j = 0; j < codeAttrs.length; j++) { - a = codeAttrs[j]; - - if (a instanceof LineNumberTable) { - LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable(); - if (useTags) { - // abracadabra, lets create tags rather than linenumbergens. - for (int k = 0; k < ln.length; k++) { - LineNumber l = ln[k]; - int lnum = l.getLineNumber(); - if (lnum > highestLineNumber) { - highestLineNumber = lnum; - } - LineNumberTag lt = new LineNumberTag(lnum); - il.findHandle(l.getStartPC(), arrayOfInstructions, true).addTargeter(lt); - } - } else { - for (int k = 0; k < ln.length; k++) { - LineNumber l = ln[k]; - addLineNumber(il.findHandle(l.getStartPC(), arrayOfInstructions, true), l.getLineNumber()); - } - } - } else if (a instanceof LocalVariableTable) { - - // Lets have a go at creating Tags directly - if (useTags) { - LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable(); - - for (int k = 0; k < lv.length; k++) { - LocalVariable l = lv[k]; - Type t = Type.getType(l.getSignature()); - LocalVariableTag lvt = new LocalVariableTag(t, l.getSignature(), l.getName(), l.getIndex(), l - .getStartPC()); - InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions, true); - byte b = t.getType(); - if (b != Constants.T_ADDRESS) { - int increment = t.getSize(); - if (l.getIndex() + increment > maxLocals) { - maxLocals = l.getIndex() + increment; - } - } - int end = l.getStartPC() + l.getLength(); - do { - start.addTargeter(lvt); - start = start.getNext(); - } while (start != null && start.getPosition() < end); - } - } else { - - LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable(); - - removeLocalVariables(); - - for (int k = 0; k < lv.length; k++) { - LocalVariable l = lv[k]; - InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions); - InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength(), arrayOfInstructions); - // AMC, this actually gives us the first instruction AFTER the range, - // so move back one... (findHandle can't cope with mid-instruction indices) - if (end != null) { - end = end.getPrev(); - } - // Repair malformed handles - if (null == start) { - start = il.getStart(); - } - if (null == end) { - end = il.getEnd(); - } - - addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end); - } - } - } else { - addCodeAttribute(a); - } - } - } else if (a instanceof ExceptionTable) { - String[] names = ((ExceptionTable) a).getExceptionNames(); - for (int j = 0; j < names.length; j++) { - addException(names[j]); - } - } else if (a instanceof RuntimeAnnos) { - RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) a; - List l = runtimeAnnotations.getAnnotations(); - annotationList.addAll(l); - // for (Iterator it = l.iterator(); it.hasNext();) { - // AnnotationGen element = it.next(); - // addAnnotation(new AnnotationGen(element, cp, false)); - // } - } else { - addAttribute(a); - } - } - } - - public LocalVariableGen addLocalVariable(String name, Type type, int slot, InstructionHandle start, InstructionHandle end) { - int size = type.getSize(); - if (slot + size > maxLocals) { - maxLocals = slot + size; - } - LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); - int i = localVariablesList.indexOf(l); - if (i >= 0) { - localVariablesList.set(i, l); // Overwrite if necessary - } else { - localVariablesList.add(l); - } - return l; - } - - /** - * Adds a local variable to this method and assigns an index automatically. - * - * @param name variable name - * @param type variable type - * @param start from where the variable is valid, if this is null, it is valid from the start - * @param end until where the variable is valid, if this is null, it is valid to the end - * @return new local variable object - * @see LocalVariable - */ - public LocalVariableGen addLocalVariable(String name, Type type, InstructionHandle start, InstructionHandle end) { - return addLocalVariable(name, type, maxLocals, start, end); - } - - /** - * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable with an explicit index argument. - */ - public void removeLocalVariable(LocalVariableGen l) { - localVariablesList.remove(l); - } - - /** - * Remove all local variables. - */ - public void removeLocalVariables() { - localVariablesList.clear(); - } - - /** - * Sort local variables by index - */ - private static final void sort(LocalVariableGen[] vars, int l, int r) { - int i = l, j = r; - int m = vars[(l + r) / 2].getIndex(); - LocalVariableGen h; - - do { - while (vars[i].getIndex() < m) { - i++; - } - while (m < vars[j].getIndex()) { - j--; - } - - if (i <= j) { - h = vars[i]; - vars[i] = vars[j]; - vars[j] = h; // Swap elements - i++; - j--; - } - } while (i <= j); - - if (l < j) { - sort(vars, l, j); - } - if (i < r) { - sort(vars, i, r); - } - } - - /* - * If the range of the variable has not been set yet, it will be set to be valid from the start to the end of the instruction - * list. - * - * @return array of declared local variables sorted by index - */ - public LocalVariableGen[] getLocalVariables() { - int size = localVariablesList.size(); - LocalVariableGen[] lg = new LocalVariableGen[size]; - localVariablesList.toArray(lg); - - for (int i = 0; i < size; i++) { - if (lg[i].getStart() == null) { - lg[i].setStart(il.getStart()); - } - - if (lg[i].getEnd() == null) { - lg[i].setEnd(il.getEnd()); - } - } - - if (size > 1) { - sort(lg, 0, size - 1); - } - - return lg; - } - - /** - * @return `LocalVariableTable' attribute of all the local variables of this method. - */ - public LocalVariableTable getLocalVariableTable(ConstantPool cp) { - LocalVariableGen[] lg = getLocalVariables(); - int size = lg.length; - LocalVariable[] lv = new LocalVariable[size]; - - for (int i = 0; i < size; i++) { - lv[i] = lg[i].getLocalVariable(cp); - } - - return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp); - } - - /** - * Give an instruction a line number corresponding to the source code line. - * - * @param ih instruction to tag - * @return new line number object - * @see LineNumber - */ - public LineNumberGen addLineNumber(InstructionHandle ih, int src_line) { - LineNumberGen l = new LineNumberGen(ih, src_line); - lineNumbersList.add(l); - return l; - } - - /** - * Remove a line number. - */ - public void removeLineNumber(LineNumberGen l) { - lineNumbersList.remove(l); - } - - /** - * Remove all line numbers. - */ - public void removeLineNumbers() { - lineNumbersList.clear(); - } - - /* - * @return array of line numbers - */ - public LineNumberGen[] getLineNumbers() { - LineNumberGen[] lg = new LineNumberGen[lineNumbersList.size()]; - lineNumbersList.toArray(lg); - return lg; - } - - /** - * @return 'LineNumberTable' attribute for all the local variables of this method. - */ - public LineNumberTable getLineNumberTable(ConstantPool cp) { - int size = lineNumbersList.size(); - LineNumber[] ln = new LineNumber[size]; - - for (int i = 0; i < size; i++) { - ln[i] = lineNumbersList.get(i).getLineNumber(); - } - - return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp); - } - - /** - * Add an exception handler, i.e., specify region where a handler is active and an instruction where the actual handling is - * done. - * - * @param start_pc Start of region (inclusive) - * @param end_pc End of region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type class type of handled exception or null if any exception is handled - * @return new exception handler object - */ - public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc, InstructionHandle end_pc, InstructionHandle handler_pc, - ObjectType catch_type) { - if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) { - throw new ClassGenException("Exception handler target is null instruction"); - } - - CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type); - exceptionsList.add(c); - return c; - } - - /** - * Remove an exception handler. - */ - public void removeExceptionHandler(CodeExceptionGen c) { - exceptionsList.remove(c); - } - - /** - * Remove all line numbers. - */ - public void removeExceptionHandlers() { - exceptionsList.clear(); - } - - /* - * @return array of declared exception handlers - */ - public CodeExceptionGen[] getExceptionHandlers() { - CodeExceptionGen[] cg = new CodeExceptionGen[exceptionsList.size()]; - exceptionsList.toArray(cg); - return cg; - } - - /** - * @return code exceptions for `Code' attribute - */ - private CodeException[] getCodeExceptions() { - int size = exceptionsList.size(); - CodeException[] c_exc = new CodeException[size]; - - try { - for (int i = 0; i < size; i++) { - CodeExceptionGen c = exceptionsList.get(i); - c_exc[i] = c.getCodeException(cp); - } - } catch (ArrayIndexOutOfBoundsException e) { - } - - return c_exc; - } - - /** - * Add an exception possibly thrown by this method. - * - * @param class_name (fully qualified) name of exception - */ - public void addException(String class_name) { - exceptionsThrown.add(class_name); - } - - /** - * Remove an exception. - */ - public void removeException(String c) { - exceptionsThrown.remove(c); - } - - /** - * Remove all exceptions. - */ - public void removeExceptions() { - exceptionsThrown.clear(); - } - - /* - * @return array of thrown exceptions - */ - public String[] getExceptions() { - String[] e = new String[exceptionsThrown.size()]; - exceptionsThrown.toArray(e); - return e; - } - - /** - * @return `Exceptions' attribute of all the exceptions thrown by this method. - */ - private ExceptionTable getExceptionTable(ConstantPool cp) { - int size = exceptionsThrown.size(); - int[] ex = new int[size]; - - try { - for (int i = 0; i < size; i++) { - ex[i] = cp.addClass(exceptionsThrown.get(i)); - } - } catch (ArrayIndexOutOfBoundsException e) { - } - - return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp); - } - - /** - * Add an attribute to the code. Currently, the JVM knows about the LineNumberTable, LocalVariableTable and StackMap attributes, - * where the former two will be generated automatically and the latter is used for the MIDP only. Other attributes will be - * ignored by the JVM but do no harm. - * - * @param a attribute to be added - */ - public void addCodeAttribute(Attribute a) { - codeAttributesList.add(a); - } - - public void addParameterAnnotationsAsAttribute(ConstantPool cp) { - if (!hasParameterAnnotations) { - return; - } - Attribute[] attrs = Utility.getParameterAnnotationAttributes(cp, param_annotations); - if (attrs != null) { - for (int i = 0; i < attrs.length; i++) { - addAttribute(attrs[i]); - } - } - } - - /** - * Remove a code attribute. - */ - public void removeCodeAttribute(Attribute a) { - codeAttributesList.remove(a); - } - - /** - * Remove all code attributes. - */ - public void removeCodeAttributes() { - codeAttributesList.clear(); - } - - /** - * @return all attributes of this method. - */ - public Attribute[] getCodeAttributes() { - Attribute[] attributes = new Attribute[codeAttributesList.size()]; - codeAttributesList.toArray(attributes); - return attributes; - } - - /** - * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively, before calling this method (the same - * applies for max locals). - * - * @return method object - */ - public Method getMethod() { - String signature = getSignature(); - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(signature); - - /* - * Also updates positions of instructions, i.e., their indices - */ - byte[] byte_code = null; - - if (il != null) { - try { - byte_code = il.getByteCode(); - } catch (Exception e) { - throw new IllegalStateException("Unexpected problem whilst preparing bytecode for " + this.getClassName() + "." - + this.getName() + this.getSignature(), e); - } - } - - LineNumberTable lnt = null; - LocalVariableTable lvt = null; - // J5TODO: LocalVariableTypeTable support! - - /* - * Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.) - */ - if ((localVariablesList.size() > 0) && !stripAttributes) { - addCodeAttribute(lvt = getLocalVariableTable(cp)); - } - - if ((lineNumbersList.size() > 0) && !stripAttributes) { - addCodeAttribute(lnt = getLineNumberTable(cp)); - } - - Attribute[] code_attrs = getCodeAttributes(); - - /* - * Each attribute causes 6 additional header bytes - */ - int attrs_len = 0; - for (int i = 0; i < code_attrs.length; i++) { - attrs_len += (code_attrs[i].getLength() + 6); - } - - CodeException[] c_exc = getCodeExceptions(); - int exc_len = c_exc.length * 8; // Every entry takes 8 bytes - - Code code = null; - - if ((il != null) && !isAbstract()) { - // Remove any stale code attribute - List attributes = getAttributes(); - for (int i = 0; i < attributes.size(); i++) { - Attribute a = attributes.get(i); - if (a instanceof Code) { - removeAttribute(a); - } - } - - code = new Code(cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code - 2 + exc_len + // exceptions - 2 + attrs_len, // attributes - maxStack, maxLocals, byte_code, c_exc, code_attrs, cp); - - addAttribute(code); - } - - addAnnotationsAsAttribute(cp); - addParameterAnnotationsAsAttribute(cp); - - ExceptionTable et = null; - - if (exceptionsThrown.size() > 0) { - addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses - } - - Method m = new Method(modifiers, name_index, signature_index, getAttributesImmutable(), cp); - - // Undo effects of adding attributes - // OPTIMIZE why redo this? is there a better way to clean up? - if (lvt != null) { - removeCodeAttribute(lvt); - } - if (lnt != null) { - removeCodeAttribute(lnt); - } - if (code != null) { - removeAttribute(code); - } - if (et != null) { - removeAttribute(et); - } - // J5TODO: Remove the annotation attributes that may have been added - return m; - } - - /** - * Set maximum number of local variables. - */ - public void setMaxLocals(int m) { - maxLocals = m; - } - - public int getMaxLocals() { - return maxLocals; - } - - /** - * Set maximum stack size for this method. - */ - public void setMaxStack(int m) { - maxStack = m; - } - - public int getMaxStack() { - return maxStack; - } - - /** - * @return class that contains this method - */ - public String getClassName() { - return classname; - } - - public void setClassName(String class_name) { - this.classname = class_name; - } - - public void setReturnType(Type return_type) { - setType(return_type); - } - - public Type getReturnType() { - return getType(); - } - - public void setArgumentTypes(Type[] arg_types) { - this.parameterTypes = arg_types; - } - - public Type[] getArgumentTypes() { - return this.parameterTypes; - }// OPTIMIZE dont need clone here? (Type[])arg_types.clone(); } - - public void setArgumentType(int i, Type type) { - parameterTypes[i] = type; - } - - public Type getArgumentType(int i) { - return parameterTypes[i]; - } - - public void setArgumentNames(String[] arg_names) { - this.parameterNames = arg_names; - } - - public String[] getArgumentNames() { - if (parameterNames != null) { - return parameterNames.clone(); - } else { - return new String[0]; - } - } - - public void setArgumentName(int i, String name) { - parameterNames[i] = name; - } - - public String getArgumentName(int i) { - return parameterNames[i]; - } - - public InstructionList getInstructionList() { - return il; - } - - public void setInstructionList(InstructionList il) { - this.il = il; - } - - @Override - public String getSignature() { - return Utility.toMethodSignature(type, parameterTypes); - } - - /** - * Computes max. stack size by performing control flow analysis. - */ - public void setMaxStack() { - if (il != null) { - maxStack = getMaxStack(cp, il, getExceptionHandlers()); - } else { - maxStack = 0; - } - } - - /** - * Compute maximum number of local variables based on the parameter count and bytecode usage of variables. - */ - public void setMaxLocals() { - setMaxLocals(false); - } - - /** - * Compute maximum number of local variables. - * - * @param respectLocalVariableTable if true and the local variable table indicates more are in use - * than the code suggests, respect the higher value from the local variable table data. - */ - public void setMaxLocals(boolean respectLocalVariableTable) { - if (il != null) { - int max = isStatic() ? 0 : 1; - - if (parameterTypes != null) { - for (int i = 0; i < parameterTypes.length; i++) { - max += parameterTypes[i].getSize(); - } - } - - for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { - Instruction ins = ih.getInstruction(); - - if ((ins instanceof InstructionLV) || (ins instanceof RET)) { - int index = ins.getIndex() + ins.getType(cp).getSize(); - - if (index > max) { - max = index; - } - } - } - if (!respectLocalVariableTable || max > maxLocals) { - maxLocals = max; - } - } else { - if (!respectLocalVariableTable) { - maxLocals = 0; - } - } - } - - public void stripAttributes(boolean flag) { - stripAttributes = flag; - } - - static final class BranchTarget { - InstructionHandle target; - int stackDepth; - - BranchTarget(InstructionHandle target, int stackDepth) { - this.target = target; - this.stackDepth = stackDepth; - } - } - - static final class BranchStack { - Stack branchTargets = new Stack(); - Hashtable visitedTargets = new Hashtable(); - - public void push(InstructionHandle target, int stackDepth) { - if (visited(target)) { - return; - } - - branchTargets.push(visit(target, stackDepth)); - } - - public BranchTarget pop() { - if (!branchTargets.empty()) { - BranchTarget bt = branchTargets.pop(); - return bt; - } - - return null; - } - - private final BranchTarget visit(InstructionHandle target, int stackDepth) { - BranchTarget bt = new BranchTarget(target, stackDepth); - visitedTargets.put(target, bt); - - return bt; - } - - private final boolean visited(InstructionHandle target) { - return (visitedTargets.get(target) != null); - } - } - - /** - * Computes stack usage of an instruction list by performing control flow analysis. - * - * @return maximum stack depth used by method - */ - public static int getMaxStack(ConstantPool cp, InstructionList il, CodeExceptionGen[] et) { - BranchStack branchTargets = new BranchStack(); - - int stackDepth = 0; - int maxStackDepth = 0; - - /* - * Initially, populate the branch stack with the exception handlers, because these aren't (necessarily) branched to - * explicitly. In each case, the stack will have depth 1, containing the exception object. - */ - for (int i = 0, max = et.length; i < max; i++) { - InstructionHandle handlerPos = et[i].getHandlerPC(); - if (handlerPos != null) { - // it must be at least 1 since there is an exception handler - maxStackDepth = 1; - branchTargets.push(handlerPos, 1); - } - } - - InstructionHandle ih = il.getStart(); - while (ih != null) { - Instruction instruction = ih.getInstruction(); - short opcode = instruction.opcode; - int prod = instruction.produceStack(cp); - int con = instruction.consumeStack(cp); - int delta = prod - con; - - stackDepth += delta; - if (stackDepth > maxStackDepth) { - maxStackDepth = stackDepth; - } - - // choose the next instruction based on whether current is a branch. - if (instruction instanceof InstructionBranch) { - InstructionBranch branch = (InstructionBranch) instruction; - if (instruction instanceof InstructionSelect) { - // explore all of the select's targets. the default target is handled below. - InstructionSelect select = (InstructionSelect) branch; - InstructionHandle[] targets = select.getTargets(); - for (int i = 0; i < targets.length; i++) { - branchTargets.push(targets[i], stackDepth); - } - // nothing to fall through to. - ih = null; - } else if (!(branch.isIfInstruction())) { - // if an instruction that comes back to following PC, - // push next instruction, with stack depth reduced by 1. - if (opcode == Constants.JSR || opcode == Constants.JSR_W) { - branchTargets.push(ih.getNext(), stackDepth - 1); - } - ih = null; - } - // for all branches, the target of the branch is pushed on the branch stack. - // conditional branches have a fall through case, selects don't, and - // jsr/jsr_w return to the next instruction. - branchTargets.push(branch.getTarget(), stackDepth); - } else { - // check for instructions that terminate the method. - if (opcode == Constants.ATHROW || opcode == Constants.RET - || (opcode >= Constants.IRETURN && opcode <= Constants.RETURN)) { - ih = null; - } - } - // normal case, go to the next instruction. - if (ih != null) { - ih = ih.getNext(); - } - // if we have no more instructions, see if there are any deferred branches to explore. - if (ih == null) { - BranchTarget bt = branchTargets.pop(); - if (bt != null) { - ih = bt.target; - stackDepth = bt.stackDepth; - } - } - } - return maxStackDepth; - } - - /** - * Return string representation close to declaration format, `public static void main(String[]) throws IOException', e.g. - * - * @return String representation of the method. - */ - @Override - public final String toString() { - String access = Utility.accessToString(modifiers); - String signature = Utility.toMethodSignature(type, parameterTypes); - - signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable(cp)); - - StringBuffer buf = new StringBuffer(signature); - - if (exceptionsThrown.size() > 0) { - for (Iterator e = exceptionsThrown.iterator(); e.hasNext();) { - buf.append("\n\t\tthrows " + e.next()); - } - } - - return buf.toString(); - } - - // J5TODO: Should param_annotations be an array of arrays? Rather than an array of lists, this - // is more likely to suggest to the caller it is readonly (which a List does not). - /** - * Return a list of AnnotationGen objects representing parameter annotations - */ - public List getAnnotationsOnParameter(int i) { - ensureExistingParameterAnnotationsUnpacked(); - if (!hasParameterAnnotations || i > parameterTypes.length) { - return null; - } - return param_annotations[i]; - } - - /** - * Goes through the attributes on the method and identifies any that are RuntimeParameterAnnotations, extracting their contents - * and storing them as parameter annotations. There are two kinds of parameter annotation - visible and invisible. Once they - * have been unpacked, these attributes are deleted. (The annotations will be rebuilt as attributes when someone builds a Method - * object out of this MethodGen object). - */ - private void ensureExistingParameterAnnotationsUnpacked() { - if (haveUnpackedParameterAnnotations) { - return; - } - // Find attributes that contain parameter annotation data - List attrs = getAttributes(); - RuntimeParamAnnos paramAnnVisAttr = null; - RuntimeParamAnnos paramAnnInvisAttr = null; - - for (Attribute attribute : attrs) { - if (attribute instanceof RuntimeParamAnnos) { - - if (!hasParameterAnnotations) { - param_annotations = new List[parameterTypes.length]; - for (int j = 0; j < parameterTypes.length; j++) { - param_annotations[j] = new ArrayList(); - } - } - - hasParameterAnnotations = true; - RuntimeParamAnnos rpa = (RuntimeParamAnnos) attribute; - if (rpa.areVisible()) { - paramAnnVisAttr = rpa; - } else { - paramAnnInvisAttr = rpa; - } - for (int j = 0; j < parameterTypes.length; j++) { - // This returns Annotation[] ... - AnnotationGen[] annos = rpa.getAnnotationsOnParameter(j); - // ... which needs transforming into an AnnotationGen[] ... - // List mutable = makeMutableVersion(immutableArray); - // ... then add these to any we already know about - for (AnnotationGen anAnnotation : annos) { - param_annotations[j].add(anAnnotation); - } - } - } - } - if (paramAnnVisAttr != null) { - removeAttribute(paramAnnVisAttr); - } - if (paramAnnInvisAttr != null) { - removeAttribute(paramAnnInvisAttr); - } - haveUnpackedParameterAnnotations = true; - } - - private List /* AnnotationGen */ makeMutableVersion(AnnotationGen[] mutableArray) { - List result = new ArrayList(); - for (int i = 0; i < mutableArray.length; i++) { - result.add(new AnnotationGen(mutableArray[i], getConstantPool(), false)); - } - return result; - } - - public void addParameterAnnotation(int parameterIndex, AnnotationGen annotation) { - ensureExistingParameterAnnotationsUnpacked(); - if (!hasParameterAnnotations) { - param_annotations = new List[parameterTypes.length]; - hasParameterAnnotations = true; - } - List existingAnnotations = param_annotations[parameterIndex]; - if (existingAnnotations != null) { - existingAnnotations.add(annotation); - } else { - List l = new ArrayList(); - l.add(annotation); - param_annotations[parameterIndex] = l; - } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ObjectType.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ObjectType.java deleted file mode 100644 index 544363f16..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ObjectType.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.Repository; -import org.aspectj.apache.bcel.classfile.JavaClass; - -/** - * Denotes reference such as java.lang.String. - * - * @version $Id: ObjectType.java,v 1.7 2009/09/28 16:39:46 aclement Exp $ - * @author M. Dahm - */ -public class ObjectType extends ReferenceType { - private String classname; - - /** - * @param class_name fully qualified class name, e.g. java.lang.String - */ - public ObjectType(String class_name) { - super(Constants.T_REFERENCE, toSignature(class_name));// "L" + class_name.replace('.', '/') + ";"); - this.classname = class_name;// .replace('/', '.'); - } - - /** - * @param classname eg. java.lang.String - * @param signature eg. Ljava/lang/String; - */ - public ObjectType(String classname, String signature) { - super(Constants.T_REFERENCE, signature); - this.classname = classname; - } - - private static String toSignature(String classname) { - StringBuffer sig = new StringBuffer(); - sig.append("L").append(classname.replace('.', '/')); - sig.append(";"); - return sig.toString(); - } - - /** - * @return name of referenced class - */ - public String getClassName() { - return classname; - } - - /** - * @return a hash code value for the object. - */ - @Override - public int hashCode() { - return classname.hashCode(); - } - - /** - * @return true if both type objects refer to the same class. - */ - @Override - public boolean equals(Object type) { - return (type instanceof ObjectType) ? ((ObjectType) type).classname.equals(classname) : false; - } - - /** - * If "this" doesn't reference a class, it references an interface or a non-existant entity. - */ - public boolean referencesClass() { - JavaClass jc = Repository.lookupClass(classname); - if (jc == null) { - return false; - } else { - return jc.isClass(); - } - } - - /** - * If "this" doesn't reference an interface, it references a class or a non-existant entity. - */ - public boolean referencesInterface() { - JavaClass jc = Repository.lookupClass(classname); - if (jc == null) { - return false; - } else { - return !jc.isClass(); - } - } - - public boolean subclassOf(ObjectType superclass) { - if (this.referencesInterface() || superclass.referencesInterface()) { - return false; - } - - return Repository.instanceOf(this.classname, superclass.classname); - } - - /** - * Java Virtual Machine Specification edition 2, 5.4.4 Access Control - */ - public boolean accessibleTo(ObjectType accessor) { - JavaClass jc = Repository.lookupClass(classname); - - if (jc.isPublic()) { - return true; - } else { - JavaClass acc = Repository.lookupClass(accessor.classname); - return acc.getPackageName().equals(jc.getPackageName()); - } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java deleted file mode 100644 index 0fd2f498d..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; - -/** - * RET - Return from subroutine - * - *
- * Stack: ..., -> ..., address
- * 
- * - * @version $Id: RET.java,v 1.5 2009/10/05 17:35:36 aclement Exp $ - * @author M. Dahm - */ -public class RET extends Instruction { - private boolean wide; - private int index; // index to local variable containing the return address - - public RET(int index, boolean wide) { - super(Constants.RET); - this.index = index; - this.wide = wide; - // this.wide = index > org.aspectj.apache.bcel.Constants.MAX_BYTE; - } - - public void dump(DataOutputStream out) throws IOException { - if (wide) { - out.writeByte(Constants.WIDE); - } - out.writeByte(opcode); - if (wide) { - out.writeShort(index); - } else { - out.writeByte(index); - } - } - - public int getLength() { - if (wide) { - return 4; - } else { - return 2; - } - } - - public final int getIndex() { - return index; - } - - public final void setIndex(int index) { - this.index = index; - this.wide = index > Constants.MAX_BYTE; - } - - public String toString(boolean verbose) { - return super.toString(verbose) + " " + index; - } - - public Type getType(ConstantPool cp) { - return ReturnaddressType.NO_TARGET; - } - - public boolean equals(Object other) { - if (!(other instanceof RET)) { - return false; - } - RET o = (RET) other; - return o.opcode == opcode && o.index == index; - } - - public int hashCode() { - return opcode * 37 + index; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ReferenceType.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ReferenceType.java deleted file mode 100644 index 1e290f5a4..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ReferenceType.java +++ /dev/null @@ -1,365 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.Repository; -import org.aspectj.apache.bcel.classfile.JavaClass; - -/** - * Super class for object and array types. - * - * @version $Id: ReferenceType.java,v 1.6 2009/09/09 22:18:20 aclement Exp $ - * @author M. Dahm - */ -public abstract class ReferenceType extends Type { - - protected ReferenceType(byte t, String s) { - super(t, s); - } - - ReferenceType() { - super(Constants.T_OBJECT, ""); - } - - /** - * Return true iff this type is castable to another type t as defined in the JVM specification. The case where this is Type.NULL - * is not defined (see the CHECKCAST definition in the JVM specification). However, because e.g. CHECKCAST doesn't throw a - * ClassCastException when casting a null reference to any Object, true is returned in this case. - */ - public boolean isCastableTo(Type t) { - if (this.equals(Type.NULL)) { - return true; // If this is ever changed in isAssignmentCompatible() - } - - return isAssignmentCompatibleWith(t); - /* - * Yes, it's true: It's the same definition. See vmspec2 AASTORE / CHECKCAST definitions. - */ - } - - /** - * Return true iff this is assignment compatible with another type t as defined in the JVM specification; see the AASTORE - * definition there. - */ - public boolean isAssignmentCompatibleWith(Type t) { - if (!(t instanceof ReferenceType)) { - return false; - } - - ReferenceType T = (ReferenceType) t; - - if (this.equals(Type.NULL)) { - return true; // This is not explicitely stated, but clear. Isn't it? - } - - /* - * If this is a class type then - */ - if (this instanceof ObjectType && ((ObjectType) this).referencesClass()) { - /* - * If T is a class type, then this must be the same class as T, or this must be a subclass of T; - */ - if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) { - if (this.equals(T)) { - return true; - } - - if (Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName())) { - return true; - } - } - - /* - * If T is an interface type, this must implement interface T. - */ - if (T instanceof ObjectType && ((ObjectType) T).referencesInterface()) { - if (Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName())) { - return true; - } - } - } - - /* - * If this is an interface type, then: - */ - if (this instanceof ObjectType && ((ObjectType) this).referencesInterface()) { - /* - * If T is a class type, then T must be Object (2.4.7). - */ - if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) { - if (T.equals(Type.OBJECT)) { - return true; - } - } - - /* - * If T is an interface type, then T must be the same interface as this or a superinterface of this (2.13.2). - */ - if (T instanceof ObjectType && ((ObjectType) T).referencesInterface()) { - if (this.equals(T)) { - return true; - } - if (Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName())) { - return true; - } - } - } - - /* - * If this is an array type, namely, the type SC[], that is, an array of components of type SC, then: - */ - if (this instanceof ArrayType) { - /* - * If T is a class type, then T must be Object (2.4.7). - */ - if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) { - if (T.equals(Type.OBJECT)) { - return true; - } - } - - /* - * If T is an array type TC[], that is, an array of components of type TC, then one of the following must be true: - */ - if (T instanceof ArrayType) { - /* - * TC and SC are the same primitive type (2.4.1). - */ - Type sc = ((ArrayType) this).getElementType(); - Type tc = ((ArrayType) this).getElementType(); - - if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) { - return true; - } - - /* - * TC and SC are reference types (2.4.6), and type SC is assignable to TC by these runtime rules. - */ - if (tc instanceof ReferenceType && sc instanceof ReferenceType - && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { - return true; - } - } - - /* If T is an interface type, T must be one of the interfaces implemented by arrays (2.15). */ - // TODO: Check if this is still valid or find a way to dynamically find out which - // interfaces arrays implement. However, as of the JVM specification edition 2, there - // are at least two different pages where assignment compatibility is defined and - // on one of them "interfaces implemented by arrays" is exchanged with "'Cloneable' or - // 'java.io.Serializable'" - if (T instanceof ObjectType && ((ObjectType) T).referencesInterface()) { - for (int ii = 0; ii < Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS.length; ii++) { - if (T.equals(new ObjectType(Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS[ii]))) { - return true; - } - } - } - } - return false; // default. - } - - /** - * This commutative operation returns the first common superclass (narrowest ReferenceType referencing a class, not an - * interface). If one of the types is a superclass of the other, the former is returned. If "this" is Type.NULL, then t is - * returned. If t is Type.NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If "this" or - * t is an ArrayType, then Type.OBJECT is returned; unless their dimensions match. Then an ArrayType of the same number of - * dimensions is returned, with its basic type being the first common super class of the basic types of "this" and t. If "this" - * or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. If not all of the two classes' superclasses - * cannot be found, "null" is returned. See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". - */ - public ReferenceType getFirstCommonSuperclass(ReferenceType t) { - if (this.equals(Type.NULL)) { - return t; - } - if (t.equals(Type.NULL)) { - return this; - } - if (this.equals(t)) { - return this; - /* - * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by Type.NULL so we can also - * say all the objects referenced by Type.NULL were derived from java.lang.Object. However, the Java Language's - * "instanceof" operator proves us wrong: "null" is not referring to an instance of java.lang.Object :) - */ - } - - /* This code is from a bug report by Konstantin Shagin */ - - if (this instanceof ArrayType && t instanceof ArrayType) { - ArrayType arrType1 = (ArrayType) this; - ArrayType arrType2 = (ArrayType) t; - if (arrType1.getDimensions() == arrType2.getDimensions() && arrType1.getBasicType() instanceof ObjectType - && arrType2.getBasicType() instanceof ObjectType) { - return new ArrayType(((ObjectType) arrType1.getBasicType()).getFirstCommonSuperclass((ObjectType) arrType2 - .getBasicType()), arrType1.getDimensions()); - - } - } - - if (this instanceof ArrayType || t instanceof ArrayType) { - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - } - - if (this instanceof ObjectType && ((ObjectType) this).referencesInterface() || t instanceof ObjectType - && ((ObjectType) t).referencesInterface()) { - return Type.OBJECT; - // TODO: The above line is correct comparing to the vmspec2. But one could - // make class file verification a bit stronger here by using the notion of - // superinterfaces or even castability or assignment compatibility. - } - - // this and t are ObjectTypes, see above. - ObjectType thiz = (ObjectType) this; - ObjectType other = (ObjectType) t; - JavaClass[] thiz_sups = Repository.lookupClass(thiz.getClassName()).getSuperClasses();// getSuperClasses(thiz.getClassName()); - JavaClass[] other_sups = Repository.lookupClass(other.getClassName()).getSuperClasses();// getSuperClasses(other.getClassName()); - - if (thiz_sups == null || other_sups == null) { - return null; - } - - // Waaahh... - JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - this_sups[0] = Repository.lookupClass(thiz.getClassName()); - t_sups[0] = Repository.lookupClass(other.getClassName()); - - for (int i = 0; i < t_sups.length; i++) { - for (int j = 0; j < this_sups.length; j++) { - if (this_sups[j].equals(t_sups[i])) { - return new ObjectType(this_sups[j].getClassName()); - } - } - } - - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; - } - - // /** - // * This commutative operation returns the first common superclass (narrowest ReferenceType referencing a class, not an - // * interface). If one of the types is a superclass of the other, the former is returned. If "this" is Type.NULL, then t is - // * returned. If t is Type.NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If "this" - // or - // * t is an ArrayType, then Type.OBJECT is returned. If "this" or t is a ReferenceType referencing an interface, then - // Type.OBJECT - // * is returned. If not all of the two classes' superclasses cannot be found, "null" is returned. See the JVM specification - // * edition 2, "4.9.2 The Bytecode Verifier". - // * - // * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has slightly changed semantics. - // */ - // public ReferenceType firstCommonSuperclass(ReferenceType t) { - // if (this.equals(Type.NULL)) { - // return t; - // } - // if (t.equals(Type.NULL)) { - // return this; - // } - // if (this.equals(t)) { - // return this; - // /* - // * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by Type.NULL so we can also - // * say all the objects referenced by Type.NULL were derived from java.lang.Object. However, the Java Language's - // * "instanceof" operator proves us wrong: "null" is not referring to an instance of java.lang.Object :) - // */ - // } - // - // if (this instanceof ArrayType || t instanceof ArrayType) { - // return Type.OBJECT; - // // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - // } - // - // if (this instanceof ObjectType && ((ObjectType) this).referencesInterface() || t instanceof ObjectType - // && ((ObjectType) t).referencesInterface()) { - // return Type.OBJECT; - // // TODO: The above line is correct comparing to the vmspec2. But one could - // // make class file verification a bit stronger here by using the notion of - // // superinterfaces or even castability or assignment compatibility. - // } - // - // // this and t are ObjectTypes, see above. - // ObjectType thiz = (ObjectType) this; - // ObjectType other = (ObjectType) t; - // JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); - // JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); - // - // if (thiz_sups == null || other_sups == null) { - // return null; - // } - // - // // Waaahh... - // JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - // JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - // System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - // System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - // this_sups[0] = Repository.lookupClass(thiz.getClassName()); - // t_sups[0] = Repository.lookupClass(other.getClassName()); - // - // for (int i = 0; i < t_sups.length; i++) { - // for (int j = 0; j < this_sups.length; j++) { - // if (this_sups[j].equals(t_sups[i])) { - // return new ObjectType(this_sups[j].getClassName()); - // } - // } - // } - // - // // Huh? Did you ask for Type.OBJECT's superclass?? - // return null; - // } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ReturnaddressType.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ReturnaddressType.java deleted file mode 100644 index a38ffedfd..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ReturnaddressType.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.generic.InstructionHandle; - -/** - * Returnaddress, the type JSR or JSR_W instructions push upon the stack. - * - * see vmspec2 3.3.3 - * @version $Id: ReturnaddressType.java,v 1.3 2008/05/28 23:52:56 aclement Exp $ - * @author Enver Haase - */ -public class ReturnaddressType extends Type { - - public static final ReturnaddressType NO_TARGET = new ReturnaddressType(); - private InstructionHandle returnTarget; - - /** - * A Returnaddress [that doesn't know where to return to]. - */ - private ReturnaddressType(){ - super(Constants.T_ADDRESS, ""); - } - - /** - * Creates a ReturnaddressType object with a target. - */ - public ReturnaddressType(InstructionHandle returnTarget) { - super(Constants.T_ADDRESS, ""); - this.returnTarget = returnTarget; - } - - /** - * Returns if the two Returnaddresses refer to the same target. - */ - public boolean equals(Object rat){ - if(!(rat instanceof ReturnaddressType)) - return false; - - return ((ReturnaddressType)rat).returnTarget.equals(this.returnTarget); - } - - /** - * @return the target of this ReturnaddressType - */ - public InstructionHandle getTarget(){ - return returnTarget; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/SwitchBuilder.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/SwitchBuilder.java deleted file mode 100644 index eac6bf364..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/SwitchBuilder.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or - * TABLESWITCH instruction, depending on whether the match values (int[]) can be - * sorted with no gaps between the numbers. - * - * @version $Id: SwitchBuilder.java,v 1.2 2008/05/28 23:52:57 aclement Exp $ - * @author M. Dahm - */ -public final class SwitchBuilder { - private int[] match; - private InstructionHandle[] targets; - private InstructionSelect instruction; - private int match_length; - - /** - * Template for switch() constructs. If the match array can be - * sorted in ascending order with gaps no larger than max_gap - * between the numbers, a TABLESWITCH instruction is generated, and - * a LOOKUPSWITCH otherwise. The former may be more efficient, but - * needs more space. - * - * Note, that the key array always will be sorted, though we leave - * the original arrays unaltered. - * - * @param match array of match values (case 2: ... case 7: ..., etc.) - * @param targets the instructions to be branched to for each case - * @param target the default target - * @param max_gap maximum gap that may between case branches - */ - public SwitchBuilder(int[] match, InstructionHandle[] targets,InstructionHandle target, int max_gap) { - this.match = (int[])match.clone(); - this.targets = (InstructionHandle[])targets.clone(); - - if((match_length = match.length) < 2) // (almost) empty switch, or just default - if (match.length==0) { - instruction = new LOOKUPSWITCH(match,targets,target); - } else { - instruction = new TABLESWITCH(match,targets,target); - } - else { - sort(0, match_length - 1); - - if(matchIsOrdered(max_gap)) { - fillup(max_gap, target); - - instruction = new TABLESWITCH(this.match, this.targets, target); - } - else - instruction = new LOOKUPSWITCH(this.match, this.targets, target); - } - } - - public SwitchBuilder(int[] match, InstructionHandle[] targets, InstructionHandle target) { - this(match, targets, target, 1); - } - - private final void fillup(int max_gap, InstructionHandle target) { - int max_size = match_length + match_length * max_gap; - int[] m_vec = new int[max_size]; - InstructionHandle[] t_vec = new InstructionHandle[max_size]; - int count = 1; - - m_vec[0] = match[0]; - t_vec[0] = targets[0]; - - for(int i=1; i < match_length; i++) { - int prev = match[i-1]; - int gap = match[i] - prev; - - for(int j=1; j < gap; j++) { - m_vec[count] = prev + j; - t_vec[count] = target; - count++; - } - - m_vec[count] = match[i]; - t_vec[count] = targets[i]; - count++; - } - - match = new int[count]; - targets = new InstructionHandle[count]; - - System.arraycopy(m_vec, 0, match, 0, count); - System.arraycopy(t_vec, 0, targets, 0, count); - } - - /** - * Sort match and targets array with QuickSort. - */ - private final void sort(int l, int r) { - int i = l, j = r; - int h, m = match[(l + r) / 2]; - InstructionHandle h2; - - do { - while(match[i] < m) i++; - while(m < match[j]) j--; - - if(i <= j) { - h=match[i]; match[i]=match[j]; match[j]=h; // Swap elements - h2=targets[i]; targets[i]=targets[j]; targets[j]=h2; // Swap instructions, too - i++; j--; - } - } while(i <= j); - - if(l < j) sort(l, j); - if(i < r) sort(i, r); - } - - /** - * @return match is sorted in ascending order with no gap bigger than max_gap? - */ - private final boolean matchIsOrdered(int max_gap) { - for(int i=1; i < match_length; i++) { - int diff = (match[i]-match[i-1]); - if(diff > max_gap || diff<0) return false; - } - return true; - } - - public final InstructionSelect getInstruction() { - return instruction; - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/TABLESWITCH.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/TABLESWITCH.java deleted file mode 100644 index 5dc26346b..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/TABLESWITCH.java +++ /dev/null @@ -1,138 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.generic; - -import java.io.DataOutputStream; -import java.io.IOException; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.util.ByteSequence; - -import com.sun.org.apache.bcel.internal.generic.SWITCH; - -/** - * TABLESWITCH - Switch within given range of values, i.e., low..high - * - * @version $Id: TABLESWITCH.java,v 1.5 2008/08/28 00:05:29 aclement Exp $ - * @author M. Dahm - * @see SWITCH - */ -public class TABLESWITCH extends InstructionSelect { - - /** - * @param match sorted array of match values, match[0] must be low value, match[match_length - 1] high value - * @param targets where to branch for matched values - * @param target default branch - */ - public TABLESWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target) { - super(org.aspectj.apache.bcel.Constants.TABLESWITCH, match, targets, target); - - // if (match_length==0) { - // throw new RuntimeException("A tableswitch with no targets should be represented as a LOOKUPSWITCH"); - // } - - // Alignment remainder assumed 0 here, until dump time - length = (short) (13 + matchLength * 4); - fixedLength = length; - } - - /** - * Dump instruction as byte code to stream out. - * - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - - int low = matchLength > 0 ? match[0] : 0; - out.writeInt(low); - - int high = matchLength > 0 ? match[matchLength - 1] : 0; - out.writeInt(high); - - // See aj bug pr104720 - // if (match_length==0) out.writeInt(0); // following the switch you need to supply "HIGH-LOW+1" entries - - for (int i = 0; i < matchLength; i++) { - out.writeInt(indices[i] = getTargetOffset(targets[i])); - } - } - - /** - * Read needed data (e.g. index) from file. - */ - public TABLESWITCH(ByteSequence bytes) throws IOException { - super(Constants.TABLESWITCH, bytes); - - int low = bytes.readInt(); - int high = bytes.readInt(); - - matchLength = high - low + 1; - fixedLength = (short) (13 + matchLength * 4); - length = (short) (fixedLength + padding); - - match = new int[matchLength]; - indices = new int[matchLength]; - targets = new InstructionHandle[matchLength]; - - for (int i = low; i <= high; i++) { - match[i - low] = i; - } - - for (int i = 0; i < matchLength; i++) { - indices[i] = bytes.readInt(); - } - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java deleted file mode 100644 index 1d6935e6d..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * PARC initial implementation - * Andy Clement pushed down into bcel module - * ******************************************************************/ - -package org.aspectj.apache.bcel.generic; - -/** - * A tag is an instruction-targeter that does not remember its target. Instruction handles will maintain a list of targeters but - * there won't be a way to get back from the tag to the instruction. Maintaining these backward/forward links just slows everything - * down. - */ -public abstract class Tag implements InstructionTargeter, Cloneable { - - public Tag() { - } - - // ---- from InstructionTargeter - public boolean containsTarget(InstructionHandle ih) { - return false; - } - - public void updateTarget(InstructionHandle oldHandle, InstructionHandle newHandle) { - oldHandle.removeTargeter(this); - if (newHandle != null) { - newHandle.addTargeter(this); - } - } - - public Tag copy() { - try { - return (Tag) clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException("Sanity check, can't clone me"); - } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/TargetLostException.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/TargetLostException.java deleted file mode 100644 index 3a195705c..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/TargetLostException.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/** - * Thrown by InstructionList.remove() when one or multiple disposed instruction - * are still being referenced by a InstructionTargeter object. I.e. the - * InstructionTargeter has to be notified that (one of) the InstructionHandle it - * is referencing is being removed from the InstructionList and thus not valid anymore. - * - * Making this an exception instead of a return value forces the user to handle - * these case explicitely in a try { ... } catch. The following code illustrates - * how this may be done: - * - *
- *     ...
- *     try {
- *	il.delete(start_ih, end_ih);
- *     } catch(TargetLostException e) {
- *       InstructionHandle[] targets = e.getTargets();
- *	 for(int i=0; i < targets.length; i++) {
- *	   InstructionTargeter[] targeters = targets[i].getTargeters();
- *     
- *	   for(int j=0; j < targeters.length; j++)
- *	     targeters[j].updateTarget(targets[i], new_target);
- *       }
- *     }
- * 
- * - * @see InstructionHandle - * @see InstructionList - * @see InstructionTargeter - * @version $Id: TargetLostException.java,v 1.3 2008/05/28 23:52:55 aclement Exp $ - * @author M. Dahm - */ -// OPTIMIZE make unchecked, or get rid of it! -public final class TargetLostException extends Exception { - private InstructionHandle[] targets; - - TargetLostException(InstructionHandle[] t, String mesg) { - super(mesg); - targets = t; - } - - /** - * @return list of instructions still being targeted. - */ - public InstructionHandle[] getTargets() { return targets; } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java deleted file mode 100644 index 9ce007b4f..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java +++ /dev/null @@ -1,508 +0,0 @@ -package org.aspectj.apache.bcel.generic; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.ConstantsInitializer; -import org.aspectj.apache.bcel.classfile.ClassFormatException; -import org.aspectj.apache.bcel.classfile.Utility; - -/** - * Abstract super class for all possible java types, namely basic types such as int, object types like String and array types, e.g. - * int[] - * - * @version $Id: Type.java,v 1.14 2011/09/28 01:14:54 aclement Exp $ - * @author M. Dahm - * - * modified: AndyClement 2-mar-05: Removed unnecessary static and optimized - */ -public abstract class Type { - protected byte type; - protected String signature; - - /* Predefined constants */ - public static final BasicType VOID = new BasicType(Constants.T_VOID); - public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN); - public static final BasicType INT = new BasicType(Constants.T_INT); - public static final BasicType SHORT = new BasicType(Constants.T_SHORT); - public static final BasicType BYTE = new BasicType(Constants.T_BYTE); - public static final BasicType LONG = new BasicType(Constants.T_LONG); - public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE); - public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT); - public static final BasicType CHAR = new BasicType(Constants.T_CHAR); - public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); - public static final ObjectType STRING = new ObjectType("java.lang.String"); - public static final ArrayType OBJECT_ARRAY = new ArrayType("java.lang.Object",1); - public static final ArrayType STRING_ARRAY = new ArrayType("java.lang.String",1); - public static final ArrayType CLASS_ARRAY = new ArrayType("java.lang.Class",1); - public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); - public static final ObjectType STRINGBUILDER = new ObjectType("java.lang.StringBuilder"); - public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); - public static final ObjectType CLASS = new ObjectType("java.lang.Class"); - public static final ObjectType INTEGER = new ObjectType("java.lang.Integer"); - public static final ObjectType EXCEPTION = new ObjectType("java.lang.Exception"); - public static final ObjectType LIST = new ObjectType("java.util.List"); - public static final ObjectType ITERATOR = new ObjectType("java.util.Iterator"); - public static final Type[] NO_ARGS = new Type[0]; - public static final ReferenceType NULL = new ReferenceType() { - }; - public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, "") { - }; - public static final Type[] STRINGARRAY1 = new Type[] { STRING }; - public static final Type[] STRINGARRAY2 = new Type[] { STRING, STRING }; - public static final Type[] STRINGARRAY3 = new Type[] { STRING, STRING, STRING }; - public static final Type[] STRINGARRAY4 = new Type[] { STRING, STRING, STRING, STRING }; - public static final Type[] STRINGARRAY5 = new Type[] { STRING, STRING, STRING, STRING, STRING }; - public static final Type[] STRINGARRAY6 = new Type[] { STRING, STRING, STRING, STRING, STRING, STRING }; - public static final Type[] STRINGARRAY7 = new Type[] { STRING, STRING, STRING, STRING, STRING, STRING, STRING }; - - private static Map commonTypes = new HashMap(); - - static { - commonTypes.put(STRING.getSignature(), STRING); - commonTypes.put(THROWABLE.getSignature(), THROWABLE); - commonTypes.put(VOID.getSignature(), VOID); - commonTypes.put(BOOLEAN.getSignature(), BOOLEAN); - commonTypes.put(BYTE.getSignature(), BYTE); - commonTypes.put(SHORT.getSignature(), SHORT); - commonTypes.put(CHAR.getSignature(), CHAR); - commonTypes.put(INT.getSignature(), INT); - commonTypes.put(LONG.getSignature(), LONG); - commonTypes.put(DOUBLE.getSignature(), DOUBLE); - commonTypes.put(FLOAT.getSignature(), FLOAT); - commonTypes.put(CLASS.getSignature(), CLASS); - commonTypes.put(OBJECT.getSignature(), OBJECT); - commonTypes.put(STRING_ARRAY.getSignature(), STRING_ARRAY); - commonTypes.put(CLASS_ARRAY.getSignature(), CLASS_ARRAY); - commonTypes.put(OBJECT_ARRAY.getSignature(), OBJECT_ARRAY); - commonTypes.put(INTEGER.getSignature(), INTEGER); - commonTypes.put(EXCEPTION.getSignature(), EXCEPTION); - commonTypes.put(STRINGBUFFER.getSignature(), STRINGBUFFER); - commonTypes.put(STRINGBUILDER.getSignature(), STRINGBUILDER); - commonTypes.put(LIST.getSignature(), LIST); - commonTypes.put(ITERATOR.getSignature(), ITERATOR); - ConstantsInitializer.initialize(); // needs calling because it will not have run properly the first time - } - - protected Type(byte t, String s) { - type = t; - signature = s; - } - - public String getSignature() { - return signature; - } - - public byte getType() { - return type; - } - - /** - * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise) - */ - public int getSize() { - switch (type) { - case Constants.T_DOUBLE: - case Constants.T_LONG: - return 2; - case Constants.T_VOID: - return 0; - default: - return 1; - } - } - - /** - * @return Type string, e.g. 'int[]' - */ - @Override - public String toString() { - return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN))) ? signature : Utility - .signatureToString(signature, false); - } - - public static final Type getType(String signature) { - Type t = commonTypes.get(signature); - if (t != null) { - return t; - } - byte type = Utility.typeOfSignature(signature); - if (type <= Constants.T_VOID) { - return BasicType.getType(type); - } else if (type == Constants.T_ARRAY) { - int dim = 0; - do { - dim++; - } while (signature.charAt(dim) == '['); - // Recurse, but just once, if the signature is ok - Type componentType = getType(signature.substring(dim)); - return new ArrayType(componentType, dim); - } else { // type == T_REFERENCE - // generics awareness - int nextAngly = signature.indexOf('<'); - // Format is 'Lblahblah;' - int index = signature.indexOf(';'); // Look for closing ';' - - String typeString = null; - if (nextAngly == -1 || nextAngly > index) { - typeString = signature.substring(1, index).replace('/', '.'); - } else { - boolean endOfSigReached = false; - int posn = nextAngly; - int genericDepth = 0; - while (!endOfSigReached) { - switch (signature.charAt(posn++)) { - case '<': - genericDepth++; - break; - case '>': - genericDepth--; - break; - case ';': - if (genericDepth == 0) { - endOfSigReached = true; - } - break; - default: - } - } - index = posn - 1; - typeString = signature.substring(1, nextAngly).replace('/', '.'); - } - // ObjectType doesn't currently store parameterized info - return new ObjectType(typeString); - } - } - - /** - * Convert signature to a Type object. - * - * @param signature signature string such as Ljava/lang/String; - * @return type object - */ - public static final TypeHolder getTypeInternal(String signature) throws StringIndexOutOfBoundsException { - byte type = Utility.typeOfSignature(signature); - - if (type <= Constants.T_VOID) { - return new TypeHolder(BasicType.getType(type), 1); - } else if (type == Constants.T_ARRAY) { - int dim = 0; - do { - dim++; - } while (signature.charAt(dim) == '['); - // Recurse, but just once, if the signature is ok - TypeHolder th = getTypeInternal(signature.substring(dim)); - return new TypeHolder(new ArrayType(th.getType(), dim), dim + th.getConsumed()); - } else { // type == T_REFERENCE - // Format is 'Lblahblah;' - int index = signature.indexOf(';'); // Look for closing ';' - if (index < 0) { - throw new ClassFormatException("Invalid signature: " + signature); - } - - // generics awareness - int nextAngly = signature.indexOf('<'); - String typeString = null; - if (nextAngly == -1 || nextAngly > index) { - typeString = signature.substring(1, index).replace('/', '.'); - } else { - boolean endOfSigReached = false; - int posn = nextAngly; - int genericDepth = 0; - while (!endOfSigReached) { - switch (signature.charAt(posn++)) { - case '<': - genericDepth++; - break; - case '>': - genericDepth--; - break; - case ';': - if (genericDepth == 0) { - endOfSigReached = true; - } - break; - default: - } - } - index = posn - 1; - typeString = signature.substring(1, nextAngly).replace('/', '.'); - } - // ObjectType doesn't currently store parameterized info - return new TypeHolder(new ObjectType(typeString), index + 1); - } - } - - /** - * Convert return value of a method (signature) to a Type object. - * - * @param signature signature string such as (Ljava/lang/String;)V - * @return return type - */ - public static Type getReturnType(String signature) { - try { - // Read return type after ')' - int index = signature.lastIndexOf(')') + 1; - return getType(signature.substring(index)); - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - /** - * Convert arguments of a method (signature) to an array of Type objects. - * - * @param signature signature string such as (Ljava/lang/String;)V - * @return array of argument types - */ - // OPTIMIZE crap impl - public static Type[] getArgumentTypes(String signature) { - List argumentTypes = new ArrayList(); - int index; - Type[] types; - - try { // Read all declarations between for `(' and `)' - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - - index = 1; // current string position - - while (signature.charAt(index) != ')') { - TypeHolder th = getTypeInternal(signature.substring(index)); - argumentTypes.add(th.getType()); - index += th.getConsumed(); // update position - } - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - - types = new Type[argumentTypes.size()]; - argumentTypes.toArray(types); - return types; - } - - /** - * Work out the type of each argument in the signature and return the cumulative sizes of all the types (size means number of - * stack slots it consumes, eg double=2, int=1). Unlike the call above, this does minimal unpacking - */ - public static int getArgumentSizes(String signature) { - int size = 0; - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - - int index = 1; // current string position - try { - while (signature.charAt(index) != ')') { - byte type = Utility.typeOfSignature(signature.charAt(index)); - if (type <= Constants.T_VOID) { - size += BasicType.getType(type).getSize(); - index++; - } else if (type == Constants.T_ARRAY) { - int dim = 0; - do { - dim++; - } while (signature.charAt(dim + index) == '['); - TypeHolder th = getTypeInternal(signature.substring(dim + index)); - size += 1; - index += dim + th.getConsumed(); - } else { // type == T_REFERENCE - // Format is 'Lblahblah;' - int index2 = signature.indexOf(';', index); // Look for closing ';' - - // generics awareness - int nextAngly = signature.indexOf('<', index); - if (nextAngly == -1 || nextAngly > index2) { - } else { - boolean endOfSigReached = false; - int posn = nextAngly; - int genericDepth = 0; - while (!endOfSigReached) { - switch (signature.charAt(posn++)) { - case '<': - genericDepth++; - break; - case '>': - genericDepth--; - break; - case ';': - if (genericDepth == 0) { - endOfSigReached = true; - } - break; - default: - } - } - index2 = posn - 1; - } - size++; - index = index2 + 1; - } - } - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - return size; - } - - /** - * Return the size of the type expressed in the signature. The signature should contain only one type. - */ - public static int getTypeSize(String signature) { - byte type = Utility.typeOfSignature(signature.charAt(0)); - if (type <= Constants.T_VOID) { - return BasicType.getType(type).getSize(); - } else if (type == Constants.T_ARRAY) { - return 1; - } else { // type == T_REFERENCE - return 1; - } - } - - /** - * Convert runtime java.lang.Class to BCEL Type object. - * - * @param cl Java class - * @return corresponding Type object - */ - public static Type getType(java.lang.Class cl) { - if (cl == null) { - throw new IllegalArgumentException("Class must not be null"); - } - - /* - * That's an amazingly easy case, because getName() returns the signature. That's what we would have liked anyway. - */ - if (cl.isArray()) { - return getType(cl.getName()); - } else if (cl.isPrimitive()) { - if (cl == Integer.TYPE) { - return INT; - } else if (cl == Void.TYPE) { - return VOID; - } else if (cl == Double.TYPE) { - return DOUBLE; - } else if (cl == Float.TYPE) { - return FLOAT; - } else if (cl == Boolean.TYPE) { - return BOOLEAN; - } else if (cl == Byte.TYPE) { - return BYTE; - } else if (cl == Short.TYPE) { - return SHORT; - } else if (cl == Byte.TYPE) { - return BYTE; - } else if (cl == Long.TYPE) { - return LONG; - } else if (cl == Character.TYPE) { - return CHAR; - } else { - throw new IllegalStateException("Ooops, what primitive type is " + cl); - } - } else { // "Real" class - return new ObjectType(cl.getName()); - } - } - - public static String getSignature(java.lang.reflect.Method meth) { - StringBuffer sb = new StringBuffer("("); - Class[] params = meth.getParameterTypes(); // avoid clone - - for (int j = 0; j < params.length; j++) { - sb.append(getType(params[j]).getSignature()); - } - - sb.append(")"); - sb.append(getType(meth.getReturnType()).getSignature()); - return sb.toString(); - } - - public static String getSignature(java.lang.reflect.Constructor cons) { - StringBuffer sb = new StringBuffer("("); - Class[] params = cons.getParameterTypes(); // avoid clone - - for (int j = 0; j < params.length; j++) { - sb.append(getType(params[j]).getSignature()); - } - - sb.append(")V"); - return sb.toString(); - } - - public static class TypeHolder { - private Type t; - private int consumed; - - public Type getType() { - return t; - } - - public int getConsumed() { - return consumed; - } - - public TypeHolder(Type t, int i) { - this.t = t; - this.consumed = i; - } - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/ByteSequence.java b/bcel-builder/src/org/aspectj/apache/bcel/util/ByteSequence.java deleted file mode 100644 index 072a7ba52..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/ByteSequence.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.aspectj.apache.bcel.util; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -import java.io.*; - -/** - * Utility class that implements a sequence of bytes which can be read - * via the `readByte()' method. This is used to implement a wrapper for the - * Java byte code stream to gain some more readability. - * - * @version $Id: ByteSequence.java,v 1.3 2008/05/28 23:52:53 aclement Exp $ - * @author M. Dahm - */ -public final class ByteSequence extends DataInputStream { - private ByteArrayStream byte_stream; - - public ByteSequence(byte[] bytes) { - super(new ByteArrayStream(bytes)); - byte_stream = (ByteArrayStream)in; - } - - public final int getIndex() { return byte_stream.getPosition(); } - final void unreadByte() { byte_stream.unreadByte(); } - - private static final class ByteArrayStream extends ByteArrayInputStream { - ByteArrayStream(byte[] bytes) { super(bytes); } - final int getPosition() { return pos; } // is protected in ByteArrayInputStream - final void unreadByte() { if(pos > 0) pos--; } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderReference.java b/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderReference.java deleted file mode 100644 index f6fcbf5f8..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderReference.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -package org.aspectj.apache.bcel.util; - -/** - * Implementors should provide access to a ClassLoader instance. The reference can be passed around and cached - * but will not cause the code that caches it to have a hard reference to the classloader, so it is easier - * to manage the classloader instance. The default implementation will just wrap a classloader object but - * more sophisticated implementations could keep a WeakReference to the loader. - */ -public interface ClassLoaderReference { - - java.lang.ClassLoader getClassLoader(); - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java b/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java deleted file mode 100644 index e3c59556b..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java +++ /dev/null @@ -1,394 +0,0 @@ -package org.aspectj.apache.bcel.util; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.AbstractMap; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.WeakHashMap; - -import org.aspectj.apache.bcel.classfile.ClassParser; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.ClassLoaderRepository.SoftHashMap.SpecialValue; - -/** - * The repository maintains information about which classes have been loaded. - * - * It loads its data from the ClassLoader implementation passed into its constructor. - * - * @see org.aspectj.apache.bcel.Repository - * - * @version $Id: ClassLoaderRepository.java,v 1.13 2009/09/09 19:56:20 aclement Exp $ - * @author M. Dahm - * @author David Dixon-Peugh - */ -public class ClassLoaderRepository implements Repository { - private static java.lang.ClassLoader bootClassLoader = null; - private ClassLoaderReference loaderRef; - - // Choice of cache... - private WeakHashMap> localCache = new WeakHashMap>(); - private static SoftHashMap /* */sharedCache = new SoftHashMap(Collections.synchronizedMap(new HashMap())); - - // For fast translation of the classname *intentionally not static* - private SoftHashMap /* */nameMap = new SoftHashMap(new HashMap(), false); - - public static boolean useSharedCache = System.getProperty("org.aspectj.apache.bcel.useSharedCache", "true").equalsIgnoreCase("true"); - - private static int cacheHitsShared = 0; - private static int missSharedEvicted = 0; // Misses in shared cache access due to reference GC - private long timeManipulatingURLs = 0L; - private long timeSpentLoading = 0L; - private int classesLoadedCount = 0; - private int misses = 0; - private int cacheHitsLocal = 0; - private int missLocalEvicted = 0; // Misses in local cache access due to reference GC - - public ClassLoaderRepository(java.lang.ClassLoader loader) { - this.loaderRef = new DefaultClassLoaderReference((loader != null) ? loader : getBootClassLoader()); - } - - public ClassLoaderRepository(ClassLoaderReference loaderRef) { - this.loaderRef = loaderRef; - } - - private static synchronized java.lang.ClassLoader getBootClassLoader() { - if (bootClassLoader == null) { - bootClassLoader = new URLClassLoader(new URL[0]); - } - return bootClassLoader; - } - - // Can track back to its key - public static class SoftHashMap extends AbstractMap { - private Map map; - boolean recordMiss = true; // only interested in recording miss stats sometimes - private ReferenceQueue rq = new ReferenceQueue(); - - public SoftHashMap(Map map) { - this.map = map; - } - - public SoftHashMap() { - this(new HashMap()); - } - - public SoftHashMap(Map map, boolean b) { - this(map); - this.recordMiss = b; - } - - class SpecialValue extends SoftReference { - private final Object key; - - SpecialValue(Object k, Object v) { - super(v, rq); - this.key = k; - } - } - - private void processQueue() { - SpecialValue sv = null; - while ((sv = (SpecialValue) rq.poll()) != null) { - map.remove(sv.key); - } - } - - @Override - public Object get(Object key) { - SpecialValue value = map.get(key); - if (value == null) - return null; - if (value.get() == null) { - // it got GC'd - map.remove(value.key); - if (recordMiss) - missSharedEvicted++; - return null; - } else { - return value.get(); - } - } - - @Override - public Object put(Object k, Object v) { - processQueue(); - return map.put(k, new SpecialValue(k, v)); - } - - @Override - public Set entrySet() { - return map.entrySet(); - } - - @Override - public void clear() { - processQueue(); - map.clear(); - } - - @Override - public int size() { - processQueue(); - return map.size(); - } - - @Override - public Object remove(Object k) { - processQueue(); - SpecialValue value = map.remove(k); - if (value == null) - return null; - if (value.get() != null) { - return value.get(); - } - return null; - } - } - - /** - * Store a new JavaClass into this repository as a soft reference and return the reference - */ - private void storeClassAsReference(URL url, JavaClass clazz) { - if (useSharedCache) { - clazz.setRepository(null); // can't risk setting repository, we'll get in a pickle! - sharedCache.put(url, clazz); - } else { - clazz.setRepository(this); - localCache.put(url, new SoftReference(clazz)); - } - } - - /** - * Store a new JavaClass into this Repository. - */ - public void storeClass(JavaClass clazz) { - storeClassAsReference(toURL(clazz.getClassName()), clazz); - } - - /** - * Remove class from repository - */ - public void removeClass(JavaClass clazz) { - if (useSharedCache) - sharedCache.remove(toURL(clazz.getClassName())); - else - localCache.remove(toURL(clazz.getClassName())); - } - - /** - * Find an already defined JavaClass in the local cache. - */ - public JavaClass findClass(String className) { - if (useSharedCache) - return findClassShared(toURL(className)); - else - return findClassLocal(toURL(className)); - } - - private JavaClass findClassLocal(URL url) { - Object o = localCache.get(url); - if (o != null) { - o = ((Reference) o).get(); - if (o != null) { - return (JavaClass) o; - } else { - missLocalEvicted++; - } - } - return null; - } - - /** - * Find an already defined JavaClass in the shared cache. - */ - private JavaClass findClassShared(URL url) { - return (JavaClass) sharedCache.get(url); - } - - private URL toURL(String className) { - URL url = (URL) nameMap.get(className); - if (url == null) { - String classFile = className.replace('.', '/'); - url = loaderRef.getClassLoader().getResource(classFile + ".class"); - nameMap.put(className, url); - } - return url; - } - - /** - * Lookup a JavaClass object from the Class Name provided. - */ - public JavaClass loadClass(String className) throws ClassNotFoundException { - - // translate to a URL - long time = System.currentTimeMillis(); - java.net.URL url = toURL(className); - timeManipulatingURLs += (System.currentTimeMillis() - time); - if (url == null) - throw new ClassNotFoundException(className + " not found - unable to determine URL"); - - JavaClass clazz = null; - - // Look in the appropriate cache - if (useSharedCache) { - clazz = findClassShared(url); - if (clazz != null) { - cacheHitsShared++; - return clazz; - } - } else { - clazz = findClassLocal(url); - if (clazz != null) { - cacheHitsLocal++; - return clazz; - } - } - - // Didn't find it in either cache - misses++; - - try { - // Load it - String classFile = className.replace('.', '/'); - InputStream is = (useSharedCache ? url.openStream() : loaderRef.getClassLoader().getResourceAsStream( - classFile + ".class")); - if (is == null) { - throw new ClassNotFoundException(className + " not found using url " + url); - } - ClassParser parser = new ClassParser(is, className); - clazz = parser.parse(); - - // Cache it - storeClassAsReference(url, clazz); - - timeSpentLoading += (System.currentTimeMillis() - time); - classesLoadedCount++; - return clazz; - } catch (IOException e) { - throw new ClassNotFoundException(e.toString()); - } - } - - /** - * Produce a report on cache usage. - */ - public String report() { - StringBuffer sb = new StringBuffer(); - sb.append("BCEL repository report."); - if (useSharedCache) - sb.append(" (shared cache)"); - else - sb.append(" (local cache)"); - sb.append(" Total time spent loading: " + timeSpentLoading + "ms."); - sb.append(" Time spent manipulating URLs: " + timeManipulatingURLs + "ms."); - sb.append(" Classes loaded: " + classesLoadedCount + "."); - if (useSharedCache) { - sb.append(" Shared cache size: " + sharedCache.size()); - sb.append(" Shared cache (hits/missDueToEviction): (" + cacheHitsShared + "/" + missSharedEvicted + ")."); - } else { - sb.append(" Local cache size: " + localCache.size()); - sb.append(" Local cache (hits/missDueToEviction): (" + cacheHitsLocal + "/" + missLocalEvicted + ")."); - } - return sb.toString(); - } - - /** - * Returns an array of the stats, for testing, the order is fixed: 0=time spent loading (static) 1=time spent manipulating URLs - * (static) 2=classes loaded (static) 3=cache hits shared (static) 4=misses in shared due to eviction (static) 5=cache hits - * local 6=misses in local due to eviction 7=shared cache size - */ - public long[] reportStats() { - return new long[] { timeSpentLoading, timeManipulatingURLs, classesLoadedCount, cacheHitsShared, missSharedEvicted, - cacheHitsLocal, missLocalEvicted, sharedCache.size() }; - } - - /** - * Reset statistics and clear all caches - */ - public void reset() { - timeManipulatingURLs = 0L; - timeSpentLoading = 0L; - classesLoadedCount = 0; - cacheHitsLocal = 0; - cacheHitsShared = 0; - missSharedEvicted = 0; - missLocalEvicted = 0; - misses = 0; - clear(); - } - - public JavaClass loadClass(Class clazz) throws ClassNotFoundException { - return loadClass(clazz.getName()); - } - - /** Clear all entries from the local cache */ - public void clear() { - if (useSharedCache) - sharedCache.clear(); - else - localCache.clear(); - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassPath.java b/bcel-builder/src/org/aspectj/apache/bcel/util/ClassPath.java deleted file mode 100644 index b7db332d2..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassPath.java +++ /dev/null @@ -1,584 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001, 2017 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ -package org.aspectj.apache.bcel.util; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.net.URI; -import java.nio.file.FileSystems; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributeView; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * Responsible for loading (class) files from the CLASSPATH. Inspired by - * sun.tools.ClassPath. - * - * @author M. Dahm - * @author Mario Ivankovits - * @author Andy Clement - */ -public class ClassPath implements Serializable { - private static final String JRT_FS = "jrt-fs.jar"; - - private static ClassPath SYSTEM_CLASS_PATH = null; - - private PathEntry[] paths; - private String class_path; - - public static ClassPath getSystemClassPath() { - if (SYSTEM_CLASS_PATH == null) { - SYSTEM_CLASS_PATH = new ClassPath(); - } - return SYSTEM_CLASS_PATH; - } - - /** - * Search for classes in given path. - */ - public ClassPath(String class_path) { - this.class_path = class_path; - - ArrayList vec = new ArrayList(); - - for (StringTokenizer tok = new StringTokenizer(class_path, System.getProperty("path.separator")); tok - .hasMoreTokens();) { - String path = tok.nextToken(); - - if (!path.equals("")) { - File file = new File(path); - - try { - if (file.exists()) { - if (file.isDirectory()) { - vec.add(new Dir(path)); - } else if (file.getName().endsWith("jrt-fs.jar")) { // TODO a bit crude... - vec.add(new JImage()); - } else { - vec.add(new Zip(new ZipFile(file))); - } - } - } catch (IOException e) { - System.err.println("CLASSPATH component " + file + ": " + e); - } - } - } - - paths = new PathEntry[vec.size()]; - vec.toArray(paths); - } - - /** - * Search for classes in CLASSPATH. - * - * @deprecated Use SYSTEM_CLASS_PATH constant - */ - @Deprecated - public ClassPath() { - this(getClassPath()); - } - - /** - * @return used class path string - */ - @Override - public String toString() { - return class_path; - } - - @Override - public int hashCode() { - return class_path.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (o instanceof ClassPath) { - return class_path.equals(((ClassPath) o).class_path); - } - - return false; - } - - private static final void getPathComponents(String path, ArrayList list) { - if (path != null) { - StringTokenizer tok = new StringTokenizer(path, File.pathSeparator); - - while (tok.hasMoreTokens()) { - String name = tok.nextToken(); - File file = new File(name); - - if (file.exists()) - list.add(name); - } - } - } - - /** - * Checks for class path components in the following properties: - * "java.class.path", "sun.boot.class.path", "java.ext.dirs" - * - * @return class path as used by default by BCEL - */ - public static final String getClassPath() { - String class_path = System.getProperty("java.class.path"); - String boot_path = System.getProperty("sun.boot.class.path"); - String ext_path = System.getProperty("java.ext.dirs"); - String vm_version = System.getProperty("java.version"); - - ArrayList list = new ArrayList(); - - getPathComponents(class_path, list); - getPathComponents(boot_path, list); - - ArrayList dirs = new ArrayList(); - getPathComponents(ext_path, dirs); - - for (Iterator e = dirs.iterator(); e.hasNext();) { - File ext_dir = new File(e.next()); - String[] extensions = ext_dir.list(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - name = name.toLowerCase(); - return name.endsWith(".zip") || name.endsWith(".jar"); - } - }); - - if (extensions != null) - for (int i = 0; i < extensions.length; i++) - list.add(ext_path + File.separatorChar + extensions[i]); - } - - StringBuffer buf = new StringBuffer(); - - for (Iterator e = list.iterator(); e.hasNext();) { - buf.append(e.next()); - - if (e.hasNext()) - buf.append(File.pathSeparatorChar); - } - - // On Java9 the sun.boot.class.path won't be set. System classes accessible through JRT filesystem - if (vm_version.startsWith("9") || vm_version.startsWith("10") || vm_version.startsWith("11")) { - buf.insert(0, File.pathSeparatorChar); - buf.insert(0, System.getProperty("java.home") + File.separator + "lib" + File.separator + JRT_FS); - } - - return buf.toString().intern(); - } - - /** - * @param name - * fully qualified class name, e.g. java.lang.String - * @return input stream for class - */ - public InputStream getInputStream(String name) throws IOException { - return getInputStream(name, ".class"); - } - - /** - * Return stream for class or resource on CLASSPATH. - * - * @param name - * fully qualified file name, e.g. java/lang/String - * @param suffix - * file name ends with suff, e.g. .java - * @return input stream for file on class path - */ - public InputStream getInputStream(String name, String suffix) throws IOException { - InputStream is = null; - - try { - is = getClass().getClassLoader().getResourceAsStream(name + suffix); - } catch (Exception e) { - } - - if (is != null) - return is; - - return getClassFile(name, suffix).getInputStream(); - } - - /** - * @param name - * fully qualified file name, e.g. java/lang/String - * @param suffix - * file name ends with suff, e.g. .java - * @return class file for the java class - */ - public ClassFile getClassFile(String name, String suffix) throws IOException { - for (int i = 0; i < paths.length; i++) { - ClassFile cf; - - if ((cf = paths[i].getClassFile(name, suffix)) != null) - return cf; - } - - throw new IOException("Couldn't find: " + name + suffix); - } - - /** - * @param name - * fully qualified class name, e.g. java.lang.String - * @return input stream for class - */ - public ClassFile getClassFile(String name) throws IOException { - return getClassFile(name, ".class"); - } - - /** - * @param name - * fully qualified file name, e.g. java/lang/String - * @param suffix - * file name ends with suffix, e.g. .java - * @return byte array for file on class path - */ - public byte[] getBytes(String name, String suffix) throws IOException { - InputStream is = getInputStream(name, suffix); - - if (is == null) - throw new IOException("Couldn't find: " + name + suffix); - - DataInputStream dis = new DataInputStream(is); - byte[] bytes = new byte[is.available()]; - dis.readFully(bytes); - dis.close(); - is.close(); - - return bytes; - } - - /** - * @return byte array for class - */ - public byte[] getBytes(String name) throws IOException { - return getBytes(name, ".class"); - } - - /** - * @param name - * name of file to search for, e.g. java/lang/String.java - * @return full (canonical) path for file - */ - public String getPath(String name) throws IOException { - int index = name.lastIndexOf('.'); - String suffix = ""; - - if (index > 0) { - suffix = name.substring(index); - name = name.substring(0, index); - } - - return getPath(name, suffix); - } - - /** - * @param name - * name of file to search for, e.g. java/lang/String - * @param suffix - * file name suffix, e.g. .java - * @return full (canonical) path for file, if it exists - */ - public String getPath(String name, String suffix) throws IOException { - return getClassFile(name, suffix).getPath(); - } - - private static abstract class PathEntry implements Serializable { - abstract ClassFile getClassFile(String name, String suffix) throws IOException; - } - - /** - * Contains information about file/ZIP entry of the Java class. - */ - public interface ClassFile { - /** - * @return input stream for class file. - */ - public abstract InputStream getInputStream() throws IOException; - - /** - * @return canonical path to class file. - */ - public abstract String getPath(); - - /** - * @return base path of found class, i.e. class is contained relative to - * that path, which may either denote a directory, or zip file - */ - public abstract String getBase(); - - /** - * @return modification time of class file. - */ - public abstract long getTime(); - - /** - * @return size of class file. - */ - public abstract long getSize(); - } - - private static class Dir extends PathEntry { - private String dir; - - Dir(String d) { - dir = d; - } - - @Override - ClassFile getClassFile(String name, String suffix) throws IOException { - final File file = new File(dir + File.separatorChar + name.replace('.', File.separatorChar) + suffix); - - return file.exists() ? new ClassFile() { - @Override - public InputStream getInputStream() throws IOException { - return new FileInputStream(file); - } - - @Override - public String getPath() { - try { - return file.getCanonicalPath(); - } catch (IOException e) { - return null; - } - - } - - @Override - public long getTime() { - return file.lastModified(); - } - - @Override - public long getSize() { - return file.length(); - } - - @Override - public String getBase() { - return dir; - } - - } : null; - } - - @Override - public String toString() { - return dir; - } - } - - private static class JImage extends PathEntry { - - private static URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$ - private static String MODULES_PATH = "modules"; //$NON-NLS-1$ - private static String JAVA_BASE_PATH = "java.base"; //$NON-NLS-1$ - - private java.nio.file.FileSystem fs; - private final Map fileMap; - - JImage() { - fs = FileSystems.getFileSystem(JRT_URI); - fileMap = buildFileMap(); - } - - private Map buildFileMap() { - final Map fileMap = new HashMap<>(); - final java.nio.file.PathMatcher matcher = fs.getPathMatcher("glob:*.class"); - Iterable roots = fs.getRootDirectories(); - for (java.nio.file.Path path : roots) { - try { - Files.walkFileTree(path, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (file.getNameCount() > 2 - && matcher.matches(file.getFileName())) { - Path classPath = file.subpath(2, file.getNameCount()); - fileMap.put(classPath.toString(), file); - } - - return FileVisitResult.CONTINUE; - } - }); - } - catch (IOException e) { - throw new RuntimeException(e); - } - } - return fileMap; - } - - private static class ByteBasedClassFile implements ClassFile { - - private byte[] bytes; - private ByteArrayInputStream bais; - private String path; - private String base; - private long time; - private long size; - - public ByteBasedClassFile(byte[] bytes, String path, String base, long time, long size) { - this.bytes = bytes; - this.path = path; - this.base = base; - this.time = time; - this.size = size; - } - - @Override - public InputStream getInputStream() throws IOException { - // TODO too costly to keep these in inflated form in memory? - this.bais = new ByteArrayInputStream(bytes); - return this.bais; - } - - @Override - public String getPath() { - return this.path; - } - - @Override - public String getBase() { - return this.base; - } - - @Override - public long getTime() { - return this.time; - } - - @Override - public long getSize() { - return this.size; - } - - } - - @Override - ClassFile getClassFile(String name, String suffix) throws IOException { - // Class files are in here under names like this: - // /modules/java.base/java/lang/Object.class (jdk9 b74) - // so within a modules top level qualifier and then the java.base module - String fileName = name.replace('.', '/') + suffix; - Path p = fileMap.get(fileName); - if (p == null) { - return null; - } - byte[] bs = Files.readAllBytes(p); - BasicFileAttributeView bfav = Files.getFileAttributeView(p, BasicFileAttributeView.class); - BasicFileAttributes bfas = bfav.readAttributes(); - long time = bfas.lastModifiedTime().toMillis(); - long size = bfas.size(); - ClassFile cf = new ByteBasedClassFile(bs, "jimage",fileName,time,size); - return cf; - } - } - - private static class Zip extends PathEntry { - private ZipFile zip; - - Zip(ZipFile z) { - zip = z; - } - - @Override - ClassFile getClassFile(String name, String suffix) throws IOException { - final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix); - - return (entry != null) ? new ClassFile() { - @Override - public InputStream getInputStream() throws IOException { - return zip.getInputStream(entry); - } - - @Override - public String getPath() { - return entry.toString(); - } - - @Override - public long getTime() { - return entry.getTime(); - } - - @Override - public long getSize() { - return entry.getSize(); - } - - @Override - public String getBase() { - return zip.getName(); - } - } : null; - } - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java b/bcel-builder/src/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java deleted file mode 100644 index 259991308..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -package org.aspectj.apache.bcel.util; - -/** - * Simplistic ClassLoaderReference that merely delegates to a classloader. More sophisticated ones could allow for the - * loader to be weakly referenced. - * - * @author Andy Clement - */ -public class DefaultClassLoaderReference implements ClassLoaderReference { - - private java.lang.ClassLoader loader; - - public DefaultClassLoaderReference(java.lang.ClassLoader classLoader) { - this.loader = classLoader; - } - - public java.lang.ClassLoader getClassLoader() { - return loader; - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java b/bcel-builder/src/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java deleted file mode 100644 index a53b9dc35..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java +++ /dev/null @@ -1,268 +0,0 @@ -package org.aspectj.apache.bcel.util; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.AbstractMap; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.aspectj.apache.bcel.classfile.ClassParser; -import org.aspectj.apache.bcel.classfile.JavaClass; - -/** - * The repository maintains information about which classes have been loaded. - * - * It loads its data from the ClassLoader implementation passed into its constructor. - * - * @see org.aspectj.apache.bcel.Repository - * - * @version $Id: NonCachingClassLoaderRepository.java,v 1.6 2009/09/09 19:56:20 aclement Exp $ - * @author M. Dahm - * @author David Dixon-Peugh - * - */ -public class NonCachingClassLoaderRepository implements Repository { - private static java.lang.ClassLoader bootClassLoader = null; - - private final ClassLoaderReference loaderRef; - private final Map loadedClasses = new SoftHashMap(); - - public static class SoftHashMap extends AbstractMap { - private Map map; - private ReferenceQueue rq = new ReferenceQueue(); - - public SoftHashMap(Map map) { - this.map = map; - } - - public SoftHashMap() { - this(new HashMap()); - } - - public SoftHashMap(Map map, boolean b) { - this(map); - } - - class SpecialValue extends SoftReference { - private final Object key; - - SpecialValue(Object k, Object v) { - super(v, rq); - this.key = k; - } - } - - private void processQueue() { - SpecialValue sv = null; - while ((sv = (SpecialValue) rq.poll()) != null) { - map.remove(sv.key); - } - } - - @Override - public Object get(Object key) { - SpecialValue value = map.get(key); - if (value == null) - return null; - if (value.get() == null) { - // it got GC'd - map.remove(value.key); - return null; - } else { - return value.get(); - } - } - - @Override - public Object put(Object k, Object v) { - processQueue(); - return map.put(k, new SpecialValue(k, v)); - } - - @Override - public Set entrySet() { - return map.entrySet(); - } - - @Override - public void clear() { - processQueue(); - Set keys = map.keySet(); - for (Iterator iterator = keys.iterator(); iterator.hasNext();) { - Object name = iterator.next(); - map.remove(name); - } - } - - @Override - public int size() { - processQueue(); - return map.size(); - } - - @Override - public Object remove(Object k) { - processQueue(); - SpecialValue value = map.remove(k); - if (value == null) - return null; - if (value.get() != null) { - return value.get(); - } - return null; - } - } - - public NonCachingClassLoaderRepository(java.lang.ClassLoader loader) { - this.loaderRef = new DefaultClassLoaderReference((loader != null) ? loader : getBootClassLoader()); - } - - public NonCachingClassLoaderRepository(ClassLoaderReference loaderRef) { - this.loaderRef = loaderRef; - } - - private static synchronized java.lang.ClassLoader getBootClassLoader() { - if (bootClassLoader == null) { - bootClassLoader = new URLClassLoader(new URL[0]); - } - return bootClassLoader; - } - - /** - * Store a new JavaClass into this Repository. - */ - public void storeClass(JavaClass clazz) { - synchronized (loadedClasses) { - loadedClasses.put(clazz.getClassName(), clazz); - } - clazz.setRepository(this); - } - - /** - * Remove class from repository - */ - public void removeClass(JavaClass clazz) { - synchronized (loadedClasses) { - loadedClasses.remove(clazz.getClassName()); - } - } - - /** - * Find an already defined JavaClass. - */ - public JavaClass findClass(String className) { - synchronized (loadedClasses) { - if (loadedClasses.containsKey(className)) { - return loadedClasses.get(className); - } else { - return null; - } - } - } - - /** - * Clear all entries from cache. - */ - public void clear() { - synchronized (loadedClasses) { - loadedClasses.clear(); - } - } - - /** - * Lookup a JavaClass object from the Class Name provided. - */ - public JavaClass loadClass(String className) throws ClassNotFoundException { - - JavaClass javaClass = findClass(className); - if (javaClass != null) { - return javaClass; - } - - javaClass = loadJavaClass(className); - storeClass(javaClass); - - return javaClass; - } - - public JavaClass loadClass(Class clazz) throws ClassNotFoundException { - return loadClass(clazz.getName()); - } - - private JavaClass loadJavaClass(String className) throws ClassNotFoundException { - String classFile = className.replace('.', '/'); - try { - InputStream is = loaderRef.getClassLoader().getResourceAsStream(classFile + ".class"); - - if (is == null) { - throw new ClassNotFoundException(className + " not found."); - } - - ClassParser parser = new ClassParser(is, className); - return parser.parse(); - } catch (IOException e) { - throw new ClassNotFoundException(e.toString()); - } - } - -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/Repository.java b/bcel-builder/src/org/aspectj/apache/bcel/util/Repository.java deleted file mode 100644 index eea889e61..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/Repository.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.aspectj.apache.bcel.util; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import org.aspectj.apache.bcel.classfile.JavaClass; - -/** - * Abstract definition of a class repository. Instances may be used to load classes from different sources and may be used in the - * Repository.setRepository method. - * - * @see org.aspectj.apache.bcel.Repository - * @version $Id: Repository.java,v 1.5 2009/09/09 19:56:20 aclement Exp $ - * @author M. Dahm - * @author David Dixon-Peugh - */ -public interface Repository { - /** - * Store the provided class under "clazz.getClassName()" - */ - public void storeClass(JavaClass clazz); - - /** - * Remove class from repository - */ - public void removeClass(JavaClass clazz); - - /** - * Find the class with the name provided, if the class isn't there, return NULL. - */ - public JavaClass findClass(String className); - - /** - * Find the class with the name provided, if the class isn't there, make an attempt to load it. - */ - public JavaClass loadClass(String className) throws java.lang.ClassNotFoundException; - - /** - * Find the JavaClass instance for the given run-time class object - */ - public JavaClass loadClass(Class clazz) throws java.lang.ClassNotFoundException; - - /** - * Clear all entries from cache. - */ - public void clear(); -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/SyntheticRepository.java b/bcel-builder/src/org/aspectj/apache/bcel/util/SyntheticRepository.java deleted file mode 100644 index ea0e49216..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/SyntheticRepository.java +++ /dev/null @@ -1,195 +0,0 @@ -package org.aspectj.apache.bcel.util; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.WeakHashMap; - -import org.aspectj.apache.bcel.classfile.ClassParser; -import org.aspectj.apache.bcel.classfile.JavaClass; - -/** - * This repository is used in situations where a Class is created outside the realm of a ClassLoader. Classes are loaded from the - * file systems using the paths specified in the given class path. By default, this is the value returned by - * ClassPath.getClassPath().
- * It is designed to be used as a singleton, however it can also be used with custom classpaths. - * - * /** Abstract definition of a class repository. Instances may be used to load classes from different sources and may be used in - * the Repository.setRepository method. - * - * @see org.aspectj.apache.bcel.Repository - * - * @version $Id: SyntheticRepository.java,v 1.8 2009/09/09 19:56:20 aclement Exp $ - * @author M. Dahm - * @author David Dixon-Peugh - */ -public class SyntheticRepository implements Repository { - private static final String DEFAULT_PATH = ClassPath.getClassPath(); - - private static HashMap _instances = new HashMap(); // CLASSPATH - // X - // REPOSITORY - - private ClassPath _path = null; - private WeakHashMap _loadedClasses = new WeakHashMap(); // CLASSNAME X JAVACLASS - - private SyntheticRepository(ClassPath path) { - _path = path; - } - - public static SyntheticRepository getInstance() { - return getInstance(ClassPath.getSystemClassPath()); - } - - public static SyntheticRepository getInstance(ClassPath classPath) { - SyntheticRepository rep = _instances.get(classPath); - - if (rep == null) { - rep = new SyntheticRepository(classPath); - _instances.put(classPath, rep); - } - - return rep; - } - - /** - * Store a new JavaClass instance into this Repository. - */ - public void storeClass(JavaClass clazz) { - _loadedClasses.put(clazz.getClassName(), clazz); - clazz.setRepository(this); - } - - /** - * Remove class from repository - */ - public void removeClass(JavaClass clazz) { - _loadedClasses.remove(clazz.getClassName()); - } - - /** - * Find an already defined (cached) JavaClass object by name. - */ - public JavaClass findClass(String className) { - return _loadedClasses.get(className); - } - - /** - * Load a JavaClass object for the given class name using the CLASSPATH environment variable. - */ - public JavaClass loadClass(String className) throws ClassNotFoundException { - if (className == null || className.equals("")) { - throw new IllegalArgumentException("Invalid class name " + className); - } - - className = className.replace('/', '.'); // Just in case, canonical form - - try { - return loadClass(_path.getInputStream(className), className); - } catch (IOException e) { - throw new ClassNotFoundException("Exception while looking for class " + className + ": " + e.toString()); - } - } - - /** - * Try to find class source via getResourceAsStream(). - * - * @see Class - * @return JavaClass object for given runtime class - */ - public JavaClass loadClass(Class clazz) throws ClassNotFoundException { - String className = clazz.getName(); - String name = className; - int i = name.lastIndexOf('.'); - - if (i > 0) { - name = name.substring(i + 1); - } - - return loadClass(clazz.getResourceAsStream(name + ".class"), className); - } - - private JavaClass loadClass(InputStream is, String className) throws ClassNotFoundException { - JavaClass clazz = findClass(className); - - if (clazz != null) { - return clazz; - } - - try { - if (is != null) { - ClassParser parser = new ClassParser(is, className); - clazz = parser.parse(); - - storeClass(clazz); - - return clazz; - } - } catch (IOException e) { - throw new ClassNotFoundException("Exception while looking for class " + className + ": " + e.toString()); - } - - throw new ClassNotFoundException("SyntheticRepository could not load " + className); - } - - /** - * Clear all entries from cache. - */ - public void clear() { - _loadedClasses.clear(); - } -} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationAccessFlagTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationAccessFlagTest.java new file mode 100644 index 000000000..96dd9e765 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationAccessFlagTest.java @@ -0,0 +1,55 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.ClassPath; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +public class AnnotationAccessFlagTest extends TestCase { + + private boolean verbose = false; + + protected void setUp() throws Exception { + super.setUp(); + } + + /** + * If you write an annotation and compile it, the class file generated should be + * marked as an annotation type - which is detectable through BCEL. + */ + public void testAnnotationClassSaysItIs() throws ClassNotFoundException { + ClassPath cp = + new ClassPath("testdata"+File.separator+"testcode.jar"+File.pathSeparator+System.getProperty("java.class.path")); + SyntheticRepository repos = SyntheticRepository.getInstance(cp); + JavaClass clazz = repos.loadClass("SimpleAnnotation"); + ConstantPool pool = clazz.getConstantPool(); + assertTrue("Expected SimpleAnnotation class to say it was an annotation - but it didn't !", + clazz.isAnnotation()); + clazz = repos.loadClass("SimpleClass"); + assertTrue("Expected SimpleClass class to say it was not an annotation - but it didn't !", + !clazz.isAnnotation()); + } + + + protected void tearDown() throws Exception { + super.tearDown(); + } + + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationDefaultAttributeTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationDefaultAttributeTest.java new file mode 100644 index 000000000..ced29d489 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationDefaultAttributeTest.java @@ -0,0 +1,49 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import org.aspectj.apache.bcel.classfile.AnnotationDefault; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; +import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; + +public class AnnotationDefaultAttributeTest extends BcelTestCase { + + protected void setUp() throws Exception { + super.setUp(); + } + + + /** + * For values in an annotation that have default values, we should be able to + * query the AnnotationDefault attribute against the method to discover the + * default value that was originally declared. + */ + public void testMethodAnnotations() throws ClassNotFoundException { + JavaClass clazz = getClassFromJar("SimpleAnnotation"); + + Method m = getMethod(clazz,"fruit"); + AnnotationDefault a = (AnnotationDefault) findAttribute("AnnotationDefault",m.getAttributes()); + SimpleElementValue val = (SimpleElementValue) a.getElementValue(); + assertTrue("Should be STRING but is "+val.getElementValueType(), + val.getElementValueType()==ElementValue.STRING); + assertTrue("Should have default of bananas but default is "+val.getValueString(), + val.getValueString().equals("bananas")); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationGenTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationGenTest.java new file mode 100644 index 000000000..901aa2ee7 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnnotationGenTest.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying + * materials are made available under the terms of the Eclipse Public License + * v1.0 which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Andy Clement - initial implementation + ******************************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Vector; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.Utility; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; +import org.aspectj.apache.bcel.generic.ClassGen; +import org.aspectj.apache.bcel.generic.ObjectType; + +public class AnnotationGenTest extends BcelTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + private ClassGen createClassGen(String classname) { + return new ClassGen(classname, "java.lang.Object", "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); + } + + /** + * Programmatically construct an mutable annotation (AnnotationGen) object. + */ + public void testConstructMutableAnnotation() { + + // Create the containing class + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + // Create the simple primitive value '4' of type 'int' + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 4); + + // Give it a name, call it 'id' + NameValuePair nvGen = new NameValuePair("id", evg, cp); + + // Check it looks right + assertTrue("Should include string 'id=4' but says: " + nvGen.toString(), nvGen.toString().indexOf("id=4") != -1); + + ObjectType t = new ObjectType("SimpleAnnotation"); + + List elements = new ArrayList(); + elements.add(nvGen); + + // Build an annotation of type 'SimpleAnnotation' with 'id=4' as the only value :) + AnnotationGen a = new AnnotationGen(t, elements, true, cp); + + // Check we can save and load it ok + checkSerialize(a, cp); + } + + public void testVisibleInvisibleAnnotationGen() { + + // Create the containing class + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + // Create the simple primitive value '4' of type 'int' + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 4); + + // Give it a name, call it 'id' + NameValuePair nvGen = new NameValuePair("id", evg, cp); + + // Check it looks right + assertTrue("Should include string 'id=4' but says: " + nvGen.toString(), nvGen.toString().indexOf("id=4") != -1); + + ObjectType t = new ObjectType("SimpleAnnotation"); + + List elements = new ArrayList(); + elements.add(nvGen); + + // Build a RV annotation of type 'SimpleAnnotation' with 'id=4' as the only value :) + AnnotationGen a = new AnnotationGen(t, elements, true, cp); + + Vector v = new Vector(); + v.add(a); + Collection attributes = Utility.getAnnotationAttributes(cp, v); + boolean foundRV = false; + for (Attribute attribute : attributes) { + if (attribute instanceof RuntimeVisAnnos) { + assertTrue(((RuntimeAnnos) attribute).areVisible()); + foundRV = true; + + } + } + assertTrue("Should have seen a RuntimeVisibleAnnotation", foundRV); + + // Build a RIV annotation of type 'SimpleAnnotation' with 'id=4' as the only value :) + AnnotationGen a2 = new AnnotationGen(t, elements, false, cp); + + Vector v2 = new Vector(); + v2.add(a2); + Collection attributes2 = Utility.getAnnotationAttributes(cp, v2); + boolean foundRIV = false; + for (Attribute attribute : attributes2) { + // for (int i = 0; i < attributes2.length; i++) { + // Attribute attribute = attributes2[i]; + if (attribute instanceof RuntimeInvisAnnos) { + assertFalse(((RuntimeAnnos) attribute).areVisible()); + foundRIV = true; + } + } + assertTrue("Should have seen a RuntimeInvisibleAnnotation", foundRIV); + } + + // // + // Helper methods + + private void checkSerialize(AnnotationGen a, ConstantPool cpg) { + try { + String beforeName = a.getTypeName(); + List beforeValues = a.getValues(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + a.dump(dos); + dos.flush(); + dos.close(); + + byte[] bs = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(bs); + DataInputStream dis = new DataInputStream(bais); + AnnotationGen annAfter = AnnotationGen.read(dis, cpg, a.isRuntimeVisible()); + + dis.close(); + + String afterName = annAfter.getTypeName(); + List afterValues = annAfter.getValues(); + + if (!beforeName.equals(afterName)) { + fail("Deserialization failed: before type='" + beforeName + "' after type='" + afterName + "'"); + } + if (a.getValues().size() != annAfter.getValues().size()) { + fail("Different numbers of element name value pairs?? " + a.getValues().size() + "!=" + annAfter.getValues().size()); + } + for (int i = 0; i < a.getValues().size(); i++) { + NameValuePair beforeElement = a.getValues().get(i); + NameValuePair afterElement = annAfter.getValues().get(i); + if (!beforeElement.getNameString().equals(afterElement.getNameString())) { + fail("Different names?? " + beforeElement.getNameString() + "!=" + afterElement.getNameString()); + } + } + + } catch (IOException ioe) { + fail("Unexpected exception whilst checking serialization: " + ioe); + } + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + +} \ No newline at end of file diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnonymousClassTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnonymousClassTest.java new file mode 100644 index 000000000..4a9bc0a3f --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/AnonymousClassTest.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2005 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer - initial implementation + */ +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.ClassPath; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +import junit.framework.TestCase; + +/** + * @author adrian colyer + * + */ +public class AnonymousClassTest extends TestCase { + + private SyntheticRepository repos; + + public void testRegularClassIsNotAnonymous() throws ClassNotFoundException { + JavaClass clazz = repos.loadClass("AnonymousClassTest"); + assertFalse("regular outer classes are not anonymous",clazz.isAnonymous()); + assertFalse("regular outer classes are not nested",clazz.isNested()); + } + + public void testNamedInnerClassIsNotAnonymous() throws ClassNotFoundException { + JavaClass clazz = repos.loadClass("AnonymousClassTest$X"); + assertFalse("regular inner classes are not anonymous",clazz.isAnonymous()); + assertTrue("regular inner classes are nested",clazz.isNested()); + } + + public void testStaticInnerClassIsNotAnonymous() throws ClassNotFoundException { + JavaClass clazz = repos.loadClass("AnonymousClassTest$Y"); + assertFalse("regular static inner classes are not anonymous",clazz.isAnonymous()); + assertTrue("regular static inner classes are nested",clazz.isNested()); + } + + public void testAnonymousInnerClassIsAnonymous() throws ClassNotFoundException { + JavaClass clazz = repos.loadClass("AnonymousClassTest$1"); + assertTrue("anonymous inner classes are anonymous",clazz.isAnonymous()); + assertTrue("anonymous inner classes are anonymous",clazz.isNested()); + } + + protected void setUp() throws Exception { + ClassPath cp = + new ClassPath("testdata"+File.separator+"testcode.jar"+File.pathSeparator+System.getProperty("java.class.path")); + repos = SyntheticRepository.getInstance(cp); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java new file mode 100644 index 000000000..ef4b8a9a7 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java @@ -0,0 +1,186 @@ +/* ******************************************************************* + * Copyright (c) 2004 - 2016 IBM, VMware, Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation {date} + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.Field; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; +import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; +import org.aspectj.apache.bcel.generic.ObjectType; +import org.aspectj.apache.bcel.util.ClassPath; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +/** + * Super class for the Java5 tests, includes various helper methods. + */ +public abstract class BcelTestCase extends TestCase { + + private boolean verbose = false; + + protected File createTestdataFile(String name) { + return new File("testdata" + File.separator + name); + } + + protected JavaClass getClassFromJar(String clazzname) throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + return repos.loadClass(clazzname); + } + + protected JavaClass getClassFromJava8Jar(String clazzname) throws ClassNotFoundException { + SyntheticRepository repos = createRepos("java8testcode.jar"); + return repos.loadClass(clazzname); + } + + protected Method getMethod(JavaClass cl, String methodname) { + Method[] methods = cl.getMethods(); + for (int i = 0; i < methods.length; i++) { + Method m = methods[i]; + if (m.getName().equals(methodname)) { + return m; + } + } + return null; + } + + protected Field getField(JavaClass cl, String fieldname) { + Field[] fields = cl.getFields(); + for (int i = 0; i < fields.length; i++) { + Field f = fields[i]; + if (f.getName().equals(fieldname)) { + return f; + } + } + return null; + } + + protected boolean wipe(String name) { + return new File("testdata" + File.separator + name).delete(); + } + + protected boolean wipe(String dir, String name) { + boolean b = wipe(dir + File.separator + name); + String[] files = new File(dir).list(); + if (files == null || files.length == 0) { + new File(dir).delete(); // Why does this not succeed? stupid thing + } + return b; + } + + public SyntheticRepository createRepos(String cpentry) { + ClassPath cp = new ClassPath("testdata" + File.separator + cpentry + File.pathSeparator + + System.getProperty("java.class.path")); + return SyntheticRepository.getInstance(cp); + } + + protected Attribute[] findAttribute(String name, JavaClass clazz) { + Attribute[] all = clazz.getAttributes(); + List chosenAttrsList = new ArrayList(); + for (int i = 0; i < all.length; i++) { + if (verbose) + System.err.println("Attribute: " + all[i].getName()); + if (all[i].getName().equals(name)) + chosenAttrsList.add(all[i]); + } + return chosenAttrsList.toArray(new Attribute[] {}); + } + + protected Attribute findAttribute(String name, Attribute[] all) { + List chosenAttrsList = new ArrayList(); + for (int i = 0; i < all.length; i++) { + if (verbose) + System.err.println("Attribute: " + all[i].getName()); + if (all[i].getName().equals(name)) + chosenAttrsList.add(all[i]); + } + assertTrue("Should be one match: " + chosenAttrsList.size(), chosenAttrsList.size() == 1); + return chosenAttrsList.get(0); + } + + protected String dumpAnnotations(AnnotationGen[] as) { + StringBuffer result = new StringBuffer(); + result.append("["); + for (int i = 0; i < as.length; i++) { + AnnotationGen annotation = as[i]; + result.append(annotation.toShortString()); + if (i + 1 < as.length) + result.append(","); + } + result.append("]"); + return result.toString(); + } + + protected String dumpAnnotations(List as) { + StringBuffer result = new StringBuffer(); + result.append("["); + for (int i = 0; i < as.size(); i++) { + AnnotationGen annotation = as.get(i); + result.append(annotation.toShortString()); + if (i + 1 < as.size()) + result.append(","); + } + result.append("]"); + return result.toString(); + } + + protected String dumpAttributes(Attribute[] as) { + StringBuffer result = new StringBuffer(); + result.append("AttributeArray:["); + for (int i = 0; i < as.length; i++) { + Attribute attr = as[i]; + result.append(attr.toString()); + if (i + 1 < as.length) + result.append(","); + } + result.append("]"); + return result.toString(); + } + + public AnnotationGen createFruitAnnotation(ConstantPool cp, String aFruit, boolean visibility) { + SimpleElementValue evg = new SimpleElementValue(ElementValue.STRING, cp, aFruit); + NameValuePair nvGen = new NameValuePair("fruit", evg, cp); + ObjectType t = new ObjectType("SimpleStringAnnotation"); + List elements = new ArrayList(); + elements.add(nvGen); + return new AnnotationGen(t, elements, visibility, cp); + } + + public Attribute getAttribute(Attribute[] attrs, byte tag) { + for (Attribute attr: attrs) { + if (attr.getTag() == tag) { + return attr; + } + } + return null; + } + + public Attribute getAttribute(Attribute[] attrs, String name) { + for (Attribute attr: attrs) { + if (attr.getName().equals(name)) { + return attr; + } + } + return null; + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ClassloaderRepositoryTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ClassloaderRepositoryTest.java new file mode 100644 index 000000000..7202be3fa --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ClassloaderRepositoryTest.java @@ -0,0 +1,89 @@ +package org.aspectj.apache.bcel.classfile.tests; + +import java.net.URL; +import java.net.URLClassLoader; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.ClassLoaderRepository; + +import junit.framework.TestCase; + +/* + * Tests create a simple classloader repository configuration and check sharing of information. + */ +public class ClassloaderRepositoryTest extends TestCase { + + private ClassLoaderRepository rep1,rep2; + + public void setUp() throws Exception { + super.setUp(); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + ClassLoader cl1 = new URLClassLoader(new URL[]{},cl); + ClassLoader cl2 = new URLClassLoader(new URL[]{},cl); + rep1 = new ClassLoaderRepository(cl1); + rep2 = new ClassLoaderRepository(cl2); + } + + // Retrieve string 5 times from same repository, 4 hits should be from local cache + public void testLocalCacheWorks() throws ClassNotFoundException { + ClassLoaderRepository.useSharedCache=false; + JavaClass jc = rep1.loadClass("java.lang.String"); + jc = rep1.loadClass("java.lang.String"); + jc = rep1.loadClass("java.lang.String"); + jc = rep1.loadClass("java.lang.String"); + jc = rep1.loadClass("java.lang.String"); + assertTrue("Should have used local cache 4 times: "+reportLocalCacheHits(rep1),reportLocalCacheHits(rep1)==4); + } + + // Retrieve string 5 times from same repository, 4 hits should be from local cache + public void testSharedCacheWorksOnOne() throws ClassNotFoundException { + ClassLoaderRepository.useSharedCache=true; + JavaClass jc = rep1.loadClass("java.lang.String"); + jc = rep1.loadClass("java.lang.String"); + jc = rep1.loadClass("java.lang.String"); + jc = rep1.loadClass("java.lang.String"); + jc = rep1.loadClass("java.lang.String"); + assertTrue("Should have used local cache 4 times: "+reportSharedCacheHits(rep1),reportSharedCacheHits(rep1)==4); + } + + // Retrieve String through one repository then load again through another, should be shared cache hit + public void testSharedCacheWorks() throws ClassNotFoundException { + ClassLoaderRepository.useSharedCache=true; + JavaClass jc = rep1.loadClass("java.lang.String"); + jc = rep2.loadClass("java.lang.String"); + assertTrue("Should have retrieved String from shared cache: "+reportSharedCacheHits(rep1), + reportSharedCacheHits(rep1)==1); + } + + // Shared cache OFF, shouldn't get a shared cache hit + public void testSharedCacheCanBeDeactivated() throws ClassNotFoundException { + try { + ClassLoaderRepository.useSharedCache=false; + JavaClass jc = rep1.loadClass("java.lang.String"); + jc = rep2.loadClass("java.lang.String"); + assertTrue("Should not have retrieved String from shared cache: "+ + reportSharedCacheHits(rep1), + reportSharedCacheHits(rep1)==0); + } finally { + ClassLoaderRepository.useSharedCache=true; + } + } + + public void tearDown() throws Exception { + super.tearDown(); + System.err.println("Rep1: "+rep1.reportStats()); + System.err.println("Rep2: "+rep2.reportStats()); + rep1.reset(); + rep2.reset(); + } + + private long reportLocalCacheHits(ClassLoaderRepository rep) { + return rep.reportStats()[5]; + } + + private long reportSharedCacheHits(ClassLoaderRepository rep) { + return rep.reportStats()[3]; + } + +} + diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ConstantPoolToStringTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ConstantPoolToStringTest.java new file mode 100644 index 000000000..3a41c6c70 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ConstantPoolToStringTest.java @@ -0,0 +1,54 @@ +/* ******************************************************************* + * Copyright (c) 2018 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +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.util.SyntheticRepository; + +public class ConstantPoolToStringTest extends BcelTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + public void testToStringLambdaElements() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("lambda.jar"); + JavaClass clazz = repos.loadClass("Code"); + ConstantPool pool = clazz.getConstantPool(); + Method[] methods = clazz.getMethods(); + String codeString = methods[1].getCode().getCodeString(); + assertEquals("Code(max_stack = 1, max_locals = 2, code_length = 13)\n" + + "0: invokedynamic #0.run ()Ljava/lang/Runnable; (2)\n" + + "5: astore_1\n" + + "6: aload_1\n" + + "7: invokeinterface java.lang.Runnable.run ()V (3) 1 0\n" + + "12: return\n",codeString); + + // #20 = MethodHandle 6:#32 // REF_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; + String cts = pool.constantToString(pool.getConstant(20)); + assertEquals("6: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;",cts); + + // #21 = MethodType #10 // ()V + cts = pool.constantToString(pool.getConstant(21)); + assertEquals("()V",cts); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ElementValueGenTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ElementValueGenTest.java new file mode 100644 index 000000000..7d91bd7d3 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ElementValueGenTest.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying + * materials are made available under the terms of the Eclipse Public License + * v1.0 which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Andy Clement - initial implementation + ******************************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Collections; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationElementValue; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; +import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; +import org.aspectj.apache.bcel.generic.ClassGen; +import org.aspectj.apache.bcel.generic.ObjectType; + +public class ElementValueGenTest extends BcelTestCase { + + protected void setUp() throws Exception { + super.setUp(); + } + + private ClassGen createClassGen(String classname) { + return new ClassGen(classname, "java.lang.Object", "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); + } + + // // + // Create primitive element values + + public void testCreateIntegerElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 555); + // Creation of an element like that should leave a new entry in the cpool + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupInteger(555), + evg.getIndex() == cp.lookupInteger(555)); + checkSerialize(evg, cp); + } + + public void testCreateFloatElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_FLOAT, cp, 111.222f); + // Creation of an element like that should leave a new entry in the cpool + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupFloat(111.222f), + evg.getIndex() == cp.lookupFloat(111.222f)); + checkSerialize(evg, cp); + } + + public void testCreateDoubleElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_DOUBLE, cp, 333.44); + // Creation of an element like that should leave a new entry in the cpool + int idx = cp.lookupDouble(333.44); + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); + checkSerialize(evg, cp); + } + + public void testCreateLongElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_LONG, cp, 3334455L); + // Creation of an element like that should leave a new entry in the cpool + int idx = cp.lookupLong(3334455L); + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); + checkSerialize(evg, cp); + } + + public void testCreateCharElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_CHAR, cp, (char) 't'); + // Creation of an element like that should leave a new entry in the cpool + int idx = cp.lookupInteger((char) 't'); + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); + checkSerialize(evg, cp); + } + + public void testCreateByteElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_CHAR, cp, (byte) 'z'); + // Creation of an element like that should leave a new entry in the cpool + int idx = cp.lookupInteger((byte) 'z'); + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); + checkSerialize(evg, cp); + } + + public void testCreateBooleanElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_BOOLEAN, cp, true); + // Creation of an element like that should leave a new entry in the cpool + int idx = cp.lookupInteger(1); // 1 == true + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); + checkSerialize(evg, cp); + } + + public void testCreateShortElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_SHORT, cp, (short) 42); + // Creation of an element like that should leave a new entry in the cpool + int idx = cp.lookupInteger(42); + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); + checkSerialize(evg, cp); + } + + // // + // Create string element values + + public void testCreateStringElementValue() { + + // Create HelloWorld + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + SimpleElementValue evg = new SimpleElementValue(ElementValue.STRING, cp, "hello"); + // Creation of an element like that should leave a new entry in the cpool + assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupUtf8("hello"), + evg.getIndex() == cp.lookupUtf8("hello")); + checkSerialize(evg, cp); + } + + // // + // Create enum element value + + public void testCreateEnumElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + ObjectType enumType = new ObjectType("SimpleEnum"); // Supports rainbow :) + + EnumElementValue evg = new EnumElementValue(enumType, "Red", cp); + // Creation of an element like that should leave a new entry in the cpool + assertTrue("The new ElementValue value index should match the contents of the constantpool but " + evg.getValueIndex() + + "!=" + cp.lookupUtf8("Red"), evg.getValueIndex() == cp.lookupUtf8("Red")); + // BCELBUG: Should the class signature or class name be in the constant pool? (see note in ConstantPool) + // assertTrue("The new ElementValue type index should match the contents of the constantpool but "+ + // evg.getTypeIndex()+"!="+cp.lookupClass(enumType.getSignature()), + // evg.getTypeIndex()==cp.lookupClass(enumType.getSignature())); + + checkSerialize(evg, cp); + } + + public void testCreateMarkerAnnotationElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + ObjectType annoType = new ObjectType("SimpleMarkerAnnotation"); + AnnotationGen annoGen = new AnnotationGen(annoType, Collections. emptyList(), true, cp); + AnnotationElementValue evg = new AnnotationElementValue(annoGen, cp); + checkSerialize(evg, cp); + } + + // // + // Create class element value + + public void testCreateClassElementValue() { + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + + ObjectType classType = new ObjectType("java.lang.Integer"); + + ClassElementValue evg = new ClassElementValue(classType, cp); + + assertTrue("Unexpected value for contained class: '" + evg.getClassString() + "'", + evg.getClassString().indexOf("Integer") != -1); + + checkSerialize(evg, cp); + } + + // // + // Helper methods + + private void checkSerialize(ElementValue evgBefore, ConstantPool cpg) { + try { + String beforeValue = evgBefore.stringifyValue(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + evgBefore.dump(dos); + dos.flush(); + dos.close(); + + byte[] bs = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(bs); + DataInputStream dis = new DataInputStream(bais); + ElementValue evgAfter = ElementValue.readElementValue(dis, cpg); + + dis.close(); + String afterValue = evgAfter.stringifyValue(); + + if (!beforeValue.equals(afterValue)) { + fail("Deserialization failed: before='" + beforeValue + "' after='" + afterValue + "'"); + } + + } catch (IOException ioe) { + fail("Unexpected exception whilst checking serialization: " + ioe); + } + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} \ No newline at end of file diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/EnclosingMethodAttributeTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/EnclosingMethodAttributeTest.java new file mode 100644 index 000000000..a03c9b386 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/EnclosingMethodAttributeTest.java @@ -0,0 +1,98 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; +import java.io.IOException; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.EnclosingMethod; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +public class EnclosingMethodAttributeTest extends BcelTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + /** + * Verify for an inner class declared inside the 'main' method that the enclosing method attribute is set correctly. + */ + public void testCheckMethodLevelNamedInnerClass() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AttributeTestClassEM01$1S"); + ConstantPool pool = clazz.getConstantPool(); + Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); + assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1); + EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; + String enclosingClassName = em.getEnclosingClass().getClassname(pool); + String enclosingMethodName = em.getEnclosingMethod().getName(pool); + assertTrue("Expected class name to be 'AttributeTestClassEM01' but was " + enclosingClassName, enclosingClassName + .equals("AttributeTestClassEM01")); + assertTrue("Expected method name to be 'main' but was " + enclosingMethodName, enclosingMethodName.equals("main")); + } + + /** + * Verify for an inner class declared at the type level that the EnclosingMethod attribute is set correctly (i.e. to a null + * value) + */ + public void testCheckClassLevelNamedInnerClass() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AttributeTestClassEM02$1"); + ConstantPool pool = clazz.getConstantPool(); + Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); + assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1); + EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; + String enclosingClassName = em.getEnclosingClass().getClassname(pool); + assertTrue("The class is not within a method, so method_index should be null, but it is " + em.getEnclosingMethodIndex(), + em.getEnclosingMethodIndex() == 0); + assertTrue("Expected class name to be 'AttributeTestClassEM02' but was " + enclosingClassName, enclosingClassName + .equals("AttributeTestClassEM02")); + } + + /** + * Check that we can save and load the attribute correctly. + */ + public void testAttributeSerializtion() throws ClassNotFoundException, IOException { + // Read in the class + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AttributeTestClassEM02$1"); + ConstantPool pool = clazz.getConstantPool(); + Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); + assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1); + + // Write it out + File tfile = createTestdataFile("AttributeTestClassEM02$1.class"); + clazz.dump(tfile); + + // Read in the new version and check it is OK + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos2.loadClass("AttributeTestClassEM02$1"); + EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; + String enclosingClassName = em.getEnclosingClass().getClassname(pool); + assertTrue("The class is not within a method, so method_index should be null, but it is " + em.getEnclosingMethodIndex(), + em.getEnclosingMethodIndex() == 0); + assertTrue("Expected class name to be 'AttributeTestClassEM02' but was " + enclosingClassName, enclosingClassName + .equals("AttributeTestClassEM02")); + assertTrue(tfile.delete()); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/EnumAccessFlagTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/EnumAccessFlagTest.java new file mode 100644 index 000000000..a91947549 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/EnumAccessFlagTest.java @@ -0,0 +1,56 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.ClassPath; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +public class EnumAccessFlagTest extends TestCase { + + private boolean verbose = false; + + protected void setUp() throws Exception { + super.setUp(); + } + + /** + * An enumerated type, once compiled, should result in a class file that + * is marked such that we can determine from the access flags (through BCEL) that + * it was originally an enum type declaration. + */ + public void testEnumClassSaysItIs() throws ClassNotFoundException { + ClassPath cp = + new ClassPath("testdata"+File.separator+"testcode.jar"+File.pathSeparator+System.getProperty("java.class.path")); + SyntheticRepository repos = SyntheticRepository.getInstance(cp); + JavaClass clazz = repos.loadClass("SimpleEnum"); + ConstantPool pool = clazz.getConstantPool(); + assertTrue("Expected SimpleEnum class to say it was an enum - but it didn't !", + clazz.isEnum()); + clazz = repos.loadClass("SimpleClass"); + assertTrue("Expected SimpleClass class to say it was not an enum - but it didn't !", + !clazz.isEnum()); + } + + + protected void tearDown() throws Exception { + super.tearDown(); + } + + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/FieldAnnotationsTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/FieldAnnotationsTest.java new file mode 100644 index 000000000..6f5a4f8f3 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/FieldAnnotationsTest.java @@ -0,0 +1,146 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import org.aspectj.apache.bcel.classfile.Field; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.generic.ClassGen; +import org.aspectj.apache.bcel.generic.FieldGen; +import org.aspectj.apache.bcel.util.SyntheticRepository; + + +public class FieldAnnotationsTest extends BcelTestCase { + + + protected void setUp() throws Exception { + super.setUp(); + } + + + /** + * Check field annotations are retrievable. + */ + public void testFieldAnnotations() throws ClassNotFoundException { + JavaClass clazz = getClassFromJar("AnnotatedFields"); + + checkAnnotatedField(clazz,"i","SimpleAnnotation","id","1"); + checkAnnotatedField(clazz,"s","SimpleAnnotation","id","2"); + + } + + /** + * Check field annotations (de)serialize ok. + */ + public void testFieldAnnotationsReadWrite() throws ClassNotFoundException,IOException { + JavaClass clazz = getClassFromJar("AnnotatedFields"); + + checkAnnotatedField(clazz,"i","SimpleAnnotation","id","1"); + checkAnnotatedField(clazz,"s","SimpleAnnotation","id","2"); + + // Write it out + File tfile = createTestdataFile("AnnotatedFields.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos2.loadClass("AnnotatedFields"); + + checkAnnotatedField(clazz,"i","SimpleAnnotation","id","1"); + checkAnnotatedField(clazz,"s","SimpleAnnotation","id","2"); + + assertTrue(tfile.delete()); + } + + /** + * Check we can load in a class, modify its field annotations, save it, reload it and + * everything is correct. + */ + public void testFieldAnnotationsModification() throws ClassNotFoundException, IOException { + boolean dbg = false; + JavaClass clazz = getClassFromJar("AnnotatedFields"); + + ClassGen clg = new ClassGen(clazz); + Field f = clg.getFields()[0]; + if (dbg) System.err.println("Field in freshly constructed class is: "+f); + if (dbg) System.err.println("Annotations on field are: "+dumpAnnotations(f.getAnnotations())); + AnnotationGen fruitBasedAnnotation = createFruitAnnotation(clg.getConstantPool(),"Tomato",false); + FieldGen fg = new FieldGen(f,clg.getConstantPool()); + if (dbg) System.err.println("Adding annotation to the field"); + fg.addAnnotation(fruitBasedAnnotation); + if (dbg) System.err.println("FieldGen (mutable field) is "+fg); + if (dbg) System.err.println("with annotations: "+dumpAnnotations(fg.getAnnotations())); + + if (dbg) System.err.println("Replacing original field with new field that has extra annotation"); + clg.removeField(f); + clg.addField(fg.getField()); + + f = clg.getFields()[1]; // there are two fields in the class, removing and readding has changed the order + // so this time index [1] is the 'int i' field + if (dbg) System.err.println("Field now looks like this: "+f); + if (dbg) System.err.println("With annotations: "+dumpAnnotations(f.getAnnotations())); + assertTrue("Should be 2 annotations on this field, but there are "+f.getAnnotations().length,f.getAnnotations().length==2); + } + + // helper methods + + public void checkAnnotatedField(JavaClass clazz,String fieldname, + String annotationName,String annotationElementName,String annotationElementValue) { + Field[] fields = clazz.getFields(); + + for (int i = 0; i < fields.length; i++) { + Field f = fields[i]; + AnnotationGen[] fieldAnnotations = f.getAnnotations(); + if (f.getName().equals(fieldname)) { + checkAnnotation(fieldAnnotations[0],annotationName,annotationElementName,annotationElementValue); + + } + } + } + + private void checkAnnotation(AnnotationGen a,String name,String elementname,String elementvalue) { + assertTrue("Expected annotation to have name "+name+" but it had name "+a.getTypeName(), + a.getTypeName().equals(name)); + assertTrue("Expected annotation to have one element but it had "+a.getValues().size(),a.getValues().size()==1); + NameValuePair envp = a.getValues().get(0); + assertTrue("Expected element name "+elementname+" but was "+envp.getNameString(), + elementname.equals(envp.getNameString())); + assertTrue("Expected element value "+elementvalue+" but was "+envp.getValue().stringifyValue(), + elementvalue.equals(envp.getValue().stringifyValue())); + } + + + // helper methods + + public void checkValue(AnnotationGen a,String name,String tostring) { + for (Iterator i = a.getValues().iterator(); i.hasNext();) { + NameValuePair element = i.next(); + if (element.getNameString().equals(name)) { + if (!element.getValue().stringifyValue().equals(tostring)) { + fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue()); + } + return; + } + } + fail("Didnt find named element "+name); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/Fundamentals.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/Fundamentals.java new file mode 100644 index 000000000..c54beb5b3 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/Fundamentals.java @@ -0,0 +1,319 @@ +package org.aspectj.apache.bcel.classfile.tests; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.generic.FieldInstruction; +import org.aspectj.apache.bcel.generic.IINC; +import org.aspectj.apache.bcel.generic.INVOKEINTERFACE; +import org.aspectj.apache.bcel.generic.Instruction; +import org.aspectj.apache.bcel.generic.InstructionBranch; +import org.aspectj.apache.bcel.generic.InstructionByte; +import org.aspectj.apache.bcel.generic.InstructionCP; +import org.aspectj.apache.bcel.generic.InstructionConstants; +import org.aspectj.apache.bcel.generic.InstructionHandle; +import org.aspectj.apache.bcel.generic.InstructionLV; +import org.aspectj.apache.bcel.generic.InstructionShort; +import org.aspectj.apache.bcel.generic.InvokeInstruction; +import org.aspectj.apache.bcel.generic.LOOKUPSWITCH; +import org.aspectj.apache.bcel.generic.MULTIANEWARRAY; +import org.aspectj.apache.bcel.generic.RET; +import org.aspectj.apache.bcel.generic.TABLESWITCH; + +import junit.framework.TestCase; + +// Check things that have to be true based on the specification +public class Fundamentals extends TestCase { + + // Checking: opcode, length, consumed stack entries, produced stack entries + public void testInstructions() { + + // Instructions 000-009 + checkInstruction(InstructionConstants.NOP,0,1,0,0); + checkInstruction(InstructionConstants.ACONST_NULL,1,1,0,1); + checkInstruction(InstructionConstants.ICONST_M1,2,1,0,1); + checkInstruction(InstructionConstants.ICONST_0,3,1,0,1); + checkInstruction(InstructionConstants.ICONST_1,4,1,0,1); + checkInstruction(InstructionConstants.ICONST_2,5,1,0,1); + checkInstruction(InstructionConstants.ICONST_3,6,1,0,1); + checkInstruction(InstructionConstants.ICONST_4,7,1,0,1); + checkInstruction(InstructionConstants.ICONST_5,8,1,0,1); + checkInstruction(InstructionConstants.LCONST_0,9,1,0,2); + + // Instructions 010-019 + checkInstruction(InstructionConstants.LCONST_1,10,1,0,2); + checkInstruction(InstructionConstants.FCONST_0,11,1,0,1); + checkInstruction(InstructionConstants.FCONST_1,12,1,0,1); + checkInstruction(InstructionConstants.FCONST_2,13,1,0,1); + checkInstruction(InstructionConstants.DCONST_0,14,1,0,2); + checkInstruction(InstructionConstants.DCONST_1,15,1,0,2); + checkInstruction(new InstructionByte(Constants.BIPUSH,b0),16,2,0,1); + checkInstruction(new InstructionShort(Constants.SIPUSH,s0),17,3,0,1); + checkInstruction(new InstructionCP(Constants.LDC,b0),18,2,0,1); + checkInstruction(new InstructionCP(Constants.LDC_W,s0),19,2,0,1); + + // Instructions 020-029 + checkInstruction(new InstructionCP(Constants.LDC2_W,s0),20,3,0,2); + checkInstruction(new InstructionLV(Constants.ILOAD,s20),21,2,0,1); + checkInstruction(new InstructionLV(Constants.LLOAD,s20),22,2,0,2); + checkInstruction(new InstructionLV(Constants.FLOAD,s20),23,2,0,1); + checkInstruction(new InstructionLV(Constants.DLOAD,s20),24,2,0,2); + checkInstruction(new InstructionLV(Constants.ALOAD,s20),25,2,0,1); + checkInstruction(InstructionConstants.ILOAD_0,26,1,0,1); + checkInstruction(InstructionConstants.ILOAD_1,27,1,0,1); + checkInstruction(InstructionConstants.ILOAD_2,28,1,0,1); + checkInstruction(InstructionConstants.ILOAD_3,29,1,0,1); + + // Instructions 030-039 + checkInstruction(InstructionConstants.LLOAD_0,30,1,0,2); + checkInstruction(InstructionConstants.LLOAD_1,31,1,0,2); + checkInstruction(InstructionConstants.LLOAD_2,32,1,0,2); + checkInstruction(InstructionConstants.LLOAD_3,33,1,0,2); + checkInstruction(InstructionConstants.FLOAD_0,34,1,0,1); + checkInstruction(InstructionConstants.FLOAD_1,35,1,0,1); + checkInstruction(InstructionConstants.FLOAD_2,36,1,0,1); + checkInstruction(InstructionConstants.FLOAD_3,37,1,0,1); + checkInstruction(InstructionConstants.DLOAD_0,38,1,0,2); + checkInstruction(InstructionConstants.DLOAD_1,39,1,0,2); + + // Instructions 040-049 + checkInstruction(InstructionConstants.DLOAD_2,40,1,0,2); + checkInstruction(InstructionConstants.DLOAD_3,41,1,0,2); + checkInstruction(InstructionConstants.ALOAD_0,42,1,0,1); + checkInstruction(InstructionConstants.ALOAD_1,43,1,0,1); + checkInstruction(InstructionConstants.ALOAD_2,44,1,0,1); + checkInstruction(InstructionConstants.ALOAD_3,45,1,0,1); + checkInstruction(InstructionConstants.IALOAD,46,1,2,1); + checkInstruction(InstructionConstants.LALOAD,47,1,2,2); + checkInstruction(InstructionConstants.FALOAD,48,1,2,1); + checkInstruction(InstructionConstants.DALOAD,49,1,2,2); + + // Instructions 050-059 + checkInstruction(InstructionConstants.AALOAD,50,1,2,1); + checkInstruction(InstructionConstants.BALOAD,51,1,2,1); + checkInstruction(InstructionConstants.CALOAD,52,1,2,1); + checkInstruction(InstructionConstants.SALOAD,53,1,2,1); + checkInstruction(new InstructionLV(Constants.ISTORE,s20),54,2,1,0); + checkInstruction(new InstructionLV(Constants.LSTORE,s20),55,2,2,0); + checkInstruction(new InstructionLV(Constants.FSTORE,s20),56,2,1,0); + checkInstruction(new InstructionLV(Constants.DSTORE,s20),57,2,2,0); + checkInstruction(new InstructionLV(Constants.ASTORE,s20),58,2,1,0); + checkInstruction(InstructionConstants.ISTORE_0,59,1,1,0); + + // Instructions 060-069 + checkInstruction(InstructionConstants.ISTORE_1,60,1,1,0); + checkInstruction(InstructionConstants.ISTORE_2,61,1,1,0); + checkInstruction(InstructionConstants.ISTORE_3,62,1,1,0); + checkInstruction(InstructionConstants.LSTORE_0,63,1,2,0); + checkInstruction(InstructionConstants.LSTORE_1,64,1,2,0); + checkInstruction(InstructionConstants.LSTORE_2,65,1,2,0); + checkInstruction(InstructionConstants.LSTORE_3,66,1,2,0); + checkInstruction(InstructionConstants.FSTORE_0,67,1,1,0); + checkInstruction(InstructionConstants.FSTORE_1,68,1,1,0); + checkInstruction(InstructionConstants.FSTORE_2,69,1,1,0); + + // Instructions 070-079 + checkInstruction(InstructionConstants.FSTORE_3,70,1,1,0); + checkInstruction(InstructionConstants.DSTORE_0,71,1,2,0); + checkInstruction(InstructionConstants.DSTORE_1,72,1,2,0); + checkInstruction(InstructionConstants.DSTORE_2,73,1,2,0); + checkInstruction(InstructionConstants.DSTORE_3,74,1,2,0); + checkInstruction(InstructionConstants.ASTORE_0,75,1,1,0); + checkInstruction(InstructionConstants.ASTORE_1,76,1,1,0); + checkInstruction(InstructionConstants.ASTORE_2,77,1,1,0); + checkInstruction(InstructionConstants.ASTORE_3,78,1,1,0); + checkInstruction(InstructionConstants.IASTORE,79,1,3,0); + + // Instructions 080-089 + checkInstruction(InstructionConstants.LASTORE,80,1,4,0); + checkInstruction(InstructionConstants.FASTORE,81,1,3,0); + checkInstruction(InstructionConstants.DASTORE,82,1,4,0); + checkInstruction(InstructionConstants.AASTORE,83,1,3,0); + checkInstruction(InstructionConstants.BASTORE,84,1,3,0); + checkInstruction(InstructionConstants.CASTORE,85,1,3,0); + checkInstruction(InstructionConstants.SASTORE,86,1,3,0); + checkInstruction(InstructionConstants.POP,87,1,1,0); + checkInstruction(InstructionConstants.POP2,88,1,2,0); + checkInstruction(InstructionConstants.DUP,89,1,1,2); + + // Instructions 090-099 + checkInstruction(InstructionConstants.DUP_X1,90,1,2,3); + checkInstruction(InstructionConstants.DUP_X2,91,1,3,4); + checkInstruction(InstructionConstants.DUP2,92,1,2,4); + checkInstruction(InstructionConstants.DUP2_X1,93,1,3,5); + checkInstruction(InstructionConstants.DUP2_X2,94,1,4,6); + checkInstruction(InstructionConstants.SWAP,95,1,2,2); + checkInstruction(InstructionConstants.IADD,96,1,2,1); + checkInstruction(InstructionConstants.LADD,97,1,4,2); + checkInstruction(InstructionConstants.FADD,98,1,2,1); + checkInstruction(InstructionConstants.DADD,99,1,4,2); + + // Instructions 100-109 + checkInstruction(InstructionConstants.ISUB,100,1,2,1); + checkInstruction(InstructionConstants.LSUB,101,1,4,2); + checkInstruction(InstructionConstants.FSUB,102,1,2,1); + checkInstruction(InstructionConstants.DSUB,103,1,4,2); + checkInstruction(InstructionConstants.IMUL,104,1,2,1); + checkInstruction(InstructionConstants.LMUL,105,1,4,2); + checkInstruction(InstructionConstants.FMUL,106,1,2,1); + checkInstruction(InstructionConstants.DMUL,107,1,4,2); + checkInstruction(InstructionConstants.IDIV,108,1,2,1); + checkInstruction(InstructionConstants.LDIV,109,1,4,2); + + // Instructions 110-119 + checkInstruction(InstructionConstants.FDIV,110,1,2,1); + checkInstruction(InstructionConstants.DDIV,111,1,4,2); + checkInstruction(InstructionConstants.IREM,112,1,2,1); + checkInstruction(InstructionConstants.LREM,113,1,4,2); + checkInstruction(InstructionConstants.FREM,114,1,2,1); + checkInstruction(InstructionConstants.DREM,115,1,4,2); + checkInstruction(InstructionConstants.INEG,116,1,1,1); + checkInstruction(InstructionConstants.LNEG,117,1,2,2); + checkInstruction(InstructionConstants.FNEG,118,1,1,1); + checkInstruction(InstructionConstants.DNEG,119,1,2,2); + + // Instructions 120-129 + checkInstruction(InstructionConstants.ISHL,120,1,2,1); + checkInstruction(InstructionConstants.LSHL,121,1,3,2); + checkInstruction(InstructionConstants.ISHR,122,1,2,1); + checkInstruction(InstructionConstants.LSHR,123,1,3,2); + checkInstruction(InstructionConstants.IUSHR,124,1,2,1); + checkInstruction(InstructionConstants.LUSHR,125,1,3,2); + checkInstruction(InstructionConstants.IAND,126,1,2,1); + checkInstruction(InstructionConstants.LAND,127,1,4,2); + checkInstruction(InstructionConstants.IOR,128,1,2,1); + checkInstruction(InstructionConstants.LOR,129,1,4,2); + + // Instructions 130-139 + checkInstruction(InstructionConstants.IXOR,130,1,2,1); + checkInstruction(InstructionConstants.LXOR,131,1,4,2); + checkInstruction(new IINC(0,0,false),132,3,0,0); + checkInstruction(InstructionConstants.I2L,133,1,1,2); + checkInstruction(InstructionConstants.I2F,134,1,1,1); + checkInstruction(InstructionConstants.I2D,135,1,1,2); + checkInstruction(InstructionConstants.L2I,136,1,2,1); + checkInstruction(InstructionConstants.L2F,137,1,2,1); + checkInstruction(InstructionConstants.L2D,138,1,2,2); + checkInstruction(InstructionConstants.F2I,139,1,1,1); + + // Instructions 140-149 + checkInstruction(InstructionConstants.F2L,140,1,1,2); + checkInstruction(InstructionConstants.F2D,141,1,1,2); + checkInstruction(InstructionConstants.D2I,142,1,2,1); + checkInstruction(InstructionConstants.D2L,143,1,2,2); + checkInstruction(InstructionConstants.D2F,144,1,2,1); + checkInstruction(InstructionConstants.I2B,145,1,1,1); + checkInstruction(InstructionConstants.I2C,146,1,1,1); + checkInstruction(InstructionConstants.I2S,147,1,1,1); + checkInstruction(InstructionConstants.LCMP,148,1,4,1); + checkInstruction(InstructionConstants.FCMPL,149,1,2,1); + + // Instructions 150-159 + checkInstruction(InstructionConstants.FCMPG,150,1,2,1); + checkInstruction(InstructionConstants.DCMPL,151,1,4,1); + checkInstruction(InstructionConstants.DCMPG,152,1,4,1); + checkInstruction(new InstructionBranch(Constants.IFEQ,s0),153,3,1,0); + checkInstruction(new InstructionBranch(Constants.IFNE,s0),154,3,1,0); + checkInstruction(new InstructionBranch(Constants.IFLT,s0),155,3,1,0); + checkInstruction(new InstructionBranch(Constants.IFGE,s0),156,3,1,0); + checkInstruction(new InstructionBranch(Constants.IFGT,s0),157,3,1,0); + checkInstruction(new InstructionBranch(Constants.IFLE,s0),158,3,1,0); + checkInstruction(new InstructionBranch(Constants.IF_ICMPEQ,s0),159,3,2,0); + + // Instructions 160-169 + checkInstruction(new InstructionBranch(Constants.IF_ICMPNE,s0),160,3,2,0); + checkInstruction(new InstructionBranch(Constants.IF_ICMPLT,s0),161,3,2,0); + checkInstruction(new InstructionBranch(Constants.IF_ICMPGE,s0),162,3,2,0); + checkInstruction(new InstructionBranch(Constants.IF_ICMPGT,s0),163,3,2,0); + checkInstruction(new InstructionBranch(Constants.IF_ICMPLE,s0),164,3,2,0); + checkInstruction(new InstructionBranch(Constants.IF_ACMPEQ,s0),165,3,2,0); + checkInstruction(new InstructionBranch(Constants.IF_ACMPNE,s0),166,3,2,0); + checkInstruction(new InstructionBranch(Constants.GOTO,s0),167,3,0,0); + checkInstruction(new InstructionBranch(Constants.JSR,s0),168,3,0,1); + checkInstruction(new RET(0,false),169,2,0,0); + + // Instructions 170-179 + checkInstruction(new TABLESWITCH(new int[]{},new InstructionHandle[]{},null),170,VARIES,1,0); + checkInstruction(new LOOKUPSWITCH(new int[]{},new InstructionHandle[]{},null),171,VARIES,1,0); + checkInstruction(InstructionConstants.IRETURN,172,1,1,0); + checkInstruction(InstructionConstants.LRETURN,173,1,2,0); + checkInstruction(InstructionConstants.FRETURN,174,1,1,0); + checkInstruction(InstructionConstants.DRETURN,175,1,2,0); + checkInstruction(InstructionConstants.ARETURN,176,1,1,0); + checkInstruction(InstructionConstants.RETURN,177,1,0,0); + checkInstruction(new FieldInstruction(Constants.GETSTATIC,0),178,3,0,VARIES); + checkInstruction(new FieldInstruction(Constants.PUTSTATIC,0),179,3,VARIES,0); + + // Instructions 180-189 + checkInstruction(new FieldInstruction(Constants.GETFIELD,0),180,3,1,VARIES); + checkInstruction(new FieldInstruction(Constants.PUTFIELD,0),181,3,VARIES,0); + checkInstruction(new InvokeInstruction(Constants.INVOKEVIRTUAL,0),182,3,VARIES,VARIES); // PRODUCE STACK VARIES OK HERE? (AND NEXT COUPLE) + checkInstruction(new InvokeInstruction(Constants.INVOKESPECIAL,0),183,3,VARIES,VARIES); + checkInstruction(new InvokeInstruction(Constants.INVOKESTATIC,0),184,3,VARIES,VARIES); + checkInstruction(new INVOKEINTERFACE(0,1,0),185,5,VARIES,VARIES); + // 186 does not exist + checkInstruction(new InstructionCP(Constants.NEW,b0),187,3,0,1); + checkInstruction(new InstructionByte(Constants.NEWARRAY,b0),188,2,1,1); + checkInstruction(new InstructionCP(Constants.ANEWARRAY,0),189,3,1,1); + + // Instructions 190-199 + checkInstruction(InstructionConstants.ARRAYLENGTH,190,1,1,1); + checkInstruction(InstructionConstants.ATHROW,191,1,1,1); + checkInstruction(new InstructionCP(Constants.CHECKCAST,s0),192,3,1,1); + checkInstruction(new InstructionCP(Constants.INSTANCEOF,s0),193,3,1,1); + checkInstruction(InstructionConstants.MONITORENTER,194,1,1,0); + checkInstruction(InstructionConstants.MONITOREXIT,195,1,1,0); + // 196 is 'wide' tag + checkInstruction(new MULTIANEWARRAY(s0,b0),197,4,VARIES,1); + checkInstruction(new InstructionBranch(Constants.IFNULL,s0),198,3,1,0); + checkInstruction(new InstructionBranch(Constants.IFNONNULL,s0),199,3,1,0); + + // Instructions 200-209 + checkInstruction(new InstructionBranch(Constants.GOTO_W,0),200,5,0,0); + checkInstruction(new InstructionBranch(Constants.JSR_W,0),201,5,0,1); + + // Internally used instructions skipped + } + + public void checkInstruction(Instruction i,int opcode, int length, int stackConsumed, int stackProduced) { + String header = new String("Checking instruction '"+i+"' "); + if (i.opcode!=opcode) + fail(header+" expected opcode "+opcode+" but it is "+i.opcode); + + if (length!=VARIES && i.getLength()!=length) + fail(header+" expected length "+length+" but it is "+i.getLength()); +// if (stackConsumed>0) { +// if ((Constants.instFlags[opcode]&Constants.STACK_CONSUMER)==0) +// fail(header+" expected it to be a STACK_CONSUMER but it is not"); +// } else { +// if ((Constants.instFlags[opcode]&Constants.STACK_CONSUMER)!=0) +// fail(header+" expected it not to be a STACK_CONSUMER but it is"); +// } + if (stackConsumed==VARIES) { + if (Constants.CONSUME_STACK[opcode]!=Constants.UNPREDICTABLE) + fail("Instruction '"+i+"' should be consuming some unpredictable number of stack entries but it says it will consume "+Constants.CONSUME_STACK[opcode]); + + } else { + if (Constants.CONSUME_STACK[opcode]!=stackConsumed) + fail("Instruction '"+i+"' should be consuming "+stackConsumed+" stack entries but it says it will consume "+Constants.CONSUME_STACK[opcode]); + } +// if (stackProduced>0) { +// if ((Constants.instFlags[opcode]&Constants.STACK_PRODUCER)==0) +// fail(header+" expected it to be a STACK_PRODUCER but it is not"); +// } else { +// if ((Constants.instFlags[opcode]&Constants.STACK_PRODUCER)!=0) +// fail(header+" expected it not to be a STACK_PRODUCER but it is"); +// } + if (stackProduced==VARIES) { + if (Constants.stackEntriesProduced[opcode]!=Constants.UNPREDICTABLE) + fail(header+" should be producing some unpredictable number of stack entries but it says it will produce "+Constants.stackEntriesProduced[opcode]); + + } else { + if (Constants.stackEntriesProduced[opcode]!=stackProduced) + fail(header+" should be producing "+stackProduced+" stack entries but it says it will produce "+Constants.stackEntriesProduced[opcode]); + } + } + + private final static byte b0 = 0; + private final static short s0 = 0; + private final static short s20 = 20; + private final static int VARIES = -1; +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GeneratingAnnotatedClassesTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GeneratingAnnotatedClassesTest.java new file mode 100644 index 000000000..94e40d491 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GeneratingAnnotatedClassesTest.java @@ -0,0 +1,572 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying + * materials are made available under the terms of the Eclipse Public License + * v1.0 which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Andy Clement - initial implementation + ******************************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +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.classfile.annotation.AnnotationElementValue; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; +import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; +import org.aspectj.apache.bcel.generic.ArrayType; +import org.aspectj.apache.bcel.generic.ClassGen; +import org.aspectj.apache.bcel.generic.InstructionBranch; +import org.aspectj.apache.bcel.generic.InstructionConstants; +import org.aspectj.apache.bcel.generic.InstructionFactory; +import org.aspectj.apache.bcel.generic.InstructionHandle; +import org.aspectj.apache.bcel.generic.InstructionList; +import org.aspectj.apache.bcel.generic.LocalVariableGen; +import org.aspectj.apache.bcel.generic.MethodGen; +import org.aspectj.apache.bcel.generic.ObjectType; +import org.aspectj.apache.bcel.generic.Type; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +/** + * The program that some of the tests generate looks like this: public class HelloWorld { public static void main(String[] argv) { + * BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String name = null; try { name = "Andy"; } + * catch(IOException e) { return; } System.out.println("Hello, " + name); } } + * + */ +public class GeneratingAnnotatedClassesTest extends BcelTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + /* + * Steps in the test: 1) Programmatically construct the HelloWorld program 2) Add two simple annotations at the class level 3) + * Save the class to disk 4) Reload the class using the 'static' variant of the BCEL classes 5) Check the attributes are OK + */ + public void testGenerateClassLevelAnnotations() throws ClassNotFoundException { + + // Create HelloWorld + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + InstructionList il = new InstructionList(); + + cg.addAnnotation(createSimpleVisibleAnnotation(cp)); + cg.addAnnotation(createSimpleInvisibleAnnotation(cp)); + + buildClassContents(cg, cp, il); + + dumpClass(cg, "HelloWorld.class"); + + JavaClass jc = getClassFrom(".", "HelloWorld"); + + AnnotationGen[] as = jc.getAnnotations(); + assertTrue("Should be two annotations but found " + as.length, as.length == 2); + AnnotationGen one = as[0]; + AnnotationGen two = as[1]; + assertTrue("Name of annotation 1 should be SimpleAnnotation but it is " + as[0].getTypeName(), as[0].getTypeName().equals( + "SimpleAnnotation")); + assertTrue("Name of annotation 2 should be SimpleAnnotation but it is " + as[1].getTypeName(), as[1].getTypeName().equals( + "SimpleAnnotation")); + List vals = as[0].getValues(); + NameValuePair nvp = vals.get(0); + assertTrue("Name of element in SimpleAnnotation should be 'id' but it is " + nvp.getNameString(), nvp.getNameString() + .equals("id")); + ElementValue ev = nvp.getValue(); + assertTrue("Type of element value should be int but it is " + ev.getElementValueType(), + ev.getElementValueType() == ElementValue.PRIMITIVE_INT); + assertTrue("Value of element should be 4 but it is " + ev.stringifyValue(), ev.stringifyValue().equals("4")); + assertTrue(createTestdataFile("HelloWorld.class").delete()); + } + + /** + * Just check that we can dump a class that has a method annotation on it and it is still there when we read it back in + */ + public void testGenerateMethodLevelAnnotations1() throws ClassNotFoundException { + // Create HelloWorld + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + InstructionList il = new InstructionList(); + + buildClassContentsWithAnnotatedMethods(cg, cp, il); + + // Check annotation is OK + int i = cg.getMethods()[0].getAnnotations().length; + assertTrue("Prior to dumping, main method should have 1 annotation but has " + i, i == 1); + + dumpClass(cg, "temp1" + File.separator + "HelloWorld.class"); + + JavaClass jc2 = getClassFrom("temp1", "HelloWorld"); + + // Check annotation is OK + i = jc2.getMethods()[0].getAnnotations().length; + assertTrue("JavaClass should say 1 annotation on main method but says " + i, i == 1); + + ClassGen cg2 = new ClassGen(jc2); + + // Check it now it is a ClassGen + Method[] m = cg2.getMethods(); + i = m[0].getAnnotations().length; + assertTrue("The main 'Method' should have one annotation but has " + i, i == 1); + MethodGen mg = new MethodGen(m[0], cg2.getClassName(), cg2.getConstantPool()); + + // Check it finally when the Method is changed to a MethodGen + i = mg.getAnnotations().size(); + assertTrue("The main 'MethodGen' should have one annotation but has " + i, i == 1); + + assertTrue(wipe("temp1" + File.separator + "HelloWorld.class")); + + } + + /** + * Going further than the last test - when we reload the method back in, let's change it (adding a new annotation) and then + * store that, read it back in and verify both annotations are there ! + */ + public void testGenerateMethodLevelAnnotations2() throws ClassNotFoundException { + // Create HelloWorld + ClassGen cg = createClassGen("HelloWorld"); + ConstantPool cp = cg.getConstantPool(); + InstructionList il = new InstructionList(); + + buildClassContentsWithAnnotatedMethods(cg, cp, il); + + dumpClass(cg, "temp2", "HelloWorld.class"); + + JavaClass jc2 = getClassFrom("temp2", "HelloWorld"); + + ClassGen cg2 = new ClassGen(jc2); + + // Main method after reading the class back in + Method mainMethod1 = jc2.getMethods()[0]; + assertTrue("The 'Method' should have one annotations but has " + mainMethod1.getAnnotations().length, mainMethod1 + .getAnnotations().length == 1); + + MethodGen mainMethod2 = new MethodGen(mainMethod1, cg2.getClassName(), cg2.getConstantPool()); + + assertTrue("The 'MethodGen' should have one annotations but has " + mainMethod2.getAnnotations().size(), mainMethod2 + .getAnnotations().size() == 1); + + mainMethod2.addAnnotation(createFruitAnnotation(cg2.getConstantPool(), "Pear")); + + cg2.removeMethod(mainMethod1); + cg2.addMethod(mainMethod2.getMethod()); + + dumpClass(cg2, "temp3", "HelloWorld.class"); + + JavaClass jc3 = getClassFrom("temp3", "HelloWorld"); + + ClassGen cg3 = new ClassGen(jc3); + + Method mainMethod3 = cg3.getMethods()[1]; + int i = mainMethod3.getAnnotations().length; + assertTrue("The 'Method' should now have two annotations but has " + i, i == 2); + + assertTrue(wipe("temp2", "HelloWorld.class")); + assertTrue(wipe("temp3", "HelloWorld.class")); + } + + // J5TODO: Need to add deleteFile calls to many of these tests + + /** + * Transform simple class from an immutable to a mutable object. + */ + public void testTransformClassToClassGen_SimpleTypes() throws ClassNotFoundException { + JavaClass jc = getClassFrom("testcode.jar", "SimpleAnnotatedClass"); + ClassGen cgen = new ClassGen(jc); + + // Check annotations are correctly preserved + AnnotationGen[] annotations = cgen.getAnnotations(); + assertTrue("Expected one annotation but found " + annotations.length, annotations.length == 1); + } + + /** + * Transform simple class from an immutable to a mutable object. The class is annotated with an annotation that uses an enum. + */ + public void testTransformClassToClassGen_EnumType() throws ClassNotFoundException { + JavaClass jc = getClassFrom("testcode.jar", "AnnotatedWithEnumClass"); + ClassGen cgen = new ClassGen(jc); + + // Check annotations are correctly preserved + AnnotationGen[] annotations = cgen.getAnnotations(); + assertTrue("Expected one annotation but found " + annotations.length, annotations.length == 1); + } + + /** + * Transform simple class from an immutable to a mutable object. The class is annotated with an annotation that uses an array of + * SimpleAnnotations. + */ + public void testTransformClassToClassGen_ArrayAndAnnotationTypes() throws ClassNotFoundException { + JavaClass jc = getClassFrom("testcode.jar", "AnnotatedWithCombinedAnnotation"); + ClassGen cgen = new ClassGen(jc); + + // Check annotations are correctly preserved + AnnotationGen[] annotations = cgen.getAnnotations(); + assertTrue("Expected one annotation but found " + annotations.length, annotations.length == 1); + AnnotationGen a = annotations[0]; + assertTrue("That annotation should only have one value but has " + a.getValues().size(), a.getValues().size() == 1); + NameValuePair nvp = a.getValues().get(0); + ElementValue value = nvp.getValue(); + assertTrue("Value should be ArrayElementValueGen but is " + value, value instanceof ArrayElementValue); + ArrayElementValue arrayValue = (ArrayElementValue) value; + assertTrue("Array value should be size one but is " + arrayValue.getElementValuesArraySize(), arrayValue + .getElementValuesArraySize() == 1); + ElementValue innerValue = arrayValue.getElementValuesArray()[0]; + assertTrue("Value in the array should be AnnotationElementValueGen but is " + innerValue, + innerValue instanceof AnnotationElementValue); + AnnotationElementValue innerAnnotationValue = (AnnotationElementValue) innerValue; + assertTrue("Should be called LSimpleAnnotation; but is called: " + innerAnnotationValue.getAnnotation().getTypeName(), + innerAnnotationValue.getAnnotation().getTypeSignature().equals("LSimpleAnnotation;")); + } + + /** + * Transform complex class from an immutable to a mutable object. + */ + public void testTransformComplexClassToClassGen() throws ClassNotFoundException { + JavaClass jc = getClassFrom("testcode.jar", "ComplexAnnotatedClass"); + ClassGen cgen = new ClassGen(jc); + + // Check annotations are correctly preserved + AnnotationGen[] annotations = cgen.getAnnotations(); + assertTrue("Expected one annotation but found " + annotations.length, annotations.length == 1); + List l = annotations[0].getValues(); + boolean found = false; + for (Iterator iter = l.iterator(); iter.hasNext();) { + NameValuePair element = iter.next(); + if (element.getNameString().equals("dval")) { + if (((SimpleElementValue) element.getValue()).stringifyValue().equals("33.4")) + found = true; + } + } + assertTrue("Did not find double annotation value with value 33.4", found); + } + + /** + * Load a class in and modify it with a new attribute - A SimpleAnnotation annotation + */ + public void testModifyingClasses1() throws ClassNotFoundException { + JavaClass jc = getClassFrom("testcode.jar", "SimpleAnnotatedClass"); + ClassGen cgen = new ClassGen(jc); + ConstantPool cp = cgen.getConstantPool(); + cgen.addAnnotation(createFruitAnnotation(cp, "Pineapple")); + assertTrue("Should now have two annotations but has " + cgen.getAnnotations().length, cgen.getAnnotations().length == 2); + dumpClass(cgen, "SimpleAnnotatedClass.class"); + assertTrue(wipe("SimpleAnnotatedClass.class")); + } + + /** + * Load a class in and modify it with a new attribute - A ComplexAnnotation annotation + */ + public void testModifyingClasses2() throws ClassNotFoundException { + JavaClass jc = getClassFrom("testcode.jar", "SimpleAnnotatedClass"); + ClassGen cgen = new ClassGen(jc); + ConstantPool cp = cgen.getConstantPool(); + cgen.addAnnotation(createCombinedAnnotation(cp)); + assertTrue("Should now have two annotations but has " + cgen.getAnnotations().length, cgen.getAnnotations().length == 2); + dumpClass(cgen, "SimpleAnnotatedClass.class"); + JavaClass jc2 = getClassFrom(".", "SimpleAnnotatedClass"); + jc2.getAnnotations(); + assertTrue(wipe("SimpleAnnotatedClass.class")); + // System.err.println(jc2.toString()); + } + + private void dumpClass(ClassGen cg, String fname) { + try { + File f = createTestdataFile(fname); + cg.getJavaClass().dump(f); + } catch (java.io.IOException e) { + System.err.println(e); + } + } + + private void dumpClass(ClassGen cg, String dir, String fname) { + dumpClass(cg, dir + File.separator + fname); + } + + private void buildClassContentsWithAnnotatedMethods(ClassGen cg, ConstantPool cp, InstructionList il) { + // Create method 'public static void main(String[]argv)' + MethodGen mg = createMethodGen("main", il, cp); + InstructionFactory factory = new InstructionFactory(cg); + mg.addAnnotation(createSimpleVisibleAnnotation(mg.getConstantPool())); + // We now define some often used types: + + ObjectType i_stream = new ObjectType("java.io.InputStream"); + ObjectType p_stream = new ObjectType("java.io.PrintStream"); + + // Create variables in and name : We call the constructors, i.e., + // execute BufferedReader(InputStreamReader(System.in)) . The reference + // to the BufferedReader object stays on top of the stack and is stored + // in the newly allocated in variable. + + il.append(factory.createNew("java.io.BufferedReader")); + il.append(InstructionConstants.DUP); // Use predefined constant + il.append(factory.createNew("java.io.InputStreamReader")); + il.append(InstructionConstants.DUP); + il.append(factory.createFieldAccess("java.lang.System", "in", i_stream, Constants.GETSTATIC)); + il.append(factory.createInvoke("java.io.InputStreamReader", "", Type.VOID, new Type[] { i_stream }, + Constants.INVOKESPECIAL)); + il.append(factory.createInvoke("java.io.BufferedReader", "", Type.VOID, + new Type[] { new ObjectType("java.io.Reader") }, Constants.INVOKESPECIAL)); + + LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null); + int in = lg.getIndex(); + lg.setStart(il.append(InstructionFactory.createASTORE(in))); // "in" valid from here + + // Create local variable name and initialize it to null + + lg = mg.addLocalVariable("name", Type.STRING, null, null); + int name = lg.getIndex(); + il.append(InstructionConstants.ACONST_NULL); + lg.setStart(il.append(InstructionFactory.createASTORE(name))); // "name" valid from here + + // Create try-catch block: We remember the start of the block, read a + // line from the standard input and store it into the variable name . + + // InstructionHandle try_start = il.append(factory.createFieldAccess( + // "java.lang.System", "out", p_stream, Constants.GETSTATIC)); + + // il.append(new PUSH(cp, "Please enter your name> ")); + // il.append(factory.createInvoke("java.io.PrintStream", "print", + // Type.VOID, new Type[] { Type.STRING }, + // Constants.INVOKEVIRTUAL)); + // il.append(new ALOAD(in)); + // il.append(factory.createInvoke("java.io.BufferedReader", "readLine", + // Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + InstructionHandle try_start = il.append(InstructionFactory.PUSH(cp, "Andy")); + il.append(InstructionFactory.createASTORE(name)); + + // Upon normal execution we jump behind exception handler, the target + // address is not known yet. + + InstructionBranch g = new InstructionBranch(Constants.GOTO); + InstructionHandle try_end = il.append(g); + + // We add the exception handler which simply returns from the method. + + LocalVariableGen var_ex = mg.addLocalVariable("ex", Type.getType("Ljava.io.IOException;"), null, null); + int var_ex_slot = var_ex.getIndex(); + + InstructionHandle handler = il.append(InstructionFactory.createASTORE(var_ex_slot)); + var_ex.setStart(handler); + var_ex.setEnd(il.append(InstructionConstants.RETURN)); + + mg.addExceptionHandler(try_start, try_end, handler, new ObjectType("java.io.IOException")); + + // "Normal" code continues, now we can set the branch target of the GOTO + // . + + InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC)); + g.setTarget(ih); + + // Printing "Hello": String concatenation compiles to StringBuffer + // operations. + + il.append(factory.createNew(Type.STRINGBUFFER)); + il.append(InstructionConstants.DUP); + il.append(InstructionFactory.PUSH(cp, "Hello, ")); + il.append(factory.createInvoke("java.lang.StringBuffer", "", Type.VOID, new Type[] { Type.STRING }, + Constants.INVOKESPECIAL)); + il.append(InstructionFactory.createALOAD(name)); + il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { Type.STRING }, + Constants.INVOKEVIRTUAL)); + il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + + il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, + Constants.INVOKEVIRTUAL)); + il.append(InstructionConstants.RETURN); + + // Finalization: Finally, we have to set the stack size, which normally + // would have to be computed on the fly and add a default constructor + // method to the class, which is empty in this case. + + mg.setMaxStack(); + mg.setMaxLocals(); + cg.addMethod(mg.getMethod()); + il.dispose(); // Allow instruction handles to be reused + cg.addEmptyConstructor(Constants.ACC_PUBLIC); + } + + private void buildClassContents(ClassGen cg, ConstantPool cp, InstructionList il) { + // Create method 'public static void main(String[]argv)' + MethodGen mg = createMethodGen("main", il, cp); + InstructionFactory factory = new InstructionFactory(cg); + // We now define some often used types: + + ObjectType i_stream = new ObjectType("java.io.InputStream"); + ObjectType p_stream = new ObjectType("java.io.PrintStream"); + + // Create variables in and name : We call the constructors, i.e., + // execute BufferedReader(InputStreamReader(System.in)) . The reference + // to the BufferedReader object stays on top of the stack and is stored + // in the newly allocated in variable. + + il.append(factory.createNew("java.io.BufferedReader")); + il.append(InstructionConstants.DUP); // Use predefined constant + il.append(factory.createNew("java.io.InputStreamReader")); + il.append(InstructionConstants.DUP); + il.append(factory.createFieldAccess("java.lang.System", "in", i_stream, Constants.GETSTATIC)); + il.append(factory.createInvoke("java.io.InputStreamReader", "", Type.VOID, new Type[] { i_stream }, + Constants.INVOKESPECIAL)); + il.append(factory.createInvoke("java.io.BufferedReader", "", Type.VOID, + new Type[] { new ObjectType("java.io.Reader") }, Constants.INVOKESPECIAL)); + + LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null); + int in = lg.getIndex(); + lg.setStart(il.append(InstructionFactory.createASTORE(in))); // "in" valid from here + + // Create local variable name and initialize it to null + + lg = mg.addLocalVariable("name", Type.STRING, null, null); + int name = lg.getIndex(); + il.append(InstructionConstants.ACONST_NULL); + lg.setStart(il.append(InstructionFactory.createASTORE(name))); // "name" valid from here + + // Create try-catch block: We remember the start of the block, read a + // line from the standard input and store it into the variable name . + + // InstructionHandle try_start = il.append(factory.createFieldAccess( + // "java.lang.System", "out", p_stream, Constants.GETSTATIC)); + + // il.append(new PUSH(cp, "Please enter your name> ")); + // il.append(factory.createInvoke("java.io.PrintStream", "print", + // Type.VOID, new Type[] { Type.STRING }, + // Constants.INVOKEVIRTUAL)); + // il.append(new ALOAD(in)); + // il.append(factory.createInvoke("java.io.BufferedReader", "readLine", + // Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + InstructionHandle try_start = il.append(InstructionFactory.PUSH(cp, "Andy")); + il.append(InstructionFactory.createASTORE(name)); + + // Upon normal execution we jump behind exception handler, the target + // address is not known yet. + + InstructionBranch g = new InstructionBranch(Constants.GOTO); + InstructionHandle try_end = il.append(g); + + // We add the exception handler which simply returns from the method. + + LocalVariableGen var_ex = mg.addLocalVariable("ex", Type.getType("Ljava.io.IOException;"), null, null); + int var_ex_slot = var_ex.getIndex(); + + InstructionHandle handler = il.append(InstructionFactory.createASTORE(var_ex_slot)); + var_ex.setStart(handler); + var_ex.setEnd(il.append(InstructionConstants.RETURN)); + + mg.addExceptionHandler(try_start, try_end, handler, new ObjectType("java.io.IOException")); + + // "Normal" code continues, now we can set the branch target of the GOTO + // . + + InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC)); + g.setTarget(ih); + + // Printing "Hello": String concatenation compiles to StringBuffer + // operations. + + il.append(factory.createNew(Type.STRINGBUFFER)); + il.append(InstructionConstants.DUP); + il.append(InstructionFactory.PUSH(cp, "Hello, ")); + il.append(factory.createInvoke("java.lang.StringBuffer", "", Type.VOID, new Type[] { Type.STRING }, + Constants.INVOKESPECIAL)); + il.append(InstructionFactory.createALOAD(name)); + il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { Type.STRING }, + Constants.INVOKEVIRTUAL)); + il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + + il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, + Constants.INVOKEVIRTUAL)); + il.append(InstructionConstants.RETURN); + + // Finalization: Finally, we have to set the stack size, which normally + // would have to be computed on the fly and add a default constructor + // method to the class, which is empty in this case. + + mg.setMaxStack(); + mg.setMaxLocals(); + cg.addMethod(mg.getMethod()); + il.dispose(); // Allow instruction handles to be reused + cg.addEmptyConstructor(Constants.ACC_PUBLIC); + } + + private JavaClass getClassFrom(String where, String clazzname) throws ClassNotFoundException { + SyntheticRepository repos = createRepos(where); + return repos.loadClass(clazzname); + } + + // helper methods + + private ClassGen createClassGen(String classname) { + return new ClassGen(classname, "java.lang.Object", "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); + } + + private MethodGen createMethodGen(String methodname, InstructionList il, ConstantPool cp) { + return new MethodGen(Constants.ACC_STATIC | Constants.ACC_PUBLIC, // access flags + Type.VOID, // return type + new Type[] { new ArrayType(Type.STRING, 1) }, // argument types + new String[] { "argv" }, // arg names + methodname, "HelloWorld", // method, class + il, cp); + } + + public AnnotationGen createSimpleVisibleAnnotation(ConstantPool cp) { + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 4); + + NameValuePair nvGen = new NameValuePair("id", evg, cp); + + ObjectType t = new ObjectType("SimpleAnnotation"); + + List elements = new ArrayList(); + elements.add(nvGen); + + AnnotationGen a = new AnnotationGen(t, elements, true, cp); + return a; + } + + public AnnotationGen createFruitAnnotation(ConstantPool cp, String aFruit) { + SimpleElementValue evg = new SimpleElementValue(ElementValue.STRING, cp, aFruit); + NameValuePair nvGen = new NameValuePair("fruit", evg, cp); + ObjectType t = new ObjectType("SimpleStringAnnotation"); + List elements = new ArrayList(); + elements.add(nvGen); + return new AnnotationGen(t, elements, true, cp); + } + + public AnnotationGen createCombinedAnnotation(ConstantPool cp) { + // Create an annotation instance + AnnotationGen a = createSimpleVisibleAnnotation(cp); + ArrayElementValue array = new ArrayElementValue(cp); + array.addElement(new AnnotationElementValue(a, cp)); + NameValuePair nvp = new NameValuePair("value", array, cp); + List elements = new ArrayList(); + elements.add(nvp); + return new AnnotationGen(new ObjectType("CombinedAnnotation"), elements, true, cp); + } + + public AnnotationGen createSimpleInvisibleAnnotation(ConstantPool cp) { + SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 4); + + NameValuePair nvGen = new NameValuePair("id", evg, cp); + + ObjectType t = new ObjectType("SimpleAnnotation"); + + List elements = new ArrayList(); + elements.add(nvGen); + + AnnotationGen a = new AnnotationGen(t, elements, false, cp); + return a; + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} \ No newline at end of file diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java new file mode 100644 index 000000000..f64e4440f --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java @@ -0,0 +1,472 @@ +/* ******************************************************************* + * Copyright (c) 2005 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement (IBM) initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.tests; + +import java.util.ArrayList; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ClassFormatException; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.Signature; +import org.aspectj.apache.bcel.classfile.Utility; + +/** + * Generics introduces more complex signature possibilities, they are no longer just + * made up of primitives or big 'L' types. The addition of 'anglies' due to + * parameterization and the ability to specify wildcards (possibly bounded) + * when talking about parameterized types means we need to be much more sophisticated. + * + * + * Notes: + * Signatures are used to encode Java programming language type informaiton + * that is not part of the JVM type system, such as generic type and method + * declarations and parameterized types. This kind of information is + * needed to support reflection and debugging, and by the Java compiler. + * + * ============================================= + * + * ClassTypeSignature = LPackageSpecifier* SimpleClassTypeSignature ClassTypeSignatureSuffix*; + * + * PackageSpecifier = Identifier/PackageSpecifier* + * SimpleClassTypeSignature= Identifier TypeArguments(opt) + * ClassTypeSignatureSuffix= .SimpleClassTypeSignature + * TypeVariableSignature = TIdentifier; + * TypeArguments = + * TypeArgument = WildcardIndiciator(opt) FieldTypeSignature + * * + * WildcardIndicator = + + * - + * ArrayTypeSignature = [TypeSignature + * TypeSignature = [FieldTypeSignature + * [BaseType + * + * + * Examples: + * Ljava/util/List; == java.util.List + * Ljava/util/List; == java.util.List + * Ljava/util/List; == java.util.List + * Ljava/util/List<+Ljava/lang/Number;>; == java.util.List + * Ljava/util/List<-Ljava/lang/Number;>; == java.util.List + * Ljava/util/List<*>; == java.util.List + * Ljava/util/Map<*-Ljava/lang/Number;>; == java.util.Map + * + * ============================================= + * + * ClassSignature = FormalTypeParameters(opt) SuperclassSignature SuperinterfaceSignatures* + * + * optional formal type parameters then a superclass signature then a superinterface signature + * + * FormalTypeParameters = + * FormalTypeParameter = Identifier ClassBound InterfaceBound* + * ClassBound = :FieldTypeSignature(opt) + * InterfaceBound = :FieldTypeSignature + * + * If it exists, a set of formal type parameters are contained in anglies and consist of an identifier a classbound (assumed to be + * object if not specified) and then an optional list of InterfaceBounds + * + * SuperclassSignature = ClassTypeSignature + * SuperinterfaceSignature = ClassTypeSignature + * FieldTypeSignature = ClassTypeSignature + * ArrayTypeSignature + * TypeVariableSignature + * + * + * MethodTypeSignature = FormalTypeParameters(opt) ( TypeSignature* ) ReturnType ThrowsSignature* + * ReturnType = TypeSignature + * VoidDescriptor + * ThrowsSignature = ^ClassTypeSignature + * ^TypeVariableSignature + * + * Examples: + * + * ;> + * + * ClassBound not supplied, Object assumed. Interface bound is Comparable + * + * "T:Ljava/lang/Object;:Ljava/lang/Comparable<-TT;>;","T extends java.lang.Object & java.lang.Comparable" + * + */ +public class GenericSignatureParsingTest extends BcelTestCase { + + + /** + * Throw some generic format signatures at the BCEL signature + * parsing code and see what it does. + */ + public void testParsingGenericSignatures_ClassTypeSignature() { + // trivial + checkClassTypeSignature("Ljava/util/List;","java.util.List"); + + // basics + checkClassTypeSignature("Ljava/util/List;","java.util.List"); + checkClassTypeSignature("Ljava/util/List;","java.util.List"); + + // madness + checkClassTypeSignature("Ljava/util/List<+Ljava/lang/Number;>;","java.util.List"); + checkClassTypeSignature("Ljava/util/List<-Ljava/lang/Number;>;","java.util.List"); + checkClassTypeSignature("Ljava/util/List<*>;", "java.util.List"); + checkClassTypeSignature("Ljava/util/Map<*-Ljava/lang/Number;>;","java.util.Map"); + + // with type params + checkClassTypeSignature("Ljava/util/Collection;","java.util.Collection"); + + // arrays + checkClassTypeSignature("Ljava/util/List<[Ljava/lang/String;>;","java.util.List"); + checkClassTypeSignature("[Ljava/util/List;","java.util.List[]"); + + } + + + public void testMethodTypeToSignature() { + checkMethodTypeToSignature("void",new String[]{"java.lang.String[]","boolean"},"([Ljava/lang/String;Z)V"); + checkMethodTypeToSignature("void",new String[]{"java.util.List"},"(Ljava/util/List;)V"); + } + + public void testMethodSignatureToArgumentTypes() { + checkMethodSignatureArgumentTypes("([Ljava/lang/String;Z)V",new String[]{"java.lang.String[]","boolean"}); +// checkMethodSignatureArgumentTypes("(Ljava/util/List;)V",new String[]{"java.util.List"}); + } + + public void testMethodSignatureReturnType() { + checkMethodSignatureReturnType("([Ljava/lang/String;)Z","boolean"); + } + + public void testLoadingGenerics() throws ClassNotFoundException { + JavaClass clazz = getClassFromJar("PossibleGenericsSigs"); + // J5TODO asc fill this bit in... + } + + + // helper methods below + + // These routines call BCEL to determine if it can correctly translate from one form to the other. + private void checkClassTypeSignature(String sig, String expected) { + StringBuffer result = new StringBuffer(); + int p = GenericSignatureParsingTest.readClassTypeSignatureFrom(sig,0,result,false); + assertTrue("Only swallowed "+p+" chars of this sig "+sig+" (len="+sig.length()+")",p==sig.length()); + assertTrue("Expected '"+expected+"' but got '"+result.toString()+"'",result.toString().equals(expected)); + } + + private void checkMethodTypeToSignature(String ret,String[] args,String expected) { + String res = GenericSignatureParsingTest.methodTypeToSignature(ret,args); + if (!res.equals(expected)) { + fail("Should match. Got: "+res+" Expected:"+expected); + } + } + + private void checkMethodSignatureReturnType(String sig,String expected) { + String result = GenericSignatureParsingTest.methodSignatureReturnType(sig,false); + if (!result.equals(expected)) { + fail("Should match. Got: "+result+" Expected:"+expected); + } + } + + private void checkMethodSignatureArgumentTypes(String in,String[] expected) { + String[] result = GenericSignatureParsingTest.methodSignatureArgumentTypes(in,false); + if (result.length!=expected.length) { + fail("Expected "+expected.length+" entries to be returned but only got "+result.length); + } + for (int i = 0; i < expected.length; i++) { + String string = result[i]; + if (!string.equals(expected[i])) + fail("Argument: "+i+" should have been "+expected[i]+" but was "+string); + } + } + + public Signature getSignatureAttribute(JavaClass clazz,String name) { + Method m = getMethod(clazz,name); + Attribute[] as = m.getAttributes(); + for (int i = 0; i < as.length; i++) { + Attribute attribute = as[i]; + if (attribute.getName().equals("Signature")) { + return (Signature)attribute; + } + } + return null; + } + + + /** + * Takes a string and consumes a single complete signature from it, returning + * how many chars it consumed. The chopit flag indicates whether to shorten + * type references ( java/lang/String => String ) + * + * FIXME asc this should also create some kind of object you can query for information about whether its parameterized, what the bounds are, etc... + */ + public static final int readClassTypeSignatureFrom(String signature, int posn, StringBuffer result, boolean chopit) { + int idx = posn; + try { + switch (signature.charAt(idx)) { + case 'B' : result.append("byte"); return 1; + case 'C' : result.append("char"); return 1; + case 'D' : result.append("double"); return 1; + case 'F' : result.append("float"); return 1; + case 'I' : result.append("int"); return 1; + case 'J' : result.append("long"); return 1; + case 'S' : result.append("short"); return 1; + case 'Z' : result.append("boolean");return 1; + case 'V' : result.append("void"); return 1; + + + //FIXME ASC Need a state machine to check we are parsing the right stuff here ! + case 'T' : + idx++; + int nextSemiIdx = signature.indexOf(';',idx); + result.append(signature.substring(idx,nextSemiIdx)); + return nextSemiIdx+1-posn; + + case '+' : + result.append("? extends "); + return readClassTypeSignatureFrom(signature,idx+1,result,chopit)+1; + + case '-' : + result.append("? super "); + return readClassTypeSignatureFrom(signature,idx+1,result,chopit)+1; + + case '*' : + result.append("?"); + return 1; + + case 'L' : // Full class name + boolean parameterized = false; + int idxSemicolon = signature.indexOf(';',idx); // Look for closing ';' or '<' + int idxAngly = signature.indexOf('<',idx); + int endOfSig = idxSemicolon; + if ((idxAngly!=-1) && idxAngly");idx++; + } + if (signature.charAt(idx)!=';') throw new RuntimeException("Did not find ';' at end of signature, found "+signature.charAt(idx)); + idx++; + return idx-posn; + + + case '[' : // Array declaration + int dim = 0; + while (signature.charAt(idx)=='[') {dim++;idx++;} + idx+=readClassTypeSignatureFrom(signature,idx,result,chopit); + while (dim>0) {result.append("[]");dim--;} + return idx-posn; + + default : throw new ClassFormatException("Invalid signature: `" + + signature + "'"); + } + } catch(StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid signature: " + e + ":" + signature); + } + } + + + public static final String readClassTypeSignatureFrom(String signature) { + StringBuffer sb = new StringBuffer(); + GenericSignatureParsingTest.readClassTypeSignatureFrom(signature,0,sb,false); + return sb.toString(); + } + + + public static int countBrackets(String brackets) { + char[] chars = brackets.toCharArray(); + int count = 0; + boolean open = false; + + for(int i=0; i 0) brackets = GenericSignatureParsingTest.countBrackets(type.substring(index)); + + type = buf.toString(); + buf.setLength(0); + + for (int i=0; i < brackets; i++) buf.append('['); + + boolean found = false; + + for(int i=Constants.T_BOOLEAN; (i <= Constants.T_VOID) && !found; i++) { + if (Constants.TYPE_NAMES[i].equals(type)) { + found = true; + buf.append(Constants.SHORT_TYPE_NAMES[i]); + } + } + + // Class name + if (!found) buf.append('L' + type.replace('.', '/') + ';'); + + return buf.toString(); + } + + + /** + * For some method signature (class file format) like '([Ljava/lang/String;)Z' this returns + * the string representing the return type its 'normal' form, e.g. 'boolean' + * + * @param signature Method signature + * @param chopit Shorten class names + * @return return type of method + */ + public static final String methodSignatureReturnType(String signature,boolean chopit) throws ClassFormatException { + int index; + String type; + try { + // Read return type after `)' + index = signature.lastIndexOf(')') + 1; + type = Utility.signatureToString(signature.substring(index), chopit); + } catch (StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature); + } + return type; + } + + + /** + * For some method signature (class file format) like '([Ljava/lang/String;)Z' this returns + * the string representing the return type its 'normal' form, e.g. 'boolean' + * + * @param signature Method signature + * @return return type of method + * @throws ClassFormatException + */ + public static final String methodSignatureReturnType(String signature) throws ClassFormatException { + return GenericSignatureParsingTest.methodSignatureReturnType(signature, true); + } + + + /** + * For some method signature (class file format) like '([Ljava/lang/String;Z)V' this returns an array + * of strings representing the arguments in their 'normal' form, e.g. '{java.lang.String[],boolean}' + * + * @param signature Method signature + * @param chopit Shorten class names + * @return Array of argument types + */ + public static final String[] methodSignatureArgumentTypes(String signature,boolean chopit) throws ClassFormatException { + ArrayList vec = new ArrayList(); + int index; + String[] types; + + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') + throw new ClassFormatException("Invalid method signature: " + signature); + + index = 1; // current string position + + while(signature.charAt(index) != ')') { + Utility.ResultHolder rh = Utility.signatureToStringInternal(signature.substring(index),chopit); + vec.add(rh.getResult()); + index += rh.getConsumedChars(); + } + } catch(StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature); + } + + types = new String[vec.size()]; + vec.toArray(types); + return types; + } + + + /** + * Converts string containing the method return and argument types + * to a byte code method signature. + * + * @param returnType Return type of method (e.g. "char" or "java.lang.String[]") + * @param methodArgs Types of method arguments + * @return Byte code representation of method signature + */ + public final static String methodTypeToSignature(String returnType, String[] methodArgs) throws ClassFormatException { + + StringBuffer buf = new StringBuffer("("); + + if (methodArgs != null) { + for (int i=0; i < methodArgs.length; i++) { + String str = GenericSignatureParsingTest.getSignature(methodArgs[i]); + + if (str.equals("V")) // void can't be a method argument + throw new ClassFormatException("Invalid type: " + methodArgs[i]); + + buf.append(str); + } + } + + buf.append(")" + GenericSignatureParsingTest.getSignature(returnType)); + + return buf.toString(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GenericsErasureTesting.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GenericsErasureTesting.java new file mode 100644 index 000000000..f0e5de738 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GenericsErasureTesting.java @@ -0,0 +1,50 @@ +/* ******************************************************************* + * Copyright (c) 2005 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement (IBM) initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.tests; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.Signature; + +/** + * Should be possible to recover original declared signatures after erasure by using + * the signature attribute. + */ +public class GenericsErasureTesting extends BcelTestCase { + + + public void testLoadingGenerics() throws ClassNotFoundException { + JavaClass clazz = getClassFromJar("ErasureTestData"); + Method m = getMethod(clazz,"getData"); + String sig = m.getDeclaredSignature(); + System.err.println(getSignatureAttribute(clazz,"getData")); + System.err.println(sig); + assertTrue("Incorrect: "+sig,sig.equals("()Ljava/util/Vector;")); + } + + + // helper methods below + + public Signature getSignatureAttribute(JavaClass clazz,String name) { + Method m = getMethod(clazz,name); + Attribute[] as = m.getAttributes(); + for (int i = 0; i < as.length; i++) { + Attribute attribute = as[i]; + if (attribute.getName().equals("Signature")) { + return (Signature)attribute; + } + } + return null; + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GetReflectMembersTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GetReflectMembersTest.java new file mode 100644 index 000000000..06bd9ccc8 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/GetReflectMembersTest.java @@ -0,0 +1,61 @@ +/* ******************************************************************* + * Copyright (c) 2005 Contributors. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.tests; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.ClassLoaderRepository; +import org.aspectj.apache.bcel.util.Repository; + +import junit.framework.TestCase; + +/** + * @author colyer + * + */ +public class GetReflectMembersTest extends TestCase { + + private Repository bcelRepository; + private JavaClass jc; + + public void testGetMethod() throws Exception { + assertNotNull(jc.getMethod(GetMe.class.getMethod("foo",new Class[] {String.class}))); + } + + public void testGetConstructor() throws Exception { + assertNotNull(jc.getMethod(GetMe.class.getConstructor(new Class[] {int.class}))); + } + + public void testGetField() throws Exception { + assertNotNull(jc.getField(GetMe.class.getDeclaredField("x"))); + } + + protected void setUp() throws Exception { + super.setUp(); + this.bcelRepository = new ClassLoaderRepository(getClass().getClassLoader()); + this.jc = bcelRepository.loadClass(GetMe.class); + } + + protected void tearDown() throws Exception { + super.tearDown(); + this.bcelRepository.clear(); + } + + private static class GetMe { + + private int x; + + public GetMe(int x) { this.x = x;} + + public void foo(String s) {}; + + } +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/LocalVariableTypeTableTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/LocalVariableTypeTableTest.java new file mode 100644 index 000000000..41eba95e0 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/LocalVariableTypeTableTest.java @@ -0,0 +1,72 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import org.aspectj.apache.bcel.classfile.Code; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.LocalVariable; +import org.aspectj.apache.bcel.classfile.LocalVariableTypeTable; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.Utility; + + +public class LocalVariableTypeTableTest extends BcelTestCase { + + + protected void setUp() throws Exception { + super.setUp(); + } + + /** + * Check the local variable type table includes information about generic signatures. + */ + public void testLocalVariableTypeTableAttribute() throws ClassNotFoundException { + JavaClass clazz = getClassFromJar("SimpleGenericsProgram"); + + Method mainMethod = getMethod(clazz,"main"); + Code codeAttr = (Code) findAttribute("Code",mainMethod.getAttributes()); + LocalVariableTypeTable localVariableTypeTable = + (LocalVariableTypeTable) findAttribute("LocalVariableTypeTable",codeAttr.getAttributes()); + + assertTrue("Should be two entries in the LocalVariableTypeTable but found "+localVariableTypeTable.getTableLength(), + localVariableTypeTable.getTableLength()==2); + + LocalVariable[] lvtable = localVariableTypeTable.getLocalVariableTypeTable(); + boolean tc1OK = false; + boolean tc2OK = false; + String errormessage = null; + for (int i = 0; i < lvtable.length; i++) { + String sig = Utility.signatureToString(lvtable[i].getSignature()); + if (lvtable[i].getName().equals("tc1")) { + if (!sig.equals("TreasureChest")) { + errormessage="Expected signature of 'TreasureChest' for tc1 but got "+sig; + } else { + tc1OK = true; + } + } + if (lvtable[i].getName().equals("tc2")) { + if (!sig.equals("TreasureChest")) { + errormessage="Expected signature of 'TreasureChest' for tc2 but got "+sig; + } else { + tc2OK = true; + } + } + } + if (!tc1OK || !tc2OK) fail(errormessage); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/MethodAnnotationsTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/MethodAnnotationsTest.java new file mode 100644 index 000000000..14d009cf0 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/MethodAnnotationsTest.java @@ -0,0 +1,107 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.util.SyntheticRepository; + + +public class MethodAnnotationsTest extends BcelTestCase { + + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testMethodAnnotations() throws ClassNotFoundException { + JavaClass clazz = getClassFromJar("AnnotatedMethods"); + + checkAnnotatedMethod(clazz,"method1","SimpleAnnotation","id","1"); + checkAnnotatedMethod(clazz,"method2","SimpleAnnotation","id","2"); + + } + + public void testMethodAnnotationsReadWrite() throws ClassNotFoundException,IOException { + JavaClass clazz = getClassFromJar("AnnotatedMethods"); + + checkAnnotatedMethod(clazz,"method1","SimpleAnnotation","id","1"); + checkAnnotatedMethod(clazz,"method2","SimpleAnnotation","id","2"); + + // Write it out + File tfile = createTestdataFile("AnnotatedMethods.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos2.loadClass("AnnotatedMethods"); + + checkAnnotatedMethod(clazz,"method1","SimpleAnnotation","id","1"); + checkAnnotatedMethod(clazz,"method2","SimpleAnnotation","id","2"); + + assertTrue(tfile.delete()); + } + + // helper methods + + public void checkAnnotatedMethod(JavaClass clazz,String methodname, + String annotationName,String annotationElementName,String annotationElementValue) { + Method[] methods = clazz.getMethods(); + + for (int i = 0; i < methods.length; i++) { + Method m = methods[i]; + AnnotationGen[] methodAnnotations = m.getAnnotations(); + if (m.getName().equals(methodname)) { + checkAnnotation(methodAnnotations[0],annotationName,annotationElementName,annotationElementValue); + + } + } + } + + private void checkAnnotation(AnnotationGen a,String name,String elementname,String elementvalue) { + assertTrue("Expected annotation to have name "+name+" but it had name "+a.getTypeName(), + a.getTypeName().equals(name)); + assertTrue("Expected annotation to have one element but it had "+a.getValues().size(),a.getValues().size()==1); + NameValuePair envp = a.getValues().get(0); + assertTrue("Expected element name "+elementname+" but was "+envp.getNameString(), + elementname.equals(envp.getNameString())); + assertTrue("Expected element value "+elementvalue+" but was "+envp.getValue().stringifyValue(), + elementvalue.equals(envp.getValue().stringifyValue())); + } + + + // helper methods + + public void checkValue(AnnotationGen a,String name,String tostring) { + for (Iterator i = a.getValues().iterator(); i.hasNext();) { + NameValuePair element = i.next(); + if (element.getNameString().equals(name)) { + if (!element.getValue().stringifyValue().equals(tostring)) { + fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue()); + } + return; + } + } + fail("Didnt find named element "+name); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/MethodParametersTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/MethodParametersTest.java new file mode 100644 index 000000000..76a9b84d8 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/MethodParametersTest.java @@ -0,0 +1,86 @@ +/* ******************************************************************* + * Copyright (c) 2013 VMware + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.tests; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.MethodParameters; + +public class MethodParametersTest extends BcelTestCase { + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testMethodParameters1() throws Exception { + JavaClass jc = getClassFromJava8Jar("Parameters"); + Method m = getMethod(jc, "foo"); + MethodParameters mp = (MethodParameters)getAttribute(m.getAttributes(),Constants.ATTR_METHOD_PARAMETERS); + assertEquals(3,mp.getParametersCount()); + assertEquals("abc",mp.getParameterName(0)); + assertEquals("def",mp.getParameterName(1)); + assertEquals("ghi",mp.getParameterName(2)); + assertFalse(mp.isFinal(0)); + assertFalse(mp.isSynthetic(0)); + assertFalse(mp.isMandated(0)); + } + + // this method specifies the receiver + public void testMethodParameters2() throws Exception { + JavaClass jc = getClassFromJava8Jar("Parameters"); + Method m = getMethod(jc, "bar"); + MethodParameters mp = (MethodParameters)getAttribute(m.getAttributes(),Constants.ATTR_METHOD_PARAMETERS); + assertEquals(1,mp.getParametersCount()); + assertEquals("abc",mp.getParameterName(0)); + assertFalse(mp.isFinal(0)); + assertFalse(mp.isSynthetic(0)); + assertFalse(mp.isMandated(0)); + } + + // access flags + public void testMethodParameters3() throws Exception { + JavaClass jc = getClassFromJava8Jar("Parameters$Inner"); + Method m = getMethod(jc, ""); + MethodParameters mp = (MethodParameters)getAttribute(m.getAttributes(),Constants.ATTR_METHOD_PARAMETERS); + assertEquals(2,mp.getParametersCount()); + + assertEquals("this$0",mp.getParameterName(0)); + assertTrue(mp.isFinal(0)); + assertFalse(mp.isSynthetic(0)); + assertTrue(mp.isMandated(0)); + + assertEquals("x",mp.getParameterName(1)); + assertFalse(mp.isFinal(1)); + assertFalse(mp.isSynthetic(1)); + assertFalse(mp.isMandated(1)); + } + + // access flags + public void testMethodParameters4() throws Exception { + JavaClass jc = getClassFromJava8Jar("Parameters$Color"); + Method m = getMethod(jc, ""); + MethodParameters mp = (MethodParameters)getAttribute(m.getAttributes(),Constants.ATTR_METHOD_PARAMETERS); + assertEquals(2,mp.getParametersCount()); + + assertEquals("$enum$name",mp.getParameterName(0)); + assertFalse(mp.isFinal(0)); + assertTrue(mp.isSynthetic(0)); + assertFalse(mp.isMandated(0)); + + assertEquals("$enum$ordinal",mp.getParameterName(1)); + assertFalse(mp.isFinal(1)); + assertTrue(mp.isSynthetic(1)); + assertFalse(mp.isMandated(1)); + } + +} \ No newline at end of file diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java new file mode 100644 index 000000000..454817df8 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java @@ -0,0 +1,136 @@ +/* ******************************************************************* + * Copyright (c) 2016-2017 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ClassParser; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Module; +import org.aspectj.apache.bcel.classfile.Module.Export; +import org.aspectj.apache.bcel.classfile.Module.Open; +import org.aspectj.apache.bcel.classfile.Module.Provide; +import org.aspectj.apache.bcel.classfile.Module.Require; +import org.aspectj.apache.bcel.classfile.Module.Uses; +import org.aspectj.apache.bcel.classfile.SourceFile; + +/** + * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html + * + * @author Andy Clement + */ +public class ModuleTest extends BcelTestCase { + + public void testLoadSimpleModuleClass() throws Exception { + String moduleFilename = "testdata/modules/one/module-info.class"; + ClassParser classParser = new ClassParser(moduleFilename); + JavaClass javaClass = classParser.parse(); + assertNotNull(javaClass); + assertEquals(Constants.MAJOR_1_9,javaClass.getMajor()); + assertEquals(Constants.MINOR_1_9,javaClass.getMinor()); + assertEquals(Constants.ACC_MODULE,javaClass.getModifiers()); + assertEquals(0,javaClass.getSuperclassNameIndex()); + assertEquals(0,javaClass.getInterfaceIndices().length); + assertEquals(0,javaClass.getFields().length); + assertEquals(0,javaClass.getMethods().length); + Attribute[] attrs = javaClass.getAttributes(); + assertEquals(2,attrs.length); + SourceFile sourceFile = (SourceFile) getAttribute(attrs,Constants.ATTR_SOURCE_FILE); + Module moduleAttr = (Module) getAttribute(attrs, Constants.ATTR_MODULE); + byte[] originalData = moduleAttr.getBytes(); + String[] requiredModuleNames = moduleAttr.getRequiredModuleNames(); + assertEquals(1,requiredModuleNames.length); + assertEquals("java.base",requiredModuleNames[0]); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + moduleAttr.dump(new DataOutputStream(baos)); + byte[] newData = baos.toByteArray(); + // The 6 offset here is because the newdata includes the 2byte cpool pointer for the name 'Module' + // and the 4byte int length field for the attribute data + if (newData.length!=originalData.length+6) { + fail("Expected the length of the original attribute ("+originalData.length+") to match the new written length ("+newData.length+")"); + } + for (int i=0;i. + */ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository; + +/** + * @author Kristian Rosenvold + */ +public class NonCachingClassLoaderRepositoryTest extends TestCase { + + private final NonCachingClassLoaderRepository nonCachingClassLoaderRepository = new NonCachingClassLoaderRepository( + NonCachingClassLoaderRepositoryTest.class.getClassLoader()); + + protected void setUp() throws Exception { + super.setUp(); + } + + abstract class DoneChecker implements Runnable { + private volatile boolean success = false; + private volatile boolean done = false; + + public boolean isSuccess() { + return success; + } + + public boolean isDone() { + return done; + } + + protected void setDone(boolean successFully) { + success = successFully; + done = true; + } + + public abstract void run(); + } + + class Loader extends DoneChecker implements Runnable { + public void run() { + try { + JavaClass javaClass = nonCachingClassLoaderRepository.loadClass(NonCachingClassLoaderRepositoryTest.class + .getCanonicalName()); + nonCachingClassLoaderRepository.clear(); + setDone(true); + } catch (Throwable e) { + e.printStackTrace(System.out); + setDone(false); + } + } + } + + class Clearer extends DoneChecker implements Runnable { + public void run() { + try { + nonCachingClassLoaderRepository.clear(); + setDone(true); + } catch (Throwable e) { + e.printStackTrace(System.out); + setDone(false); + } + } + } + + public void testConcurrency() throws ClassNotFoundException, InterruptedException { + List loaders = new ArrayList(); + int i1 = 1000; + for (int i = 0; i < i1; i++) { + DoneChecker loader = new Loader(); + loaders.add(loader); + new Thread(loader).start(); + DoneChecker clearer = new Clearer(); + loaders.add(clearer); + new Thread(clearer).start(); + } + + for (int i = 0; i < i1 * 2; i++) { + DoneChecker loader = loaders.get(i); + while (!loader.isDone()) { + Thread.sleep(10); + } + assertTrue("Loader " + i + " is supposed to run successfully", loader.isSuccess()); + } + + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ParameterAnnotationsTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ParameterAnnotationsTest.java new file mode 100644 index 000000000..093a4b6e4 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/ParameterAnnotationsTest.java @@ -0,0 +1,590 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying + * materials are made available under the terms of the Eclipse Public License + * v1.0 which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Andy Clement - initial implementation + ******************************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +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.classfile.annotation.AnnotationElementValue; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; +import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; +import org.aspectj.apache.bcel.generic.ArrayType; +import org.aspectj.apache.bcel.generic.ClassGen; +import org.aspectj.apache.bcel.generic.InstructionBranch; +import org.aspectj.apache.bcel.generic.InstructionConstants; +import org.aspectj.apache.bcel.generic.InstructionFactory; +import org.aspectj.apache.bcel.generic.InstructionHandle; +import org.aspectj.apache.bcel.generic.InstructionLV; +import org.aspectj.apache.bcel.generic.InstructionList; +import org.aspectj.apache.bcel.generic.LocalVariableGen; +import org.aspectj.apache.bcel.generic.MethodGen; +import org.aspectj.apache.bcel.generic.ObjectType; +import org.aspectj.apache.bcel.generic.Type; +import org.aspectj.apache.bcel.util.SyntheticRepository; + +/** + * The program that some of the tests generate looks like this: + public class HelloWorld { + public static void main(String[] argv) { + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + String name = null; + try { + name = "Andy"; + } catch(IOException e) { return; } + System.out.println("Hello, " + name); + } + } + * + */ +public class ParameterAnnotationsTest extends BcelTestCase { + + protected void setUp() throws Exception { + super.setUp(); + } + + /** + * Programmatically construct a class and add an annotation to the main method parameter 'argv' + */ + public void testParameterAnnotations_builtOK() { + ClassGen clg = createClassGen("HelloWorld"); + ConstantPool cpg = clg.getConstantPool(); + InstructionList il = new InstructionList(); + + buildClassContentsWithAnnotatedMethods(clg,cpg,il,true); + + int i = clg.getMethods().length; + assertTrue("Class should have 2 methods but has "+i,i==2); + + Method mainMethod = clg.getMethods()[0]; + AnnotationGen[] annos = mainMethod.getAnnotationsOnParameter(0); + assertTrue("Should be two annotation on the 'argv' parameter to main() but there are "+annos.length,annos.length==2); + assertTrue("This annotation should contain the string 'fruit=Apples' but it is "+annos[0].toString(), + annos[0].toString().indexOf("fruit=Apples")!=-1); + assertTrue("This annotation should contain the string 'fruit=Oranges' but it is "+annos[1].toString(), + annos[1].toString().indexOf("fruit=Oranges")!=-1); + } + + + + /** + * Check we can save and load a constructed class that contains parameter annotations + */ + public void testParameterAnnotations_savedAndLoadedOK() throws ClassNotFoundException { + ClassGen clg = createClassGen("HelloWorld"); + ConstantPool cpg = clg.getConstantPool(); + InstructionList il = new InstructionList(); + + buildClassContentsWithAnnotatedMethods(clg,cpg,il,true); + + dumpClass(clg,"temp5","HelloWorld.class"); + + JavaClass jc = getClassFrom("temp5","HelloWorld"); + + clg = new ClassGen(jc); + + int i = clg.getMethods().length; + assertTrue("Class should have 2 methods but has "+i,i==2); + + Method mainMethod = clg.getMethods()[0]; + AnnotationGen[] annos = mainMethod.getAnnotationsOnParameter(0); + assertTrue("Should be two annotation on the 'argv' parameter to main() but there are "+annos.length,annos.length==2); + assertTrue("This annotation should contain the string 'fruit=Apples' but it is "+annos[0].toString(), + annos[0].toString().indexOf("fruit=Apples")!=-1); + assertTrue("This annotation should contain the string 'fruit=Oranges' but it is "+annos[1].toString(), + annos[1].toString().indexOf("fruit=Oranges")!=-1); + assertTrue(wipe("temp5","HelloWorld.class")); + + } + + + + /* + * Load an existing class, add new parameter annotations, save and then reload it + */ + public void testParameterAnnotations_loadedThenModifiedThenSavedAndLoadedOK() throws ClassNotFoundException { + JavaClass jc = getClassFrom("testcode.jar","AnnotatedParameters"); + + ClassGen clg = new ClassGen(jc); + ConstantPool cpg = clg.getConstantPool(); + + // + // Foo method looks like this: + // public void foo(@SimpleAnnotation(id=2) int arg1, + // @SimpleAnnotation(id=3) @AnnotationEnumElement(enumval=SimpleEnum.Red) String arg2) + Method m = findMethod(clg,"foo"); + assertTrue("Should be able to find method foo but couldn't",m!=null); + + + /////////////////////// 1. Check the right number of annotations are there + int i = m.getAnnotationsOnParameter(1).length; + assertTrue("Should be two annotations on the second parameter but found: "+i,i==2); + + + /////////////////////// 2. Let's add a new parameter annotation, a visible one, to the first parameter. + + // Build a modifiable version of the foo method + MethodGen mg = new MethodGen(m,clg.getClassName(),cpg); + + // Check the annotations survived that transform + i = mg.getAnnotationsOnParameter(1).size(); + assertTrue("Should be two annotations on the second parameter but found: "+i,i==2); + + // That worked, so let's add a new parameter annotation + mg.addParameterAnnotation(0,createFruitAnnotation(cpg,"Banana",true)); + + // Foo method should now look like this: + // public void foo(@SimpleAnnotation(id=2) @SimpleStringAnnotation(fruit=Banana) int arg1, + // @SimpleAnnotation(id=3) @AnnotationEnumElement(enumval=SimpleEnum.Red) String arg2) + i = mg.getAnnotationsOnParameter(0).size(); + assertTrue("Should now be 2 parameter annotations but found "+i,i==2); + i = mg.getAnnotationsOnParameter(0).get(1).toString().indexOf("fruit=Banana"); + assertTrue("Expected 'fruit=Banana' in the 2nd annotation on the first argument but got "+ + mg.getAnnotationsOnParameter(0).get(1).toString(),i!=-1); + + // delete the old method and add the new one + clg.removeMethod(m); + clg.addMethod(mg.getMethod()); + + /////////////////////// 3. Dump it to disk + dumpClass(clg,"temp2","AnnotatedParameters.class"); + + /////////////////////// 4. Load it back in and verify the annotations persisted + JavaClass jc2 = getClassFrom("temp2","AnnotatedParameters"); + + m = jc2.getMethods()[2]; + AnnotationGen[] p1annotations = m.getAnnotationsOnParameter(0); + AnnotationGen[] p2annotations = m.getAnnotationsOnParameter(1); + + assertTrue("Expected two annotations on the first parameter but found "+p1annotations.length,p1annotations.length==2); + assertTrue("Expected two annotations on the second parameter but found "+p2annotations.length,p2annotations.length==2); + String expectedString = "[@SimpleAnnotation(id=2),@SimpleStringAnnotation(fruit=Banana)]"; + assertTrue("Expected formatted short string of '"+expectedString+"' but it was '"+dumpAnnotations(p1annotations)+"'", + dumpAnnotations(p1annotations).equals(expectedString)); + expectedString = "[@SimpleAnnotation(id=3),@AnnotationEnumElement(enumval=LSimpleEnum;Red)]"; + assertTrue("Expected formatted short string of '"+expectedString+"' but it was '"+dumpAnnotations(p2annotations)+"'", + dumpAnnotations(p2annotations).equals(expectedString)); + + assertTrue(wipe("temp2","AnnotatedParameters.class")); + } + + + /** + * same as above test but attaching invisible runtime parameter annotations + */ + public void testParameterAnnotations_loadedThenModifiedWithInvisibleAnnotationThenSavedAndLoadedOK() throws ClassNotFoundException { + JavaClass jc = getClassFrom("testcode.jar","AnnotatedParameters"); + ClassGen clg = new ClassGen(jc); + ConstantPool cpg = clg.getConstantPool(); + + // + // Foo method looks like this: + // public void foo(@SimpleAnnotation(id=2) int arg1, + // @SimpleAnnotation(id=3) @AnnotationEnumElement(enumval=SimpleEnum.Red) String arg2) + Method m = findMethod(clg,"foo"); + assertTrue("Should be able to find method foo but couldn't",m!=null); + + + /////////////////////// 1. Check the right number of annotations are there + int i = m.getAnnotationsOnParameter(1).length; + assertTrue("Should be two annotations on the second parameter but found: "+i,i==2); + + + /////////////////////// 2. Let's add a new parameter annotation, a visible one, to the first parameter. + + // Build a modifiable version of the foo method + MethodGen mg = new MethodGen(m,clg.getClassName(),cpg); + + // Check the annotations survived that transform + i = mg.getAnnotationsOnParameter(1).size(); + assertTrue("Should be two annotations on the second parameter but found: "+i,i==2); + + // That worked, so let's add a new parameter annotation + mg.addParameterAnnotation(0,createFruitAnnotation(cpg,"Banana",false)); + + // Foo method should now look like this: + // public void foo(@SimpleAnnotation(id=2) @SimpleStringAnnotation(fruit=Banana) int arg1, + // @SimpleAnnotation(id=3) @AnnotationEnumElement(enumval=SimpleEnum.Red) String arg2) + i = mg.getAnnotationsOnParameter(0).size(); + assertTrue("Should now be 2 parameter annotations but found "+i,i==2); + i = mg.getAnnotationsOnParameter(0).get(1).toString().indexOf("fruit=Banana"); + assertTrue("Expected 'fruit=Banana' in the 2nd annotation on the first argument but got "+ + mg.getAnnotationsOnParameter(0).get(1).toString(),i!=-1); + assertTrue("New annotation should be runtime invisible?",!((AnnotationGen)mg.getAnnotationsOnParameter(0).get(1)).isRuntimeVisible()); + + // delete the old method and add the new one + clg.removeMethod(m); + clg.addMethod(mg.getMethod()); + + /////////////////////// 3. Dump it to disk + dumpClass(clg,"temp3","AnnotatedParameters.class"); + + /////////////////////// 4. Load it back in and verify the annotations persisted + + JavaClass jc2 = getClassFrom("temp3","AnnotatedParameters"); + + m = jc2.getMethods()[2]; + AnnotationGen[] p1annotations = m.getAnnotationsOnParameter(0); + AnnotationGen[] p2annotations = m.getAnnotationsOnParameter(1); + + assertTrue("Expected two annotations on the first parameter but found "+p1annotations.length,p1annotations.length==2); + assertTrue("Expected two annotations on the second parameter but found "+p2annotations.length,p2annotations.length==2); + String expectedString = "[@SimpleAnnotation(id=2),@SimpleStringAnnotation(fruit=Banana)]"; + assertTrue("Expected formatted short string of '"+expectedString+"' but it was '"+dumpAnnotations(p1annotations)+"'", + dumpAnnotations(p1annotations).equals(expectedString)); + expectedString = "[@SimpleAnnotation(id=3),@AnnotationEnumElement(enumval=LSimpleEnum;Red)]"; + assertTrue("Expected formatted short string of '"+expectedString+"' but it was '"+dumpAnnotations(p2annotations)+"'", + dumpAnnotations(p2annotations).equals(expectedString)); + + assertTrue("Second annotation on first parameter should be runtime invisible?", + !p1annotations[1].isRuntimeVisible()); + assertTrue(wipe("temp3","AnnotatedParameters.class")); + + + // 5. Verify that when annotations for parameters are unpacked from attributes, the + // attributes vanish ! + clg = new ClassGen(jc2); + mg = new MethodGen(m,clg.getClassName(),clg.getConstantPool()); + List as = mg.getAttributes(); + assertTrue("Should be 2 (RIPA and RVPA) but there are "+mg.getAttributes().size(),mg.getAttributes().size()==2); + List l = mg.getAnnotationsOnParameter(0); + assertTrue("Should be 2 annotations on first parameter but there is only "+l.size()+":"+l.toString(), + l.size()==2); + assertTrue("Should be 0 but there are "+mg.getAttributes().size(),mg.getAttributes().size()==0); + } + + + private Method findMethod(ClassGen c,String mname) { + Method[] ms = c.getMethods(); + for (int i = 0; i < ms.length; i++) { + if (ms[i].getName().equals(mname)) return ms[i]; + } + return null; + } + + private void dumpClass(ClassGen cg, String fname) { + try { + File f = createTestdataFile(fname); + cg.getJavaClass().dump(f); + } catch (java.io.IOException e) { + System.err.println(e); + } + } + + + private void dumpClass(ClassGen cg, String dir, String fname) { + dumpClass(cg,dir+File.separator+fname); + } + + private void buildClassContentsWithAnnotatedMethods(ClassGen cg, ConstantPool cp, InstructionList il,boolean addParameterAnnotations) { + // Create method 'public static void main(String[]argv)' + MethodGen mg = createMethodGen("main",il,cp); + InstructionFactory factory = new InstructionFactory(cg); + mg.addAnnotation(createSimpleVisibleAnnotation(mg.getConstantPool())); + // We now define some often used types: + + ObjectType i_stream = new ObjectType("java.io.InputStream"); + ObjectType p_stream = new ObjectType("java.io.PrintStream"); + + // Create variables in and name : We call the constructors, i.e., + // execute BufferedReader(InputStreamReader(System.in)) . The reference + // to the BufferedReader object stays on top of the stack and is stored + // in the newly allocated in variable. + + il.append(factory.createNew("java.io.BufferedReader")); + il.append(InstructionConstants.DUP); // Use predefined constant + il.append(factory.createNew("java.io.InputStreamReader")); + il.append(InstructionConstants.DUP); + il.append(factory.createFieldAccess("java.lang.System", "in", i_stream,Constants.GETSTATIC)); + il.append(factory.createInvoke("java.io.InputStreamReader", "", + Type.VOID, new Type[] { i_stream }, Constants.INVOKESPECIAL)); + il.append(factory.createInvoke("java.io.BufferedReader", "", + Type.VOID, new Type[] { new ObjectType("java.io.Reader") }, + Constants.INVOKESPECIAL)); + + LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType( + "java.io.BufferedReader"), null, null); + int in = lg.getIndex(); + lg.setStart(il.append(InstructionFactory.createASTORE(in))); // "in" valid from here + + // Create local variable name and initialize it to null + + lg = mg.addLocalVariable("name", Type.STRING, null, null); + int name = lg.getIndex(); + il.append(InstructionConstants.ACONST_NULL); + lg.setStart(il.append(InstructionFactory.createASTORE(name))); // "name" valid from here + + // Create try-catch block: We remember the start of the block, read a + // line from the standard input and store it into the variable name . + +// InstructionHandle try_start = il.append(factory.createFieldAccess( +// "java.lang.System", "out", p_stream, Constants.GETSTATIC)); + +// il.append(new PUSH(cp, "Please enter your name> ")); +// il.append(factory.createInvoke("java.io.PrintStream", "print", +// Type.VOID, new Type[] { Type.STRING }, +// Constants.INVOKEVIRTUAL)); +// il.append(new ALOAD(in)); +// il.append(factory.createInvoke("java.io.BufferedReader", "readLine", +// Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + InstructionHandle try_start = il.append(InstructionFactory.PUSH(cp,"Andy")); + il.append(InstructionFactory.createASTORE(name)); + + // Upon normal execution we jump behind exception handler, the target + // address is not known yet. + + InstructionBranch g = new InstructionBranch(Constants.GOTO); + InstructionHandle try_end = il.append(g); + + // We add the exception handler which simply returns from the method. + + LocalVariableGen var_ex = mg.addLocalVariable("ex",Type.getType("Ljava.io.IOException;"),null,null); + int var_ex_slot = var_ex.getIndex(); + + InstructionHandle handler = il.append(InstructionFactory.createASTORE(var_ex_slot)); + var_ex.setStart(handler); + var_ex.setEnd(il.append(InstructionConstants.RETURN)); + + mg.addExceptionHandler(try_start, try_end, handler, + new ObjectType("java.io.IOException")); + + // "Normal" code continues, now we can set the branch target of the GOTO + // . + + InstructionHandle ih = il.append(factory.createFieldAccess( + "java.lang.System", "out", p_stream, Constants.GETSTATIC)); + g.setTarget(ih); + + // Printing "Hello": String concatenation compiles to StringBuffer + // operations. + + il.append(factory.createNew(Type.STRINGBUFFER)); + il.append(InstructionConstants.DUP); + il.append(InstructionFactory.PUSH(cp, "Hello, ")); + il + .append(factory.createInvoke("java.lang.StringBuffer", + "", Type.VOID, new Type[] { Type.STRING }, + Constants.INVOKESPECIAL)); + il.append(new InstructionLV(Constants.ALOAD,name)); + il.append(factory.createInvoke("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.STRING }, + Constants.INVOKEVIRTUAL)); + il.append(factory.createInvoke("java.lang.StringBuffer", "toString", + Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + + il.append(factory.createInvoke("java.io.PrintStream", "println", + Type.VOID, new Type[] { Type.STRING }, + Constants.INVOKEVIRTUAL)); + il.append(InstructionConstants.RETURN); + + // Finalization: Finally, we have to set the stack size, which normally + // would have to be computed on the fly and add a default constructor + // method to the class, which is empty in this case. + + mg.addParameterAnnotation(0,createFruitAnnotation(cp,"Apples",true)); + mg.addParameterAnnotation(0,createFruitAnnotation(cp,"Oranges",true)); + mg.setMaxStack(); + mg.setMaxLocals(); + cg.addMethod(mg.getMethod()); + il.dispose(); // Allow instruction handles to be reused + cg.addEmptyConstructor(Constants.ACC_PUBLIC); + } + + private void buildClassContents(ClassGen cg, ConstantPool cp, InstructionList il) { + // Create method 'public static void main(String[]argv)' + MethodGen mg = createMethodGen("main",il,cp); + InstructionFactory factory = new InstructionFactory(cg); + // We now define some often used types: + + ObjectType i_stream = new ObjectType("java.io.InputStream"); + ObjectType p_stream = new ObjectType("java.io.PrintStream"); + + // Create variables in and name : We call the constructors, i.e., + // execute BufferedReader(InputStreamReader(System.in)) . The reference + // to the BufferedReader object stays on top of the stack and is stored + // in the newly allocated in variable. + + il.append(factory.createNew("java.io.BufferedReader")); + il.append(InstructionConstants.DUP); // Use predefined constant + il.append(factory.createNew("java.io.InputStreamReader")); + il.append(InstructionConstants.DUP); + il.append(factory.createFieldAccess("java.lang.System", "in", i_stream,Constants.GETSTATIC)); + il.append(factory.createInvoke("java.io.InputStreamReader", "", + Type.VOID, new Type[] { i_stream }, Constants.INVOKESPECIAL)); + il.append(factory.createInvoke("java.io.BufferedReader", "", + Type.VOID, new Type[] { new ObjectType("java.io.Reader") }, + Constants.INVOKESPECIAL)); + + LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType( + "java.io.BufferedReader"), null, null); + int in = lg.getIndex(); + lg.setStart(il.append(InstructionFactory.createASTORE(in))); // "in" valid from here + + // Create local variable name and initialize it to null + + lg = mg.addLocalVariable("name", Type.STRING, null, null); + int name = lg.getIndex(); + il.append(InstructionConstants.ACONST_NULL); + lg.setStart(il.append(InstructionFactory.createASTORE(name))); // "name" valid from here + + // Create try-catch block: We remember the start of the block, read a + // line from the standard input and store it into the variable name . + +// InstructionHandle try_start = il.append(factory.createFieldAccess( +// "java.lang.System", "out", p_stream, Constants.GETSTATIC)); + +// il.append(new PUSH(cp, "Please enter your name> ")); +// il.append(factory.createInvoke("java.io.PrintStream", "print", +// Type.VOID, new Type[] { Type.STRING }, +// Constants.INVOKEVIRTUAL)); +// il.append(new ALOAD(in)); +// il.append(factory.createInvoke("java.io.BufferedReader", "readLine", +// Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + InstructionHandle try_start = il.append(InstructionFactory.PUSH(cp,"Andy")); + il.append(InstructionFactory.createASTORE(name)); + + // Upon normal execution we jump behind exception handler, the target + // address is not known yet. + + InstructionBranch g = new InstructionBranch(Constants.GOTO); + InstructionHandle try_end = il.append(g); + + // We add the exception handler which simply returns from the method. + + LocalVariableGen var_ex = mg.addLocalVariable("ex",Type.getType("Ljava.io.IOException;"),null,null); + int var_ex_slot = var_ex.getIndex(); + + InstructionHandle handler = il.append(InstructionFactory.createASTORE(var_ex_slot)); + var_ex.setStart(handler); + var_ex.setEnd(il.append(InstructionConstants.RETURN)); + + mg.addExceptionHandler(try_start, try_end, handler, + new ObjectType("java.io.IOException")); + + // "Normal" code continues, now we can set the branch target of the GOTO + // . + + InstructionHandle ih = il.append(factory.createFieldAccess( + "java.lang.System", "out", p_stream, Constants.GETSTATIC)); + g.setTarget(ih); + + // Printing "Hello": String concatenation compiles to StringBuffer + // operations. + + il.append(factory.createNew(Type.STRINGBUFFER)); + il.append(InstructionConstants.DUP); + il.append(InstructionFactory.PUSH(cp, "Hello, ")); + il + .append(factory.createInvoke("java.lang.StringBuffer", + "", Type.VOID, new Type[] { Type.STRING }, + Constants.INVOKESPECIAL)); + il.append(InstructionFactory.createALOAD(name)); + il.append(factory.createInvoke("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.STRING }, + Constants.INVOKEVIRTUAL)); + il.append(factory.createInvoke("java.lang.StringBuffer", "toString", + Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + + il.append(factory.createInvoke("java.io.PrintStream", "println", + Type.VOID, new Type[] { Type.STRING }, + Constants.INVOKEVIRTUAL)); + il.append(InstructionConstants.RETURN); + + // Finalization: Finally, we have to set the stack size, which normally + // would have to be computed on the fly and add a default constructor + // method to the class, which is empty in this case. + + mg.setMaxStack(); + mg.setMaxLocals(); + cg.addMethod(mg.getMethod()); + il.dispose(); // Allow instruction handles to be reused + cg.addEmptyConstructor(Constants.ACC_PUBLIC); + } + + private JavaClass getClassFrom(String where,String clazzname) throws ClassNotFoundException { + SyntheticRepository repos = createRepos(where); + return repos.loadClass(clazzname); + } + + + + + // helper methods + + + private ClassGen createClassGen(String classname) { + return new ClassGen(classname, "java.lang.Object", + "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); + } + + private MethodGen createMethodGen(String methodname,InstructionList il,ConstantPool cp) { + return new MethodGen( + Constants.ACC_STATIC | Constants.ACC_PUBLIC, // access flags + Type.VOID, // return type + new Type[] { new ArrayType(Type.STRING, 1) }, // argument types + new String[] { "argv" }, // arg names + methodname, "HelloWorld", // method, class + il, cp); + } + + + public AnnotationGen createSimpleVisibleAnnotation(ConstantPool cp) { + SimpleElementValue evg = new SimpleElementValue( + ElementValue.PRIMITIVE_INT, cp, 4); + + NameValuePair nvGen = new NameValuePair("id", evg,cp); + + ObjectType t = new ObjectType("SimpleAnnotation"); + + List elements = new ArrayList(); + elements.add(nvGen); + + AnnotationGen a = new AnnotationGen(t, elements,true, cp); + return a; + } + + public AnnotationGen createCombinedAnnotation(ConstantPool cp) { + // Create an annotation instance + AnnotationGen a = createSimpleVisibleAnnotation(cp); + ArrayElementValue array = new ArrayElementValue(cp); + array.addElement(new AnnotationElementValue(a,cp)); + NameValuePair nvp = new NameValuePair("value",array,cp); + List elements = new ArrayList(); + elements.add(nvp); + return new AnnotationGen(new ObjectType("CombinedAnnotation"),elements,true,cp); + } + + public AnnotationGen createSimpleInvisibleAnnotation(ConstantPool cp) { + SimpleElementValue evg = new SimpleElementValue( + ElementValue.PRIMITIVE_INT, cp, 4); + + NameValuePair nvGen = new NameValuePair("id", evg,cp); + + ObjectType t = new ObjectType("SimpleAnnotation"); + + List elements = new ArrayList(); + elements.add(nvGen); + + AnnotationGen a = new AnnotationGen(t, elements,false, cp); + return a; + } + protected void tearDown() throws Exception { + super.tearDown(); + } + +} \ No newline at end of file diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleAnnotationAttributeTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleAnnotationAttributeTest.java new file mode 100644 index 000000000..0f82b2059 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleAnnotationAttributeTest.java @@ -0,0 +1,395 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Utility; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationElementValue; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; +import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; +import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; +import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; +import org.aspectj.apache.bcel.generic.ClassGen; +import org.aspectj.apache.bcel.util.SyntheticRepository; + + +public class RuntimeVisibleAnnotationAttributeTest extends BcelTestCase { + + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testSeeAnnotationsAsAttribute() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("SimpleAnnotatedClass"); + ConstantPool pool = clazz.getConstantPool(); + Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz); + assertTrue("Expected a RuntimeVisibleAnnotations attribute but found none", + rvaAttr.length==1); + } + + public void testAnnotationsAttributeContainsRightData() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("SimpleAnnotatedClass"); + ConstantPool pool = clazz.getConstantPool(); + Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz); + RuntimeVisAnnos rva = (RuntimeVisAnnos) rvaAttr[0]; + List anns = rva.getAnnotations(); + assertTrue("Should be one annotation but found "+anns.size(), + anns.size()==1); + AnnotationGen ann = anns.get(0); + assertTrue("Should be called 'SimpleAnnotation' but was called "+ann.getTypeName(), + ann.getTypeName().equals("SimpleAnnotation")); + List l = ann.getValues(); + assertTrue("Should be one value for annotation 'SimpleAnnotation' but found "+l.size(), + l.size()==1); + NameValuePair envp = l.get(0); + assertTrue("Name of element in SimpleAnnotation should be 'id' but it is "+envp.getNameString(), + envp.getNameString().equals("id")); + SimpleElementValue evalue = (SimpleElementValue)envp.getValue(); + assertTrue("'id' should be of type int, but it is "+evalue.getElementValueType(),evalue.getElementValueType()==SimpleElementValue.PRIMITIVE_INT); + assertTrue("'id' should have value 4 but it is "+evalue.getValueInt(), + evalue.getValueInt()==4); + } + + public void testAccessingAnnotationsOnClazz() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("SimpleAnnotatedClass"); + ConstantPool pool = clazz.getConstantPool(); + AnnotationGen[] anns = clazz.getAnnotations(); + assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length, + anns.length==1); + } + + public void testReadingWritingAnnotations() throws ClassNotFoundException, IOException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("SimpleAnnotatedClass"); + ConstantPool pool = clazz.getConstantPool(); + AnnotationGen[] anns = clazz.getAnnotations(); + assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length, + anns.length==1); + + // Write it out + File tfile = createTestdataFile("SimpleAnnotatedClass.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos.loadClass("SimpleAnnotatedClass"); + ConstantPool pool2 = clazz2.getConstantPool(); + AnnotationGen[] anns2 = clazz2.getAnnotations(); + assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns2.length, + anns2.length==1); + + assertTrue(tfile.delete()); + } + + + + //// + // Test for annotations containing string elements + + public void testAnnotationStringElement() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedClass"); + verifyAnnotationStringElement(clazz); + } + + + public void testAnnotationStringElementReadWrite() throws ClassNotFoundException, IOException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedClass"); + verifyAnnotationStringElement(clazz); + + // Write it out + File tfile = createTestdataFile("AnnotatedClass.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos2.loadClass("AnnotatedClass"); + verifyAnnotationStringElement(clazz2); + + assertTrue(tfile.delete()); + } + + private void verifyAnnotationStringElement(JavaClass clazz) { + AnnotationGen[] anns = clazz.getAnnotations(); + assertTrue("should be one annotation but found "+anns.length,anns.length==1); + AnnotationGen ann = anns[0]; + assertTrue("should be called 'AnnotationStringElement' but was called "+ann.getTypeName(), + ann.getTypeName().equals("AnnotationStringElement")); + List l = ann.getValues(); + assertTrue("Should be one value but there were "+l.size(),l.size()==1); + NameValuePair nvp = l.get(0); + assertTrue("Name of element should be 'stringval' but was "+nvp.getNameString(), + nvp.getNameString().equals("stringval")); + SimpleElementValue ev = (SimpleElementValue)nvp.getValue(); + assertTrue("String value should be 'hello' but was '"+ev.getValueString()+"'", + ev.getValueString().equals("hello")); + } + + //// + // Test for complex annotation that includes all primitives + + public void testComplexAnnotation() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("ComplexAnnotatedClass"); + verifyComplexAnnotation(clazz); + } + + + public void testComplexAnnotationsReadWrite() throws ClassNotFoundException, IOException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("ComplexAnnotatedClass"); + verifyComplexAnnotation(clazz); + + // Write it out + File tfile = createTestdataFile("ComplexAnnotatedClass.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos.loadClass("ComplexAnnotatedClass"); + verifyComplexAnnotation(clazz2); + + assertTrue(tfile.delete()); + + } + + private void verifyComplexAnnotation(JavaClass clazz) { + AnnotationGen[] anns = clazz.getAnnotations(); + assertTrue("Should be one annotation but found "+anns.length,anns.length==1); + AnnotationGen ann = anns[0]; + assertTrue("Should be called 'ComplexAnnotation' but was called "+ann.getTypeName(), + ann.getTypeName().equals("ComplexAnnotation")); + List l = ann.getValues(); + assertTrue("Should be eight values for annotation 'ComplexAnnotation' but found "+l.size(), + l.size()==8); + List names = RuntimeVisibleAnnotationAttributeTest.getListOfAnnotationNames(ann); + assertTrue("Cant find expected element ",names.contains("ival")); + assertTrue("Cant find expected element ",names.contains("dval")); + assertTrue("Cant find expected element ",names.contains("zval")); + assertTrue("Cant find expected element ",names.contains("fval")); + assertTrue("Cant find expected element ",names.contains("jval")); + assertTrue("Cant find expected element ",names.contains("sval")); + assertTrue("Cant find expected element ",names.contains("bval")); + assertTrue("Cant find expected element ",names.contains("cval")); + + checkValue(ann,"ival","4"); + checkValue(ann,"jval","56"); + checkValue(ann,"fval","3.0"); + checkValue(ann,"dval","33.4"); + checkValue(ann,"sval","99"); + checkValue(ann,"bval","2"); + checkValue(ann,"cval",new Character('5').toString()); + checkValue(ann,"zval","false"); + + } + + private void checkValue(AnnotationGen a,String name,String tostring) { + for (Iterator i = a.getValues().iterator(); i.hasNext();) { + NameValuePair element = i.next(); + if (element.getNameString().equals(name)) { + if (!element.getValue().stringifyValue().equals(tostring)) { + fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue()); + } + return; + } + } + fail("Didnt find named element "+name); + } + + //// + // Test an annotation containing a 'Class' element + + public void testAnnotationClassElement() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedWithClassClass"); + verifyClassAnnotation(clazz); + } + + public void testAnnotationClassElementCopying() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedWithClassClass"); + AnnotationGen[] anns = clazz.getAnnotations(); + ClassGen cg = new ClassGen(clazz); + // Checks we can copy class values in an annotation + new AnnotationGen(anns[0],cg.getConstantPool(),true); + new AnnotationGen(anns[0],cg.getConstantPool(),false); + } + + public void testAnnotationClassElementReadWrite() throws ClassNotFoundException,IOException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedWithClassClass"); + verifyClassAnnotation(clazz); + + // Write it out + File tfile = createTestdataFile("AnnotatedWithClassClass.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos2.loadClass("AnnotatedWithClassClass"); + verifyClassAnnotation(clazz2); + + assertTrue(wipe("AnnotatedWithClassClass.class")); + } + + private void verifyClassAnnotation(JavaClass clazz) { + AnnotationGen[] anns = clazz.getAnnotations(); + assertTrue("should be one annotation but found "+anns.length,anns.length==1); + AnnotationGen ann = anns[0]; + assertTrue("should be called 'AnnotationClassElement' but was called "+ann.getTypeName(), + ann.getTypeName().equals("AnnotationClassElement")); + List l = ann.getValues(); + assertTrue("Should be one value but there were "+l.size(),l.size()==1); + NameValuePair nvp = l.get(0); + assertTrue("Name of element should be 'clz' but was "+nvp.getNameString(), + nvp.getNameString().equals("clz")); + ClassElementValue ev = (ClassElementValue)nvp.getValue(); + assertTrue("String value should be 'Ljava/lang/Integer;' but was '"+ev.getClassString()+"'", + ev.getClassString().equals("Ljava/lang/Integer;")); + + } + + //// + // Test an annotation containing an enum element + + public void testAnnotationEnumElement() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedWithEnumClass"); + verifyAnnotationEnumElement(clazz); + } + + public void testAnnotationEnumElementReadWrite() throws ClassNotFoundException, IOException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedWithEnumClass"); + verifyAnnotationEnumElement(clazz); + + // Write it out + File tfile = createTestdataFile("AnnotatedWithEnumClass.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos2.loadClass("AnnotatedWithEnumClass"); + verifyAnnotationEnumElement(clazz2); + + assertTrue(tfile.delete()); + } + + public void verifyAnnotationEnumElement(JavaClass clazz) { + AnnotationGen[] anns = clazz.getAnnotations(); + assertTrue("should be one annotation but found "+anns.length,anns.length==1); + AnnotationGen ann = anns[0]; + assertTrue("should be called 'AnnotationEnumElement' but was called "+ann.getTypeName(), + ann.getTypeName().equals("AnnotationEnumElement")); + List l = ann.getValues(); + assertTrue("Should be one value but there were "+l.size(),l.size()==1); + NameValuePair nvp = l.get(0); + assertTrue("Name of element should be 'enumval' but was "+nvp.getNameString(), + nvp.getNameString().equals("enumval")); + ElementValue ev = nvp.getValue(); + assertTrue("Should be of type EnumElementValue but is "+ev,ev instanceof EnumElementValue); + EnumElementValue eev = (EnumElementValue)ev; + assertTrue("Should be an enum type value but is "+eev.getElementValueType(),eev.getElementValueType()==SimpleElementValue.ENUM_CONSTANT); + assertTrue("Enum type for annotation should be 'SimpleEnum' but is "+Utility.signatureToString(eev.getEnumTypeString()),Utility.signatureToString(eev.getEnumTypeString()).equals("SimpleEnum")); + assertTrue("String value should be 'Red' but was '"+eev.getEnumValueString()+"'", + eev.getEnumValueString().equals("Red")); + } + + //// + // Test an annotation with an array element + + public void testAnnotationArraysOfAnnotations() throws ClassNotFoundException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedWithCombinedAnnotation"); + AnnotationGen[] anns = clazz.getAnnotations(); + assertTrue("should be one annotation but found "+anns.length,anns.length==1); + checkCombinedAnnotation(anns[0]); + } + + public void testAnnotationArraysOfAnnotationsReadWrite() throws ClassNotFoundException, IOException { + SyntheticRepository repos = createRepos("testcode.jar"); + JavaClass clazz = repos.loadClass("AnnotatedWithCombinedAnnotation"); + AnnotationGen[] anns = clazz.getAnnotations(); + assertTrue("should be one annotation but found "+anns.length,anns.length==1); + checkCombinedAnnotation(anns[0]); + + // Write it out + File tfile = createTestdataFile("AnnotatedWithCombinedAnnotation.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos2.loadClass("AnnotatedWithCombinedAnnotation"); + AnnotationGen[] anns2 = clazz2.getAnnotations(); + assertTrue("should be one annotation but found "+anns2.length,anns2.length==1); + checkCombinedAnnotation(anns2[0]); + + assertTrue(tfile.delete()); + } + + + private void checkCombinedAnnotation(AnnotationGen ann) { + assertTrue("should be called 'CombinedAnnotation' but was called "+ann.getTypeName(), + ann.getTypeName().equals("CombinedAnnotation")); + List l = ann.getValues(); + assertTrue("Should be one value but there were "+l.size(),l.size()==1); + NameValuePair nvp = l.get(0); + assertTrue("Name of element should be 'value' but was "+nvp.getNameString(), + nvp.getNameString().equals("value")); + ElementValue ev = nvp.getValue(); + assertTrue("Should be of type ArrayElementValue but is "+ev,ev instanceof ArrayElementValue); + ArrayElementValue aev = (ArrayElementValue)ev; + + assertTrue("Array element value should be of size 1 but is "+aev.getElementValuesArraySize(), + aev.getElementValuesArraySize()==1); + ElementValue[] evs = aev.getElementValuesArray(); + assertTrue("Entry in the array should be AnnotationElementValue but is "+evs[0], + evs[0] instanceof AnnotationElementValue); + AnnotationElementValue inner_ev = (AnnotationElementValue)evs[0]; + AnnotationGen a = inner_ev.getAnnotation(); + assertTrue("Should be SimpleAnnotation but is "+a.getTypeName(),a.getTypeName().equals("SimpleAnnotation")); + List envps = a.getValues(); + assertTrue("Should be one name value pair but found "+envps.size(),envps.size()==1); + NameValuePair envp = envps.get(0); + assertTrue("Name should be 'id' but it is "+envp.getNameString(),envp.getNameString().equals("id")); + assertTrue("Value of 'id' should be 4 but it is "+envp.getValue().stringifyValue(), + envp.getValue().stringifyValue().equals("4")); + } + + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public static List getListOfAnnotationNames(AnnotationGen a) { + List l = a.getValues(); + List names = new ArrayList(); + for (Iterator i = l.iterator(); i.hasNext();) { + NameValuePair element = i.next(); + names.add(element.getNameString()); + } + return names; + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleParameterAnnotationAttributeTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleParameterAnnotationAttributeTest.java new file mode 100644 index 000000000..1b8af7419 --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleParameterAnnotationAttributeTest.java @@ -0,0 +1,143 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; +import org.aspectj.apache.bcel.util.SyntheticRepository; + + +public class RuntimeVisibleParameterAnnotationAttributeTest extends BcelTestCase { + + + protected void setUp() throws Exception { + super.setUp(); + } + + + public void testAccessingRuntimeVisibleParameterAnnotations() throws ClassNotFoundException { + JavaClass clazz = getClassFromJar("AnnotatedParameters"); + Attribute[] rvaAttr = findAttribute("RuntimeVisibleParameterAnnotations",clazz); + Method[] methods = clazz.getMethods(); + + for (int i = 0; i < methods.length; i++) { + Method m = methods[i]; + if (m.getName().equals("foo")) { + RuntimeVisParamAnnos paramAnns = + (RuntimeVisParamAnnos) findAttribute("RuntimeVisibleParameterAnnotations",m.getAttributes()); + assertTrue("foo takes two parameters, not "+paramAnns.getParameterAnnotations().size(), + paramAnns.getParameterAnnotations().size()==2); + + AnnotationGen[] firstParamAnnotations = paramAnns.getAnnotationsOnParameter(0); + checkAnnotation(firstParamAnnotations[0],"SimpleAnnotation","id","2"); + + AnnotationGen[] secondParamAnnotations = paramAnns.getAnnotationsOnParameter(1); + checkAnnotation(secondParamAnnotations[0],"SimpleAnnotation","id","3"); + checkAnnotation(secondParamAnnotations[1],"AnnotationEnumElement","enumval","LSimpleEnum;Red"); + + } + if (m.getName().equals("main")) { + RuntimeVisParamAnnos paramAnns = + (RuntimeVisParamAnnos) findAttribute("RuntimeVisibleParameterAnnotations",m.getAttributes()); + assertTrue("main takes one parameter, not "+paramAnns.getParameterAnnotations().size(), + paramAnns.getParameterAnnotations().size()==1); + + AnnotationGen[] firstParamAnnotations = paramAnns.getAnnotationsOnParameter(0); + checkAnnotation(firstParamAnnotations[0],"SimpleAnnotation","id","1"); + } + } + } + + public void testAccessingParameterAnnotationsThroughGetAnnotations() throws ClassNotFoundException { + JavaClass clazz = getClassFromJar("AnnotatedParameters"); + Attribute[] rvaAttr = findAttribute("RuntimeVisibleParameterAnnotations",clazz); + + checkFooMethod(clazz); + } + + public void testParameterAnnotationsReadWrite() throws ClassNotFoundException,IOException { + JavaClass clazz = getClassFromJar("AnnotatedParameters"); + + checkFooMethod(clazz); + + // Write it out + File tfile = createTestdataFile("AnnotatedParameters.class"); + clazz.dump(tfile); + + SyntheticRepository repos2 = createRepos("."); + JavaClass clazz2 = repos2.loadClass("AnnotatedParameters"); + + checkFooMethod(clazz); + + assertTrue(tfile.delete()); + } + + + public void checkFooMethod(JavaClass clazz) { + Method[] methods = clazz.getMethods(); + + for (int i = 0; i < methods.length; i++) { + Method m = methods[i]; + if (m.getName().equals("foo")) { + + AnnotationGen[] firstParamAnnotations = m.getAnnotationsOnParameter(0); + checkAnnotation(firstParamAnnotations[0],"SimpleAnnotation","id","2"); + + AnnotationGen[] secondParamAnnotations = m.getAnnotationsOnParameter(1); + checkAnnotation(secondParamAnnotations[0],"SimpleAnnotation","id","3"); + checkAnnotation(secondParamAnnotations[1],"AnnotationEnumElement","enumval","LSimpleEnum;Red"); + + } + } + } + + private void checkAnnotation(AnnotationGen a,String name,String elementname,String elementvalue) { + assertTrue("Expected annotation to have name "+name+" but it had name "+a.getTypeName(), + a.getTypeName().equals(name)); + assertTrue("Expected annotation to have one element but it had "+a.getValues().size(),a.getValues().size()==1); + NameValuePair envp = a.getValues().get(0); + assertTrue("Expected element name "+elementname+" but was "+envp.getNameString(), + elementname.equals(envp.getNameString())); + assertTrue("Expected element value "+elementvalue+" but was "+envp.getValue().stringifyValue(), + elementvalue.equals(envp.getValue().stringifyValue())); + } + + + // helper methods + + public void checkValue(AnnotationGen a,String name,String tostring) { + for (Iterator i = a.getValues().iterator(); i.hasNext();) { + NameValuePair element = i.next(); + if (element.getNameString().equals(name)) { + if (!element.getValue().stringifyValue().equals(tostring)) { + fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue()); + } + return; + } + } + fail("Didnt find named element "+name); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java new file mode 100644 index 000000000..be3e3d5ac --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java @@ -0,0 +1,374 @@ +/* ******************************************************************* + * Copyright (c) 2013 VMware + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial implementation + * ******************************************************************/ +package org.aspectj.apache.bcel.classfile.tests; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.Field; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeTypeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.TypeAnnotationGen; + +public class TypeAnnotationsTest extends BcelTestCase { + + protected void setUp() throws Exception { + super.setUp(); + } + + public Attribute getAttribute(Attribute[] attrs, byte tag) { + for (Attribute attr: attrs) { + if (attr.getTag() == tag) { + return attr; + } + } + return null; + } + + public void testClassTypeParameter() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnClassTypeParameter"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(2,tas.length); + checkTypeAnnotationClassTypeParameter(tas[0],0,"@Anno"); + checkTypeAnnotationClassTypeParameter(tas[1],1,"@Anno(value=2)"); + } + + public void testMethodTypeParameter() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodTypeParameter"); + Method m = getMethod(jc, "m"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(m.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(1,tas.length); + checkTypeAnnotationMethodTypeParameter(tas[0],0,"@Anno"); + } + + public void testSuperinterface() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnSuperinterface1"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(1,tas.length); + TypeAnnotationGen ta = tas[0]; + checkTypeAnnotationClassExtends(ta, 0, "@Anno"); + } + + public void testSupertypes() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnSupertypes"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(3,tas.length); + checkTypeAnnotationClassExtends(tas[0],-1,"@Anno(value=1)"); + checkTypeAnnotationClassExtends(tas[1],0,"@Anno"); + checkTypeAnnotationClassExtends(tas[2],1,"@Anno(value=2)"); + } + + public void testClassTypeParameterBound() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnClassTypeParameterBound"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(3,tas.length); + checkTypeAnnotationClassTypeParameterBound(tas[0],0,0,"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationClassTypeParameterBound(tas[1],0,1,"@Anno(value=2)"); + checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationClassTypeParameterBound(tas[2],0,1,"@Anno(value=3)"); + checkTypePath(tas[2],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0}); + } + + public void testMethodTypeParameterBound() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodTypeParameterBound"); + Method m = getMethod(jc, "m"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(m.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(3,tas.length); + checkTypeAnnotationMethodTypeParameterBound(tas[0],0,0,"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationMethodTypeParameterBound(tas[1],0,1,"@Anno(value=2)"); + checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationMethodTypeParameterBound(tas[2],0,1,"@Anno(value=3)"); + checkTypePath(tas[2],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,1}); + } + + public void testField() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnField"); + Field f = getField(jc,"f1"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(f.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(1,tas.length); + checkTypeAnnotationField(tas[0],"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + + tas = getTypeAnnotations(getField(jc,"f2"),true); + checkTypeAnnotationField(tas[0],"@Anno"); + checkTypePath(tas[0],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0}); + + tas = getTypeAnnotations(getField(jc,"f3"),true); + checkTypeAnnotationField(tas[0],"@Anno"); + checkTypePath(tas[0],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0}); + + tas = getTypeAnnotations(getField(jc,"f4"),true); + checkTypeAnnotationField(tas[0],"@Anno"); + checkTypePath(tas[0],new int[]{ + TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0, + TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0 + }); + } + + public void testMethodReturn() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodReturn"); + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); + checkTypeAnnotationMethodReturn(tas[0],"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + } + + public void testMethodReceiver() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodReceiver"); + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); + checkTypeAnnotationMethodReceiver(tas[0],"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + } + + public void testMethodFormalParameter() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodFormalParameter"); + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); + checkTypeAnnotationMethodFormalParameter(tas[0],0, "@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + } + + public void testThrows() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnThrows"); + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); + checkTypeAnnotationThrows(tas[0],0, "@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationThrows(tas[1],1, "@Anno(value=2)"); + checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); + } + + public void testLocalVariable() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnLocalVariable"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(1,tas.length); + checkTypeAnnotationLocalVariable(tas[0],new int[]{11,8,1}, "@Anno"); + } + + public void testResourceVariable() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnResourceVariable"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(2,tas.length); + checkTypeAnnotationResourceVariable(tas[0],new int[]{17,204,1}, "@Anno"); + checkTypeAnnotationResourceVariable(tas[1],new int[]{36,114,3}, "@Anno(value=99)"); + } + + public void testExceptionParameter() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnExceptionParameter"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(2,tas.length); + checkTypeAnnotationExceptionParameter(tas[0],0, "@Anno(value=99)"); + checkTypeAnnotationExceptionParameter(tas[1],0, "@Anno"); + } + + public void testInstanceOf() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnInstanceOf"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(2,tas.length); + checkTypeAnnotationInstanceOf(tas[0],3, "@Anno(value=1)"); + checkTypeAnnotationInstanceOf(tas[1],18, "@Anno(value=1)"); + } + + public void testNew() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnNew"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(4,tas.length); + checkTypeAnnotationNew(tas[0],0, "@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + + // TODO type path bugs in javac b90 according to the spec +// checkTypeAnnotationNew(tas[1],8, "@Anno(value=2)"); +// checkTypePath(tas[1],new int[]{ +// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 +// }); +// checkTypeAnnotationNew(tas[2],13, "@Anno(value=4)"); +// checkTypePath(tas[2],TypeAnnotationGen.NO_TYPE_PATH); +// checkTypeAnnotationNew(tas[3],13, "@Anno(value=3)"); +// checkTypePath(tas[3],new int[]{ +// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0, +// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 +// }); + } + + + // --- + private TypeAnnotationGen[] getTypeAnnotations(Attribute[] attrs, boolean visible) { + RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(attrs, visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); + return rvta.getTypeAnnotations(); + } + + private TypeAnnotationGen[] getTypeAnnotations(Method m, boolean visible) { + RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(m.getAttributes(), visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); + return rvta.getTypeAnnotations(); + } + + private TypeAnnotationGen[] getTypeAnnotations(Field f, boolean visible) { + RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(f.getAttributes(), visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); + return rvta.getTypeAnnotations(); + } + + private void checkTypePath(TypeAnnotationGen ta, int[] expectedTypePath) { + int[] typepath = ta.getTypePath(); + if (expectedTypePath==TypeAnnotationGen.NO_TYPE_PATH || expectedTypePath==null) { + if (typepath!=TypeAnnotationGen.NO_TYPE_PATH) { + fail("Expected no type path but was "+ta.getTypePathString()); + } + } else { + assertEquals(expectedTypePath.length, typepath.length); + for (int i=0;i0); + assertTrue(cf.getTime()>0); + } +} diff --git a/bcel-builder/src/test/java/org/aspectj/apache/bcel/util/Play.java b/bcel-builder/src/test/java/org/aspectj/apache/bcel/util/Play.java new file mode 100644 index 000000000..abea68c1d --- /dev/null +++ b/bcel-builder/src/test/java/org/aspectj/apache/bcel/util/Play.java @@ -0,0 +1,84 @@ +package org.aspectj.apache.bcel.util; + +import java.io.File; +import java.io.FileInputStream; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ClassParser; +import org.aspectj.apache.bcel.classfile.Field; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; + +public class Play { + + public static void printBytes(byte[] bs) { + StringBuilder sb = new StringBuilder("Bytes:"+bs.length+"["); + for (int i=0;i0) sb.append(" "); + sb.append(bs[i]); + } + sb.append("]"); + System.out.println(sb); + } + + public static void main(String[] args) throws Exception { + if (args==null || args.length==0 ) { + System.out.println("Specify a file"); + return; + } + if (!args[0].endsWith(".class")) { + args[0] = args[0]+".class"; + } + FileInputStream fis = new FileInputStream(new File(args[0])); + ClassParser cp = new ClassParser(fis,args[0]); + JavaClass jc = cp.parse(); + Attribute[] attributes = jc.getAttributes(); + printUsefulAttributes(attributes); + System.out.println("Fields"); + Field[] fs = jc.getFields(); + if (fs!=null) { + for (Field f: fs) { + System.out.println(f); + printUsefulAttributes(f.getAttributes()); + } + } + System.out.println("Methods"); + Method[] ms = jc.getMethods(); + if (ms!=null) { + for (Method m: ms) { + System.out.println(m); + printUsefulAttributes(m.getAttributes()); + System.out.println("Code attributes:"); + printUsefulAttributes(m.getCode().getAttributes()); + } + } +// Method[] ms = jc.getMethods(); +// for (Method m: ms) { +// System.out.println("=========="); +// System.out.println("Method: "+m.getName()+" modifiers=0x"+Integer.toHexString(m.getModifiers())); +// Attribute[] as = m.getAttributes(); +// for (Attribute a: as) { +// if (a.getName().toLowerCase().contains("synthetic")) { +// System.out.println("> "+a.getName()); +// } +// } +// } + } + + private static void printUsefulAttributes(Attribute[] attributes) throws Exception { + for (Attribute attribute: attributes) { + String n = attribute.getName(); + if (n.equals("RuntimeInvisibleAnnotations") || + n.equals("RuntimeVisibleAnnotations")) { + RuntimeAnnos ra = (RuntimeAnnos)attribute; + // private byte[] annotation_data; + java.lang.reflect.Field f = RuntimeAnnos.class.getDeclaredField("annotation_data"); + f.setAccessible(true); + byte[] bs = (byte[])f.get(ra); +// byte[] bs = unknown.getBytes(); + printBytes(bs); + } + } + } +} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java deleted file mode 100644 index 440a3ee17..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import org.aspectj.apache.bcel.util.ClassPathTests; - -import junit.framework.Test; -import junit.framework.TestSuite; - -public class AllTests { - - public static Test suite() { - TestSuite suite = new TestSuite("Tests for BCEL"); - // $JUnit-BEGIN$ - suite.addTestSuite(Fundamentals.class); - suite.addTestSuite(RuntimeVisibleParameterAnnotationAttributeTest.class); - suite.addTestSuite(AnnotationDefaultAttributeTest.class); - suite.addTestSuite(ConstantPoolToStringTest.class); - suite.addTestSuite(EnclosingMethodAttributeTest.class); - suite.addTestSuite(MethodAnnotationsTest.class); - suite.addTestSuite(RuntimeVisibleAnnotationAttributeTest.class); - suite.addTestSuite(ClassloaderRepositoryTest.class); - suite.addTestSuite(NonCachingClassLoaderRepositoryTest.class); - suite.addTestSuite(EnumAccessFlagTest.class); - suite.addTestSuite(LocalVariableTypeTableTest.class); - suite.addTestSuite(VarargsTest.class); - suite.addTestSuite(AnnotationAccessFlagTest.class); - suite.addTestSuite(ElementValueGenTest.class); - suite.addTestSuite(FieldAnnotationsTest.class); - suite.addTestSuite(ClassPathTests.class); - suite.addTestSuite(AnnotationGenTest.class); - suite.addTestSuite(ParameterAnnotationsTest.class); - suite.addTestSuite(GeneratingAnnotatedClassesTest.class); - suite.addTestSuite(TypeAnnotationsTest.class); - suite.addTestSuite(UtilTests.class); - suite.addTestSuite(GenericSignatureParsingTest.class); - suite.addTestSuite(GenericsErasureTesting.class); - suite.addTestSuite(AnonymousClassTest.class); - // $JUnit-END$ - return suite; - } -} \ No newline at end of file diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationAccessFlagTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationAccessFlagTest.java deleted file mode 100644 index 96dd9e765..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationAccessFlagTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; - -import junit.framework.TestCase; - -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.ClassPath; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -public class AnnotationAccessFlagTest extends TestCase { - - private boolean verbose = false; - - protected void setUp() throws Exception { - super.setUp(); - } - - /** - * If you write an annotation and compile it, the class file generated should be - * marked as an annotation type - which is detectable through BCEL. - */ - public void testAnnotationClassSaysItIs() throws ClassNotFoundException { - ClassPath cp = - new ClassPath("testdata"+File.separator+"testcode.jar"+File.pathSeparator+System.getProperty("java.class.path")); - SyntheticRepository repos = SyntheticRepository.getInstance(cp); - JavaClass clazz = repos.loadClass("SimpleAnnotation"); - ConstantPool pool = clazz.getConstantPool(); - assertTrue("Expected SimpleAnnotation class to say it was an annotation - but it didn't !", - clazz.isAnnotation()); - clazz = repos.loadClass("SimpleClass"); - assertTrue("Expected SimpleClass class to say it was not an annotation - but it didn't !", - !clazz.isAnnotation()); - } - - - protected void tearDown() throws Exception { - super.tearDown(); - } - - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationDefaultAttributeTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationDefaultAttributeTest.java deleted file mode 100644 index ced29d489..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationDefaultAttributeTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import org.aspectj.apache.bcel.classfile.AnnotationDefault; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.annotation.ElementValue; -import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; - -public class AnnotationDefaultAttributeTest extends BcelTestCase { - - protected void setUp() throws Exception { - super.setUp(); - } - - - /** - * For values in an annotation that have default values, we should be able to - * query the AnnotationDefault attribute against the method to discover the - * default value that was originally declared. - */ - public void testMethodAnnotations() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("SimpleAnnotation"); - - Method m = getMethod(clazz,"fruit"); - AnnotationDefault a = (AnnotationDefault) findAttribute("AnnotationDefault",m.getAttributes()); - SimpleElementValue val = (SimpleElementValue) a.getElementValue(); - assertTrue("Should be STRING but is "+val.getElementValueType(), - val.getElementValueType()==ElementValue.STRING); - assertTrue("Should have default of bananas but default is "+val.getValueString(), - val.getValueString().equals("bananas")); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationGenTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationGenTest.java deleted file mode 100644 index 901aa2ee7..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnnotationGenTest.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying - * materials are made available under the terms of the Eclipse Public License - * v1.0 which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: Andy Clement - initial implementation - ******************************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Vector; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.Utility; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.classfile.annotation.ElementValue; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; -import org.aspectj.apache.bcel.generic.ClassGen; -import org.aspectj.apache.bcel.generic.ObjectType; - -public class AnnotationGenTest extends BcelTestCase { - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - private ClassGen createClassGen(String classname) { - return new ClassGen(classname, "java.lang.Object", "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); - } - - /** - * Programmatically construct an mutable annotation (AnnotationGen) object. - */ - public void testConstructMutableAnnotation() { - - // Create the containing class - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - // Create the simple primitive value '4' of type 'int' - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 4); - - // Give it a name, call it 'id' - NameValuePair nvGen = new NameValuePair("id", evg, cp); - - // Check it looks right - assertTrue("Should include string 'id=4' but says: " + nvGen.toString(), nvGen.toString().indexOf("id=4") != -1); - - ObjectType t = new ObjectType("SimpleAnnotation"); - - List elements = new ArrayList(); - elements.add(nvGen); - - // Build an annotation of type 'SimpleAnnotation' with 'id=4' as the only value :) - AnnotationGen a = new AnnotationGen(t, elements, true, cp); - - // Check we can save and load it ok - checkSerialize(a, cp); - } - - public void testVisibleInvisibleAnnotationGen() { - - // Create the containing class - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - // Create the simple primitive value '4' of type 'int' - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 4); - - // Give it a name, call it 'id' - NameValuePair nvGen = new NameValuePair("id", evg, cp); - - // Check it looks right - assertTrue("Should include string 'id=4' but says: " + nvGen.toString(), nvGen.toString().indexOf("id=4") != -1); - - ObjectType t = new ObjectType("SimpleAnnotation"); - - List elements = new ArrayList(); - elements.add(nvGen); - - // Build a RV annotation of type 'SimpleAnnotation' with 'id=4' as the only value :) - AnnotationGen a = new AnnotationGen(t, elements, true, cp); - - Vector v = new Vector(); - v.add(a); - Collection attributes = Utility.getAnnotationAttributes(cp, v); - boolean foundRV = false; - for (Attribute attribute : attributes) { - if (attribute instanceof RuntimeVisAnnos) { - assertTrue(((RuntimeAnnos) attribute).areVisible()); - foundRV = true; - - } - } - assertTrue("Should have seen a RuntimeVisibleAnnotation", foundRV); - - // Build a RIV annotation of type 'SimpleAnnotation' with 'id=4' as the only value :) - AnnotationGen a2 = new AnnotationGen(t, elements, false, cp); - - Vector v2 = new Vector(); - v2.add(a2); - Collection attributes2 = Utility.getAnnotationAttributes(cp, v2); - boolean foundRIV = false; - for (Attribute attribute : attributes2) { - // for (int i = 0; i < attributes2.length; i++) { - // Attribute attribute = attributes2[i]; - if (attribute instanceof RuntimeInvisAnnos) { - assertFalse(((RuntimeAnnos) attribute).areVisible()); - foundRIV = true; - } - } - assertTrue("Should have seen a RuntimeInvisibleAnnotation", foundRIV); - } - - // // - // Helper methods - - private void checkSerialize(AnnotationGen a, ConstantPool cpg) { - try { - String beforeName = a.getTypeName(); - List beforeValues = a.getValues(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - a.dump(dos); - dos.flush(); - dos.close(); - - byte[] bs = baos.toByteArray(); - - ByteArrayInputStream bais = new ByteArrayInputStream(bs); - DataInputStream dis = new DataInputStream(bais); - AnnotationGen annAfter = AnnotationGen.read(dis, cpg, a.isRuntimeVisible()); - - dis.close(); - - String afterName = annAfter.getTypeName(); - List afterValues = annAfter.getValues(); - - if (!beforeName.equals(afterName)) { - fail("Deserialization failed: before type='" + beforeName + "' after type='" + afterName + "'"); - } - if (a.getValues().size() != annAfter.getValues().size()) { - fail("Different numbers of element name value pairs?? " + a.getValues().size() + "!=" + annAfter.getValues().size()); - } - for (int i = 0; i < a.getValues().size(); i++) { - NameValuePair beforeElement = a.getValues().get(i); - NameValuePair afterElement = annAfter.getValues().get(i); - if (!beforeElement.getNameString().equals(afterElement.getNameString())) { - fail("Different names?? " + beforeElement.getNameString() + "!=" + afterElement.getNameString()); - } - } - - } catch (IOException ioe) { - fail("Unexpected exception whilst checking serialization: " + ioe); - } - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - -} \ No newline at end of file diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnonymousClassTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnonymousClassTest.java deleted file mode 100644 index 4a9bc0a3f..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AnonymousClassTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2005 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer - initial implementation - */ -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; - -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.ClassPath; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -import junit.framework.TestCase; - -/** - * @author adrian colyer - * - */ -public class AnonymousClassTest extends TestCase { - - private SyntheticRepository repos; - - public void testRegularClassIsNotAnonymous() throws ClassNotFoundException { - JavaClass clazz = repos.loadClass("AnonymousClassTest"); - assertFalse("regular outer classes are not anonymous",clazz.isAnonymous()); - assertFalse("regular outer classes are not nested",clazz.isNested()); - } - - public void testNamedInnerClassIsNotAnonymous() throws ClassNotFoundException { - JavaClass clazz = repos.loadClass("AnonymousClassTest$X"); - assertFalse("regular inner classes are not anonymous",clazz.isAnonymous()); - assertTrue("regular inner classes are nested",clazz.isNested()); - } - - public void testStaticInnerClassIsNotAnonymous() throws ClassNotFoundException { - JavaClass clazz = repos.loadClass("AnonymousClassTest$Y"); - assertFalse("regular static inner classes are not anonymous",clazz.isAnonymous()); - assertTrue("regular static inner classes are nested",clazz.isNested()); - } - - public void testAnonymousInnerClassIsAnonymous() throws ClassNotFoundException { - JavaClass clazz = repos.loadClass("AnonymousClassTest$1"); - assertTrue("anonymous inner classes are anonymous",clazz.isAnonymous()); - assertTrue("anonymous inner classes are anonymous",clazz.isNested()); - } - - protected void setUp() throws Exception { - ClassPath cp = - new ClassPath("testdata"+File.separator+"testcode.jar"+File.pathSeparator+System.getProperty("java.class.path")); - repos = SyntheticRepository.getInstance(cp); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java deleted file mode 100644 index ef4b8a9a7..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java +++ /dev/null @@ -1,186 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 - 2016 IBM, VMware, Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation {date} - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import junit.framework.TestCase; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.Field; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.classfile.annotation.ElementValue; -import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; -import org.aspectj.apache.bcel.generic.ObjectType; -import org.aspectj.apache.bcel.util.ClassPath; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -/** - * Super class for the Java5 tests, includes various helper methods. - */ -public abstract class BcelTestCase extends TestCase { - - private boolean verbose = false; - - protected File createTestdataFile(String name) { - return new File("testdata" + File.separator + name); - } - - protected JavaClass getClassFromJar(String clazzname) throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - return repos.loadClass(clazzname); - } - - protected JavaClass getClassFromJava8Jar(String clazzname) throws ClassNotFoundException { - SyntheticRepository repos = createRepos("java8testcode.jar"); - return repos.loadClass(clazzname); - } - - protected Method getMethod(JavaClass cl, String methodname) { - Method[] methods = cl.getMethods(); - for (int i = 0; i < methods.length; i++) { - Method m = methods[i]; - if (m.getName().equals(methodname)) { - return m; - } - } - return null; - } - - protected Field getField(JavaClass cl, String fieldname) { - Field[] fields = cl.getFields(); - for (int i = 0; i < fields.length; i++) { - Field f = fields[i]; - if (f.getName().equals(fieldname)) { - return f; - } - } - return null; - } - - protected boolean wipe(String name) { - return new File("testdata" + File.separator + name).delete(); - } - - protected boolean wipe(String dir, String name) { - boolean b = wipe(dir + File.separator + name); - String[] files = new File(dir).list(); - if (files == null || files.length == 0) { - new File(dir).delete(); // Why does this not succeed? stupid thing - } - return b; - } - - public SyntheticRepository createRepos(String cpentry) { - ClassPath cp = new ClassPath("testdata" + File.separator + cpentry + File.pathSeparator - + System.getProperty("java.class.path")); - return SyntheticRepository.getInstance(cp); - } - - protected Attribute[] findAttribute(String name, JavaClass clazz) { - Attribute[] all = clazz.getAttributes(); - List chosenAttrsList = new ArrayList(); - for (int i = 0; i < all.length; i++) { - if (verbose) - System.err.println("Attribute: " + all[i].getName()); - if (all[i].getName().equals(name)) - chosenAttrsList.add(all[i]); - } - return chosenAttrsList.toArray(new Attribute[] {}); - } - - protected Attribute findAttribute(String name, Attribute[] all) { - List chosenAttrsList = new ArrayList(); - for (int i = 0; i < all.length; i++) { - if (verbose) - System.err.println("Attribute: " + all[i].getName()); - if (all[i].getName().equals(name)) - chosenAttrsList.add(all[i]); - } - assertTrue("Should be one match: " + chosenAttrsList.size(), chosenAttrsList.size() == 1); - return chosenAttrsList.get(0); - } - - protected String dumpAnnotations(AnnotationGen[] as) { - StringBuffer result = new StringBuffer(); - result.append("["); - for (int i = 0; i < as.length; i++) { - AnnotationGen annotation = as[i]; - result.append(annotation.toShortString()); - if (i + 1 < as.length) - result.append(","); - } - result.append("]"); - return result.toString(); - } - - protected String dumpAnnotations(List as) { - StringBuffer result = new StringBuffer(); - result.append("["); - for (int i = 0; i < as.size(); i++) { - AnnotationGen annotation = as.get(i); - result.append(annotation.toShortString()); - if (i + 1 < as.size()) - result.append(","); - } - result.append("]"); - return result.toString(); - } - - protected String dumpAttributes(Attribute[] as) { - StringBuffer result = new StringBuffer(); - result.append("AttributeArray:["); - for (int i = 0; i < as.length; i++) { - Attribute attr = as[i]; - result.append(attr.toString()); - if (i + 1 < as.length) - result.append(","); - } - result.append("]"); - return result.toString(); - } - - public AnnotationGen createFruitAnnotation(ConstantPool cp, String aFruit, boolean visibility) { - SimpleElementValue evg = new SimpleElementValue(ElementValue.STRING, cp, aFruit); - NameValuePair nvGen = new NameValuePair("fruit", evg, cp); - ObjectType t = new ObjectType("SimpleStringAnnotation"); - List elements = new ArrayList(); - elements.add(nvGen); - return new AnnotationGen(t, elements, visibility, cp); - } - - public Attribute getAttribute(Attribute[] attrs, byte tag) { - for (Attribute attr: attrs) { - if (attr.getTag() == tag) { - return attr; - } - } - return null; - } - - public Attribute getAttribute(Attribute[] attrs, String name) { - for (Attribute attr: attrs) { - if (attr.getName().equals(name)) { - return attr; - } - } - return null; - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ClassloaderRepositoryTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ClassloaderRepositoryTest.java deleted file mode 100644 index 7202be3fa..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ClassloaderRepositoryTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.aspectj.apache.bcel.classfile.tests; - -import java.net.URL; -import java.net.URLClassLoader; - -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.ClassLoaderRepository; - -import junit.framework.TestCase; - -/* - * Tests create a simple classloader repository configuration and check sharing of information. - */ -public class ClassloaderRepositoryTest extends TestCase { - - private ClassLoaderRepository rep1,rep2; - - public void setUp() throws Exception { - super.setUp(); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - ClassLoader cl1 = new URLClassLoader(new URL[]{},cl); - ClassLoader cl2 = new URLClassLoader(new URL[]{},cl); - rep1 = new ClassLoaderRepository(cl1); - rep2 = new ClassLoaderRepository(cl2); - } - - // Retrieve string 5 times from same repository, 4 hits should be from local cache - public void testLocalCacheWorks() throws ClassNotFoundException { - ClassLoaderRepository.useSharedCache=false; - JavaClass jc = rep1.loadClass("java.lang.String"); - jc = rep1.loadClass("java.lang.String"); - jc = rep1.loadClass("java.lang.String"); - jc = rep1.loadClass("java.lang.String"); - jc = rep1.loadClass("java.lang.String"); - assertTrue("Should have used local cache 4 times: "+reportLocalCacheHits(rep1),reportLocalCacheHits(rep1)==4); - } - - // Retrieve string 5 times from same repository, 4 hits should be from local cache - public void testSharedCacheWorksOnOne() throws ClassNotFoundException { - ClassLoaderRepository.useSharedCache=true; - JavaClass jc = rep1.loadClass("java.lang.String"); - jc = rep1.loadClass("java.lang.String"); - jc = rep1.loadClass("java.lang.String"); - jc = rep1.loadClass("java.lang.String"); - jc = rep1.loadClass("java.lang.String"); - assertTrue("Should have used local cache 4 times: "+reportSharedCacheHits(rep1),reportSharedCacheHits(rep1)==4); - } - - // Retrieve String through one repository then load again through another, should be shared cache hit - public void testSharedCacheWorks() throws ClassNotFoundException { - ClassLoaderRepository.useSharedCache=true; - JavaClass jc = rep1.loadClass("java.lang.String"); - jc = rep2.loadClass("java.lang.String"); - assertTrue("Should have retrieved String from shared cache: "+reportSharedCacheHits(rep1), - reportSharedCacheHits(rep1)==1); - } - - // Shared cache OFF, shouldn't get a shared cache hit - public void testSharedCacheCanBeDeactivated() throws ClassNotFoundException { - try { - ClassLoaderRepository.useSharedCache=false; - JavaClass jc = rep1.loadClass("java.lang.String"); - jc = rep2.loadClass("java.lang.String"); - assertTrue("Should not have retrieved String from shared cache: "+ - reportSharedCacheHits(rep1), - reportSharedCacheHits(rep1)==0); - } finally { - ClassLoaderRepository.useSharedCache=true; - } - } - - public void tearDown() throws Exception { - super.tearDown(); - System.err.println("Rep1: "+rep1.reportStats()); - System.err.println("Rep2: "+rep2.reportStats()); - rep1.reset(); - rep2.reset(); - } - - private long reportLocalCacheHits(ClassLoaderRepository rep) { - return rep.reportStats()[5]; - } - - private long reportSharedCacheHits(ClassLoaderRepository rep) { - return rep.reportStats()[3]; - } - -} - diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ConstantPoolToStringTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ConstantPoolToStringTest.java deleted file mode 100644 index 3a41c6c70..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ConstantPoolToStringTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2018 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -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.util.SyntheticRepository; - -public class ConstantPoolToStringTest extends BcelTestCase { - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testToStringLambdaElements() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("lambda.jar"); - JavaClass clazz = repos.loadClass("Code"); - ConstantPool pool = clazz.getConstantPool(); - Method[] methods = clazz.getMethods(); - String codeString = methods[1].getCode().getCodeString(); - assertEquals("Code(max_stack = 1, max_locals = 2, code_length = 13)\n" + - "0: invokedynamic #0.run ()Ljava/lang/Runnable; (2)\n" + - "5: astore_1\n" + - "6: aload_1\n" + - "7: invokeinterface java.lang.Runnable.run ()V (3) 1 0\n" + - "12: return\n",codeString); - - // #20 = MethodHandle 6:#32 // REF_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; - String cts = pool.constantToString(pool.getConstant(20)); - assertEquals("6: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;",cts); - - // #21 = MethodType #10 // ()V - cts = pool.constantToString(pool.getConstant(21)); - assertEquals("()V",cts); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ElementValueGenTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ElementValueGenTest.java deleted file mode 100644 index 7d91bd7d3..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ElementValueGenTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying - * materials are made available under the terms of the Eclipse Public License - * v1.0 which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: Andy Clement - initial implementation - ******************************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Collections; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationElementValue; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; -import org.aspectj.apache.bcel.classfile.annotation.ElementValue; -import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; -import org.aspectj.apache.bcel.generic.ClassGen; -import org.aspectj.apache.bcel.generic.ObjectType; - -public class ElementValueGenTest extends BcelTestCase { - - protected void setUp() throws Exception { - super.setUp(); - } - - private ClassGen createClassGen(String classname) { - return new ClassGen(classname, "java.lang.Object", "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); - } - - // // - // Create primitive element values - - public void testCreateIntegerElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 555); - // Creation of an element like that should leave a new entry in the cpool - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupInteger(555), - evg.getIndex() == cp.lookupInteger(555)); - checkSerialize(evg, cp); - } - - public void testCreateFloatElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_FLOAT, cp, 111.222f); - // Creation of an element like that should leave a new entry in the cpool - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupFloat(111.222f), - evg.getIndex() == cp.lookupFloat(111.222f)); - checkSerialize(evg, cp); - } - - public void testCreateDoubleElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_DOUBLE, cp, 333.44); - // Creation of an element like that should leave a new entry in the cpool - int idx = cp.lookupDouble(333.44); - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); - checkSerialize(evg, cp); - } - - public void testCreateLongElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_LONG, cp, 3334455L); - // Creation of an element like that should leave a new entry in the cpool - int idx = cp.lookupLong(3334455L); - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); - checkSerialize(evg, cp); - } - - public void testCreateCharElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_CHAR, cp, (char) 't'); - // Creation of an element like that should leave a new entry in the cpool - int idx = cp.lookupInteger((char) 't'); - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); - checkSerialize(evg, cp); - } - - public void testCreateByteElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_CHAR, cp, (byte) 'z'); - // Creation of an element like that should leave a new entry in the cpool - int idx = cp.lookupInteger((byte) 'z'); - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); - checkSerialize(evg, cp); - } - - public void testCreateBooleanElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_BOOLEAN, cp, true); - // Creation of an element like that should leave a new entry in the cpool - int idx = cp.lookupInteger(1); // 1 == true - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); - checkSerialize(evg, cp); - } - - public void testCreateShortElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_SHORT, cp, (short) 42); - // Creation of an element like that should leave a new entry in the cpool - int idx = cp.lookupInteger(42); - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); - checkSerialize(evg, cp); - } - - // // - // Create string element values - - public void testCreateStringElementValue() { - - // Create HelloWorld - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - SimpleElementValue evg = new SimpleElementValue(ElementValue.STRING, cp, "hello"); - // Creation of an element like that should leave a new entry in the cpool - assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupUtf8("hello"), - evg.getIndex() == cp.lookupUtf8("hello")); - checkSerialize(evg, cp); - } - - // // - // Create enum element value - - public void testCreateEnumElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - ObjectType enumType = new ObjectType("SimpleEnum"); // Supports rainbow :) - - EnumElementValue evg = new EnumElementValue(enumType, "Red", cp); - // Creation of an element like that should leave a new entry in the cpool - assertTrue("The new ElementValue value index should match the contents of the constantpool but " + evg.getValueIndex() - + "!=" + cp.lookupUtf8("Red"), evg.getValueIndex() == cp.lookupUtf8("Red")); - // BCELBUG: Should the class signature or class name be in the constant pool? (see note in ConstantPool) - // assertTrue("The new ElementValue type index should match the contents of the constantpool but "+ - // evg.getTypeIndex()+"!="+cp.lookupClass(enumType.getSignature()), - // evg.getTypeIndex()==cp.lookupClass(enumType.getSignature())); - - checkSerialize(evg, cp); - } - - public void testCreateMarkerAnnotationElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - ObjectType annoType = new ObjectType("SimpleMarkerAnnotation"); - AnnotationGen annoGen = new AnnotationGen(annoType, Collections. emptyList(), true, cp); - AnnotationElementValue evg = new AnnotationElementValue(annoGen, cp); - checkSerialize(evg, cp); - } - - // // - // Create class element value - - public void testCreateClassElementValue() { - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - - ObjectType classType = new ObjectType("java.lang.Integer"); - - ClassElementValue evg = new ClassElementValue(classType, cp); - - assertTrue("Unexpected value for contained class: '" + evg.getClassString() + "'", - evg.getClassString().indexOf("Integer") != -1); - - checkSerialize(evg, cp); - } - - // // - // Helper methods - - private void checkSerialize(ElementValue evgBefore, ConstantPool cpg) { - try { - String beforeValue = evgBefore.stringifyValue(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - evgBefore.dump(dos); - dos.flush(); - dos.close(); - - byte[] bs = baos.toByteArray(); - - ByteArrayInputStream bais = new ByteArrayInputStream(bs); - DataInputStream dis = new DataInputStream(bais); - ElementValue evgAfter = ElementValue.readElementValue(dis, cpg); - - dis.close(); - String afterValue = evgAfter.stringifyValue(); - - if (!beforeValue.equals(afterValue)) { - fail("Deserialization failed: before='" + beforeValue + "' after='" + afterValue + "'"); - } - - } catch (IOException ioe) { - fail("Unexpected exception whilst checking serialization: " + ioe); - } - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - -} \ No newline at end of file diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/EnclosingMethodAttributeTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/EnclosingMethodAttributeTest.java deleted file mode 100644 index a03c9b386..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/EnclosingMethodAttributeTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; -import java.io.IOException; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.EnclosingMethod; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -public class EnclosingMethodAttributeTest extends BcelTestCase { - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - /** - * Verify for an inner class declared inside the 'main' method that the enclosing method attribute is set correctly. - */ - public void testCheckMethodLevelNamedInnerClass() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AttributeTestClassEM01$1S"); - ConstantPool pool = clazz.getConstantPool(); - Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); - assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1); - EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; - String enclosingClassName = em.getEnclosingClass().getClassname(pool); - String enclosingMethodName = em.getEnclosingMethod().getName(pool); - assertTrue("Expected class name to be 'AttributeTestClassEM01' but was " + enclosingClassName, enclosingClassName - .equals("AttributeTestClassEM01")); - assertTrue("Expected method name to be 'main' but was " + enclosingMethodName, enclosingMethodName.equals("main")); - } - - /** - * Verify for an inner class declared at the type level that the EnclosingMethod attribute is set correctly (i.e. to a null - * value) - */ - public void testCheckClassLevelNamedInnerClass() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AttributeTestClassEM02$1"); - ConstantPool pool = clazz.getConstantPool(); - Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); - assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1); - EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; - String enclosingClassName = em.getEnclosingClass().getClassname(pool); - assertTrue("The class is not within a method, so method_index should be null, but it is " + em.getEnclosingMethodIndex(), - em.getEnclosingMethodIndex() == 0); - assertTrue("Expected class name to be 'AttributeTestClassEM02' but was " + enclosingClassName, enclosingClassName - .equals("AttributeTestClassEM02")); - } - - /** - * Check that we can save and load the attribute correctly. - */ - public void testAttributeSerializtion() throws ClassNotFoundException, IOException { - // Read in the class - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AttributeTestClassEM02$1"); - ConstantPool pool = clazz.getConstantPool(); - Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); - assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1); - - // Write it out - File tfile = createTestdataFile("AttributeTestClassEM02$1.class"); - clazz.dump(tfile); - - // Read in the new version and check it is OK - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos2.loadClass("AttributeTestClassEM02$1"); - EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; - String enclosingClassName = em.getEnclosingClass().getClassname(pool); - assertTrue("The class is not within a method, so method_index should be null, but it is " + em.getEnclosingMethodIndex(), - em.getEnclosingMethodIndex() == 0); - assertTrue("Expected class name to be 'AttributeTestClassEM02' but was " + enclosingClassName, enclosingClassName - .equals("AttributeTestClassEM02")); - assertTrue(tfile.delete()); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/EnumAccessFlagTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/EnumAccessFlagTest.java deleted file mode 100644 index a91947549..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/EnumAccessFlagTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; - -import junit.framework.TestCase; - -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.ClassPath; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -public class EnumAccessFlagTest extends TestCase { - - private boolean verbose = false; - - protected void setUp() throws Exception { - super.setUp(); - } - - /** - * An enumerated type, once compiled, should result in a class file that - * is marked such that we can determine from the access flags (through BCEL) that - * it was originally an enum type declaration. - */ - public void testEnumClassSaysItIs() throws ClassNotFoundException { - ClassPath cp = - new ClassPath("testdata"+File.separator+"testcode.jar"+File.pathSeparator+System.getProperty("java.class.path")); - SyntheticRepository repos = SyntheticRepository.getInstance(cp); - JavaClass clazz = repos.loadClass("SimpleEnum"); - ConstantPool pool = clazz.getConstantPool(); - assertTrue("Expected SimpleEnum class to say it was an enum - but it didn't !", - clazz.isEnum()); - clazz = repos.loadClass("SimpleClass"); - assertTrue("Expected SimpleClass class to say it was not an enum - but it didn't !", - !clazz.isEnum()); - } - - - protected void tearDown() throws Exception { - super.tearDown(); - } - - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/FieldAnnotationsTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/FieldAnnotationsTest.java deleted file mode 100644 index 6f5a4f8f3..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/FieldAnnotationsTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; -import java.io.IOException; -import java.util.Iterator; - -import org.aspectj.apache.bcel.classfile.Field; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.generic.ClassGen; -import org.aspectj.apache.bcel.generic.FieldGen; -import org.aspectj.apache.bcel.util.SyntheticRepository; - - -public class FieldAnnotationsTest extends BcelTestCase { - - - protected void setUp() throws Exception { - super.setUp(); - } - - - /** - * Check field annotations are retrievable. - */ - public void testFieldAnnotations() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("AnnotatedFields"); - - checkAnnotatedField(clazz,"i","SimpleAnnotation","id","1"); - checkAnnotatedField(clazz,"s","SimpleAnnotation","id","2"); - - } - - /** - * Check field annotations (de)serialize ok. - */ - public void testFieldAnnotationsReadWrite() throws ClassNotFoundException,IOException { - JavaClass clazz = getClassFromJar("AnnotatedFields"); - - checkAnnotatedField(clazz,"i","SimpleAnnotation","id","1"); - checkAnnotatedField(clazz,"s","SimpleAnnotation","id","2"); - - // Write it out - File tfile = createTestdataFile("AnnotatedFields.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos2.loadClass("AnnotatedFields"); - - checkAnnotatedField(clazz,"i","SimpleAnnotation","id","1"); - checkAnnotatedField(clazz,"s","SimpleAnnotation","id","2"); - - assertTrue(tfile.delete()); - } - - /** - * Check we can load in a class, modify its field annotations, save it, reload it and - * everything is correct. - */ - public void testFieldAnnotationsModification() throws ClassNotFoundException, IOException { - boolean dbg = false; - JavaClass clazz = getClassFromJar("AnnotatedFields"); - - ClassGen clg = new ClassGen(clazz); - Field f = clg.getFields()[0]; - if (dbg) System.err.println("Field in freshly constructed class is: "+f); - if (dbg) System.err.println("Annotations on field are: "+dumpAnnotations(f.getAnnotations())); - AnnotationGen fruitBasedAnnotation = createFruitAnnotation(clg.getConstantPool(),"Tomato",false); - FieldGen fg = new FieldGen(f,clg.getConstantPool()); - if (dbg) System.err.println("Adding annotation to the field"); - fg.addAnnotation(fruitBasedAnnotation); - if (dbg) System.err.println("FieldGen (mutable field) is "+fg); - if (dbg) System.err.println("with annotations: "+dumpAnnotations(fg.getAnnotations())); - - if (dbg) System.err.println("Replacing original field with new field that has extra annotation"); - clg.removeField(f); - clg.addField(fg.getField()); - - f = clg.getFields()[1]; // there are two fields in the class, removing and readding has changed the order - // so this time index [1] is the 'int i' field - if (dbg) System.err.println("Field now looks like this: "+f); - if (dbg) System.err.println("With annotations: "+dumpAnnotations(f.getAnnotations())); - assertTrue("Should be 2 annotations on this field, but there are "+f.getAnnotations().length,f.getAnnotations().length==2); - } - - // helper methods - - public void checkAnnotatedField(JavaClass clazz,String fieldname, - String annotationName,String annotationElementName,String annotationElementValue) { - Field[] fields = clazz.getFields(); - - for (int i = 0; i < fields.length; i++) { - Field f = fields[i]; - AnnotationGen[] fieldAnnotations = f.getAnnotations(); - if (f.getName().equals(fieldname)) { - checkAnnotation(fieldAnnotations[0],annotationName,annotationElementName,annotationElementValue); - - } - } - } - - private void checkAnnotation(AnnotationGen a,String name,String elementname,String elementvalue) { - assertTrue("Expected annotation to have name "+name+" but it had name "+a.getTypeName(), - a.getTypeName().equals(name)); - assertTrue("Expected annotation to have one element but it had "+a.getValues().size(),a.getValues().size()==1); - NameValuePair envp = a.getValues().get(0); - assertTrue("Expected element name "+elementname+" but was "+envp.getNameString(), - elementname.equals(envp.getNameString())); - assertTrue("Expected element value "+elementvalue+" but was "+envp.getValue().stringifyValue(), - elementvalue.equals(envp.getValue().stringifyValue())); - } - - - // helper methods - - public void checkValue(AnnotationGen a,String name,String tostring) { - for (Iterator i = a.getValues().iterator(); i.hasNext();) { - NameValuePair element = i.next(); - if (element.getNameString().equals(name)) { - if (!element.getValue().stringifyValue().equals(tostring)) { - fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue()); - } - return; - } - } - fail("Didnt find named element "+name); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/Fundamentals.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/Fundamentals.java deleted file mode 100644 index c54beb5b3..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/Fundamentals.java +++ /dev/null @@ -1,319 +0,0 @@ -package org.aspectj.apache.bcel.classfile.tests; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.generic.FieldInstruction; -import org.aspectj.apache.bcel.generic.IINC; -import org.aspectj.apache.bcel.generic.INVOKEINTERFACE; -import org.aspectj.apache.bcel.generic.Instruction; -import org.aspectj.apache.bcel.generic.InstructionBranch; -import org.aspectj.apache.bcel.generic.InstructionByte; -import org.aspectj.apache.bcel.generic.InstructionCP; -import org.aspectj.apache.bcel.generic.InstructionConstants; -import org.aspectj.apache.bcel.generic.InstructionHandle; -import org.aspectj.apache.bcel.generic.InstructionLV; -import org.aspectj.apache.bcel.generic.InstructionShort; -import org.aspectj.apache.bcel.generic.InvokeInstruction; -import org.aspectj.apache.bcel.generic.LOOKUPSWITCH; -import org.aspectj.apache.bcel.generic.MULTIANEWARRAY; -import org.aspectj.apache.bcel.generic.RET; -import org.aspectj.apache.bcel.generic.TABLESWITCH; - -import junit.framework.TestCase; - -// Check things that have to be true based on the specification -public class Fundamentals extends TestCase { - - // Checking: opcode, length, consumed stack entries, produced stack entries - public void testInstructions() { - - // Instructions 000-009 - checkInstruction(InstructionConstants.NOP,0,1,0,0); - checkInstruction(InstructionConstants.ACONST_NULL,1,1,0,1); - checkInstruction(InstructionConstants.ICONST_M1,2,1,0,1); - checkInstruction(InstructionConstants.ICONST_0,3,1,0,1); - checkInstruction(InstructionConstants.ICONST_1,4,1,0,1); - checkInstruction(InstructionConstants.ICONST_2,5,1,0,1); - checkInstruction(InstructionConstants.ICONST_3,6,1,0,1); - checkInstruction(InstructionConstants.ICONST_4,7,1,0,1); - checkInstruction(InstructionConstants.ICONST_5,8,1,0,1); - checkInstruction(InstructionConstants.LCONST_0,9,1,0,2); - - // Instructions 010-019 - checkInstruction(InstructionConstants.LCONST_1,10,1,0,2); - checkInstruction(InstructionConstants.FCONST_0,11,1,0,1); - checkInstruction(InstructionConstants.FCONST_1,12,1,0,1); - checkInstruction(InstructionConstants.FCONST_2,13,1,0,1); - checkInstruction(InstructionConstants.DCONST_0,14,1,0,2); - checkInstruction(InstructionConstants.DCONST_1,15,1,0,2); - checkInstruction(new InstructionByte(Constants.BIPUSH,b0),16,2,0,1); - checkInstruction(new InstructionShort(Constants.SIPUSH,s0),17,3,0,1); - checkInstruction(new InstructionCP(Constants.LDC,b0),18,2,0,1); - checkInstruction(new InstructionCP(Constants.LDC_W,s0),19,2,0,1); - - // Instructions 020-029 - checkInstruction(new InstructionCP(Constants.LDC2_W,s0),20,3,0,2); - checkInstruction(new InstructionLV(Constants.ILOAD,s20),21,2,0,1); - checkInstruction(new InstructionLV(Constants.LLOAD,s20),22,2,0,2); - checkInstruction(new InstructionLV(Constants.FLOAD,s20),23,2,0,1); - checkInstruction(new InstructionLV(Constants.DLOAD,s20),24,2,0,2); - checkInstruction(new InstructionLV(Constants.ALOAD,s20),25,2,0,1); - checkInstruction(InstructionConstants.ILOAD_0,26,1,0,1); - checkInstruction(InstructionConstants.ILOAD_1,27,1,0,1); - checkInstruction(InstructionConstants.ILOAD_2,28,1,0,1); - checkInstruction(InstructionConstants.ILOAD_3,29,1,0,1); - - // Instructions 030-039 - checkInstruction(InstructionConstants.LLOAD_0,30,1,0,2); - checkInstruction(InstructionConstants.LLOAD_1,31,1,0,2); - checkInstruction(InstructionConstants.LLOAD_2,32,1,0,2); - checkInstruction(InstructionConstants.LLOAD_3,33,1,0,2); - checkInstruction(InstructionConstants.FLOAD_0,34,1,0,1); - checkInstruction(InstructionConstants.FLOAD_1,35,1,0,1); - checkInstruction(InstructionConstants.FLOAD_2,36,1,0,1); - checkInstruction(InstructionConstants.FLOAD_3,37,1,0,1); - checkInstruction(InstructionConstants.DLOAD_0,38,1,0,2); - checkInstruction(InstructionConstants.DLOAD_1,39,1,0,2); - - // Instructions 040-049 - checkInstruction(InstructionConstants.DLOAD_2,40,1,0,2); - checkInstruction(InstructionConstants.DLOAD_3,41,1,0,2); - checkInstruction(InstructionConstants.ALOAD_0,42,1,0,1); - checkInstruction(InstructionConstants.ALOAD_1,43,1,0,1); - checkInstruction(InstructionConstants.ALOAD_2,44,1,0,1); - checkInstruction(InstructionConstants.ALOAD_3,45,1,0,1); - checkInstruction(InstructionConstants.IALOAD,46,1,2,1); - checkInstruction(InstructionConstants.LALOAD,47,1,2,2); - checkInstruction(InstructionConstants.FALOAD,48,1,2,1); - checkInstruction(InstructionConstants.DALOAD,49,1,2,2); - - // Instructions 050-059 - checkInstruction(InstructionConstants.AALOAD,50,1,2,1); - checkInstruction(InstructionConstants.BALOAD,51,1,2,1); - checkInstruction(InstructionConstants.CALOAD,52,1,2,1); - checkInstruction(InstructionConstants.SALOAD,53,1,2,1); - checkInstruction(new InstructionLV(Constants.ISTORE,s20),54,2,1,0); - checkInstruction(new InstructionLV(Constants.LSTORE,s20),55,2,2,0); - checkInstruction(new InstructionLV(Constants.FSTORE,s20),56,2,1,0); - checkInstruction(new InstructionLV(Constants.DSTORE,s20),57,2,2,0); - checkInstruction(new InstructionLV(Constants.ASTORE,s20),58,2,1,0); - checkInstruction(InstructionConstants.ISTORE_0,59,1,1,0); - - // Instructions 060-069 - checkInstruction(InstructionConstants.ISTORE_1,60,1,1,0); - checkInstruction(InstructionConstants.ISTORE_2,61,1,1,0); - checkInstruction(InstructionConstants.ISTORE_3,62,1,1,0); - checkInstruction(InstructionConstants.LSTORE_0,63,1,2,0); - checkInstruction(InstructionConstants.LSTORE_1,64,1,2,0); - checkInstruction(InstructionConstants.LSTORE_2,65,1,2,0); - checkInstruction(InstructionConstants.LSTORE_3,66,1,2,0); - checkInstruction(InstructionConstants.FSTORE_0,67,1,1,0); - checkInstruction(InstructionConstants.FSTORE_1,68,1,1,0); - checkInstruction(InstructionConstants.FSTORE_2,69,1,1,0); - - // Instructions 070-079 - checkInstruction(InstructionConstants.FSTORE_3,70,1,1,0); - checkInstruction(InstructionConstants.DSTORE_0,71,1,2,0); - checkInstruction(InstructionConstants.DSTORE_1,72,1,2,0); - checkInstruction(InstructionConstants.DSTORE_2,73,1,2,0); - checkInstruction(InstructionConstants.DSTORE_3,74,1,2,0); - checkInstruction(InstructionConstants.ASTORE_0,75,1,1,0); - checkInstruction(InstructionConstants.ASTORE_1,76,1,1,0); - checkInstruction(InstructionConstants.ASTORE_2,77,1,1,0); - checkInstruction(InstructionConstants.ASTORE_3,78,1,1,0); - checkInstruction(InstructionConstants.IASTORE,79,1,3,0); - - // Instructions 080-089 - checkInstruction(InstructionConstants.LASTORE,80,1,4,0); - checkInstruction(InstructionConstants.FASTORE,81,1,3,0); - checkInstruction(InstructionConstants.DASTORE,82,1,4,0); - checkInstruction(InstructionConstants.AASTORE,83,1,3,0); - checkInstruction(InstructionConstants.BASTORE,84,1,3,0); - checkInstruction(InstructionConstants.CASTORE,85,1,3,0); - checkInstruction(InstructionConstants.SASTORE,86,1,3,0); - checkInstruction(InstructionConstants.POP,87,1,1,0); - checkInstruction(InstructionConstants.POP2,88,1,2,0); - checkInstruction(InstructionConstants.DUP,89,1,1,2); - - // Instructions 090-099 - checkInstruction(InstructionConstants.DUP_X1,90,1,2,3); - checkInstruction(InstructionConstants.DUP_X2,91,1,3,4); - checkInstruction(InstructionConstants.DUP2,92,1,2,4); - checkInstruction(InstructionConstants.DUP2_X1,93,1,3,5); - checkInstruction(InstructionConstants.DUP2_X2,94,1,4,6); - checkInstruction(InstructionConstants.SWAP,95,1,2,2); - checkInstruction(InstructionConstants.IADD,96,1,2,1); - checkInstruction(InstructionConstants.LADD,97,1,4,2); - checkInstruction(InstructionConstants.FADD,98,1,2,1); - checkInstruction(InstructionConstants.DADD,99,1,4,2); - - // Instructions 100-109 - checkInstruction(InstructionConstants.ISUB,100,1,2,1); - checkInstruction(InstructionConstants.LSUB,101,1,4,2); - checkInstruction(InstructionConstants.FSUB,102,1,2,1); - checkInstruction(InstructionConstants.DSUB,103,1,4,2); - checkInstruction(InstructionConstants.IMUL,104,1,2,1); - checkInstruction(InstructionConstants.LMUL,105,1,4,2); - checkInstruction(InstructionConstants.FMUL,106,1,2,1); - checkInstruction(InstructionConstants.DMUL,107,1,4,2); - checkInstruction(InstructionConstants.IDIV,108,1,2,1); - checkInstruction(InstructionConstants.LDIV,109,1,4,2); - - // Instructions 110-119 - checkInstruction(InstructionConstants.FDIV,110,1,2,1); - checkInstruction(InstructionConstants.DDIV,111,1,4,2); - checkInstruction(InstructionConstants.IREM,112,1,2,1); - checkInstruction(InstructionConstants.LREM,113,1,4,2); - checkInstruction(InstructionConstants.FREM,114,1,2,1); - checkInstruction(InstructionConstants.DREM,115,1,4,2); - checkInstruction(InstructionConstants.INEG,116,1,1,1); - checkInstruction(InstructionConstants.LNEG,117,1,2,2); - checkInstruction(InstructionConstants.FNEG,118,1,1,1); - checkInstruction(InstructionConstants.DNEG,119,1,2,2); - - // Instructions 120-129 - checkInstruction(InstructionConstants.ISHL,120,1,2,1); - checkInstruction(InstructionConstants.LSHL,121,1,3,2); - checkInstruction(InstructionConstants.ISHR,122,1,2,1); - checkInstruction(InstructionConstants.LSHR,123,1,3,2); - checkInstruction(InstructionConstants.IUSHR,124,1,2,1); - checkInstruction(InstructionConstants.LUSHR,125,1,3,2); - checkInstruction(InstructionConstants.IAND,126,1,2,1); - checkInstruction(InstructionConstants.LAND,127,1,4,2); - checkInstruction(InstructionConstants.IOR,128,1,2,1); - checkInstruction(InstructionConstants.LOR,129,1,4,2); - - // Instructions 130-139 - checkInstruction(InstructionConstants.IXOR,130,1,2,1); - checkInstruction(InstructionConstants.LXOR,131,1,4,2); - checkInstruction(new IINC(0,0,false),132,3,0,0); - checkInstruction(InstructionConstants.I2L,133,1,1,2); - checkInstruction(InstructionConstants.I2F,134,1,1,1); - checkInstruction(InstructionConstants.I2D,135,1,1,2); - checkInstruction(InstructionConstants.L2I,136,1,2,1); - checkInstruction(InstructionConstants.L2F,137,1,2,1); - checkInstruction(InstructionConstants.L2D,138,1,2,2); - checkInstruction(InstructionConstants.F2I,139,1,1,1); - - // Instructions 140-149 - checkInstruction(InstructionConstants.F2L,140,1,1,2); - checkInstruction(InstructionConstants.F2D,141,1,1,2); - checkInstruction(InstructionConstants.D2I,142,1,2,1); - checkInstruction(InstructionConstants.D2L,143,1,2,2); - checkInstruction(InstructionConstants.D2F,144,1,2,1); - checkInstruction(InstructionConstants.I2B,145,1,1,1); - checkInstruction(InstructionConstants.I2C,146,1,1,1); - checkInstruction(InstructionConstants.I2S,147,1,1,1); - checkInstruction(InstructionConstants.LCMP,148,1,4,1); - checkInstruction(InstructionConstants.FCMPL,149,1,2,1); - - // Instructions 150-159 - checkInstruction(InstructionConstants.FCMPG,150,1,2,1); - checkInstruction(InstructionConstants.DCMPL,151,1,4,1); - checkInstruction(InstructionConstants.DCMPG,152,1,4,1); - checkInstruction(new InstructionBranch(Constants.IFEQ,s0),153,3,1,0); - checkInstruction(new InstructionBranch(Constants.IFNE,s0),154,3,1,0); - checkInstruction(new InstructionBranch(Constants.IFLT,s0),155,3,1,0); - checkInstruction(new InstructionBranch(Constants.IFGE,s0),156,3,1,0); - checkInstruction(new InstructionBranch(Constants.IFGT,s0),157,3,1,0); - checkInstruction(new InstructionBranch(Constants.IFLE,s0),158,3,1,0); - checkInstruction(new InstructionBranch(Constants.IF_ICMPEQ,s0),159,3,2,0); - - // Instructions 160-169 - checkInstruction(new InstructionBranch(Constants.IF_ICMPNE,s0),160,3,2,0); - checkInstruction(new InstructionBranch(Constants.IF_ICMPLT,s0),161,3,2,0); - checkInstruction(new InstructionBranch(Constants.IF_ICMPGE,s0),162,3,2,0); - checkInstruction(new InstructionBranch(Constants.IF_ICMPGT,s0),163,3,2,0); - checkInstruction(new InstructionBranch(Constants.IF_ICMPLE,s0),164,3,2,0); - checkInstruction(new InstructionBranch(Constants.IF_ACMPEQ,s0),165,3,2,0); - checkInstruction(new InstructionBranch(Constants.IF_ACMPNE,s0),166,3,2,0); - checkInstruction(new InstructionBranch(Constants.GOTO,s0),167,3,0,0); - checkInstruction(new InstructionBranch(Constants.JSR,s0),168,3,0,1); - checkInstruction(new RET(0,false),169,2,0,0); - - // Instructions 170-179 - checkInstruction(new TABLESWITCH(new int[]{},new InstructionHandle[]{},null),170,VARIES,1,0); - checkInstruction(new LOOKUPSWITCH(new int[]{},new InstructionHandle[]{},null),171,VARIES,1,0); - checkInstruction(InstructionConstants.IRETURN,172,1,1,0); - checkInstruction(InstructionConstants.LRETURN,173,1,2,0); - checkInstruction(InstructionConstants.FRETURN,174,1,1,0); - checkInstruction(InstructionConstants.DRETURN,175,1,2,0); - checkInstruction(InstructionConstants.ARETURN,176,1,1,0); - checkInstruction(InstructionConstants.RETURN,177,1,0,0); - checkInstruction(new FieldInstruction(Constants.GETSTATIC,0),178,3,0,VARIES); - checkInstruction(new FieldInstruction(Constants.PUTSTATIC,0),179,3,VARIES,0); - - // Instructions 180-189 - checkInstruction(new FieldInstruction(Constants.GETFIELD,0),180,3,1,VARIES); - checkInstruction(new FieldInstruction(Constants.PUTFIELD,0),181,3,VARIES,0); - checkInstruction(new InvokeInstruction(Constants.INVOKEVIRTUAL,0),182,3,VARIES,VARIES); // PRODUCE STACK VARIES OK HERE? (AND NEXT COUPLE) - checkInstruction(new InvokeInstruction(Constants.INVOKESPECIAL,0),183,3,VARIES,VARIES); - checkInstruction(new InvokeInstruction(Constants.INVOKESTATIC,0),184,3,VARIES,VARIES); - checkInstruction(new INVOKEINTERFACE(0,1,0),185,5,VARIES,VARIES); - // 186 does not exist - checkInstruction(new InstructionCP(Constants.NEW,b0),187,3,0,1); - checkInstruction(new InstructionByte(Constants.NEWARRAY,b0),188,2,1,1); - checkInstruction(new InstructionCP(Constants.ANEWARRAY,0),189,3,1,1); - - // Instructions 190-199 - checkInstruction(InstructionConstants.ARRAYLENGTH,190,1,1,1); - checkInstruction(InstructionConstants.ATHROW,191,1,1,1); - checkInstruction(new InstructionCP(Constants.CHECKCAST,s0),192,3,1,1); - checkInstruction(new InstructionCP(Constants.INSTANCEOF,s0),193,3,1,1); - checkInstruction(InstructionConstants.MONITORENTER,194,1,1,0); - checkInstruction(InstructionConstants.MONITOREXIT,195,1,1,0); - // 196 is 'wide' tag - checkInstruction(new MULTIANEWARRAY(s0,b0),197,4,VARIES,1); - checkInstruction(new InstructionBranch(Constants.IFNULL,s0),198,3,1,0); - checkInstruction(new InstructionBranch(Constants.IFNONNULL,s0),199,3,1,0); - - // Instructions 200-209 - checkInstruction(new InstructionBranch(Constants.GOTO_W,0),200,5,0,0); - checkInstruction(new InstructionBranch(Constants.JSR_W,0),201,5,0,1); - - // Internally used instructions skipped - } - - public void checkInstruction(Instruction i,int opcode, int length, int stackConsumed, int stackProduced) { - String header = new String("Checking instruction '"+i+"' "); - if (i.opcode!=opcode) - fail(header+" expected opcode "+opcode+" but it is "+i.opcode); - - if (length!=VARIES && i.getLength()!=length) - fail(header+" expected length "+length+" but it is "+i.getLength()); -// if (stackConsumed>0) { -// if ((Constants.instFlags[opcode]&Constants.STACK_CONSUMER)==0) -// fail(header+" expected it to be a STACK_CONSUMER but it is not"); -// } else { -// if ((Constants.instFlags[opcode]&Constants.STACK_CONSUMER)!=0) -// fail(header+" expected it not to be a STACK_CONSUMER but it is"); -// } - if (stackConsumed==VARIES) { - if (Constants.CONSUME_STACK[opcode]!=Constants.UNPREDICTABLE) - fail("Instruction '"+i+"' should be consuming some unpredictable number of stack entries but it says it will consume "+Constants.CONSUME_STACK[opcode]); - - } else { - if (Constants.CONSUME_STACK[opcode]!=stackConsumed) - fail("Instruction '"+i+"' should be consuming "+stackConsumed+" stack entries but it says it will consume "+Constants.CONSUME_STACK[opcode]); - } -// if (stackProduced>0) { -// if ((Constants.instFlags[opcode]&Constants.STACK_PRODUCER)==0) -// fail(header+" expected it to be a STACK_PRODUCER but it is not"); -// } else { -// if ((Constants.instFlags[opcode]&Constants.STACK_PRODUCER)!=0) -// fail(header+" expected it not to be a STACK_PRODUCER but it is"); -// } - if (stackProduced==VARIES) { - if (Constants.stackEntriesProduced[opcode]!=Constants.UNPREDICTABLE) - fail(header+" should be producing some unpredictable number of stack entries but it says it will produce "+Constants.stackEntriesProduced[opcode]); - - } else { - if (Constants.stackEntriesProduced[opcode]!=stackProduced) - fail(header+" should be producing "+stackProduced+" stack entries but it says it will produce "+Constants.stackEntriesProduced[opcode]); - } - } - - private final static byte b0 = 0; - private final static short s0 = 0; - private final static short s20 = 20; - private final static int VARIES = -1; -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GeneratingAnnotatedClassesTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GeneratingAnnotatedClassesTest.java deleted file mode 100644 index 94e40d491..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GeneratingAnnotatedClassesTest.java +++ /dev/null @@ -1,572 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying - * materials are made available under the terms of the Eclipse Public License - * v1.0 which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: Andy Clement - initial implementation - ******************************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.apache.bcel.Constants; -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.classfile.annotation.AnnotationElementValue; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.classfile.annotation.ElementValue; -import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; -import org.aspectj.apache.bcel.generic.ArrayType; -import org.aspectj.apache.bcel.generic.ClassGen; -import org.aspectj.apache.bcel.generic.InstructionBranch; -import org.aspectj.apache.bcel.generic.InstructionConstants; -import org.aspectj.apache.bcel.generic.InstructionFactory; -import org.aspectj.apache.bcel.generic.InstructionHandle; -import org.aspectj.apache.bcel.generic.InstructionList; -import org.aspectj.apache.bcel.generic.LocalVariableGen; -import org.aspectj.apache.bcel.generic.MethodGen; -import org.aspectj.apache.bcel.generic.ObjectType; -import org.aspectj.apache.bcel.generic.Type; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -/** - * The program that some of the tests generate looks like this: public class HelloWorld { public static void main(String[] argv) { - * BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String name = null; try { name = "Andy"; } - * catch(IOException e) { return; } System.out.println("Hello, " + name); } } - * - */ -public class GeneratingAnnotatedClassesTest extends BcelTestCase { - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - /* - * Steps in the test: 1) Programmatically construct the HelloWorld program 2) Add two simple annotations at the class level 3) - * Save the class to disk 4) Reload the class using the 'static' variant of the BCEL classes 5) Check the attributes are OK - */ - public void testGenerateClassLevelAnnotations() throws ClassNotFoundException { - - // Create HelloWorld - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - InstructionList il = new InstructionList(); - - cg.addAnnotation(createSimpleVisibleAnnotation(cp)); - cg.addAnnotation(createSimpleInvisibleAnnotation(cp)); - - buildClassContents(cg, cp, il); - - dumpClass(cg, "HelloWorld.class"); - - JavaClass jc = getClassFrom(".", "HelloWorld"); - - AnnotationGen[] as = jc.getAnnotations(); - assertTrue("Should be two annotations but found " + as.length, as.length == 2); - AnnotationGen one = as[0]; - AnnotationGen two = as[1]; - assertTrue("Name of annotation 1 should be SimpleAnnotation but it is " + as[0].getTypeName(), as[0].getTypeName().equals( - "SimpleAnnotation")); - assertTrue("Name of annotation 2 should be SimpleAnnotation but it is " + as[1].getTypeName(), as[1].getTypeName().equals( - "SimpleAnnotation")); - List vals = as[0].getValues(); - NameValuePair nvp = vals.get(0); - assertTrue("Name of element in SimpleAnnotation should be 'id' but it is " + nvp.getNameString(), nvp.getNameString() - .equals("id")); - ElementValue ev = nvp.getValue(); - assertTrue("Type of element value should be int but it is " + ev.getElementValueType(), - ev.getElementValueType() == ElementValue.PRIMITIVE_INT); - assertTrue("Value of element should be 4 but it is " + ev.stringifyValue(), ev.stringifyValue().equals("4")); - assertTrue(createTestdataFile("HelloWorld.class").delete()); - } - - /** - * Just check that we can dump a class that has a method annotation on it and it is still there when we read it back in - */ - public void testGenerateMethodLevelAnnotations1() throws ClassNotFoundException { - // Create HelloWorld - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - InstructionList il = new InstructionList(); - - buildClassContentsWithAnnotatedMethods(cg, cp, il); - - // Check annotation is OK - int i = cg.getMethods()[0].getAnnotations().length; - assertTrue("Prior to dumping, main method should have 1 annotation but has " + i, i == 1); - - dumpClass(cg, "temp1" + File.separator + "HelloWorld.class"); - - JavaClass jc2 = getClassFrom("temp1", "HelloWorld"); - - // Check annotation is OK - i = jc2.getMethods()[0].getAnnotations().length; - assertTrue("JavaClass should say 1 annotation on main method but says " + i, i == 1); - - ClassGen cg2 = new ClassGen(jc2); - - // Check it now it is a ClassGen - Method[] m = cg2.getMethods(); - i = m[0].getAnnotations().length; - assertTrue("The main 'Method' should have one annotation but has " + i, i == 1); - MethodGen mg = new MethodGen(m[0], cg2.getClassName(), cg2.getConstantPool()); - - // Check it finally when the Method is changed to a MethodGen - i = mg.getAnnotations().size(); - assertTrue("The main 'MethodGen' should have one annotation but has " + i, i == 1); - - assertTrue(wipe("temp1" + File.separator + "HelloWorld.class")); - - } - - /** - * Going further than the last test - when we reload the method back in, let's change it (adding a new annotation) and then - * store that, read it back in and verify both annotations are there ! - */ - public void testGenerateMethodLevelAnnotations2() throws ClassNotFoundException { - // Create HelloWorld - ClassGen cg = createClassGen("HelloWorld"); - ConstantPool cp = cg.getConstantPool(); - InstructionList il = new InstructionList(); - - buildClassContentsWithAnnotatedMethods(cg, cp, il); - - dumpClass(cg, "temp2", "HelloWorld.class"); - - JavaClass jc2 = getClassFrom("temp2", "HelloWorld"); - - ClassGen cg2 = new ClassGen(jc2); - - // Main method after reading the class back in - Method mainMethod1 = jc2.getMethods()[0]; - assertTrue("The 'Method' should have one annotations but has " + mainMethod1.getAnnotations().length, mainMethod1 - .getAnnotations().length == 1); - - MethodGen mainMethod2 = new MethodGen(mainMethod1, cg2.getClassName(), cg2.getConstantPool()); - - assertTrue("The 'MethodGen' should have one annotations but has " + mainMethod2.getAnnotations().size(), mainMethod2 - .getAnnotations().size() == 1); - - mainMethod2.addAnnotation(createFruitAnnotation(cg2.getConstantPool(), "Pear")); - - cg2.removeMethod(mainMethod1); - cg2.addMethod(mainMethod2.getMethod()); - - dumpClass(cg2, "temp3", "HelloWorld.class"); - - JavaClass jc3 = getClassFrom("temp3", "HelloWorld"); - - ClassGen cg3 = new ClassGen(jc3); - - Method mainMethod3 = cg3.getMethods()[1]; - int i = mainMethod3.getAnnotations().length; - assertTrue("The 'Method' should now have two annotations but has " + i, i == 2); - - assertTrue(wipe("temp2", "HelloWorld.class")); - assertTrue(wipe("temp3", "HelloWorld.class")); - } - - // J5TODO: Need to add deleteFile calls to many of these tests - - /** - * Transform simple class from an immutable to a mutable object. - */ - public void testTransformClassToClassGen_SimpleTypes() throws ClassNotFoundException { - JavaClass jc = getClassFrom("testcode.jar", "SimpleAnnotatedClass"); - ClassGen cgen = new ClassGen(jc); - - // Check annotations are correctly preserved - AnnotationGen[] annotations = cgen.getAnnotations(); - assertTrue("Expected one annotation but found " + annotations.length, annotations.length == 1); - } - - /** - * Transform simple class from an immutable to a mutable object. The class is annotated with an annotation that uses an enum. - */ - public void testTransformClassToClassGen_EnumType() throws ClassNotFoundException { - JavaClass jc = getClassFrom("testcode.jar", "AnnotatedWithEnumClass"); - ClassGen cgen = new ClassGen(jc); - - // Check annotations are correctly preserved - AnnotationGen[] annotations = cgen.getAnnotations(); - assertTrue("Expected one annotation but found " + annotations.length, annotations.length == 1); - } - - /** - * Transform simple class from an immutable to a mutable object. The class is annotated with an annotation that uses an array of - * SimpleAnnotations. - */ - public void testTransformClassToClassGen_ArrayAndAnnotationTypes() throws ClassNotFoundException { - JavaClass jc = getClassFrom("testcode.jar", "AnnotatedWithCombinedAnnotation"); - ClassGen cgen = new ClassGen(jc); - - // Check annotations are correctly preserved - AnnotationGen[] annotations = cgen.getAnnotations(); - assertTrue("Expected one annotation but found " + annotations.length, annotations.length == 1); - AnnotationGen a = annotations[0]; - assertTrue("That annotation should only have one value but has " + a.getValues().size(), a.getValues().size() == 1); - NameValuePair nvp = a.getValues().get(0); - ElementValue value = nvp.getValue(); - assertTrue("Value should be ArrayElementValueGen but is " + value, value instanceof ArrayElementValue); - ArrayElementValue arrayValue = (ArrayElementValue) value; - assertTrue("Array value should be size one but is " + arrayValue.getElementValuesArraySize(), arrayValue - .getElementValuesArraySize() == 1); - ElementValue innerValue = arrayValue.getElementValuesArray()[0]; - assertTrue("Value in the array should be AnnotationElementValueGen but is " + innerValue, - innerValue instanceof AnnotationElementValue); - AnnotationElementValue innerAnnotationValue = (AnnotationElementValue) innerValue; - assertTrue("Should be called LSimpleAnnotation; but is called: " + innerAnnotationValue.getAnnotation().getTypeName(), - innerAnnotationValue.getAnnotation().getTypeSignature().equals("LSimpleAnnotation;")); - } - - /** - * Transform complex class from an immutable to a mutable object. - */ - public void testTransformComplexClassToClassGen() throws ClassNotFoundException { - JavaClass jc = getClassFrom("testcode.jar", "ComplexAnnotatedClass"); - ClassGen cgen = new ClassGen(jc); - - // Check annotations are correctly preserved - AnnotationGen[] annotations = cgen.getAnnotations(); - assertTrue("Expected one annotation but found " + annotations.length, annotations.length == 1); - List l = annotations[0].getValues(); - boolean found = false; - for (Iterator iter = l.iterator(); iter.hasNext();) { - NameValuePair element = iter.next(); - if (element.getNameString().equals("dval")) { - if (((SimpleElementValue) element.getValue()).stringifyValue().equals("33.4")) - found = true; - } - } - assertTrue("Did not find double annotation value with value 33.4", found); - } - - /** - * Load a class in and modify it with a new attribute - A SimpleAnnotation annotation - */ - public void testModifyingClasses1() throws ClassNotFoundException { - JavaClass jc = getClassFrom("testcode.jar", "SimpleAnnotatedClass"); - ClassGen cgen = new ClassGen(jc); - ConstantPool cp = cgen.getConstantPool(); - cgen.addAnnotation(createFruitAnnotation(cp, "Pineapple")); - assertTrue("Should now have two annotations but has " + cgen.getAnnotations().length, cgen.getAnnotations().length == 2); - dumpClass(cgen, "SimpleAnnotatedClass.class"); - assertTrue(wipe("SimpleAnnotatedClass.class")); - } - - /** - * Load a class in and modify it with a new attribute - A ComplexAnnotation annotation - */ - public void testModifyingClasses2() throws ClassNotFoundException { - JavaClass jc = getClassFrom("testcode.jar", "SimpleAnnotatedClass"); - ClassGen cgen = new ClassGen(jc); - ConstantPool cp = cgen.getConstantPool(); - cgen.addAnnotation(createCombinedAnnotation(cp)); - assertTrue("Should now have two annotations but has " + cgen.getAnnotations().length, cgen.getAnnotations().length == 2); - dumpClass(cgen, "SimpleAnnotatedClass.class"); - JavaClass jc2 = getClassFrom(".", "SimpleAnnotatedClass"); - jc2.getAnnotations(); - assertTrue(wipe("SimpleAnnotatedClass.class")); - // System.err.println(jc2.toString()); - } - - private void dumpClass(ClassGen cg, String fname) { - try { - File f = createTestdataFile(fname); - cg.getJavaClass().dump(f); - } catch (java.io.IOException e) { - System.err.println(e); - } - } - - private void dumpClass(ClassGen cg, String dir, String fname) { - dumpClass(cg, dir + File.separator + fname); - } - - private void buildClassContentsWithAnnotatedMethods(ClassGen cg, ConstantPool cp, InstructionList il) { - // Create method 'public static void main(String[]argv)' - MethodGen mg = createMethodGen("main", il, cp); - InstructionFactory factory = new InstructionFactory(cg); - mg.addAnnotation(createSimpleVisibleAnnotation(mg.getConstantPool())); - // We now define some often used types: - - ObjectType i_stream = new ObjectType("java.io.InputStream"); - ObjectType p_stream = new ObjectType("java.io.PrintStream"); - - // Create variables in and name : We call the constructors, i.e., - // execute BufferedReader(InputStreamReader(System.in)) . The reference - // to the BufferedReader object stays on top of the stack and is stored - // in the newly allocated in variable. - - il.append(factory.createNew("java.io.BufferedReader")); - il.append(InstructionConstants.DUP); // Use predefined constant - il.append(factory.createNew("java.io.InputStreamReader")); - il.append(InstructionConstants.DUP); - il.append(factory.createFieldAccess("java.lang.System", "in", i_stream, Constants.GETSTATIC)); - il.append(factory.createInvoke("java.io.InputStreamReader", "", Type.VOID, new Type[] { i_stream }, - Constants.INVOKESPECIAL)); - il.append(factory.createInvoke("java.io.BufferedReader", "", Type.VOID, - new Type[] { new ObjectType("java.io.Reader") }, Constants.INVOKESPECIAL)); - - LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null); - int in = lg.getIndex(); - lg.setStart(il.append(InstructionFactory.createASTORE(in))); // "in" valid from here - - // Create local variable name and initialize it to null - - lg = mg.addLocalVariable("name", Type.STRING, null, null); - int name = lg.getIndex(); - il.append(InstructionConstants.ACONST_NULL); - lg.setStart(il.append(InstructionFactory.createASTORE(name))); // "name" valid from here - - // Create try-catch block: We remember the start of the block, read a - // line from the standard input and store it into the variable name . - - // InstructionHandle try_start = il.append(factory.createFieldAccess( - // "java.lang.System", "out", p_stream, Constants.GETSTATIC)); - - // il.append(new PUSH(cp, "Please enter your name> ")); - // il.append(factory.createInvoke("java.io.PrintStream", "print", - // Type.VOID, new Type[] { Type.STRING }, - // Constants.INVOKEVIRTUAL)); - // il.append(new ALOAD(in)); - // il.append(factory.createInvoke("java.io.BufferedReader", "readLine", - // Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - InstructionHandle try_start = il.append(InstructionFactory.PUSH(cp, "Andy")); - il.append(InstructionFactory.createASTORE(name)); - - // Upon normal execution we jump behind exception handler, the target - // address is not known yet. - - InstructionBranch g = new InstructionBranch(Constants.GOTO); - InstructionHandle try_end = il.append(g); - - // We add the exception handler which simply returns from the method. - - LocalVariableGen var_ex = mg.addLocalVariable("ex", Type.getType("Ljava.io.IOException;"), null, null); - int var_ex_slot = var_ex.getIndex(); - - InstructionHandle handler = il.append(InstructionFactory.createASTORE(var_ex_slot)); - var_ex.setStart(handler); - var_ex.setEnd(il.append(InstructionConstants.RETURN)); - - mg.addExceptionHandler(try_start, try_end, handler, new ObjectType("java.io.IOException")); - - // "Normal" code continues, now we can set the branch target of the GOTO - // . - - InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC)); - g.setTarget(ih); - - // Printing "Hello": String concatenation compiles to StringBuffer - // operations. - - il.append(factory.createNew(Type.STRINGBUFFER)); - il.append(InstructionConstants.DUP); - il.append(InstructionFactory.PUSH(cp, "Hello, ")); - il.append(factory.createInvoke("java.lang.StringBuffer", "", Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKESPECIAL)); - il.append(InstructionFactory.createALOAD(name)); - il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - - il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(InstructionConstants.RETURN); - - // Finalization: Finally, we have to set the stack size, which normally - // would have to be computed on the fly and add a default constructor - // method to the class, which is empty in this case. - - mg.setMaxStack(); - mg.setMaxLocals(); - cg.addMethod(mg.getMethod()); - il.dispose(); // Allow instruction handles to be reused - cg.addEmptyConstructor(Constants.ACC_PUBLIC); - } - - private void buildClassContents(ClassGen cg, ConstantPool cp, InstructionList il) { - // Create method 'public static void main(String[]argv)' - MethodGen mg = createMethodGen("main", il, cp); - InstructionFactory factory = new InstructionFactory(cg); - // We now define some often used types: - - ObjectType i_stream = new ObjectType("java.io.InputStream"); - ObjectType p_stream = new ObjectType("java.io.PrintStream"); - - // Create variables in and name : We call the constructors, i.e., - // execute BufferedReader(InputStreamReader(System.in)) . The reference - // to the BufferedReader object stays on top of the stack and is stored - // in the newly allocated in variable. - - il.append(factory.createNew("java.io.BufferedReader")); - il.append(InstructionConstants.DUP); // Use predefined constant - il.append(factory.createNew("java.io.InputStreamReader")); - il.append(InstructionConstants.DUP); - il.append(factory.createFieldAccess("java.lang.System", "in", i_stream, Constants.GETSTATIC)); - il.append(factory.createInvoke("java.io.InputStreamReader", "", Type.VOID, new Type[] { i_stream }, - Constants.INVOKESPECIAL)); - il.append(factory.createInvoke("java.io.BufferedReader", "", Type.VOID, - new Type[] { new ObjectType("java.io.Reader") }, Constants.INVOKESPECIAL)); - - LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null); - int in = lg.getIndex(); - lg.setStart(il.append(InstructionFactory.createASTORE(in))); // "in" valid from here - - // Create local variable name and initialize it to null - - lg = mg.addLocalVariable("name", Type.STRING, null, null); - int name = lg.getIndex(); - il.append(InstructionConstants.ACONST_NULL); - lg.setStart(il.append(InstructionFactory.createASTORE(name))); // "name" valid from here - - // Create try-catch block: We remember the start of the block, read a - // line from the standard input and store it into the variable name . - - // InstructionHandle try_start = il.append(factory.createFieldAccess( - // "java.lang.System", "out", p_stream, Constants.GETSTATIC)); - - // il.append(new PUSH(cp, "Please enter your name> ")); - // il.append(factory.createInvoke("java.io.PrintStream", "print", - // Type.VOID, new Type[] { Type.STRING }, - // Constants.INVOKEVIRTUAL)); - // il.append(new ALOAD(in)); - // il.append(factory.createInvoke("java.io.BufferedReader", "readLine", - // Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - InstructionHandle try_start = il.append(InstructionFactory.PUSH(cp, "Andy")); - il.append(InstructionFactory.createASTORE(name)); - - // Upon normal execution we jump behind exception handler, the target - // address is not known yet. - - InstructionBranch g = new InstructionBranch(Constants.GOTO); - InstructionHandle try_end = il.append(g); - - // We add the exception handler which simply returns from the method. - - LocalVariableGen var_ex = mg.addLocalVariable("ex", Type.getType("Ljava.io.IOException;"), null, null); - int var_ex_slot = var_ex.getIndex(); - - InstructionHandle handler = il.append(InstructionFactory.createASTORE(var_ex_slot)); - var_ex.setStart(handler); - var_ex.setEnd(il.append(InstructionConstants.RETURN)); - - mg.addExceptionHandler(try_start, try_end, handler, new ObjectType("java.io.IOException")); - - // "Normal" code continues, now we can set the branch target of the GOTO - // . - - InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC)); - g.setTarget(ih); - - // Printing "Hello": String concatenation compiles to StringBuffer - // operations. - - il.append(factory.createNew(Type.STRINGBUFFER)); - il.append(InstructionConstants.DUP); - il.append(InstructionFactory.PUSH(cp, "Hello, ")); - il.append(factory.createInvoke("java.lang.StringBuffer", "", Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKESPECIAL)); - il.append(InstructionFactory.createALOAD(name)); - il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - - il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(InstructionConstants.RETURN); - - // Finalization: Finally, we have to set the stack size, which normally - // would have to be computed on the fly and add a default constructor - // method to the class, which is empty in this case. - - mg.setMaxStack(); - mg.setMaxLocals(); - cg.addMethod(mg.getMethod()); - il.dispose(); // Allow instruction handles to be reused - cg.addEmptyConstructor(Constants.ACC_PUBLIC); - } - - private JavaClass getClassFrom(String where, String clazzname) throws ClassNotFoundException { - SyntheticRepository repos = createRepos(where); - return repos.loadClass(clazzname); - } - - // helper methods - - private ClassGen createClassGen(String classname) { - return new ClassGen(classname, "java.lang.Object", "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); - } - - private MethodGen createMethodGen(String methodname, InstructionList il, ConstantPool cp) { - return new MethodGen(Constants.ACC_STATIC | Constants.ACC_PUBLIC, // access flags - Type.VOID, // return type - new Type[] { new ArrayType(Type.STRING, 1) }, // argument types - new String[] { "argv" }, // arg names - methodname, "HelloWorld", // method, class - il, cp); - } - - public AnnotationGen createSimpleVisibleAnnotation(ConstantPool cp) { - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 4); - - NameValuePair nvGen = new NameValuePair("id", evg, cp); - - ObjectType t = new ObjectType("SimpleAnnotation"); - - List elements = new ArrayList(); - elements.add(nvGen); - - AnnotationGen a = new AnnotationGen(t, elements, true, cp); - return a; - } - - public AnnotationGen createFruitAnnotation(ConstantPool cp, String aFruit) { - SimpleElementValue evg = new SimpleElementValue(ElementValue.STRING, cp, aFruit); - NameValuePair nvGen = new NameValuePair("fruit", evg, cp); - ObjectType t = new ObjectType("SimpleStringAnnotation"); - List elements = new ArrayList(); - elements.add(nvGen); - return new AnnotationGen(t, elements, true, cp); - } - - public AnnotationGen createCombinedAnnotation(ConstantPool cp) { - // Create an annotation instance - AnnotationGen a = createSimpleVisibleAnnotation(cp); - ArrayElementValue array = new ArrayElementValue(cp); - array.addElement(new AnnotationElementValue(a, cp)); - NameValuePair nvp = new NameValuePair("value", array, cp); - List elements = new ArrayList(); - elements.add(nvp); - return new AnnotationGen(new ObjectType("CombinedAnnotation"), elements, true, cp); - } - - public AnnotationGen createSimpleInvisibleAnnotation(ConstantPool cp) { - SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 4); - - NameValuePair nvGen = new NameValuePair("id", evg, cp); - - ObjectType t = new ObjectType("SimpleAnnotation"); - - List elements = new ArrayList(); - elements.add(nvGen); - - AnnotationGen a = new AnnotationGen(t, elements, false, cp); - return a; - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - -} \ No newline at end of file diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java deleted file mode 100644 index f64e4440f..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java +++ /dev/null @@ -1,472 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement (IBM) initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.tests; - -import java.util.ArrayList; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ClassFormatException; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.Signature; -import org.aspectj.apache.bcel.classfile.Utility; - -/** - * Generics introduces more complex signature possibilities, they are no longer just - * made up of primitives or big 'L' types. The addition of 'anglies' due to - * parameterization and the ability to specify wildcards (possibly bounded) - * when talking about parameterized types means we need to be much more sophisticated. - * - * - * Notes: - * Signatures are used to encode Java programming language type informaiton - * that is not part of the JVM type system, such as generic type and method - * declarations and parameterized types. This kind of information is - * needed to support reflection and debugging, and by the Java compiler. - * - * ============================================= - * - * ClassTypeSignature = LPackageSpecifier* SimpleClassTypeSignature ClassTypeSignatureSuffix*; - * - * PackageSpecifier = Identifier/PackageSpecifier* - * SimpleClassTypeSignature= Identifier TypeArguments(opt) - * ClassTypeSignatureSuffix= .SimpleClassTypeSignature - * TypeVariableSignature = TIdentifier; - * TypeArguments = - * TypeArgument = WildcardIndiciator(opt) FieldTypeSignature - * * - * WildcardIndicator = + - * - - * ArrayTypeSignature = [TypeSignature - * TypeSignature = [FieldTypeSignature - * [BaseType - * - * - * Examples: - * Ljava/util/List; == java.util.List - * Ljava/util/List; == java.util.List - * Ljava/util/List; == java.util.List - * Ljava/util/List<+Ljava/lang/Number;>; == java.util.List - * Ljava/util/List<-Ljava/lang/Number;>; == java.util.List - * Ljava/util/List<*>; == java.util.List - * Ljava/util/Map<*-Ljava/lang/Number;>; == java.util.Map - * - * ============================================= - * - * ClassSignature = FormalTypeParameters(opt) SuperclassSignature SuperinterfaceSignatures* - * - * optional formal type parameters then a superclass signature then a superinterface signature - * - * FormalTypeParameters = - * FormalTypeParameter = Identifier ClassBound InterfaceBound* - * ClassBound = :FieldTypeSignature(opt) - * InterfaceBound = :FieldTypeSignature - * - * If it exists, a set of formal type parameters are contained in anglies and consist of an identifier a classbound (assumed to be - * object if not specified) and then an optional list of InterfaceBounds - * - * SuperclassSignature = ClassTypeSignature - * SuperinterfaceSignature = ClassTypeSignature - * FieldTypeSignature = ClassTypeSignature - * ArrayTypeSignature - * TypeVariableSignature - * - * - * MethodTypeSignature = FormalTypeParameters(opt) ( TypeSignature* ) ReturnType ThrowsSignature* - * ReturnType = TypeSignature - * VoidDescriptor - * ThrowsSignature = ^ClassTypeSignature - * ^TypeVariableSignature - * - * Examples: - * - * ;> - * - * ClassBound not supplied, Object assumed. Interface bound is Comparable - * - * "T:Ljava/lang/Object;:Ljava/lang/Comparable<-TT;>;","T extends java.lang.Object & java.lang.Comparable" - * - */ -public class GenericSignatureParsingTest extends BcelTestCase { - - - /** - * Throw some generic format signatures at the BCEL signature - * parsing code and see what it does. - */ - public void testParsingGenericSignatures_ClassTypeSignature() { - // trivial - checkClassTypeSignature("Ljava/util/List;","java.util.List"); - - // basics - checkClassTypeSignature("Ljava/util/List;","java.util.List"); - checkClassTypeSignature("Ljava/util/List;","java.util.List"); - - // madness - checkClassTypeSignature("Ljava/util/List<+Ljava/lang/Number;>;","java.util.List"); - checkClassTypeSignature("Ljava/util/List<-Ljava/lang/Number;>;","java.util.List"); - checkClassTypeSignature("Ljava/util/List<*>;", "java.util.List"); - checkClassTypeSignature("Ljava/util/Map<*-Ljava/lang/Number;>;","java.util.Map"); - - // with type params - checkClassTypeSignature("Ljava/util/Collection;","java.util.Collection"); - - // arrays - checkClassTypeSignature("Ljava/util/List<[Ljava/lang/String;>;","java.util.List"); - checkClassTypeSignature("[Ljava/util/List;","java.util.List[]"); - - } - - - public void testMethodTypeToSignature() { - checkMethodTypeToSignature("void",new String[]{"java.lang.String[]","boolean"},"([Ljava/lang/String;Z)V"); - checkMethodTypeToSignature("void",new String[]{"java.util.List"},"(Ljava/util/List;)V"); - } - - public void testMethodSignatureToArgumentTypes() { - checkMethodSignatureArgumentTypes("([Ljava/lang/String;Z)V",new String[]{"java.lang.String[]","boolean"}); -// checkMethodSignatureArgumentTypes("(Ljava/util/List;)V",new String[]{"java.util.List"}); - } - - public void testMethodSignatureReturnType() { - checkMethodSignatureReturnType("([Ljava/lang/String;)Z","boolean"); - } - - public void testLoadingGenerics() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("PossibleGenericsSigs"); - // J5TODO asc fill this bit in... - } - - - // helper methods below - - // These routines call BCEL to determine if it can correctly translate from one form to the other. - private void checkClassTypeSignature(String sig, String expected) { - StringBuffer result = new StringBuffer(); - int p = GenericSignatureParsingTest.readClassTypeSignatureFrom(sig,0,result,false); - assertTrue("Only swallowed "+p+" chars of this sig "+sig+" (len="+sig.length()+")",p==sig.length()); - assertTrue("Expected '"+expected+"' but got '"+result.toString()+"'",result.toString().equals(expected)); - } - - private void checkMethodTypeToSignature(String ret,String[] args,String expected) { - String res = GenericSignatureParsingTest.methodTypeToSignature(ret,args); - if (!res.equals(expected)) { - fail("Should match. Got: "+res+" Expected:"+expected); - } - } - - private void checkMethodSignatureReturnType(String sig,String expected) { - String result = GenericSignatureParsingTest.methodSignatureReturnType(sig,false); - if (!result.equals(expected)) { - fail("Should match. Got: "+result+" Expected:"+expected); - } - } - - private void checkMethodSignatureArgumentTypes(String in,String[] expected) { - String[] result = GenericSignatureParsingTest.methodSignatureArgumentTypes(in,false); - if (result.length!=expected.length) { - fail("Expected "+expected.length+" entries to be returned but only got "+result.length); - } - for (int i = 0; i < expected.length; i++) { - String string = result[i]; - if (!string.equals(expected[i])) - fail("Argument: "+i+" should have been "+expected[i]+" but was "+string); - } - } - - public Signature getSignatureAttribute(JavaClass clazz,String name) { - Method m = getMethod(clazz,name); - Attribute[] as = m.getAttributes(); - for (int i = 0; i < as.length; i++) { - Attribute attribute = as[i]; - if (attribute.getName().equals("Signature")) { - return (Signature)attribute; - } - } - return null; - } - - - /** - * Takes a string and consumes a single complete signature from it, returning - * how many chars it consumed. The chopit flag indicates whether to shorten - * type references ( java/lang/String => String ) - * - * FIXME asc this should also create some kind of object you can query for information about whether its parameterized, what the bounds are, etc... - */ - public static final int readClassTypeSignatureFrom(String signature, int posn, StringBuffer result, boolean chopit) { - int idx = posn; - try { - switch (signature.charAt(idx)) { - case 'B' : result.append("byte"); return 1; - case 'C' : result.append("char"); return 1; - case 'D' : result.append("double"); return 1; - case 'F' : result.append("float"); return 1; - case 'I' : result.append("int"); return 1; - case 'J' : result.append("long"); return 1; - case 'S' : result.append("short"); return 1; - case 'Z' : result.append("boolean");return 1; - case 'V' : result.append("void"); return 1; - - - //FIXME ASC Need a state machine to check we are parsing the right stuff here ! - case 'T' : - idx++; - int nextSemiIdx = signature.indexOf(';',idx); - result.append(signature.substring(idx,nextSemiIdx)); - return nextSemiIdx+1-posn; - - case '+' : - result.append("? extends "); - return readClassTypeSignatureFrom(signature,idx+1,result,chopit)+1; - - case '-' : - result.append("? super "); - return readClassTypeSignatureFrom(signature,idx+1,result,chopit)+1; - - case '*' : - result.append("?"); - return 1; - - case 'L' : // Full class name - boolean parameterized = false; - int idxSemicolon = signature.indexOf(';',idx); // Look for closing ';' or '<' - int idxAngly = signature.indexOf('<',idx); - int endOfSig = idxSemicolon; - if ((idxAngly!=-1) && idxAngly");idx++; - } - if (signature.charAt(idx)!=';') throw new RuntimeException("Did not find ';' at end of signature, found "+signature.charAt(idx)); - idx++; - return idx-posn; - - - case '[' : // Array declaration - int dim = 0; - while (signature.charAt(idx)=='[') {dim++;idx++;} - idx+=readClassTypeSignatureFrom(signature,idx,result,chopit); - while (dim>0) {result.append("[]");dim--;} - return idx-posn; - - default : throw new ClassFormatException("Invalid signature: `" + - signature + "'"); - } - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid signature: " + e + ":" + signature); - } - } - - - public static final String readClassTypeSignatureFrom(String signature) { - StringBuffer sb = new StringBuffer(); - GenericSignatureParsingTest.readClassTypeSignatureFrom(signature,0,sb,false); - return sb.toString(); - } - - - public static int countBrackets(String brackets) { - char[] chars = brackets.toCharArray(); - int count = 0; - boolean open = false; - - for(int i=0; i 0) brackets = GenericSignatureParsingTest.countBrackets(type.substring(index)); - - type = buf.toString(); - buf.setLength(0); - - for (int i=0; i < brackets; i++) buf.append('['); - - boolean found = false; - - for(int i=Constants.T_BOOLEAN; (i <= Constants.T_VOID) && !found; i++) { - if (Constants.TYPE_NAMES[i].equals(type)) { - found = true; - buf.append(Constants.SHORT_TYPE_NAMES[i]); - } - } - - // Class name - if (!found) buf.append('L' + type.replace('.', '/') + ';'); - - return buf.toString(); - } - - - /** - * For some method signature (class file format) like '([Ljava/lang/String;)Z' this returns - * the string representing the return type its 'normal' form, e.g. 'boolean' - * - * @param signature Method signature - * @param chopit Shorten class names - * @return return type of method - */ - public static final String methodSignatureReturnType(String signature,boolean chopit) throws ClassFormatException { - int index; - String type; - try { - // Read return type after `)' - index = signature.lastIndexOf(')') + 1; - type = Utility.signatureToString(signature.substring(index), chopit); - } catch (StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature); - } - return type; - } - - - /** - * For some method signature (class file format) like '([Ljava/lang/String;)Z' this returns - * the string representing the return type its 'normal' form, e.g. 'boolean' - * - * @param signature Method signature - * @return return type of method - * @throws ClassFormatException - */ - public static final String methodSignatureReturnType(String signature) throws ClassFormatException { - return GenericSignatureParsingTest.methodSignatureReturnType(signature, true); - } - - - /** - * For some method signature (class file format) like '([Ljava/lang/String;Z)V' this returns an array - * of strings representing the arguments in their 'normal' form, e.g. '{java.lang.String[],boolean}' - * - * @param signature Method signature - * @param chopit Shorten class names - * @return Array of argument types - */ - public static final String[] methodSignatureArgumentTypes(String signature,boolean chopit) throws ClassFormatException { - ArrayList vec = new ArrayList(); - int index; - String[] types; - - try { // Read all declarations between for `(' and `)' - if (signature.charAt(0) != '(') - throw new ClassFormatException("Invalid method signature: " + signature); - - index = 1; // current string position - - while(signature.charAt(index) != ')') { - Utility.ResultHolder rh = Utility.signatureToStringInternal(signature.substring(index),chopit); - vec.add(rh.getResult()); - index += rh.getConsumedChars(); - } - } catch(StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature); - } - - types = new String[vec.size()]; - vec.toArray(types); - return types; - } - - - /** - * Converts string containing the method return and argument types - * to a byte code method signature. - * - * @param returnType Return type of method (e.g. "char" or "java.lang.String[]") - * @param methodArgs Types of method arguments - * @return Byte code representation of method signature - */ - public final static String methodTypeToSignature(String returnType, String[] methodArgs) throws ClassFormatException { - - StringBuffer buf = new StringBuffer("("); - - if (methodArgs != null) { - for (int i=0; i < methodArgs.length; i++) { - String str = GenericSignatureParsingTest.getSignature(methodArgs[i]); - - if (str.equals("V")) // void can't be a method argument - throw new ClassFormatException("Invalid type: " + methodArgs[i]); - - buf.append(str); - } - } - - buf.append(")" + GenericSignatureParsingTest.getSignature(returnType)); - - return buf.toString(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericsErasureTesting.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericsErasureTesting.java deleted file mode 100644 index f0e5de738..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericsErasureTesting.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement (IBM) initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.tests; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.Signature; - -/** - * Should be possible to recover original declared signatures after erasure by using - * the signature attribute. - */ -public class GenericsErasureTesting extends BcelTestCase { - - - public void testLoadingGenerics() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("ErasureTestData"); - Method m = getMethod(clazz,"getData"); - String sig = m.getDeclaredSignature(); - System.err.println(getSignatureAttribute(clazz,"getData")); - System.err.println(sig); - assertTrue("Incorrect: "+sig,sig.equals("()Ljava/util/Vector;")); - } - - - // helper methods below - - public Signature getSignatureAttribute(JavaClass clazz,String name) { - Method m = getMethod(clazz,name); - Attribute[] as = m.getAttributes(); - for (int i = 0; i < as.length; i++) { - Attribute attribute = as[i]; - if (attribute.getName().equals("Signature")) { - return (Signature)attribute; - } - } - return null; - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GetReflectMembersTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GetReflectMembersTest.java deleted file mode 100644 index 06bd9ccc8..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GetReflectMembersTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer Initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.tests; - -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.ClassLoaderRepository; -import org.aspectj.apache.bcel.util.Repository; - -import junit.framework.TestCase; - -/** - * @author colyer - * - */ -public class GetReflectMembersTest extends TestCase { - - private Repository bcelRepository; - private JavaClass jc; - - public void testGetMethod() throws Exception { - assertNotNull(jc.getMethod(GetMe.class.getMethod("foo",new Class[] {String.class}))); - } - - public void testGetConstructor() throws Exception { - assertNotNull(jc.getMethod(GetMe.class.getConstructor(new Class[] {int.class}))); - } - - public void testGetField() throws Exception { - assertNotNull(jc.getField(GetMe.class.getDeclaredField("x"))); - } - - protected void setUp() throws Exception { - super.setUp(); - this.bcelRepository = new ClassLoaderRepository(getClass().getClassLoader()); - this.jc = bcelRepository.loadClass(GetMe.class); - } - - protected void tearDown() throws Exception { - super.tearDown(); - this.bcelRepository.clear(); - } - - private static class GetMe { - - private int x; - - public GetMe(int x) { this.x = x;} - - public void foo(String s) {}; - - } -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/LocalVariableTypeTableTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/LocalVariableTypeTableTest.java deleted file mode 100644 index 41eba95e0..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/LocalVariableTypeTableTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import org.aspectj.apache.bcel.classfile.Code; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.LocalVariable; -import org.aspectj.apache.bcel.classfile.LocalVariableTypeTable; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.Utility; - - -public class LocalVariableTypeTableTest extends BcelTestCase { - - - protected void setUp() throws Exception { - super.setUp(); - } - - /** - * Check the local variable type table includes information about generic signatures. - */ - public void testLocalVariableTypeTableAttribute() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("SimpleGenericsProgram"); - - Method mainMethod = getMethod(clazz,"main"); - Code codeAttr = (Code) findAttribute("Code",mainMethod.getAttributes()); - LocalVariableTypeTable localVariableTypeTable = - (LocalVariableTypeTable) findAttribute("LocalVariableTypeTable",codeAttr.getAttributes()); - - assertTrue("Should be two entries in the LocalVariableTypeTable but found "+localVariableTypeTable.getTableLength(), - localVariableTypeTable.getTableLength()==2); - - LocalVariable[] lvtable = localVariableTypeTable.getLocalVariableTypeTable(); - boolean tc1OK = false; - boolean tc2OK = false; - String errormessage = null; - for (int i = 0; i < lvtable.length; i++) { - String sig = Utility.signatureToString(lvtable[i].getSignature()); - if (lvtable[i].getName().equals("tc1")) { - if (!sig.equals("TreasureChest")) { - errormessage="Expected signature of 'TreasureChest' for tc1 but got "+sig; - } else { - tc1OK = true; - } - } - if (lvtable[i].getName().equals("tc2")) { - if (!sig.equals("TreasureChest")) { - errormessage="Expected signature of 'TreasureChest' for tc2 but got "+sig; - } else { - tc2OK = true; - } - } - } - if (!tc1OK || !tc2OK) fail(errormessage); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/MethodAnnotationsTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/MethodAnnotationsTest.java deleted file mode 100644 index 14d009cf0..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/MethodAnnotationsTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; -import java.io.IOException; -import java.util.Iterator; - -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.util.SyntheticRepository; - - -public class MethodAnnotationsTest extends BcelTestCase { - - - protected void setUp() throws Exception { - super.setUp(); - } - - public void testMethodAnnotations() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("AnnotatedMethods"); - - checkAnnotatedMethod(clazz,"method1","SimpleAnnotation","id","1"); - checkAnnotatedMethod(clazz,"method2","SimpleAnnotation","id","2"); - - } - - public void testMethodAnnotationsReadWrite() throws ClassNotFoundException,IOException { - JavaClass clazz = getClassFromJar("AnnotatedMethods"); - - checkAnnotatedMethod(clazz,"method1","SimpleAnnotation","id","1"); - checkAnnotatedMethod(clazz,"method2","SimpleAnnotation","id","2"); - - // Write it out - File tfile = createTestdataFile("AnnotatedMethods.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos2.loadClass("AnnotatedMethods"); - - checkAnnotatedMethod(clazz,"method1","SimpleAnnotation","id","1"); - checkAnnotatedMethod(clazz,"method2","SimpleAnnotation","id","2"); - - assertTrue(tfile.delete()); - } - - // helper methods - - public void checkAnnotatedMethod(JavaClass clazz,String methodname, - String annotationName,String annotationElementName,String annotationElementValue) { - Method[] methods = clazz.getMethods(); - - for (int i = 0; i < methods.length; i++) { - Method m = methods[i]; - AnnotationGen[] methodAnnotations = m.getAnnotations(); - if (m.getName().equals(methodname)) { - checkAnnotation(methodAnnotations[0],annotationName,annotationElementName,annotationElementValue); - - } - } - } - - private void checkAnnotation(AnnotationGen a,String name,String elementname,String elementvalue) { - assertTrue("Expected annotation to have name "+name+" but it had name "+a.getTypeName(), - a.getTypeName().equals(name)); - assertTrue("Expected annotation to have one element but it had "+a.getValues().size(),a.getValues().size()==1); - NameValuePair envp = a.getValues().get(0); - assertTrue("Expected element name "+elementname+" but was "+envp.getNameString(), - elementname.equals(envp.getNameString())); - assertTrue("Expected element value "+elementvalue+" but was "+envp.getValue().stringifyValue(), - elementvalue.equals(envp.getValue().stringifyValue())); - } - - - // helper methods - - public void checkValue(AnnotationGen a,String name,String tostring) { - for (Iterator i = a.getValues().iterator(); i.hasNext();) { - NameValuePair element = i.next(); - if (element.getNameString().equals(name)) { - if (!element.getValue().stringifyValue().equals(tostring)) { - fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue()); - } - return; - } - } - fail("Didnt find named element "+name); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/MethodParametersTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/MethodParametersTest.java deleted file mode 100644 index 76a9b84d8..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/MethodParametersTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2013 VMware - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.tests; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.MethodParameters; - -public class MethodParametersTest extends BcelTestCase { - - protected void setUp() throws Exception { - super.setUp(); - } - - public void testMethodParameters1() throws Exception { - JavaClass jc = getClassFromJava8Jar("Parameters"); - Method m = getMethod(jc, "foo"); - MethodParameters mp = (MethodParameters)getAttribute(m.getAttributes(),Constants.ATTR_METHOD_PARAMETERS); - assertEquals(3,mp.getParametersCount()); - assertEquals("abc",mp.getParameterName(0)); - assertEquals("def",mp.getParameterName(1)); - assertEquals("ghi",mp.getParameterName(2)); - assertFalse(mp.isFinal(0)); - assertFalse(mp.isSynthetic(0)); - assertFalse(mp.isMandated(0)); - } - - // this method specifies the receiver - public void testMethodParameters2() throws Exception { - JavaClass jc = getClassFromJava8Jar("Parameters"); - Method m = getMethod(jc, "bar"); - MethodParameters mp = (MethodParameters)getAttribute(m.getAttributes(),Constants.ATTR_METHOD_PARAMETERS); - assertEquals(1,mp.getParametersCount()); - assertEquals("abc",mp.getParameterName(0)); - assertFalse(mp.isFinal(0)); - assertFalse(mp.isSynthetic(0)); - assertFalse(mp.isMandated(0)); - } - - // access flags - public void testMethodParameters3() throws Exception { - JavaClass jc = getClassFromJava8Jar("Parameters$Inner"); - Method m = getMethod(jc, ""); - MethodParameters mp = (MethodParameters)getAttribute(m.getAttributes(),Constants.ATTR_METHOD_PARAMETERS); - assertEquals(2,mp.getParametersCount()); - - assertEquals("this$0",mp.getParameterName(0)); - assertTrue(mp.isFinal(0)); - assertFalse(mp.isSynthetic(0)); - assertTrue(mp.isMandated(0)); - - assertEquals("x",mp.getParameterName(1)); - assertFalse(mp.isFinal(1)); - assertFalse(mp.isSynthetic(1)); - assertFalse(mp.isMandated(1)); - } - - // access flags - public void testMethodParameters4() throws Exception { - JavaClass jc = getClassFromJava8Jar("Parameters$Color"); - Method m = getMethod(jc, ""); - MethodParameters mp = (MethodParameters)getAttribute(m.getAttributes(),Constants.ATTR_METHOD_PARAMETERS); - assertEquals(2,mp.getParametersCount()); - - assertEquals("$enum$name",mp.getParameterName(0)); - assertFalse(mp.isFinal(0)); - assertTrue(mp.isSynthetic(0)); - assertFalse(mp.isMandated(0)); - - assertEquals("$enum$ordinal",mp.getParameterName(1)); - assertFalse(mp.isFinal(1)); - assertTrue(mp.isSynthetic(1)); - assertFalse(mp.isMandated(1)); - } - -} \ No newline at end of file diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java deleted file mode 100644 index 454817df8..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2016-2017 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ClassParser; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Module; -import org.aspectj.apache.bcel.classfile.Module.Export; -import org.aspectj.apache.bcel.classfile.Module.Open; -import org.aspectj.apache.bcel.classfile.Module.Provide; -import org.aspectj.apache.bcel.classfile.Module.Require; -import org.aspectj.apache.bcel.classfile.Module.Uses; -import org.aspectj.apache.bcel.classfile.SourceFile; - -/** - * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html - * - * @author Andy Clement - */ -public class ModuleTest extends BcelTestCase { - - public void testLoadSimpleModuleClass() throws Exception { - String moduleFilename = "testdata/modules/one/module-info.class"; - ClassParser classParser = new ClassParser(moduleFilename); - JavaClass javaClass = classParser.parse(); - assertNotNull(javaClass); - assertEquals(Constants.MAJOR_1_9,javaClass.getMajor()); - assertEquals(Constants.MINOR_1_9,javaClass.getMinor()); - assertEquals(Constants.ACC_MODULE,javaClass.getModifiers()); - assertEquals(0,javaClass.getSuperclassNameIndex()); - assertEquals(0,javaClass.getInterfaceIndices().length); - assertEquals(0,javaClass.getFields().length); - assertEquals(0,javaClass.getMethods().length); - Attribute[] attrs = javaClass.getAttributes(); - assertEquals(2,attrs.length); - SourceFile sourceFile = (SourceFile) getAttribute(attrs,Constants.ATTR_SOURCE_FILE); - Module moduleAttr = (Module) getAttribute(attrs, Constants.ATTR_MODULE); - byte[] originalData = moduleAttr.getBytes(); - String[] requiredModuleNames = moduleAttr.getRequiredModuleNames(); - assertEquals(1,requiredModuleNames.length); - assertEquals("java.base",requiredModuleNames[0]); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - moduleAttr.dump(new DataOutputStream(baos)); - byte[] newData = baos.toByteArray(); - // The 6 offset here is because the newdata includes the 2byte cpool pointer for the name 'Module' - // and the 4byte int length field for the attribute data - if (newData.length!=originalData.length+6) { - fail("Expected the length of the original attribute ("+originalData.length+") to match the new written length ("+newData.length+")"); - } - for (int i=0;i. - */ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.util.ArrayList; -import java.util.List; - -import junit.framework.TestCase; - -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository; - -/** - * @author Kristian Rosenvold - */ -public class NonCachingClassLoaderRepositoryTest extends TestCase { - - private final NonCachingClassLoaderRepository nonCachingClassLoaderRepository = new NonCachingClassLoaderRepository( - NonCachingClassLoaderRepositoryTest.class.getClassLoader()); - - protected void setUp() throws Exception { - super.setUp(); - } - - abstract class DoneChecker implements Runnable { - private volatile boolean success = false; - private volatile boolean done = false; - - public boolean isSuccess() { - return success; - } - - public boolean isDone() { - return done; - } - - protected void setDone(boolean successFully) { - success = successFully; - done = true; - } - - public abstract void run(); - } - - class Loader extends DoneChecker implements Runnable { - public void run() { - try { - JavaClass javaClass = nonCachingClassLoaderRepository.loadClass(NonCachingClassLoaderRepositoryTest.class - .getCanonicalName()); - nonCachingClassLoaderRepository.clear(); - setDone(true); - } catch (Throwable e) { - e.printStackTrace(System.out); - setDone(false); - } - } - } - - class Clearer extends DoneChecker implements Runnable { - public void run() { - try { - nonCachingClassLoaderRepository.clear(); - setDone(true); - } catch (Throwable e) { - e.printStackTrace(System.out); - setDone(false); - } - } - } - - public void testConcurrency() throws ClassNotFoundException, InterruptedException { - List loaders = new ArrayList(); - int i1 = 1000; - for (int i = 0; i < i1; i++) { - DoneChecker loader = new Loader(); - loaders.add(loader); - new Thread(loader).start(); - DoneChecker clearer = new Clearer(); - loaders.add(clearer); - new Thread(clearer).start(); - } - - for (int i = 0; i < i1 * 2; i++) { - DoneChecker loader = loaders.get(i); - while (!loader.isDone()) { - Thread.sleep(10); - } - assertTrue("Loader " + i + " is supposed to run successfully", loader.isSuccess()); - } - - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ParameterAnnotationsTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ParameterAnnotationsTest.java deleted file mode 100644 index 093a4b6e4..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ParameterAnnotationsTest.java +++ /dev/null @@ -1,590 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM All rights reserved. This program and the accompanying - * materials are made available under the terms of the Eclipse Public License - * v1.0 which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: Andy Clement - initial implementation - ******************************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -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.classfile.annotation.AnnotationElementValue; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.classfile.annotation.ElementValue; -import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; -import org.aspectj.apache.bcel.generic.ArrayType; -import org.aspectj.apache.bcel.generic.ClassGen; -import org.aspectj.apache.bcel.generic.InstructionBranch; -import org.aspectj.apache.bcel.generic.InstructionConstants; -import org.aspectj.apache.bcel.generic.InstructionFactory; -import org.aspectj.apache.bcel.generic.InstructionHandle; -import org.aspectj.apache.bcel.generic.InstructionLV; -import org.aspectj.apache.bcel.generic.InstructionList; -import org.aspectj.apache.bcel.generic.LocalVariableGen; -import org.aspectj.apache.bcel.generic.MethodGen; -import org.aspectj.apache.bcel.generic.ObjectType; -import org.aspectj.apache.bcel.generic.Type; -import org.aspectj.apache.bcel.util.SyntheticRepository; - -/** - * The program that some of the tests generate looks like this: - public class HelloWorld { - public static void main(String[] argv) { - BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); - String name = null; - try { - name = "Andy"; - } catch(IOException e) { return; } - System.out.println("Hello, " + name); - } - } - * - */ -public class ParameterAnnotationsTest extends BcelTestCase { - - protected void setUp() throws Exception { - super.setUp(); - } - - /** - * Programmatically construct a class and add an annotation to the main method parameter 'argv' - */ - public void testParameterAnnotations_builtOK() { - ClassGen clg = createClassGen("HelloWorld"); - ConstantPool cpg = clg.getConstantPool(); - InstructionList il = new InstructionList(); - - buildClassContentsWithAnnotatedMethods(clg,cpg,il,true); - - int i = clg.getMethods().length; - assertTrue("Class should have 2 methods but has "+i,i==2); - - Method mainMethod = clg.getMethods()[0]; - AnnotationGen[] annos = mainMethod.getAnnotationsOnParameter(0); - assertTrue("Should be two annotation on the 'argv' parameter to main() but there are "+annos.length,annos.length==2); - assertTrue("This annotation should contain the string 'fruit=Apples' but it is "+annos[0].toString(), - annos[0].toString().indexOf("fruit=Apples")!=-1); - assertTrue("This annotation should contain the string 'fruit=Oranges' but it is "+annos[1].toString(), - annos[1].toString().indexOf("fruit=Oranges")!=-1); - } - - - - /** - * Check we can save and load a constructed class that contains parameter annotations - */ - public void testParameterAnnotations_savedAndLoadedOK() throws ClassNotFoundException { - ClassGen clg = createClassGen("HelloWorld"); - ConstantPool cpg = clg.getConstantPool(); - InstructionList il = new InstructionList(); - - buildClassContentsWithAnnotatedMethods(clg,cpg,il,true); - - dumpClass(clg,"temp5","HelloWorld.class"); - - JavaClass jc = getClassFrom("temp5","HelloWorld"); - - clg = new ClassGen(jc); - - int i = clg.getMethods().length; - assertTrue("Class should have 2 methods but has "+i,i==2); - - Method mainMethod = clg.getMethods()[0]; - AnnotationGen[] annos = mainMethod.getAnnotationsOnParameter(0); - assertTrue("Should be two annotation on the 'argv' parameter to main() but there are "+annos.length,annos.length==2); - assertTrue("This annotation should contain the string 'fruit=Apples' but it is "+annos[0].toString(), - annos[0].toString().indexOf("fruit=Apples")!=-1); - assertTrue("This annotation should contain the string 'fruit=Oranges' but it is "+annos[1].toString(), - annos[1].toString().indexOf("fruit=Oranges")!=-1); - assertTrue(wipe("temp5","HelloWorld.class")); - - } - - - - /* - * Load an existing class, add new parameter annotations, save and then reload it - */ - public void testParameterAnnotations_loadedThenModifiedThenSavedAndLoadedOK() throws ClassNotFoundException { - JavaClass jc = getClassFrom("testcode.jar","AnnotatedParameters"); - - ClassGen clg = new ClassGen(jc); - ConstantPool cpg = clg.getConstantPool(); - - // - // Foo method looks like this: - // public void foo(@SimpleAnnotation(id=2) int arg1, - // @SimpleAnnotation(id=3) @AnnotationEnumElement(enumval=SimpleEnum.Red) String arg2) - Method m = findMethod(clg,"foo"); - assertTrue("Should be able to find method foo but couldn't",m!=null); - - - /////////////////////// 1. Check the right number of annotations are there - int i = m.getAnnotationsOnParameter(1).length; - assertTrue("Should be two annotations on the second parameter but found: "+i,i==2); - - - /////////////////////// 2. Let's add a new parameter annotation, a visible one, to the first parameter. - - // Build a modifiable version of the foo method - MethodGen mg = new MethodGen(m,clg.getClassName(),cpg); - - // Check the annotations survived that transform - i = mg.getAnnotationsOnParameter(1).size(); - assertTrue("Should be two annotations on the second parameter but found: "+i,i==2); - - // That worked, so let's add a new parameter annotation - mg.addParameterAnnotation(0,createFruitAnnotation(cpg,"Banana",true)); - - // Foo method should now look like this: - // public void foo(@SimpleAnnotation(id=2) @SimpleStringAnnotation(fruit=Banana) int arg1, - // @SimpleAnnotation(id=3) @AnnotationEnumElement(enumval=SimpleEnum.Red) String arg2) - i = mg.getAnnotationsOnParameter(0).size(); - assertTrue("Should now be 2 parameter annotations but found "+i,i==2); - i = mg.getAnnotationsOnParameter(0).get(1).toString().indexOf("fruit=Banana"); - assertTrue("Expected 'fruit=Banana' in the 2nd annotation on the first argument but got "+ - mg.getAnnotationsOnParameter(0).get(1).toString(),i!=-1); - - // delete the old method and add the new one - clg.removeMethod(m); - clg.addMethod(mg.getMethod()); - - /////////////////////// 3. Dump it to disk - dumpClass(clg,"temp2","AnnotatedParameters.class"); - - /////////////////////// 4. Load it back in and verify the annotations persisted - JavaClass jc2 = getClassFrom("temp2","AnnotatedParameters"); - - m = jc2.getMethods()[2]; - AnnotationGen[] p1annotations = m.getAnnotationsOnParameter(0); - AnnotationGen[] p2annotations = m.getAnnotationsOnParameter(1); - - assertTrue("Expected two annotations on the first parameter but found "+p1annotations.length,p1annotations.length==2); - assertTrue("Expected two annotations on the second parameter but found "+p2annotations.length,p2annotations.length==2); - String expectedString = "[@SimpleAnnotation(id=2),@SimpleStringAnnotation(fruit=Banana)]"; - assertTrue("Expected formatted short string of '"+expectedString+"' but it was '"+dumpAnnotations(p1annotations)+"'", - dumpAnnotations(p1annotations).equals(expectedString)); - expectedString = "[@SimpleAnnotation(id=3),@AnnotationEnumElement(enumval=LSimpleEnum;Red)]"; - assertTrue("Expected formatted short string of '"+expectedString+"' but it was '"+dumpAnnotations(p2annotations)+"'", - dumpAnnotations(p2annotations).equals(expectedString)); - - assertTrue(wipe("temp2","AnnotatedParameters.class")); - } - - - /** - * same as above test but attaching invisible runtime parameter annotations - */ - public void testParameterAnnotations_loadedThenModifiedWithInvisibleAnnotationThenSavedAndLoadedOK() throws ClassNotFoundException { - JavaClass jc = getClassFrom("testcode.jar","AnnotatedParameters"); - ClassGen clg = new ClassGen(jc); - ConstantPool cpg = clg.getConstantPool(); - - // - // Foo method looks like this: - // public void foo(@SimpleAnnotation(id=2) int arg1, - // @SimpleAnnotation(id=3) @AnnotationEnumElement(enumval=SimpleEnum.Red) String arg2) - Method m = findMethod(clg,"foo"); - assertTrue("Should be able to find method foo but couldn't",m!=null); - - - /////////////////////// 1. Check the right number of annotations are there - int i = m.getAnnotationsOnParameter(1).length; - assertTrue("Should be two annotations on the second parameter but found: "+i,i==2); - - - /////////////////////// 2. Let's add a new parameter annotation, a visible one, to the first parameter. - - // Build a modifiable version of the foo method - MethodGen mg = new MethodGen(m,clg.getClassName(),cpg); - - // Check the annotations survived that transform - i = mg.getAnnotationsOnParameter(1).size(); - assertTrue("Should be two annotations on the second parameter but found: "+i,i==2); - - // That worked, so let's add a new parameter annotation - mg.addParameterAnnotation(0,createFruitAnnotation(cpg,"Banana",false)); - - // Foo method should now look like this: - // public void foo(@SimpleAnnotation(id=2) @SimpleStringAnnotation(fruit=Banana) int arg1, - // @SimpleAnnotation(id=3) @AnnotationEnumElement(enumval=SimpleEnum.Red) String arg2) - i = mg.getAnnotationsOnParameter(0).size(); - assertTrue("Should now be 2 parameter annotations but found "+i,i==2); - i = mg.getAnnotationsOnParameter(0).get(1).toString().indexOf("fruit=Banana"); - assertTrue("Expected 'fruit=Banana' in the 2nd annotation on the first argument but got "+ - mg.getAnnotationsOnParameter(0).get(1).toString(),i!=-1); - assertTrue("New annotation should be runtime invisible?",!((AnnotationGen)mg.getAnnotationsOnParameter(0).get(1)).isRuntimeVisible()); - - // delete the old method and add the new one - clg.removeMethod(m); - clg.addMethod(mg.getMethod()); - - /////////////////////// 3. Dump it to disk - dumpClass(clg,"temp3","AnnotatedParameters.class"); - - /////////////////////// 4. Load it back in and verify the annotations persisted - - JavaClass jc2 = getClassFrom("temp3","AnnotatedParameters"); - - m = jc2.getMethods()[2]; - AnnotationGen[] p1annotations = m.getAnnotationsOnParameter(0); - AnnotationGen[] p2annotations = m.getAnnotationsOnParameter(1); - - assertTrue("Expected two annotations on the first parameter but found "+p1annotations.length,p1annotations.length==2); - assertTrue("Expected two annotations on the second parameter but found "+p2annotations.length,p2annotations.length==2); - String expectedString = "[@SimpleAnnotation(id=2),@SimpleStringAnnotation(fruit=Banana)]"; - assertTrue("Expected formatted short string of '"+expectedString+"' but it was '"+dumpAnnotations(p1annotations)+"'", - dumpAnnotations(p1annotations).equals(expectedString)); - expectedString = "[@SimpleAnnotation(id=3),@AnnotationEnumElement(enumval=LSimpleEnum;Red)]"; - assertTrue("Expected formatted short string of '"+expectedString+"' but it was '"+dumpAnnotations(p2annotations)+"'", - dumpAnnotations(p2annotations).equals(expectedString)); - - assertTrue("Second annotation on first parameter should be runtime invisible?", - !p1annotations[1].isRuntimeVisible()); - assertTrue(wipe("temp3","AnnotatedParameters.class")); - - - // 5. Verify that when annotations for parameters are unpacked from attributes, the - // attributes vanish ! - clg = new ClassGen(jc2); - mg = new MethodGen(m,clg.getClassName(),clg.getConstantPool()); - List as = mg.getAttributes(); - assertTrue("Should be 2 (RIPA and RVPA) but there are "+mg.getAttributes().size(),mg.getAttributes().size()==2); - List l = mg.getAnnotationsOnParameter(0); - assertTrue("Should be 2 annotations on first parameter but there is only "+l.size()+":"+l.toString(), - l.size()==2); - assertTrue("Should be 0 but there are "+mg.getAttributes().size(),mg.getAttributes().size()==0); - } - - - private Method findMethod(ClassGen c,String mname) { - Method[] ms = c.getMethods(); - for (int i = 0; i < ms.length; i++) { - if (ms[i].getName().equals(mname)) return ms[i]; - } - return null; - } - - private void dumpClass(ClassGen cg, String fname) { - try { - File f = createTestdataFile(fname); - cg.getJavaClass().dump(f); - } catch (java.io.IOException e) { - System.err.println(e); - } - } - - - private void dumpClass(ClassGen cg, String dir, String fname) { - dumpClass(cg,dir+File.separator+fname); - } - - private void buildClassContentsWithAnnotatedMethods(ClassGen cg, ConstantPool cp, InstructionList il,boolean addParameterAnnotations) { - // Create method 'public static void main(String[]argv)' - MethodGen mg = createMethodGen("main",il,cp); - InstructionFactory factory = new InstructionFactory(cg); - mg.addAnnotation(createSimpleVisibleAnnotation(mg.getConstantPool())); - // We now define some often used types: - - ObjectType i_stream = new ObjectType("java.io.InputStream"); - ObjectType p_stream = new ObjectType("java.io.PrintStream"); - - // Create variables in and name : We call the constructors, i.e., - // execute BufferedReader(InputStreamReader(System.in)) . The reference - // to the BufferedReader object stays on top of the stack and is stored - // in the newly allocated in variable. - - il.append(factory.createNew("java.io.BufferedReader")); - il.append(InstructionConstants.DUP); // Use predefined constant - il.append(factory.createNew("java.io.InputStreamReader")); - il.append(InstructionConstants.DUP); - il.append(factory.createFieldAccess("java.lang.System", "in", i_stream,Constants.GETSTATIC)); - il.append(factory.createInvoke("java.io.InputStreamReader", "", - Type.VOID, new Type[] { i_stream }, Constants.INVOKESPECIAL)); - il.append(factory.createInvoke("java.io.BufferedReader", "", - Type.VOID, new Type[] { new ObjectType("java.io.Reader") }, - Constants.INVOKESPECIAL)); - - LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType( - "java.io.BufferedReader"), null, null); - int in = lg.getIndex(); - lg.setStart(il.append(InstructionFactory.createASTORE(in))); // "in" valid from here - - // Create local variable name and initialize it to null - - lg = mg.addLocalVariable("name", Type.STRING, null, null); - int name = lg.getIndex(); - il.append(InstructionConstants.ACONST_NULL); - lg.setStart(il.append(InstructionFactory.createASTORE(name))); // "name" valid from here - - // Create try-catch block: We remember the start of the block, read a - // line from the standard input and store it into the variable name . - -// InstructionHandle try_start = il.append(factory.createFieldAccess( -// "java.lang.System", "out", p_stream, Constants.GETSTATIC)); - -// il.append(new PUSH(cp, "Please enter your name> ")); -// il.append(factory.createInvoke("java.io.PrintStream", "print", -// Type.VOID, new Type[] { Type.STRING }, -// Constants.INVOKEVIRTUAL)); -// il.append(new ALOAD(in)); -// il.append(factory.createInvoke("java.io.BufferedReader", "readLine", -// Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - InstructionHandle try_start = il.append(InstructionFactory.PUSH(cp,"Andy")); - il.append(InstructionFactory.createASTORE(name)); - - // Upon normal execution we jump behind exception handler, the target - // address is not known yet. - - InstructionBranch g = new InstructionBranch(Constants.GOTO); - InstructionHandle try_end = il.append(g); - - // We add the exception handler which simply returns from the method. - - LocalVariableGen var_ex = mg.addLocalVariable("ex",Type.getType("Ljava.io.IOException;"),null,null); - int var_ex_slot = var_ex.getIndex(); - - InstructionHandle handler = il.append(InstructionFactory.createASTORE(var_ex_slot)); - var_ex.setStart(handler); - var_ex.setEnd(il.append(InstructionConstants.RETURN)); - - mg.addExceptionHandler(try_start, try_end, handler, - new ObjectType("java.io.IOException")); - - // "Normal" code continues, now we can set the branch target of the GOTO - // . - - InstructionHandle ih = il.append(factory.createFieldAccess( - "java.lang.System", "out", p_stream, Constants.GETSTATIC)); - g.setTarget(ih); - - // Printing "Hello": String concatenation compiles to StringBuffer - // operations. - - il.append(factory.createNew(Type.STRINGBUFFER)); - il.append(InstructionConstants.DUP); - il.append(InstructionFactory.PUSH(cp, "Hello, ")); - il - .append(factory.createInvoke("java.lang.StringBuffer", - "", Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKESPECIAL)); - il.append(new InstructionLV(Constants.ALOAD,name)); - il.append(factory.createInvoke("java.lang.StringBuffer", "append", - Type.STRINGBUFFER, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(factory.createInvoke("java.lang.StringBuffer", "toString", - Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - - il.append(factory.createInvoke("java.io.PrintStream", "println", - Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(InstructionConstants.RETURN); - - // Finalization: Finally, we have to set the stack size, which normally - // would have to be computed on the fly and add a default constructor - // method to the class, which is empty in this case. - - mg.addParameterAnnotation(0,createFruitAnnotation(cp,"Apples",true)); - mg.addParameterAnnotation(0,createFruitAnnotation(cp,"Oranges",true)); - mg.setMaxStack(); - mg.setMaxLocals(); - cg.addMethod(mg.getMethod()); - il.dispose(); // Allow instruction handles to be reused - cg.addEmptyConstructor(Constants.ACC_PUBLIC); - } - - private void buildClassContents(ClassGen cg, ConstantPool cp, InstructionList il) { - // Create method 'public static void main(String[]argv)' - MethodGen mg = createMethodGen("main",il,cp); - InstructionFactory factory = new InstructionFactory(cg); - // We now define some often used types: - - ObjectType i_stream = new ObjectType("java.io.InputStream"); - ObjectType p_stream = new ObjectType("java.io.PrintStream"); - - // Create variables in and name : We call the constructors, i.e., - // execute BufferedReader(InputStreamReader(System.in)) . The reference - // to the BufferedReader object stays on top of the stack and is stored - // in the newly allocated in variable. - - il.append(factory.createNew("java.io.BufferedReader")); - il.append(InstructionConstants.DUP); // Use predefined constant - il.append(factory.createNew("java.io.InputStreamReader")); - il.append(InstructionConstants.DUP); - il.append(factory.createFieldAccess("java.lang.System", "in", i_stream,Constants.GETSTATIC)); - il.append(factory.createInvoke("java.io.InputStreamReader", "", - Type.VOID, new Type[] { i_stream }, Constants.INVOKESPECIAL)); - il.append(factory.createInvoke("java.io.BufferedReader", "", - Type.VOID, new Type[] { new ObjectType("java.io.Reader") }, - Constants.INVOKESPECIAL)); - - LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType( - "java.io.BufferedReader"), null, null); - int in = lg.getIndex(); - lg.setStart(il.append(InstructionFactory.createASTORE(in))); // "in" valid from here - - // Create local variable name and initialize it to null - - lg = mg.addLocalVariable("name", Type.STRING, null, null); - int name = lg.getIndex(); - il.append(InstructionConstants.ACONST_NULL); - lg.setStart(il.append(InstructionFactory.createASTORE(name))); // "name" valid from here - - // Create try-catch block: We remember the start of the block, read a - // line from the standard input and store it into the variable name . - -// InstructionHandle try_start = il.append(factory.createFieldAccess( -// "java.lang.System", "out", p_stream, Constants.GETSTATIC)); - -// il.append(new PUSH(cp, "Please enter your name> ")); -// il.append(factory.createInvoke("java.io.PrintStream", "print", -// Type.VOID, new Type[] { Type.STRING }, -// Constants.INVOKEVIRTUAL)); -// il.append(new ALOAD(in)); -// il.append(factory.createInvoke("java.io.BufferedReader", "readLine", -// Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - InstructionHandle try_start = il.append(InstructionFactory.PUSH(cp,"Andy")); - il.append(InstructionFactory.createASTORE(name)); - - // Upon normal execution we jump behind exception handler, the target - // address is not known yet. - - InstructionBranch g = new InstructionBranch(Constants.GOTO); - InstructionHandle try_end = il.append(g); - - // We add the exception handler which simply returns from the method. - - LocalVariableGen var_ex = mg.addLocalVariable("ex",Type.getType("Ljava.io.IOException;"),null,null); - int var_ex_slot = var_ex.getIndex(); - - InstructionHandle handler = il.append(InstructionFactory.createASTORE(var_ex_slot)); - var_ex.setStart(handler); - var_ex.setEnd(il.append(InstructionConstants.RETURN)); - - mg.addExceptionHandler(try_start, try_end, handler, - new ObjectType("java.io.IOException")); - - // "Normal" code continues, now we can set the branch target of the GOTO - // . - - InstructionHandle ih = il.append(factory.createFieldAccess( - "java.lang.System", "out", p_stream, Constants.GETSTATIC)); - g.setTarget(ih); - - // Printing "Hello": String concatenation compiles to StringBuffer - // operations. - - il.append(factory.createNew(Type.STRINGBUFFER)); - il.append(InstructionConstants.DUP); - il.append(InstructionFactory.PUSH(cp, "Hello, ")); - il - .append(factory.createInvoke("java.lang.StringBuffer", - "", Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKESPECIAL)); - il.append(InstructionFactory.createALOAD(name)); - il.append(factory.createInvoke("java.lang.StringBuffer", "append", - Type.STRINGBUFFER, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(factory.createInvoke("java.lang.StringBuffer", "toString", - Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - - il.append(factory.createInvoke("java.io.PrintStream", "println", - Type.VOID, new Type[] { Type.STRING }, - Constants.INVOKEVIRTUAL)); - il.append(InstructionConstants.RETURN); - - // Finalization: Finally, we have to set the stack size, which normally - // would have to be computed on the fly and add a default constructor - // method to the class, which is empty in this case. - - mg.setMaxStack(); - mg.setMaxLocals(); - cg.addMethod(mg.getMethod()); - il.dispose(); // Allow instruction handles to be reused - cg.addEmptyConstructor(Constants.ACC_PUBLIC); - } - - private JavaClass getClassFrom(String where,String clazzname) throws ClassNotFoundException { - SyntheticRepository repos = createRepos(where); - return repos.loadClass(clazzname); - } - - - - - // helper methods - - - private ClassGen createClassGen(String classname) { - return new ClassGen(classname, "java.lang.Object", - "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); - } - - private MethodGen createMethodGen(String methodname,InstructionList il,ConstantPool cp) { - return new MethodGen( - Constants.ACC_STATIC | Constants.ACC_PUBLIC, // access flags - Type.VOID, // return type - new Type[] { new ArrayType(Type.STRING, 1) }, // argument types - new String[] { "argv" }, // arg names - methodname, "HelloWorld", // method, class - il, cp); - } - - - public AnnotationGen createSimpleVisibleAnnotation(ConstantPool cp) { - SimpleElementValue evg = new SimpleElementValue( - ElementValue.PRIMITIVE_INT, cp, 4); - - NameValuePair nvGen = new NameValuePair("id", evg,cp); - - ObjectType t = new ObjectType("SimpleAnnotation"); - - List elements = new ArrayList(); - elements.add(nvGen); - - AnnotationGen a = new AnnotationGen(t, elements,true, cp); - return a; - } - - public AnnotationGen createCombinedAnnotation(ConstantPool cp) { - // Create an annotation instance - AnnotationGen a = createSimpleVisibleAnnotation(cp); - ArrayElementValue array = new ArrayElementValue(cp); - array.addElement(new AnnotationElementValue(a,cp)); - NameValuePair nvp = new NameValuePair("value",array,cp); - List elements = new ArrayList(); - elements.add(nvp); - return new AnnotationGen(new ObjectType("CombinedAnnotation"),elements,true,cp); - } - - public AnnotationGen createSimpleInvisibleAnnotation(ConstantPool cp) { - SimpleElementValue evg = new SimpleElementValue( - ElementValue.PRIMITIVE_INT, cp, 4); - - NameValuePair nvGen = new NameValuePair("id", evg,cp); - - ObjectType t = new ObjectType("SimpleAnnotation"); - - List elements = new ArrayList(); - elements.add(nvGen); - - AnnotationGen a = new AnnotationGen(t, elements,false, cp); - return a; - } - protected void tearDown() throws Exception { - super.tearDown(); - } - -} \ No newline at end of file diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleAnnotationAttributeTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleAnnotationAttributeTest.java deleted file mode 100644 index 0f82b2059..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleAnnotationAttributeTest.java +++ /dev/null @@ -1,395 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ConstantPool; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Utility; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationElementValue; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; -import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.classfile.annotation.ElementValue; -import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; -import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; -import org.aspectj.apache.bcel.generic.ClassGen; -import org.aspectj.apache.bcel.util.SyntheticRepository; - - -public class RuntimeVisibleAnnotationAttributeTest extends BcelTestCase { - - - protected void setUp() throws Exception { - super.setUp(); - } - - public void testSeeAnnotationsAsAttribute() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("SimpleAnnotatedClass"); - ConstantPool pool = clazz.getConstantPool(); - Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz); - assertTrue("Expected a RuntimeVisibleAnnotations attribute but found none", - rvaAttr.length==1); - } - - public void testAnnotationsAttributeContainsRightData() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("SimpleAnnotatedClass"); - ConstantPool pool = clazz.getConstantPool(); - Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz); - RuntimeVisAnnos rva = (RuntimeVisAnnos) rvaAttr[0]; - List anns = rva.getAnnotations(); - assertTrue("Should be one annotation but found "+anns.size(), - anns.size()==1); - AnnotationGen ann = anns.get(0); - assertTrue("Should be called 'SimpleAnnotation' but was called "+ann.getTypeName(), - ann.getTypeName().equals("SimpleAnnotation")); - List l = ann.getValues(); - assertTrue("Should be one value for annotation 'SimpleAnnotation' but found "+l.size(), - l.size()==1); - NameValuePair envp = l.get(0); - assertTrue("Name of element in SimpleAnnotation should be 'id' but it is "+envp.getNameString(), - envp.getNameString().equals("id")); - SimpleElementValue evalue = (SimpleElementValue)envp.getValue(); - assertTrue("'id' should be of type int, but it is "+evalue.getElementValueType(),evalue.getElementValueType()==SimpleElementValue.PRIMITIVE_INT); - assertTrue("'id' should have value 4 but it is "+evalue.getValueInt(), - evalue.getValueInt()==4); - } - - public void testAccessingAnnotationsOnClazz() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("SimpleAnnotatedClass"); - ConstantPool pool = clazz.getConstantPool(); - AnnotationGen[] anns = clazz.getAnnotations(); - assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length, - anns.length==1); - } - - public void testReadingWritingAnnotations() throws ClassNotFoundException, IOException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("SimpleAnnotatedClass"); - ConstantPool pool = clazz.getConstantPool(); - AnnotationGen[] anns = clazz.getAnnotations(); - assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length, - anns.length==1); - - // Write it out - File tfile = createTestdataFile("SimpleAnnotatedClass.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos.loadClass("SimpleAnnotatedClass"); - ConstantPool pool2 = clazz2.getConstantPool(); - AnnotationGen[] anns2 = clazz2.getAnnotations(); - assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns2.length, - anns2.length==1); - - assertTrue(tfile.delete()); - } - - - - //// - // Test for annotations containing string elements - - public void testAnnotationStringElement() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedClass"); - verifyAnnotationStringElement(clazz); - } - - - public void testAnnotationStringElementReadWrite() throws ClassNotFoundException, IOException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedClass"); - verifyAnnotationStringElement(clazz); - - // Write it out - File tfile = createTestdataFile("AnnotatedClass.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos2.loadClass("AnnotatedClass"); - verifyAnnotationStringElement(clazz2); - - assertTrue(tfile.delete()); - } - - private void verifyAnnotationStringElement(JavaClass clazz) { - AnnotationGen[] anns = clazz.getAnnotations(); - assertTrue("should be one annotation but found "+anns.length,anns.length==1); - AnnotationGen ann = anns[0]; - assertTrue("should be called 'AnnotationStringElement' but was called "+ann.getTypeName(), - ann.getTypeName().equals("AnnotationStringElement")); - List l = ann.getValues(); - assertTrue("Should be one value but there were "+l.size(),l.size()==1); - NameValuePair nvp = l.get(0); - assertTrue("Name of element should be 'stringval' but was "+nvp.getNameString(), - nvp.getNameString().equals("stringval")); - SimpleElementValue ev = (SimpleElementValue)nvp.getValue(); - assertTrue("String value should be 'hello' but was '"+ev.getValueString()+"'", - ev.getValueString().equals("hello")); - } - - //// - // Test for complex annotation that includes all primitives - - public void testComplexAnnotation() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("ComplexAnnotatedClass"); - verifyComplexAnnotation(clazz); - } - - - public void testComplexAnnotationsReadWrite() throws ClassNotFoundException, IOException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("ComplexAnnotatedClass"); - verifyComplexAnnotation(clazz); - - // Write it out - File tfile = createTestdataFile("ComplexAnnotatedClass.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos.loadClass("ComplexAnnotatedClass"); - verifyComplexAnnotation(clazz2); - - assertTrue(tfile.delete()); - - } - - private void verifyComplexAnnotation(JavaClass clazz) { - AnnotationGen[] anns = clazz.getAnnotations(); - assertTrue("Should be one annotation but found "+anns.length,anns.length==1); - AnnotationGen ann = anns[0]; - assertTrue("Should be called 'ComplexAnnotation' but was called "+ann.getTypeName(), - ann.getTypeName().equals("ComplexAnnotation")); - List l = ann.getValues(); - assertTrue("Should be eight values for annotation 'ComplexAnnotation' but found "+l.size(), - l.size()==8); - List names = RuntimeVisibleAnnotationAttributeTest.getListOfAnnotationNames(ann); - assertTrue("Cant find expected element ",names.contains("ival")); - assertTrue("Cant find expected element ",names.contains("dval")); - assertTrue("Cant find expected element ",names.contains("zval")); - assertTrue("Cant find expected element ",names.contains("fval")); - assertTrue("Cant find expected element ",names.contains("jval")); - assertTrue("Cant find expected element ",names.contains("sval")); - assertTrue("Cant find expected element ",names.contains("bval")); - assertTrue("Cant find expected element ",names.contains("cval")); - - checkValue(ann,"ival","4"); - checkValue(ann,"jval","56"); - checkValue(ann,"fval","3.0"); - checkValue(ann,"dval","33.4"); - checkValue(ann,"sval","99"); - checkValue(ann,"bval","2"); - checkValue(ann,"cval",new Character('5').toString()); - checkValue(ann,"zval","false"); - - } - - private void checkValue(AnnotationGen a,String name,String tostring) { - for (Iterator i = a.getValues().iterator(); i.hasNext();) { - NameValuePair element = i.next(); - if (element.getNameString().equals(name)) { - if (!element.getValue().stringifyValue().equals(tostring)) { - fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue()); - } - return; - } - } - fail("Didnt find named element "+name); - } - - //// - // Test an annotation containing a 'Class' element - - public void testAnnotationClassElement() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedWithClassClass"); - verifyClassAnnotation(clazz); - } - - public void testAnnotationClassElementCopying() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedWithClassClass"); - AnnotationGen[] anns = clazz.getAnnotations(); - ClassGen cg = new ClassGen(clazz); - // Checks we can copy class values in an annotation - new AnnotationGen(anns[0],cg.getConstantPool(),true); - new AnnotationGen(anns[0],cg.getConstantPool(),false); - } - - public void testAnnotationClassElementReadWrite() throws ClassNotFoundException,IOException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedWithClassClass"); - verifyClassAnnotation(clazz); - - // Write it out - File tfile = createTestdataFile("AnnotatedWithClassClass.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos2.loadClass("AnnotatedWithClassClass"); - verifyClassAnnotation(clazz2); - - assertTrue(wipe("AnnotatedWithClassClass.class")); - } - - private void verifyClassAnnotation(JavaClass clazz) { - AnnotationGen[] anns = clazz.getAnnotations(); - assertTrue("should be one annotation but found "+anns.length,anns.length==1); - AnnotationGen ann = anns[0]; - assertTrue("should be called 'AnnotationClassElement' but was called "+ann.getTypeName(), - ann.getTypeName().equals("AnnotationClassElement")); - List l = ann.getValues(); - assertTrue("Should be one value but there were "+l.size(),l.size()==1); - NameValuePair nvp = l.get(0); - assertTrue("Name of element should be 'clz' but was "+nvp.getNameString(), - nvp.getNameString().equals("clz")); - ClassElementValue ev = (ClassElementValue)nvp.getValue(); - assertTrue("String value should be 'Ljava/lang/Integer;' but was '"+ev.getClassString()+"'", - ev.getClassString().equals("Ljava/lang/Integer;")); - - } - - //// - // Test an annotation containing an enum element - - public void testAnnotationEnumElement() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedWithEnumClass"); - verifyAnnotationEnumElement(clazz); - } - - public void testAnnotationEnumElementReadWrite() throws ClassNotFoundException, IOException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedWithEnumClass"); - verifyAnnotationEnumElement(clazz); - - // Write it out - File tfile = createTestdataFile("AnnotatedWithEnumClass.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos2.loadClass("AnnotatedWithEnumClass"); - verifyAnnotationEnumElement(clazz2); - - assertTrue(tfile.delete()); - } - - public void verifyAnnotationEnumElement(JavaClass clazz) { - AnnotationGen[] anns = clazz.getAnnotations(); - assertTrue("should be one annotation but found "+anns.length,anns.length==1); - AnnotationGen ann = anns[0]; - assertTrue("should be called 'AnnotationEnumElement' but was called "+ann.getTypeName(), - ann.getTypeName().equals("AnnotationEnumElement")); - List l = ann.getValues(); - assertTrue("Should be one value but there were "+l.size(),l.size()==1); - NameValuePair nvp = l.get(0); - assertTrue("Name of element should be 'enumval' but was "+nvp.getNameString(), - nvp.getNameString().equals("enumval")); - ElementValue ev = nvp.getValue(); - assertTrue("Should be of type EnumElementValue but is "+ev,ev instanceof EnumElementValue); - EnumElementValue eev = (EnumElementValue)ev; - assertTrue("Should be an enum type value but is "+eev.getElementValueType(),eev.getElementValueType()==SimpleElementValue.ENUM_CONSTANT); - assertTrue("Enum type for annotation should be 'SimpleEnum' but is "+Utility.signatureToString(eev.getEnumTypeString()),Utility.signatureToString(eev.getEnumTypeString()).equals("SimpleEnum")); - assertTrue("String value should be 'Red' but was '"+eev.getEnumValueString()+"'", - eev.getEnumValueString().equals("Red")); - } - - //// - // Test an annotation with an array element - - public void testAnnotationArraysOfAnnotations() throws ClassNotFoundException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedWithCombinedAnnotation"); - AnnotationGen[] anns = clazz.getAnnotations(); - assertTrue("should be one annotation but found "+anns.length,anns.length==1); - checkCombinedAnnotation(anns[0]); - } - - public void testAnnotationArraysOfAnnotationsReadWrite() throws ClassNotFoundException, IOException { - SyntheticRepository repos = createRepos("testcode.jar"); - JavaClass clazz = repos.loadClass("AnnotatedWithCombinedAnnotation"); - AnnotationGen[] anns = clazz.getAnnotations(); - assertTrue("should be one annotation but found "+anns.length,anns.length==1); - checkCombinedAnnotation(anns[0]); - - // Write it out - File tfile = createTestdataFile("AnnotatedWithCombinedAnnotation.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos2.loadClass("AnnotatedWithCombinedAnnotation"); - AnnotationGen[] anns2 = clazz2.getAnnotations(); - assertTrue("should be one annotation but found "+anns2.length,anns2.length==1); - checkCombinedAnnotation(anns2[0]); - - assertTrue(tfile.delete()); - } - - - private void checkCombinedAnnotation(AnnotationGen ann) { - assertTrue("should be called 'CombinedAnnotation' but was called "+ann.getTypeName(), - ann.getTypeName().equals("CombinedAnnotation")); - List l = ann.getValues(); - assertTrue("Should be one value but there were "+l.size(),l.size()==1); - NameValuePair nvp = l.get(0); - assertTrue("Name of element should be 'value' but was "+nvp.getNameString(), - nvp.getNameString().equals("value")); - ElementValue ev = nvp.getValue(); - assertTrue("Should be of type ArrayElementValue but is "+ev,ev instanceof ArrayElementValue); - ArrayElementValue aev = (ArrayElementValue)ev; - - assertTrue("Array element value should be of size 1 but is "+aev.getElementValuesArraySize(), - aev.getElementValuesArraySize()==1); - ElementValue[] evs = aev.getElementValuesArray(); - assertTrue("Entry in the array should be AnnotationElementValue but is "+evs[0], - evs[0] instanceof AnnotationElementValue); - AnnotationElementValue inner_ev = (AnnotationElementValue)evs[0]; - AnnotationGen a = inner_ev.getAnnotation(); - assertTrue("Should be SimpleAnnotation but is "+a.getTypeName(),a.getTypeName().equals("SimpleAnnotation")); - List envps = a.getValues(); - assertTrue("Should be one name value pair but found "+envps.size(),envps.size()==1); - NameValuePair envp = envps.get(0); - assertTrue("Name should be 'id' but it is "+envp.getNameString(),envp.getNameString().equals("id")); - assertTrue("Value of 'id' should be 4 but it is "+envp.getValue().stringifyValue(), - envp.getValue().stringifyValue().equals("4")); - } - - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public static List getListOfAnnotationNames(AnnotationGen a) { - List l = a.getValues(); - List names = new ArrayList(); - for (Iterator i = l.iterator(); i.hasNext();) { - NameValuePair element = i.next(); - names.add(element.getNameString()); - } - return names; - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleParameterAnnotationAttributeTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleParameterAnnotationAttributeTest.java deleted file mode 100644 index 1b8af7419..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/RuntimeVisibleParameterAnnotationAttributeTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ - -package org.aspectj.apache.bcel.classfile.tests; - -import java.io.File; -import java.io.IOException; -import java.util.Iterator; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; -import org.aspectj.apache.bcel.util.SyntheticRepository; - - -public class RuntimeVisibleParameterAnnotationAttributeTest extends BcelTestCase { - - - protected void setUp() throws Exception { - super.setUp(); - } - - - public void testAccessingRuntimeVisibleParameterAnnotations() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("AnnotatedParameters"); - Attribute[] rvaAttr = findAttribute("RuntimeVisibleParameterAnnotations",clazz); - Method[] methods = clazz.getMethods(); - - for (int i = 0; i < methods.length; i++) { - Method m = methods[i]; - if (m.getName().equals("foo")) { - RuntimeVisParamAnnos paramAnns = - (RuntimeVisParamAnnos) findAttribute("RuntimeVisibleParameterAnnotations",m.getAttributes()); - assertTrue("foo takes two parameters, not "+paramAnns.getParameterAnnotations().size(), - paramAnns.getParameterAnnotations().size()==2); - - AnnotationGen[] firstParamAnnotations = paramAnns.getAnnotationsOnParameter(0); - checkAnnotation(firstParamAnnotations[0],"SimpleAnnotation","id","2"); - - AnnotationGen[] secondParamAnnotations = paramAnns.getAnnotationsOnParameter(1); - checkAnnotation(secondParamAnnotations[0],"SimpleAnnotation","id","3"); - checkAnnotation(secondParamAnnotations[1],"AnnotationEnumElement","enumval","LSimpleEnum;Red"); - - } - if (m.getName().equals("main")) { - RuntimeVisParamAnnos paramAnns = - (RuntimeVisParamAnnos) findAttribute("RuntimeVisibleParameterAnnotations",m.getAttributes()); - assertTrue("main takes one parameter, not "+paramAnns.getParameterAnnotations().size(), - paramAnns.getParameterAnnotations().size()==1); - - AnnotationGen[] firstParamAnnotations = paramAnns.getAnnotationsOnParameter(0); - checkAnnotation(firstParamAnnotations[0],"SimpleAnnotation","id","1"); - } - } - } - - public void testAccessingParameterAnnotationsThroughGetAnnotations() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("AnnotatedParameters"); - Attribute[] rvaAttr = findAttribute("RuntimeVisibleParameterAnnotations",clazz); - - checkFooMethod(clazz); - } - - public void testParameterAnnotationsReadWrite() throws ClassNotFoundException,IOException { - JavaClass clazz = getClassFromJar("AnnotatedParameters"); - - checkFooMethod(clazz); - - // Write it out - File tfile = createTestdataFile("AnnotatedParameters.class"); - clazz.dump(tfile); - - SyntheticRepository repos2 = createRepos("."); - JavaClass clazz2 = repos2.loadClass("AnnotatedParameters"); - - checkFooMethod(clazz); - - assertTrue(tfile.delete()); - } - - - public void checkFooMethod(JavaClass clazz) { - Method[] methods = clazz.getMethods(); - - for (int i = 0; i < methods.length; i++) { - Method m = methods[i]; - if (m.getName().equals("foo")) { - - AnnotationGen[] firstParamAnnotations = m.getAnnotationsOnParameter(0); - checkAnnotation(firstParamAnnotations[0],"SimpleAnnotation","id","2"); - - AnnotationGen[] secondParamAnnotations = m.getAnnotationsOnParameter(1); - checkAnnotation(secondParamAnnotations[0],"SimpleAnnotation","id","3"); - checkAnnotation(secondParamAnnotations[1],"AnnotationEnumElement","enumval","LSimpleEnum;Red"); - - } - } - } - - private void checkAnnotation(AnnotationGen a,String name,String elementname,String elementvalue) { - assertTrue("Expected annotation to have name "+name+" but it had name "+a.getTypeName(), - a.getTypeName().equals(name)); - assertTrue("Expected annotation to have one element but it had "+a.getValues().size(),a.getValues().size()==1); - NameValuePair envp = a.getValues().get(0); - assertTrue("Expected element name "+elementname+" but was "+envp.getNameString(), - elementname.equals(envp.getNameString())); - assertTrue("Expected element value "+elementvalue+" but was "+envp.getValue().stringifyValue(), - elementvalue.equals(envp.getValue().stringifyValue())); - } - - - // helper methods - - public void checkValue(AnnotationGen a,String name,String tostring) { - for (Iterator i = a.getValues().iterator(); i.hasNext();) { - NameValuePair element = i.next(); - if (element.getNameString().equals(name)) { - if (!element.getValue().stringifyValue().equals(tostring)) { - fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue()); - } - return; - } - } - fail("Didnt find named element "+name); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java deleted file mode 100644 index be3e3d5ac..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java +++ /dev/null @@ -1,374 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2013 VMware - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation - * ******************************************************************/ -package org.aspectj.apache.bcel.classfile.tests; - -import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.Field; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeTypeAnnos; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; -import org.aspectj.apache.bcel.classfile.annotation.TypeAnnotationGen; - -public class TypeAnnotationsTest extends BcelTestCase { - - protected void setUp() throws Exception { - super.setUp(); - } - - public Attribute getAttribute(Attribute[] attrs, byte tag) { - for (Attribute attr: attrs) { - if (attr.getTag() == tag) { - return attr; - } - } - return null; - } - - public void testClassTypeParameter() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnClassTypeParameter"); - RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); - assertTrue(rvta.areVisible()); - TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); - assertEquals(2,tas.length); - checkTypeAnnotationClassTypeParameter(tas[0],0,"@Anno"); - checkTypeAnnotationClassTypeParameter(tas[1],1,"@Anno(value=2)"); - } - - public void testMethodTypeParameter() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodTypeParameter"); - Method m = getMethod(jc, "m"); - RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(m.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); - assertTrue(rvta.areVisible()); - TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); - assertEquals(1,tas.length); - checkTypeAnnotationMethodTypeParameter(tas[0],0,"@Anno"); - } - - public void testSuperinterface() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnSuperinterface1"); - RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); - assertTrue(rvta.areVisible()); - TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); - assertEquals(1,tas.length); - TypeAnnotationGen ta = tas[0]; - checkTypeAnnotationClassExtends(ta, 0, "@Anno"); - } - - public void testSupertypes() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnSupertypes"); - RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); - assertTrue(rvta.areVisible()); - TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); - assertEquals(3,tas.length); - checkTypeAnnotationClassExtends(tas[0],-1,"@Anno(value=1)"); - checkTypeAnnotationClassExtends(tas[1],0,"@Anno"); - checkTypeAnnotationClassExtends(tas[2],1,"@Anno(value=2)"); - } - - public void testClassTypeParameterBound() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnClassTypeParameterBound"); - RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); - assertTrue(rvta.areVisible()); - TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); - assertEquals(3,tas.length); - checkTypeAnnotationClassTypeParameterBound(tas[0],0,0,"@Anno"); - checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); - checkTypeAnnotationClassTypeParameterBound(tas[1],0,1,"@Anno(value=2)"); - checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); - checkTypeAnnotationClassTypeParameterBound(tas[2],0,1,"@Anno(value=3)"); - checkTypePath(tas[2],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0}); - } - - public void testMethodTypeParameterBound() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodTypeParameterBound"); - Method m = getMethod(jc, "m"); - RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(m.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); - assertTrue(rvta.areVisible()); - TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); - assertEquals(3,tas.length); - checkTypeAnnotationMethodTypeParameterBound(tas[0],0,0,"@Anno"); - checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); - checkTypeAnnotationMethodTypeParameterBound(tas[1],0,1,"@Anno(value=2)"); - checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); - checkTypeAnnotationMethodTypeParameterBound(tas[2],0,1,"@Anno(value=3)"); - checkTypePath(tas[2],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,1}); - } - - public void testField() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnField"); - Field f = getField(jc,"f1"); - RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(f.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); - assertTrue(rvta.areVisible()); - TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); - assertEquals(1,tas.length); - checkTypeAnnotationField(tas[0],"@Anno"); - checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); - - tas = getTypeAnnotations(getField(jc,"f2"),true); - checkTypeAnnotationField(tas[0],"@Anno"); - checkTypePath(tas[0],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0}); - - tas = getTypeAnnotations(getField(jc,"f3"),true); - checkTypeAnnotationField(tas[0],"@Anno"); - checkTypePath(tas[0],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0}); - - tas = getTypeAnnotations(getField(jc,"f4"),true); - checkTypeAnnotationField(tas[0],"@Anno"); - checkTypePath(tas[0],new int[]{ - TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0, - TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0 - }); - } - - public void testMethodReturn() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodReturn"); - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); - checkTypeAnnotationMethodReturn(tas[0],"@Anno"); - checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); - } - - public void testMethodReceiver() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodReceiver"); - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); - checkTypeAnnotationMethodReceiver(tas[0],"@Anno"); - checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); - } - - public void testMethodFormalParameter() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodFormalParameter"); - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); - checkTypeAnnotationMethodFormalParameter(tas[0],0, "@Anno"); - checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); - } - - public void testThrows() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnThrows"); - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); - checkTypeAnnotationThrows(tas[0],0, "@Anno"); - checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); - checkTypeAnnotationThrows(tas[1],1, "@Anno(value=2)"); - checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); - } - - public void testLocalVariable() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnLocalVariable"); - // TODO I think the attribute should be on the code for the method, not the method - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); - assertEquals(1,tas.length); - checkTypeAnnotationLocalVariable(tas[0],new int[]{11,8,1}, "@Anno"); - } - - public void testResourceVariable() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnResourceVariable"); - // TODO I think the attribute should be on the code for the method, not the method - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); - assertEquals(2,tas.length); - checkTypeAnnotationResourceVariable(tas[0],new int[]{17,204,1}, "@Anno"); - checkTypeAnnotationResourceVariable(tas[1],new int[]{36,114,3}, "@Anno(value=99)"); - } - - public void testExceptionParameter() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnExceptionParameter"); - // TODO I think the attribute should be on the code for the method, not the method - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); - assertEquals(2,tas.length); - checkTypeAnnotationExceptionParameter(tas[0],0, "@Anno(value=99)"); - checkTypeAnnotationExceptionParameter(tas[1],0, "@Anno"); - } - - public void testInstanceOf() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnInstanceOf"); - // TODO I think the attribute should be on the code for the method, not the method - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); - assertEquals(2,tas.length); - checkTypeAnnotationInstanceOf(tas[0],3, "@Anno(value=1)"); - checkTypeAnnotationInstanceOf(tas[1],18, "@Anno(value=1)"); - } - - public void testNew() throws Exception { - JavaClass jc = getClassFromJava8Jar("TypeAnnoOnNew"); - // TODO I think the attribute should be on the code for the method, not the method - TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); - assertEquals(4,tas.length); - checkTypeAnnotationNew(tas[0],0, "@Anno"); - checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); - - // TODO type path bugs in javac b90 according to the spec -// checkTypeAnnotationNew(tas[1],8, "@Anno(value=2)"); -// checkTypePath(tas[1],new int[]{ -// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 -// }); -// checkTypeAnnotationNew(tas[2],13, "@Anno(value=4)"); -// checkTypePath(tas[2],TypeAnnotationGen.NO_TYPE_PATH); -// checkTypeAnnotationNew(tas[3],13, "@Anno(value=3)"); -// checkTypePath(tas[3],new int[]{ -// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0, -// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 -// }); - } - - - // --- - private TypeAnnotationGen[] getTypeAnnotations(Attribute[] attrs, boolean visible) { - RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(attrs, visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); - return rvta.getTypeAnnotations(); - } - - private TypeAnnotationGen[] getTypeAnnotations(Method m, boolean visible) { - RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(m.getAttributes(), visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); - return rvta.getTypeAnnotations(); - } - - private TypeAnnotationGen[] getTypeAnnotations(Field f, boolean visible) { - RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(f.getAttributes(), visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); - return rvta.getTypeAnnotations(); - } - - private void checkTypePath(TypeAnnotationGen ta, int[] expectedTypePath) { - int[] typepath = ta.getTypePath(); - if (expectedTypePath==TypeAnnotationGen.NO_TYPE_PATH || expectedTypePath==null) { - if (typepath!=TypeAnnotationGen.NO_TYPE_PATH) { - fail("Expected no type path but was "+ta.getTypePathString()); - } - } else { - assertEquals(expectedTypePath.length, typepath.length); - for (int i=0;i0); - assertTrue(cf.getTime()>0); - } -} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/util/Play.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/util/Play.java deleted file mode 100644 index abea68c1d..000000000 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/util/Play.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.aspectj.apache.bcel.util; - -import java.io.File; -import java.io.FileInputStream; - -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.ClassParser; -import org.aspectj.apache.bcel.classfile.Field; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; - -public class Play { - - public static void printBytes(byte[] bs) { - StringBuilder sb = new StringBuilder("Bytes:"+bs.length+"["); - for (int i=0;i0) sb.append(" "); - sb.append(bs[i]); - } - sb.append("]"); - System.out.println(sb); - } - - public static void main(String[] args) throws Exception { - if (args==null || args.length==0 ) { - System.out.println("Specify a file"); - return; - } - if (!args[0].endsWith(".class")) { - args[0] = args[0]+".class"; - } - FileInputStream fis = new FileInputStream(new File(args[0])); - ClassParser cp = new ClassParser(fis,args[0]); - JavaClass jc = cp.parse(); - Attribute[] attributes = jc.getAttributes(); - printUsefulAttributes(attributes); - System.out.println("Fields"); - Field[] fs = jc.getFields(); - if (fs!=null) { - for (Field f: fs) { - System.out.println(f); - printUsefulAttributes(f.getAttributes()); - } - } - System.out.println("Methods"); - Method[] ms = jc.getMethods(); - if (ms!=null) { - for (Method m: ms) { - System.out.println(m); - printUsefulAttributes(m.getAttributes()); - System.out.println("Code attributes:"); - printUsefulAttributes(m.getCode().getAttributes()); - } - } -// Method[] ms = jc.getMethods(); -// for (Method m: ms) { -// System.out.println("=========="); -// System.out.println("Method: "+m.getName()+" modifiers=0x"+Integer.toHexString(m.getModifiers())); -// Attribute[] as = m.getAttributes(); -// for (Attribute a: as) { -// if (a.getName().toLowerCase().contains("synthetic")) { -// System.out.println("> "+a.getName()); -// } -// } -// } - } - - private static void printUsefulAttributes(Attribute[] attributes) throws Exception { - for (Attribute attribute: attributes) { - String n = attribute.getName(); - if (n.equals("RuntimeInvisibleAnnotations") || - n.equals("RuntimeVisibleAnnotations")) { - RuntimeAnnos ra = (RuntimeAnnos)attribute; - // private byte[] annotation_data; - java.lang.reflect.Field f = RuntimeAnnos.class.getDeclaredField("annotation_data"); - f.setAccessible(true); - byte[] bs = (byte[])f.get(ra); -// byte[] bs = unknown.getBytes(); - printBytes(bs); - } - } - } -} -- cgit v1.2.3