summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYing Wang <wangying@google.com>2012-02-27 10:21:35 -0800
committerYing Wang <wangying@google.com>2012-02-27 11:54:51 -0800
commitcfead78069f3dc32998dc118ee08cab3867acea2 (patch)
tree9600f15eed62fa9ba63ce5894d1f09fe686d5997 /src
parent10aa7224f49abe49d123bde5d34346202d49aaca (diff)
downloadexternal_proguard-cfead78069f3dc32998dc118ee08cab3867acea2.tar.gz
external_proguard-cfead78069f3dc32998dc118ee08cab3867acea2.tar.bz2
external_proguard-cfead78069f3dc32998dc118ee08cab3867acea2.zip
Upgrade from Progaurd 4.4 to 4.7.
Change-Id: Ie185d0be411a80cc6a330cafa8547252a7dc1d9c You can find the changelog here http://proguard.sourceforge.net/#downloads.html
Diffstat (limited to 'src')
-rw-r--r--src/proguard/ArgumentWordReader.java7
-rw-r--r--src/proguard/ClassPath.java2
-rw-r--r--src/proguard/ClassPathEntry.java137
-rw-r--r--src/proguard/ClassSpecification.java2
-rw-r--r--src/proguard/ClassSpecificationVisitorFactory.java5
-rw-r--r--src/proguard/Configuration.java11
-rw-r--r--src/proguard/ConfigurationConstants.java4
-rw-r--r--src/proguard/ConfigurationParser.java172
-rw-r--r--src/proguard/ConfigurationWriter.java44
-rw-r--r--src/proguard/DataEntryReaderFactory.java24
-rw-r--r--src/proguard/DataEntryWriterFactory.java26
-rw-r--r--src/proguard/DescriptorKeepChecker.java62
-rw-r--r--src/proguard/DuplicateClassPrinter.java2
-rw-r--r--src/proguard/FileWordReader.java52
-rw-r--r--src/proguard/FullyQualifiedClassNameChecker.java9
-rw-r--r--src/proguard/GPL.java14
-rw-r--r--src/proguard/Initializer.java23
-rw-r--r--src/proguard/InputReader.java4
-rw-r--r--src/proguard/KeepClassMemberChecker.java87
-rw-r--r--src/proguard/KeepClassSpecification.java2
-rw-r--r--src/proguard/LineWordReader.java74
-rw-r--r--src/proguard/MemberSpecification.java2
-rw-r--r--src/proguard/OutputWriter.java66
-rw-r--r--src/proguard/ParseException.java2
-rw-r--r--src/proguard/ProGuard.java51
-rw-r--r--src/proguard/SeedPrinter.java97
-rw-r--r--src/proguard/SubclassedClassFilter.java2
-rw-r--r--src/proguard/Targeter.java2
-rw-r--r--src/proguard/UpToDateChecker.java219
-rw-r--r--src/proguard/WordReader.java127
-rw-r--r--src/proguard/ant/ClassPathElement.java2
-rw-r--r--src/proguard/ant/ClassSpecificationElement.java3
-rw-r--r--src/proguard/ant/ConfigurationElement.java2
-rw-r--r--src/proguard/ant/ConfigurationTask.java5
-rw-r--r--src/proguard/ant/FilterElement.java2
-rw-r--r--src/proguard/ant/KeepSpecificationElement.java2
-rw-r--r--src/proguard/ant/MemberSpecificationElement.java5
-rw-r--r--src/proguard/ant/ProGuardTask.java38
-rw-r--r--src/proguard/classfile/ClassConstants.java103
-rw-r--r--src/proguard/classfile/ClassPool.java19
-rw-r--r--src/proguard/classfile/Clazz.java31
-rw-r--r--src/proguard/classfile/Field.java2
-rw-r--r--src/proguard/classfile/LibraryClass.java61
-rw-r--r--src/proguard/classfile/LibraryField.java2
-rw-r--r--src/proguard/classfile/LibraryMember.java2
-rw-r--r--src/proguard/classfile/LibraryMethod.java2
-rw-r--r--src/proguard/classfile/Member.java2
-rw-r--r--src/proguard/classfile/Method.java2
-rw-r--r--src/proguard/classfile/ProgramClass.java92
-rw-r--r--src/proguard/classfile/ProgramField.java2
-rw-r--r--src/proguard/classfile/ProgramMember.java2
-rw-r--r--src/proguard/classfile/ProgramMethod.java2
-rw-r--r--src/proguard/classfile/VisitorAccepter.java2
-rw-r--r--src/proguard/classfile/attribute/Attribute.java2
-rwxr-xr-xsrc/proguard/classfile/attribute/BootstrapMethodInfo.java89
-rwxr-xr-xsrc/proguard/classfile/attribute/BootstrapMethodsAttribute.java95
-rw-r--r--src/proguard/classfile/attribute/CodeAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/ConstantValueAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/DeprecatedAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/EnclosingMethodAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/ExceptionInfo.java2
-rw-r--r--src/proguard/classfile/attribute/ExceptionsAttribute.java8
-rw-r--r--src/proguard/classfile/attribute/InnerClassesAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/InnerClassesInfo.java11
-rw-r--r--src/proguard/classfile/attribute/LineNumberInfo.java2
-rw-r--r--src/proguard/classfile/attribute/LineNumberTableAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/LocalVariableInfo.java20
-rw-r--r--src/proguard/classfile/attribute/LocalVariableTableAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/LocalVariableTypeInfo.java20
-rw-r--r--src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/SignatureAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/SourceDirAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/SourceFileAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/SyntheticAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/UnknownAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/Annotation.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/AnnotationElementValue.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/ArrayElementValue.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/ClassElementValue.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/ConstantElementValue.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/ElementValue.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/DoubleType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/FloatType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/FullFrame.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/IntegerType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/LessZeroFrame.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/LongType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/MoreZeroFrame.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/NullType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/ObjectType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/SameOneFrame.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/SameZeroFrame.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/StackMapAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/StackMapFrame.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/TopType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/UninitializedThisType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/UninitializedType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/VerificationType.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java55
-rw-r--r--src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java55
-rw-r--r--src/proguard/classfile/attribute/visitor/AttributeNameFilter.java29
-rw-r--r--src/proguard/classfile/attribute/visitor/AttributeVisitor.java13
-rwxr-xr-xsrc/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java40
-rw-r--r--src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java2
-rw-r--r--src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java11
-rw-r--r--src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java293
-rw-r--r--src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java11
-rw-r--r--src/proguard/classfile/attribute/visitor/StackSizeComputer.java9
-rw-r--r--src/proguard/classfile/constant/ClassConstant.java2
-rw-r--r--src/proguard/classfile/constant/Constant.java2
-rw-r--r--src/proguard/classfile/constant/DoubleConstant.java2
-rw-r--r--src/proguard/classfile/constant/FieldrefConstant.java2
-rw-r--r--src/proguard/classfile/constant/FloatConstant.java2
-rw-r--r--src/proguard/classfile/constant/IntegerConstant.java2
-rw-r--r--src/proguard/classfile/constant/InterfaceMethodrefConstant.java2
-rwxr-xr-xsrc/proguard/classfile/constant/InvokeDynamicConstant.java148
-rw-r--r--src/proguard/classfile/constant/LongConstant.java2
-rwxr-xr-xsrc/proguard/classfile/constant/MethodHandleConstant.java124
-rw-r--r--src/proguard/classfile/constant/MethodTypeConstant.java93
-rw-r--r--src/proguard/classfile/constant/MethodrefConstant.java2
-rw-r--r--src/proguard/classfile/constant/NameAndTypeConstant.java2
-rw-r--r--src/proguard/classfile/constant/RefConstant.java2
-rw-r--r--src/proguard/classfile/constant/StringConstant.java2
-rw-r--r--src/proguard/classfile/constant/Utf8Constant.java2
-rw-r--r--src/proguard/classfile/constant/visitor/AllConstantVisitor.java2
-rw-r--r--src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java100
-rw-r--r--src/proguard/classfile/constant/visitor/ConstantTagFilter.java86
-rw-r--r--src/proguard/classfile/constant/visitor/ConstantVisitor.java5
-rw-r--r--src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java12
-rw-r--r--src/proguard/classfile/constant/visitor/MethodrefTraveler.java (renamed from src/proguard/classfile/visitor/ClassForNameClassVisitor.java)32
-rw-r--r--src/proguard/classfile/editor/AccessFixer.java28
-rw-r--r--src/proguard/classfile/editor/AnnotationAdder.java2
-rw-r--r--src/proguard/classfile/editor/AnnotationsAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/AttributeAdder.java4
-rw-r--r--src/proguard/classfile/editor/AttributeSorter.java2
-rw-r--r--src/proguard/classfile/editor/AttributesEditor.java2
-rw-r--r--src/proguard/classfile/editor/BridgeMethodFixer.java117
-rw-r--r--src/proguard/classfile/editor/ClassEditor.java2
-rw-r--r--src/proguard/classfile/editor/ClassElementSorter.java2
-rw-r--r--src/proguard/classfile/editor/ClassMemberSorter.java2
-rw-r--r--src/proguard/classfile/editor/ClassReferenceFixer.java2
-rw-r--r--src/proguard/classfile/editor/CodeAttributeComposer.java48
-rw-r--r--src/proguard/classfile/editor/CodeAttributeEditor.java161
-rw-r--r--src/proguard/classfile/editor/CodeAttributeEditorResetter.java2
-rw-r--r--src/proguard/classfile/editor/ComparableConstant.java83
-rw-r--r--src/proguard/classfile/editor/ConstantAdder.java47
-rw-r--r--src/proguard/classfile/editor/ConstantPoolEditor.java119
-rw-r--r--src/proguard/classfile/editor/ConstantPoolRemapper.java105
-rw-r--r--src/proguard/classfile/editor/ConstantPoolShrinker.java578
-rw-r--r--src/proguard/classfile/editor/ConstantPoolSorter.java7
-rw-r--r--src/proguard/classfile/editor/ElementValueAdder.java2
-rw-r--r--src/proguard/classfile/editor/ElementValuesEditor.java2
-rw-r--r--src/proguard/classfile/editor/ExceptionAdder.java2
-rw-r--r--src/proguard/classfile/editor/ExceptionInfoAdder.java2
-rw-r--r--src/proguard/classfile/editor/ExceptionsAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/InnerClassesAccessFixer.java83
-rw-r--r--src/proguard/classfile/editor/InstructionAdder.java2
-rw-r--r--src/proguard/classfile/editor/InstructionWriter.java2
-rw-r--r--src/proguard/classfile/editor/InterfaceAdder.java2
-rw-r--r--src/proguard/classfile/editor/InterfaceSorter.java119
-rw-r--r--src/proguard/classfile/editor/InterfacesEditor.java2
-rw-r--r--src/proguard/classfile/editor/LineNumberInfoAdder.java2
-rw-r--r--src/proguard/classfile/editor/LineNumberTableAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableInfoAdder.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/MemberAdder.java49
-rw-r--r--src/proguard/classfile/editor/MemberReferenceFixer.java37
-rw-r--r--src/proguard/classfile/editor/MethodInvocationFixer.java57
-rw-r--r--src/proguard/classfile/editor/NameAndTypeShrinker.java (renamed from src/proguard/obfuscate/NameAndTypeUsageMarker.java)101
-rw-r--r--src/proguard/classfile/editor/NamedAttributeDeleter.java2
-rw-r--r--src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/StackSizeUpdater.java2
-rw-r--r--src/proguard/classfile/editor/SubclassAdder.java2
-rw-r--r--src/proguard/classfile/editor/SubclassToAdder.java2
-rw-r--r--src/proguard/classfile/editor/Utf8Shrinker.java (renamed from src/proguard/obfuscate/Utf8UsageMarker.java)81
-rw-r--r--src/proguard/classfile/editor/VariableCleaner.java204
-rw-r--r--src/proguard/classfile/editor/VariableEditor.java11
-rw-r--r--src/proguard/classfile/editor/VariableRemapper.java75
-rw-r--r--src/proguard/classfile/editor/VariableSizeUpdater.java13
-rw-r--r--src/proguard/classfile/instruction/BranchInstruction.java2
-rw-r--r--src/proguard/classfile/instruction/ConstantInstruction.java34
-rw-r--r--src/proguard/classfile/instruction/Instruction.java8
-rw-r--r--src/proguard/classfile/instruction/InstructionConstants.java36
-rw-r--r--src/proguard/classfile/instruction/InstructionFactory.java3
-rw-r--r--src/proguard/classfile/instruction/InstructionUtil.java2
-rw-r--r--src/proguard/classfile/instruction/LookUpSwitchInstruction.java2
-rw-r--r--src/proguard/classfile/instruction/SimpleInstruction.java2
-rw-r--r--src/proguard/classfile/instruction/SwitchInstruction.java2
-rw-r--r--src/proguard/classfile/instruction/TableSwitchInstruction.java2
-rw-r--r--src/proguard/classfile/instruction/VariableInstruction.java2
-rw-r--r--src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java2
-rw-r--r--src/proguard/classfile/instruction/visitor/InstructionCounter.java2
-rw-r--r--src/proguard/classfile/instruction/visitor/InstructionVisitor.java2
-rw-r--r--src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java2
-rw-r--r--src/proguard/classfile/io/LibraryClassReader.java25
-rw-r--r--src/proguard/classfile/io/ProgramClassReader.java79
-rw-r--r--src/proguard/classfile/io/ProgramClassWriter.java53
-rw-r--r--src/proguard/classfile/io/RuntimeDataInput.java2
-rw-r--r--src/proguard/classfile/io/RuntimeDataOutput.java2
-rw-r--r--src/proguard/classfile/util/AccessUtil.java2
-rw-r--r--src/proguard/classfile/util/ClassReferenceInitializer.java108
-rw-r--r--src/proguard/classfile/util/ClassSubHierarchyInitializer.java2
-rw-r--r--src/proguard/classfile/util/ClassSuperHierarchyInitializer.java7
-rw-r--r--src/proguard/classfile/util/ClassUtil.java85
-rw-r--r--src/proguard/classfile/util/DescriptorClassEnumeration.java2
-rw-r--r--src/proguard/classfile/util/DynamicClassReferenceInitializer.java21
-rw-r--r--src/proguard/classfile/util/DynamicMemberReferenceInitializer.java484
-rw-r--r--src/proguard/classfile/util/ExternalTypeEnumeration.java2
-rw-r--r--src/proguard/classfile/util/InstructionSequenceMatcher.java182
-rw-r--r--src/proguard/classfile/util/InternalTypeEnumeration.java2
-rw-r--r--src/proguard/classfile/util/MemberFinder.java2
-rw-r--r--src/proguard/classfile/util/MethodLinker.java19
-rw-r--r--src/proguard/classfile/util/SimplifiedVisitor.java28
-rw-r--r--src/proguard/classfile/util/StringReferenceInitializer.java5
-rw-r--r--src/proguard/classfile/util/StringSharer.java21
-rw-r--r--src/proguard/classfile/util/WarningPrinter.java2
-rw-r--r--src/proguard/classfile/visitor/AllClassVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/AllFieldVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/AllMemberVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/AllMethodVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/BottomClassFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ClassAccessFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ClassCleaner.java2
-rw-r--r--src/proguard/classfile/visitor/ClassCollector.java2
-rw-r--r--src/proguard/classfile/visitor/ClassCounter.java2
-rw-r--r--src/proguard/classfile/visitor/ClassHierarchyTraveler.java2
-rw-r--r--src/proguard/classfile/visitor/ClassNameFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ClassPoolFiller.java2
-rw-r--r--src/proguard/classfile/visitor/ClassPoolVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/ClassPresenceFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ClassPrinter.java69
-rw-r--r--src/proguard/classfile/visitor/ClassVersionFilter.java15
-rw-r--r--src/proguard/classfile/visitor/ClassVersionSetter.java2
-rw-r--r--src/proguard/classfile/visitor/ClassVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/ConcreteClassDownTraveler.java2
-rw-r--r--src/proguard/classfile/visitor/DotClassClassVisitor.java4
-rw-r--r--src/proguard/classfile/visitor/ExceptClassFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ExceptClassesFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ExceptionCounter.java2
-rw-r--r--src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/ExceptionHandlerFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ExceptionOffsetFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ExceptionRangeFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ImplementedClassConstantFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ImplementedClassFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ImplementingClassConstantFilter.java2
-rw-r--r--src/proguard/classfile/visitor/LibraryClassFilter.java2
-rw-r--r--src/proguard/classfile/visitor/LibraryMemberFilter.java2
-rw-r--r--src/proguard/classfile/visitor/MemberAccessFilter.java2
-rw-r--r--src/proguard/classfile/visitor/MemberClassAccessFilter.java2
-rw-r--r--src/proguard/classfile/visitor/MemberCollector.java2
-rw-r--r--src/proguard/classfile/visitor/MemberCounter.java2
-rw-r--r--src/proguard/classfile/visitor/MemberDescriptorFilter.java2
-rw-r--r--src/proguard/classfile/visitor/MemberNameFilter.java2
-rw-r--r--src/proguard/classfile/visitor/MemberToClassVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/MemberVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/MethodImplementationFilter.java2
-rw-r--r--src/proguard/classfile/visitor/MethodImplementationTraveler.java2
-rw-r--r--src/proguard/classfile/visitor/MultiClassPoolVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/MultiClassVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/MultiMemberVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/NamedClassVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/NamedFieldVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/NamedMethodVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/ProgramClassFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ProgramMemberFilter.java2
-rw-r--r--src/proguard/classfile/visitor/ReferencedClassVisitor.java9
-rw-r--r--src/proguard/classfile/visitor/ReferencedMemberVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/SimilarMemberVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/SimpleClassPrinter.java2
-rw-r--r--src/proguard/classfile/visitor/SubclassFilter.java2
-rw-r--r--src/proguard/classfile/visitor/SubclassTraveler.java2
-rw-r--r--src/proguard/classfile/visitor/VariableClassVisitor.java2
-rw-r--r--src/proguard/classfile/visitor/VariableMemberVisitor.java2
-rw-r--r--src/proguard/evaluation/BasicBranchUnit.java2
-rw-r--r--src/proguard/evaluation/BasicInvocationUnit.java47
-rw-r--r--src/proguard/evaluation/BranchUnit.java2
-rw-r--r--src/proguard/evaluation/ClassConstantValueFactory.java53
-rw-r--r--src/proguard/evaluation/ConstantValueFactory.java113
-rw-r--r--src/proguard/evaluation/InvocationUnit.java2
-rw-r--r--src/proguard/evaluation/Processor.java101
-rw-r--r--src/proguard/evaluation/Stack.java9
-rw-r--r--src/proguard/evaluation/TracedStack.java2
-rw-r--r--src/proguard/evaluation/TracedVariables.java32
-rw-r--r--src/proguard/evaluation/Variables.java9
-rw-r--r--src/proguard/evaluation/value/Category1Value.java2
-rw-r--r--src/proguard/evaluation/value/Category2Value.java2
-rw-r--r--src/proguard/evaluation/value/ComparisonValue.java10
-rw-r--r--src/proguard/evaluation/value/CompositeDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/CompositeFloatValue.java10
-rw-r--r--src/proguard/evaluation/value/CompositeIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/CompositeLongValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedByteValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedCharacterValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedLongValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedShortValue.java2
-rw-r--r--src/proguard/evaluation/value/DoubleValue.java7
-rw-r--r--src/proguard/evaluation/value/FloatValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedLongValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedReferenceValue.java13
-rw-r--r--src/proguard/evaluation/value/IdentifiedValueFactory.java2
-rw-r--r--src/proguard/evaluation/value/InstructionOffsetValue.java2
-rw-r--r--src/proguard/evaluation/value/IntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/LongValue.java2
-rw-r--r--src/proguard/evaluation/value/NegatedDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/NegatedFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/NegatedIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/NegatedLongValue.java2
-rw-r--r--src/proguard/evaluation/value/ParticularDoubleValue.java14
-rw-r--r--src/proguard/evaluation/value/ParticularFloatValue.java14
-rw-r--r--src/proguard/evaluation/value/ParticularIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/ParticularLongValue.java2
-rw-r--r--src/proguard/evaluation/value/ReferenceValue.java40
-rw-r--r--src/proguard/evaluation/value/SpecificDoubleValue.java11
-rw-r--r--src/proguard/evaluation/value/SpecificFloatValue.java11
-rw-r--r--src/proguard/evaluation/value/SpecificIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/SpecificLongValue.java2
-rw-r--r--src/proguard/evaluation/value/SpecificValueFactory.java14
-rw-r--r--src/proguard/evaluation/value/TopValue.java2
-rw-r--r--src/proguard/evaluation/value/UnknownDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/UnknownFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/UnknownIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/UnknownLongValue.java2
-rw-r--r--src/proguard/evaluation/value/Value.java2
-rw-r--r--src/proguard/evaluation/value/ValueFactory.java2
-rw-r--r--src/proguard/gui/ClassPathPanel.java8
-rw-r--r--src/proguard/gui/ClassSpecificationDialog.java22
-rw-r--r--src/proguard/gui/ClassSpecificationsPanel.java2
-rw-r--r--src/proguard/gui/ExtensionFileFilter.java2
-rw-r--r--src/proguard/gui/FilterBuilder.java2
-rw-r--r--src/proguard/gui/FilterDialog.java12
-rw-r--r--src/proguard/gui/GUIResources.java2
-rw-r--r--src/proguard/gui/GUIResources.properties46
-rw-r--r--src/proguard/gui/KeepSpecificationsPanel.java2
-rw-r--r--src/proguard/gui/ListPanel.java2
-rw-r--r--src/proguard/gui/MemberSpecificationDialog.java14
-rw-r--r--src/proguard/gui/MemberSpecificationsPanel.java2
-rw-r--r--src/proguard/gui/MessageDialogRunnable.java2
-rw-r--r--src/proguard/gui/OptimizationsDialog.java2
-rw-r--r--src/proguard/gui/ProGuardGUI.java173
-rw-r--r--src/proguard/gui/ProGuardRunnable.java2
-rw-r--r--src/proguard/gui/ReTraceRunnable.java2
-rw-r--r--src/proguard/gui/SwingUtil.java2
-rw-r--r--src/proguard/gui/TabbedPane.java2
-rw-r--r--src/proguard/gui/TextAreaOutputStream.java2
-rw-r--r--src/proguard/gui/splash/BufferedSprite.java2
-rw-r--r--src/proguard/gui/splash/CircleSprite.java2
-rw-r--r--src/proguard/gui/splash/ClipSprite.java2
-rw-r--r--src/proguard/gui/splash/ColorSprite.java2
-rw-r--r--src/proguard/gui/splash/CompositeSprite.java2
-rw-r--r--src/proguard/gui/splash/ConstantColor.java2
-rw-r--r--src/proguard/gui/splash/ConstantDouble.java2
-rw-r--r--src/proguard/gui/splash/ConstantFont.java2
-rw-r--r--src/proguard/gui/splash/ConstantInt.java2
-rw-r--r--src/proguard/gui/splash/ConstantString.java2
-rw-r--r--src/proguard/gui/splash/ConstantTiming.java2
-rw-r--r--src/proguard/gui/splash/FontSprite.java2
-rw-r--r--src/proguard/gui/splash/ImageSprite.java2
-rw-r--r--src/proguard/gui/splash/LinearColor.java2
-rw-r--r--src/proguard/gui/splash/LinearDouble.java2
-rw-r--r--src/proguard/gui/splash/LinearInt.java2
-rw-r--r--src/proguard/gui/splash/LinearTiming.java2
-rw-r--r--src/proguard/gui/splash/OverrideGraphics2D.java2
-rw-r--r--src/proguard/gui/splash/RectangleSprite.java2
-rw-r--r--src/proguard/gui/splash/SawToothTiming.java2
-rw-r--r--src/proguard/gui/splash/ShadowedSprite.java2
-rw-r--r--src/proguard/gui/splash/SineTiming.java2
-rw-r--r--src/proguard/gui/splash/SmoothTiming.java2
-rw-r--r--src/proguard/gui/splash/SplashPanel.java2
-rw-r--r--src/proguard/gui/splash/Sprite.java2
-rw-r--r--src/proguard/gui/splash/TextSprite.java2
-rw-r--r--src/proguard/gui/splash/TimeSwitchSprite.java2
-rw-r--r--src/proguard/gui/splash/Timing.java2
-rw-r--r--src/proguard/gui/splash/TypeWriterString.java2
-rw-r--r--src/proguard/gui/splash/VariableColor.java2
-rw-r--r--src/proguard/gui/splash/VariableDouble.java2
-rw-r--r--src/proguard/gui/splash/VariableFont.java2
-rw-r--r--src/proguard/gui/splash/VariableInt.java2
-rw-r--r--src/proguard/gui/splash/VariableSizeFont.java2
-rw-r--r--src/proguard/gui/splash/VariableString.java2
-rw-r--r--src/proguard/io/CascadingDataEntryWriter.java2
-rw-r--r--src/proguard/io/ClassFilter.java2
-rw-r--r--src/proguard/io/ClassReader.java4
-rw-r--r--src/proguard/io/ClassRewriter.java2
-rw-r--r--src/proguard/io/DataEntry.java2
-rw-r--r--src/proguard/io/DataEntryClassWriter.java85
-rw-r--r--src/proguard/io/DataEntryCopier.java2
-rw-r--r--src/proguard/io/DataEntryDirectoryFilter.java2
-rw-r--r--src/proguard/io/DataEntryFilter.java2
-rw-r--r--src/proguard/io/DataEntryNameFilter.java2
-rw-r--r--src/proguard/io/DataEntryObfuscator.java47
-rw-r--r--src/proguard/io/DataEntryParentFilter.java2
-rw-r--r--src/proguard/io/DataEntryPump.java2
-rw-r--r--src/proguard/io/DataEntryReader.java2
-rw-r--r--src/proguard/io/DataEntryRenamer.java6
-rw-r--r--src/proguard/io/DataEntryRewriter.java2
-rw-r--r--src/proguard/io/DataEntryWriter.java2
-rw-r--r--src/proguard/io/DirectoryFilter.java2
-rw-r--r--src/proguard/io/DirectoryPump.java2
-rw-r--r--src/proguard/io/DirectoryWriter.java2
-rw-r--r--src/proguard/io/FileDataEntry.java2
-rw-r--r--src/proguard/io/FilteredDataEntryReader.java2
-rw-r--r--src/proguard/io/FilteredDataEntryWriter.java2
-rw-r--r--src/proguard/io/Finisher.java2
-rw-r--r--src/proguard/io/JarReader.java2
-rw-r--r--src/proguard/io/JarWriter.java2
-rw-r--r--src/proguard/io/ManifestRewriter.java2
-rw-r--r--src/proguard/io/NameFilter.java2
-rw-r--r--src/proguard/io/ParentDataEntryWriter.java2
-rw-r--r--src/proguard/io/RenamedDataEntry.java2
-rw-r--r--src/proguard/io/ZipDataEntry.java2
-rw-r--r--src/proguard/obfuscate/AttributeShrinker.java9
-rw-r--r--src/proguard/obfuscate/AttributeUsageMarker.java4
-rw-r--r--src/proguard/obfuscate/ClassObfuscator.java16
-rw-r--r--src/proguard/obfuscate/ClassRenamer.java2
-rw-r--r--src/proguard/obfuscate/DictionaryNameFactory.java2
-rw-r--r--src/proguard/obfuscate/MapCleaner.java2
-rw-r--r--src/proguard/obfuscate/MappingKeeper.java2
-rw-r--r--src/proguard/obfuscate/MappingPrinter.java2
-rw-r--r--src/proguard/obfuscate/MappingProcessor.java2
-rw-r--r--src/proguard/obfuscate/MappingReader.java2
-rw-r--r--src/proguard/obfuscate/MemberNameCleaner.java2
-rw-r--r--src/proguard/obfuscate/MemberNameCollector.java2
-rw-r--r--src/proguard/obfuscate/MemberNameConflictFixer.java2
-rw-r--r--src/proguard/obfuscate/MemberNameFilter.java120
-rw-r--r--src/proguard/obfuscate/MemberObfuscator.java2
-rw-r--r--src/proguard/obfuscate/MemberSpecialNameFilter.java12
-rw-r--r--src/proguard/obfuscate/MultiMappingProcessor.java2
-rw-r--r--src/proguard/obfuscate/NameAndTypeShrinker.java112
-rw-r--r--src/proguard/obfuscate/NameFactory.java2
-rw-r--r--src/proguard/obfuscate/NameFactoryResetter.java2
-rw-r--r--src/proguard/obfuscate/NameMarker.java2
-rw-r--r--src/proguard/obfuscate/NumericNameFactory.java2
-rw-r--r--src/proguard/obfuscate/Obfuscator.java44
-rw-r--r--src/proguard/obfuscate/ParameterNameMarker.java128
-rw-r--r--src/proguard/obfuscate/SimpleNameFactory.java2
-rw-r--r--src/proguard/obfuscate/SourceFileRenamer.java2
-rw-r--r--src/proguard/obfuscate/SpecialNameFactory.java2
-rw-r--r--src/proguard/obfuscate/Utf8Shrinker.java110
-rw-r--r--src/proguard/optimize/BootstrapMethodArgumentShrinker.java103
-rw-r--r--src/proguard/optimize/ChangedCodePrinter.java8
-rw-r--r--src/proguard/optimize/ConstantMemberFilter.java2
-rw-r--r--src/proguard/optimize/ConstantParameterFilter.java2
-rw-r--r--src/proguard/optimize/DuplicateInitializerFixer.java34
-rw-r--r--src/proguard/optimize/DuplicateInitializerInvocationFixer.java37
-rw-r--r--src/proguard/optimize/KeepMarker.java2
-rw-r--r--src/proguard/optimize/KeptClassFilter.java69
-rw-r--r--src/proguard/optimize/KeptMemberFilter.java88
-rw-r--r--src/proguard/optimize/MemberDescriptorSpecializer.java4
-rw-r--r--src/proguard/optimize/MethodDescriptorShrinker.java12
-rw-r--r--src/proguard/optimize/MethodStaticizer.java2
-rw-r--r--src/proguard/optimize/OptimizationInfoMemberFilter.java2
-rw-r--r--src/proguard/optimize/Optimizer.java197
-rw-r--r--src/proguard/optimize/ParameterShrinker.java4
-rw-r--r--src/proguard/optimize/TailRecursionSimplifier.java101
-rw-r--r--src/proguard/optimize/WriteOnlyFieldFilter.java2
-rw-r--r--src/proguard/optimize/evaluation/EvaluationShrinker.java290
-rw-r--r--src/proguard/optimize/evaluation/EvaluationSimplifier.java15
-rw-r--r--src/proguard/optimize/evaluation/LivenessAnalyzer.java12
-rw-r--r--src/proguard/optimize/evaluation/LoadingInvocationUnit.java20
-rw-r--r--src/proguard/optimize/evaluation/PartialEvaluator.java141
-rw-r--r--src/proguard/optimize/evaluation/StoringInvocationUnit.java2
-rw-r--r--src/proguard/optimize/evaluation/TracedBranchUnit.java2
-rw-r--r--src/proguard/optimize/evaluation/VariableOptimizer.java127
-rw-r--r--src/proguard/optimize/info/AccessMethodMarker.java19
-rw-r--r--src/proguard/optimize/info/BackwardBranchMarker.java2
-rw-r--r--src/proguard/optimize/info/CatchExceptionMarker.java2
-rw-r--r--src/proguard/optimize/info/CaughtClassFilter.java2
-rw-r--r--src/proguard/optimize/info/CaughtClassMarker.java7
-rw-r--r--src/proguard/optimize/info/ClassOptimizationInfo.java16
-rw-r--r--src/proguard/optimize/info/ClassOptimizationInfoSetter.java2
-rw-r--r--src/proguard/optimize/info/DotClassFilter.java2
-rw-r--r--src/proguard/optimize/info/DotClassMarker.java2
-rw-r--r--src/proguard/optimize/info/ExceptionInstructionChecker.java104
-rw-r--r--src/proguard/optimize/info/FieldOptimizationInfo.java56
-rw-r--r--src/proguard/optimize/info/InstanceofClassFilter.java2
-rw-r--r--src/proguard/optimize/info/InstanceofClassMarker.java2
-rw-r--r--src/proguard/optimize/info/InstantiationClassFilter.java2
-rw-r--r--src/proguard/optimize/info/InstantiationClassMarker.java2
-rw-r--r--src/proguard/optimize/info/MemberOptimizationInfoSetter.java18
-rw-r--r--src/proguard/optimize/info/MethodInvocationMarker.java2
-rw-r--r--src/proguard/optimize/info/MethodOptimizationInfo.java6
-rw-r--r--src/proguard/optimize/info/NoSideEffectMethodMarker.java2
-rw-r--r--src/proguard/optimize/info/NonPrivateMemberMarker.java16
-rw-r--r--src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java28
-rw-r--r--src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java72
-rw-r--r--src/proguard/optimize/info/ParameterUsageMarker.java8
-rw-r--r--src/proguard/optimize/info/ReadWriteFieldMarker.java2
-rw-r--r--src/proguard/optimize/info/SideEffectInstructionChecker.java109
-rw-r--r--src/proguard/optimize/info/SideEffectMethodMarker.java2
-rw-r--r--src/proguard/optimize/info/StaticInitializerContainingClassFilter.java62
-rw-r--r--src/proguard/optimize/info/StaticInitializerContainingClassMarker.java65
-rw-r--r--src/proguard/optimize/info/SuperInvocationMarker.java2
-rw-r--r--src/proguard/optimize/info/VariableUsageMarker.java11
-rw-r--r--src/proguard/optimize/peephole/BranchTargetFinder.java28
-rw-r--r--src/proguard/optimize/peephole/ClassFinalizer.java2
-rw-r--r--src/proguard/optimize/peephole/ClassMerger.java57
-rw-r--r--src/proguard/optimize/peephole/GotoCommonCodeReplacer.java2
-rw-r--r--src/proguard/optimize/peephole/GotoGotoReplacer.java7
-rw-r--r--src/proguard/optimize/peephole/GotoReturnReplacer.java2
-rw-r--r--src/proguard/optimize/peephole/HorizontalClassMerger.java2
-rw-r--r--src/proguard/optimize/peephole/InstructionSequenceConstants.java1233
-rw-r--r--src/proguard/optimize/peephole/InstructionSequenceReplacer.java164
-rw-r--r--src/proguard/optimize/peephole/InstructionSequencesReplacer.java2
-rw-r--r--src/proguard/optimize/peephole/MemberPrivatizer.java2
-rw-r--r--src/proguard/optimize/peephole/MethodFinalizer.java2
-rw-r--r--src/proguard/optimize/peephole/MethodInliner.java120
-rw-r--r--src/proguard/optimize/peephole/NopRemover.java2
-rw-r--r--src/proguard/optimize/peephole/PeepholeOptimizer.java2
-rw-r--r--src/proguard/optimize/peephole/ReachableCodeMarker.java9
-rw-r--r--src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java44
-rw-r--r--src/proguard/optimize/peephole/TargetClassChanger.java62
-rw-r--r--src/proguard/optimize/peephole/UnreachableCodeRemover.java2
-rw-r--r--src/proguard/optimize/peephole/UnreachableExceptionRemover.java2
-rw-r--r--src/proguard/optimize/peephole/VariableShrinker.java2
-rw-r--r--src/proguard/optimize/peephole/VerticalClassMerger.java2
-rw-r--r--src/proguard/preverify/CodePreverifier.java2
-rw-r--r--src/proguard/preverify/CodeSubroutineInliner.java3
-rw-r--r--src/proguard/preverify/Preverifier.java7
-rw-r--r--src/proguard/preverify/SubroutineInliner.java3
-rw-r--r--src/proguard/retrace/ReTrace.java4
-rw-r--r--src/proguard/shrink/AnnotationUsageMarker.java38
-rw-r--r--src/proguard/shrink/ClassShrinker.java52
-rw-r--r--src/proguard/shrink/InnerUsageMarker.java2
-rw-r--r--src/proguard/shrink/InterfaceUsageMarker.java2
-rw-r--r--src/proguard/shrink/ShortestUsageMark.java2
-rw-r--r--src/proguard/shrink/ShortestUsageMarker.java2
-rw-r--r--src/proguard/shrink/ShortestUsagePrinter.java2
-rw-r--r--src/proguard/shrink/Shrinker.java17
-rw-r--r--src/proguard/shrink/UsageMarker.java174
-rw-r--r--src/proguard/shrink/UsagePrinter.java2
-rw-r--r--src/proguard/shrink/UsedClassFilter.java2
-rw-r--r--src/proguard/shrink/UsedMemberFilter.java4
-rw-r--r--src/proguard/util/AndMatcher.java2
-rw-r--r--src/proguard/util/ClassNameParser.java2
-rw-r--r--src/proguard/util/ConstantMatcher.java2
-rw-r--r--src/proguard/util/EmptyStringMatcher.java2
-rw-r--r--src/proguard/util/ExtensionMatcher.java2
-rw-r--r--src/proguard/util/FileNameParser.java2
-rw-r--r--src/proguard/util/FixedStringMatcher.java2
-rw-r--r--src/proguard/util/ListMatcher.java2
-rw-r--r--src/proguard/util/ListParser.java2
-rw-r--r--src/proguard/util/ListUtil.java15
-rw-r--r--src/proguard/util/NameParser.java2
-rw-r--r--src/proguard/util/NotMatcher.java2
-rw-r--r--src/proguard/util/OrMatcher.java2
-rw-r--r--src/proguard/util/SettableMatcher.java2
-rw-r--r--src/proguard/util/StringMatcher.java2
-rw-r--r--src/proguard/util/StringParser.java2
-rw-r--r--src/proguard/util/VariableStringMatcher.java2
-rw-r--r--src/proguard/wtk/ProGuardObfuscator.java2
584 files changed, 9800 insertions, 2833 deletions
diff --git a/src/proguard/ArgumentWordReader.java b/src/proguard/ArgumentWordReader.java
index 89f3824..eb0e642 100644
--- a/src/proguard/ArgumentWordReader.java
+++ b/src/proguard/ArgumentWordReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -32,7 +32,8 @@ import java.io.*;
public class ArgumentWordReader extends WordReader
{
private final String[] arguments;
- private int index = 0;
+
+ private int index = 0;
// /**
@@ -86,7 +87,7 @@ public class ArgumentWordReader extends WordReader
{
while (true)
{
- String word = reader.nextWord();
+ String word = reader.nextWord(false);
if (word == null)
System.exit(-1);
diff --git a/src/proguard/ClassPath.java b/src/proguard/ClassPath.java
index f4eeaad..6851a84 100644
--- a/src/proguard/ClassPath.java
+++ b/src/proguard/ClassPath.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ClassPathEntry.java b/src/proguard/ClassPathEntry.java
index 28483be..17f1f54 100644
--- a/src/proguard/ClassPathEntry.java
+++ b/src/proguard/ClassPathEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -20,6 +20,8 @@
*/
package proguard;
+import proguard.util.ListUtil;
+
import java.io.*;
import java.util.List;
@@ -44,7 +46,7 @@ public class ClassPathEntry
/**
- * Creates a new ClassPathEntry with the given name and type.
+ * Creates a new ClassPathEntry with the given file and output flag.
*/
public ClassPathEntry(File file, boolean isOutput)
{
@@ -69,81 +71,212 @@ public class ClassPathEntry
}
+ /**
+ * Returns the file.
+ */
public File getFile()
{
return file;
}
+ /**
+ * Sets the file.
+ */
public void setFile(File file)
{
this.file = file;
}
+ /**
+ * Returns whether this data entry is an output entry.
+ */
public boolean isOutput()
{
return output;
}
+ /**
+ * Specifies whether this data entry is an output entry.
+ */
public void setOutput(boolean output)
{
this.output = output;
}
+ /**
+ * Returns whether this data entry is a jar file.
+ */
+ public boolean isJar()
+ {
+ return hasExtension(".jar");
+ }
+
+
+ /**
+ * Returns whether this data entry is a war file.
+ */
+ public boolean isWar()
+ {
+ return hasExtension(".war");
+ }
+
+
+ /**
+ * Returns whether this data entry is a ear file.
+ */
+ public boolean isEar()
+ {
+ return hasExtension(".ear");
+ }
+
+
+ /**
+ * Returns whether this data entry is a zip file.
+ */
+ public boolean isZip()
+ {
+ return hasExtension(".zip");
+ }
+
+
+ /**
+ * Returns whether this data entry has the given extension.
+ */
+ private boolean hasExtension(String extension)
+ {
+ return endsWithIgnoreCase(file.getPath(), extension);
+ }
+
+
+ /**
+ * Returns whether the given string ends with the given suffix, ignoring
+ * its case.
+ */
+ private static boolean endsWithIgnoreCase(String string, String suffix)
+ {
+ int stringLength = string.length();
+ int suffixLength = suffix.length();
+
+ return string.regionMatches(true, stringLength -
+ suffixLength, suffix, 0, suffixLength);
+ }
+
+
+ /**
+ * Returns the name filter that is applied to bottom-level files in this entry.
+ */
public List getFilter()
{
return filter;
}
+ /**
+ * Sets the name filter that is applied to bottom-level files in this entry.
+ */
public void setFilter(List filter)
{
this.filter = filter == null || filter.size() == 0 ? null : filter;
}
+ /**
+ * Returns the name filter that is applied to jar files in this entry, if any.
+ */
public List getJarFilter()
{
return jarFilter;
}
+ /**
+ * Sets the name filter that is applied to jar files in this entry, if any.
+ */
public void setJarFilter(List filter)
{
this.jarFilter = filter == null || filter.size() == 0 ? null : filter;
}
+ /**
+ * Returns the name filter that is applied to war files in this entry, if any.
+ */
public List getWarFilter()
{
return warFilter;
}
+ /**
+ * Sets the name filter that is applied to war files in this entry, if any.
+ */
public void setWarFilter(List filter)
{
this.warFilter = filter == null || filter.size() == 0 ? null : filter;
}
+ /**
+ * Returns the name filter that is applied to ear files in this entry, if any.
+ */
public List getEarFilter()
{
return earFilter;
}
+ /**
+ * Sets the name filter that is applied to ear files in this entry, if any.
+ */
public void setEarFilter(List filter)
{
this.earFilter = filter == null || filter.size() == 0 ? null : filter;
}
+ /**
+ * Returns the name filter that is applied to zip files in this entry, if any.
+ */
public List getZipFilter()
{
return zipFilter;
}
+ /**
+ * Sets the name filter that is applied to zip files in this entry, if any.
+ */
public void setZipFilter(List filter)
{
this.zipFilter = filter == null || filter.size() == 0 ? null : filter;
}
+
+
+ // Implementations for Object.
+
+ public String toString()
+ {
+ String string = getName();
+
+ if (filter != null ||
+ jarFilter != null ||
+ warFilter != null ||
+ earFilter != null ||
+ zipFilter != null)
+ {
+ string +=
+ ConfigurationConstants.OPEN_ARGUMENTS_KEYWORD +
+ (zipFilter != null ? ListUtil.commaSeparatedString(zipFilter, true) : "") +
+ ConfigurationConstants.SEPARATOR_KEYWORD +
+ (earFilter != null ? ListUtil.commaSeparatedString(earFilter, true) : "") +
+ ConfigurationConstants.SEPARATOR_KEYWORD +
+ (warFilter != null ? ListUtil.commaSeparatedString(warFilter, true) : "") +
+ ConfigurationConstants.SEPARATOR_KEYWORD +
+ (jarFilter != null ? ListUtil.commaSeparatedString(jarFilter, true) : "") +
+ ConfigurationConstants.SEPARATOR_KEYWORD +
+ (filter != null ? ListUtil.commaSeparatedString(filter, true) : "") +
+ ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD;
+ }
+
+ return string;
+ }
}
diff --git a/src/proguard/ClassSpecification.java b/src/proguard/ClassSpecification.java
index a84e0c8..eb52fc3 100644
--- a/src/proguard/ClassSpecification.java
+++ b/src/proguard/ClassSpecification.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ClassSpecificationVisitorFactory.java b/src/proguard/ClassSpecificationVisitorFactory.java
index c99ab2c..042a367 100644
--- a/src/proguard/ClassSpecificationVisitorFactory.java
+++ b/src/proguard/ClassSpecificationVisitorFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -493,7 +493,8 @@ public class ClassSpecificationVisitorFactory
private static boolean containsWildCards(String string)
{
return string != null &&
- (string.indexOf('*') >= 0 ||
+ (string.indexOf('!') >= 0 ||
+ string.indexOf('*') >= 0 ||
string.indexOf('?') >= 0 ||
string.indexOf('%') >= 0 ||
string.indexOf(',') >= 0 ||
diff --git a/src/proguard/Configuration.java b/src/proguard/Configuration.java
index d513e2c..2a39870 100644
--- a/src/proguard/Configuration.java
+++ b/src/proguard/Configuration.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -50,7 +50,7 @@ public class Configuration
* Specifies whether to skip non-public library classes while reading
* library jars.
*/
- public boolean skipNonPublicLibraryClasses = true;
+ public boolean skipNonPublicLibraryClasses = false;
/**
* Specifies whether to skip non-public library class members while reading
@@ -237,6 +237,13 @@ public class Configuration
public List keepAttributes;
/**
+ * Specifies whether method parameter names and types should be kept for
+ * methods that are not obfuscated. This is achieved by keeping partial
+ * "LocalVariableTable" and "LocalVariableTypeTable" attributes.
+ */
+ public boolean keepParameterNames = false;
+
+ /**
* An optional replacement for all SourceFile attributes.
*/
public String newSourceFileAttribute;
diff --git a/src/proguard/ConfigurationConstants.java b/src/proguard/ConfigurationConstants.java
index 694e006..0da4b5d 100644
--- a/src/proguard/ConfigurationConstants.java
+++ b/src/proguard/ConfigurationConstants.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -73,6 +73,7 @@ class ConfigurationConstants
public static final String REPACKAGE_CLASSES_OPTION = "-repackageclasses";
public static final String DEFAULT_PACKAGE_OPTION = "-defaultpackage";
public static final String KEEP_ATTRIBUTES_OPTION = "-keepattributes";
+ public static final String KEEP_PARAMETER_NAMES_OPTION = "-keepparameternames";
public static final String RENAME_SOURCE_FILE_ATTRIBUTE_OPTION = "-renamesourcefileattribute";
public static final String ADAPT_CLASS_STRINGS_OPTION = "-adaptclassstrings";
public static final String ADAPT_RESOURCE_FILE_NAMES_OPTION = "-adaptresourcefilenames";
@@ -87,6 +88,7 @@ class ConfigurationConstants
public static final String IGNORE_WARNINGS_OPTION = "-ignorewarnings";
public static final String PRINT_CONFIGURATION_OPTION = "-printconfiguration";
public static final String DUMP_OPTION = "-dump";
+ public static final String SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION = "-skipnonpubliclibraryclasses";
public static final String DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION = "-dontskipnonpubliclibraryclasses";
public static final String DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION = "-dontskipnonpubliclibraryclassmembers";
public static final String TARGET_OPTION = "-target";
diff --git a/src/proguard/ConfigurationParser.java b/src/proguard/ConfigurationParser.java
index e01809e..0a6e296 100644
--- a/src/proguard/ConfigurationParser.java
+++ b/src/proguard/ConfigurationParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -58,9 +58,21 @@ public class ConfigurationParser
public ConfigurationParser(String[] args,
File baseDir) throws IOException
{
- reader = new ArgumentWordReader(args, baseDir);
+ this(new ArgumentWordReader(args, baseDir));
+ }
- readNextWord();
+
+ /**
+ * Creates a new ConfigurationParser for the given lines,
+ * with the given base directory.
+ */
+ public ConfigurationParser(String lines,
+ String description,
+ File baseDir) throws IOException
+ {
+ this(new LineWordReader(new LineNumberReader(new StringReader(lines)),
+ description,
+ baseDir));
}
@@ -69,9 +81,7 @@ public class ConfigurationParser
*/
public ConfigurationParser(File file) throws IOException
{
- reader = new FileWordReader(file);
-
- readNextWord();
+ this(new FileWordReader(file));
}
@@ -80,7 +90,16 @@ public class ConfigurationParser
*/
public ConfigurationParser(URL url) throws IOException
{
- reader = new FileWordReader(url);
+ this(new FileWordReader(url));
+ }
+
+
+ /**
+ * Creates a new ConfigurationParser for the given word reader.
+ */
+ public ConfigurationParser(WordReader reader) throws IOException
+ {
+ this.reader = reader;
readNextWord();
}
@@ -110,6 +129,7 @@ public class ConfigurationParser
else if (ConfigurationConstants.OUTJARS_OPTION .startsWith(nextWord)) configuration.programJars = parseClassPathArgument(configuration.programJars, true);
else if (ConfigurationConstants.LIBRARYJARS_OPTION .startsWith(nextWord)) configuration.libraryJars = parseClassPathArgument(configuration.libraryJars, false);
else if (ConfigurationConstants.RESOURCEJARS_OPTION .startsWith(nextWord)) throw new ParseException("The '-resourcejars' option is no longer supported. Please use the '-injars' option for all input");
+ else if (ConfigurationConstants.SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION .startsWith(nextWord)) configuration.skipNonPublicLibraryClasses = parseNoArgument(true);
else if (ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION .startsWith(nextWord)) configuration.skipNonPublicLibraryClasses = parseNoArgument(false);
else if (ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION.startsWith(nextWord)) configuration.skipNonPublicLibraryClassMembers = parseNoArgument(false);
else if (ConfigurationConstants.TARGET_OPTION .startsWith(nextWord)) configuration.targetClassVersion = parseClassVersion();
@@ -124,7 +144,7 @@ public class ConfigurationParser
else if (ConfigurationConstants.PRINT_SEEDS_OPTION .startsWith(nextWord)) configuration.printSeeds = parseOptionalFile();
// After '-keep'.
- else if (ConfigurationConstants.KEEP_DIRECTORIES_OPTION .startsWith(nextWord)) configuration.keepDirectories = parseCommaSeparatedList("directory name", true, true, false, false, true, false, false, configuration.keepDirectories);
+ else if (ConfigurationConstants.KEEP_DIRECTORIES_OPTION .startsWith(nextWord)) configuration.keepDirectories = parseCommaSeparatedList("directory name", true, true, false, true, false, true, false, false, configuration.keepDirectories);
else if (ConfigurationConstants.DONT_SHRINK_OPTION .startsWith(nextWord)) configuration.shrink = parseNoArgument(false);
else if (ConfigurationConstants.PRINT_USAGE_OPTION .startsWith(nextWord)) configuration.printUsage = parseOptionalFile();
@@ -132,7 +152,7 @@ public class ConfigurationParser
else if (ConfigurationConstants.DONT_OPTIMIZE_OPTION .startsWith(nextWord)) configuration.optimize = parseNoArgument(false);
else if (ConfigurationConstants.OPTIMIZATION_PASSES .startsWith(nextWord)) configuration.optimizationPasses = parseIntegerArgument();
- else if (ConfigurationConstants.OPTIMIZATIONS .startsWith(nextWord)) configuration.optimizations = parseCommaSeparatedList("optimization name", true, false, false, false, false, false, false, configuration.optimizations);
+ else if (ConfigurationConstants.OPTIMIZATIONS .startsWith(nextWord)) configuration.optimizations = parseCommaSeparatedList("optimization name", true, false, false, false, false, false, false, false, configuration.optimizations);
else if (ConfigurationConstants.ASSUME_NO_SIDE_EFFECTS_OPTION .startsWith(nextWord)) configuration.assumeNoSideEffects = parseClassSpecificationArguments(configuration.assumeNoSideEffects);
else if (ConfigurationConstants.ALLOW_ACCESS_MODIFICATION_OPTION .startsWith(nextWord)) configuration.allowAccessModification = parseNoArgument(true);
else if (ConfigurationConstants.MERGE_INTERFACES_AGGRESSIVELY_OPTION .startsWith(nextWord)) configuration.mergeInterfacesAggressively = parseNoArgument(true);
@@ -146,22 +166,23 @@ public class ConfigurationParser
else if (ConfigurationConstants.OVERLOAD_AGGRESSIVELY_OPTION .startsWith(nextWord)) configuration.overloadAggressively = parseNoArgument(true);
else if (ConfigurationConstants.USE_UNIQUE_CLASS_MEMBER_NAMES_OPTION .startsWith(nextWord)) configuration.useUniqueClassMemberNames = parseNoArgument(true);
else if (ConfigurationConstants.DONT_USE_MIXED_CASE_CLASS_NAMES_OPTION .startsWith(nextWord)) configuration.useMixedCaseClassNames = parseNoArgument(false);
- else if (ConfigurationConstants.KEEP_PACKAGE_NAMES_OPTION .startsWith(nextWord)) configuration.keepPackageNames = parseCommaSeparatedList("package name", true, true, false, true, false, true, false, configuration.keepPackageNames);
+ else if (ConfigurationConstants.KEEP_PACKAGE_NAMES_OPTION .startsWith(nextWord)) configuration.keepPackageNames = parseCommaSeparatedList("package name", true, true, false, false, true, false, true, false, configuration.keepPackageNames);
else if (ConfigurationConstants.FLATTEN_PACKAGE_HIERARCHY_OPTION .startsWith(nextWord)) configuration.flattenPackageHierarchy = ClassUtil.internalClassName(parseOptionalArgument());
else if (ConfigurationConstants.REPACKAGE_CLASSES_OPTION .startsWith(nextWord)) configuration.repackageClasses = ClassUtil.internalClassName(parseOptionalArgument());
else if (ConfigurationConstants.DEFAULT_PACKAGE_OPTION .startsWith(nextWord)) configuration.repackageClasses = ClassUtil.internalClassName(parseOptionalArgument());
- else if (ConfigurationConstants.KEEP_ATTRIBUTES_OPTION .startsWith(nextWord)) configuration.keepAttributes = parseCommaSeparatedList("attribute name", true, true, false, true, false, false, false, configuration.keepAttributes);
+ else if (ConfigurationConstants.KEEP_ATTRIBUTES_OPTION .startsWith(nextWord)) configuration.keepAttributes = parseCommaSeparatedList("attribute name", true, true, false, false, true, false, false, false, configuration.keepAttributes);
+ else if (ConfigurationConstants.KEEP_PARAMETER_NAMES_OPTION .startsWith(nextWord)) configuration.keepParameterNames = parseNoArgument(true);
else if (ConfigurationConstants.RENAME_SOURCE_FILE_ATTRIBUTE_OPTION .startsWith(nextWord)) configuration.newSourceFileAttribute = parseOptionalArgument();
- else if (ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION .startsWith(nextWord)) configuration.adaptClassStrings = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.adaptClassStrings);
- else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION .startsWith(nextWord)) configuration.adaptResourceFileNames = parseCommaSeparatedList("resource file name", true, true, false, false, false, false, false, configuration.adaptResourceFileNames);
- else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_CONTENTS_OPTION .startsWith(nextWord)) configuration.adaptResourceFileContents = parseCommaSeparatedList("resource file name", true, true, false, false, false, false, false, configuration.adaptResourceFileContents);
+ else if (ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION .startsWith(nextWord)) configuration.adaptClassStrings = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.adaptClassStrings);
+ else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION .startsWith(nextWord)) configuration.adaptResourceFileNames = parseCommaSeparatedList("resource file name", true, true, false, true, false, false, false, false, configuration.adaptResourceFileNames);
+ else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_CONTENTS_OPTION .startsWith(nextWord)) configuration.adaptResourceFileContents = parseCommaSeparatedList("resource file name", true, true, false, true, false, false, false, false, configuration.adaptResourceFileContents);
else if (ConfigurationConstants.DONT_PREVERIFY_OPTION .startsWith(nextWord)) configuration.preverify = parseNoArgument(false);
else if (ConfigurationConstants.MICRO_EDITION_OPTION .startsWith(nextWord)) configuration.microEdition = parseNoArgument(true);
else if (ConfigurationConstants.VERBOSE_OPTION .startsWith(nextWord)) configuration.verbose = parseNoArgument(true);
- else if (ConfigurationConstants.DONT_NOTE_OPTION .startsWith(nextWord)) configuration.note = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.note);
- else if (ConfigurationConstants.DONT_WARN_OPTION .startsWith(nextWord)) configuration.warn = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.warn);
+ else if (ConfigurationConstants.DONT_NOTE_OPTION .startsWith(nextWord)) configuration.note = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.note);
+ else if (ConfigurationConstants.DONT_WARN_OPTION .startsWith(nextWord)) configuration.warn = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.warn);
else if (ConfigurationConstants.IGNORE_WARNINGS_OPTION .startsWith(nextWord)) configuration.ignoreWarnings = parseNoArgument(true);
else if (ConfigurationConstants.PRINT_CONFIGURATION_OPTION .startsWith(nextWord)) configuration.printConfiguration = parseOptionalFile();
else if (ConfigurationConstants.DUMP_OPTION .startsWith(nextWord)) configuration.dump = parseOptionalFile();
@@ -190,7 +211,7 @@ public class ConfigurationParser
private long parseIncludeArgument(long lastModified) throws ParseException, IOException
{
// Read the configuation file name.
- readNextWord("configuration file name");
+ readNextWord("configuration file name", true, false);
File file = file(nextWord);
reader.includeWordReader(new FileWordReader(file));
@@ -204,7 +225,7 @@ public class ConfigurationParser
private void parseBaseDirectoryArgument() throws ParseException, IOException
{
// Read the base directory name.
- readNextWord("base directory name");
+ readNextWord("base directory name", true, false);
reader.setBaseDir(file(nextWord));
@@ -225,7 +246,7 @@ public class ConfigurationParser
while (true)
{
// Read the next jar name.
- readNextWord("jar or directory name");
+ readNextWord("jar or directory name", true, false);
// Create a new class path entry.
ClassPathEntry entry = new ClassPathEntry(file(nextWord), isOutput);
@@ -245,7 +266,7 @@ public class ConfigurationParser
{
// Read the filter.
filters[counter++] =
- parseCommaSeparatedList("filter", true, false, true, false, true, false, false, null);
+ parseCommaSeparatedList("filter", true, false, true, true, false, true, false, false, null);
}
while (counter < filters.length &&
ConfigurationConstants.SEPARATOR_KEYWORD.equals(nextWord));
@@ -343,7 +364,7 @@ public class ConfigurationParser
throws ParseException, IOException
{
// Read the obligatory file name.
- readNextWord("file name");
+ readNextWord("file name", true, false);
// Make sure the file is properly resolved.
File file = file(nextWord);
@@ -358,7 +379,7 @@ public class ConfigurationParser
throws ParseException, IOException
{
// Read the optional file name.
- readNextWord();
+ readNextWord(true);
// Didn't the user specify a file name?
if (configurationEnd())
@@ -386,11 +407,11 @@ public class ConfigurationParser
return "";
}
- String fileName = nextWord;
+ String argument = nextWord;
readNextWord();
- return fileName;
+ return argument;
}
@@ -431,7 +452,8 @@ public class ConfigurationParser
{
readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD +
"', '" + ClassConstants.EXTERNAL_ACC_INTERFACE +
- "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true);
+ "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'",
+ false, true);
if (!ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD.equals(nextWord))
{
@@ -491,7 +513,8 @@ public class ConfigurationParser
// Read and add the class configuration.
readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD +
"', '" + ClassConstants.EXTERNAL_ACC_INTERFACE +
- "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true);
+ "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'",
+ false, true);
classSpecifications.add(parseClassSpecificationArguments());
@@ -512,30 +535,21 @@ public class ConfigurationParser
// Parse the class annotations and access modifiers until the class keyword.
while (!ConfigurationConstants.CLASS_KEYWORD.equals(nextWord))
{
- // Parse the annotation type, if any.
-// if (ConfigurationConstants.ANNOTATION_KEYWORD.equals(nextWord))
-// {
-// annotationType =
-// ClassUtil.internalType(
-// ListUtil.commaSeparatedString(
-// parseCommaSeparatedList("annotation type",
-// true, false, false, true, false, null)));
-//
-// continue;
-// }
-
// Strip the negating sign, if any.
- String strippedWord = nextWord.startsWith(ConfigurationConstants.NEGATOR_KEYWORD) ?
+ boolean negated =
+ nextWord.startsWith(ConfigurationConstants.NEGATOR_KEYWORD);
+
+ String strippedWord = negated ?
nextWord.substring(1) :
nextWord;
// Parse the class access modifiers.
- // TODO: Distinguish annotation from annotation modifier.
int accessFlag =
strippedWord.equals(ClassConstants.EXTERNAL_ACC_PUBLIC) ? ClassConstants.INTERNAL_ACC_PUBLIC :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_FINAL) ? ClassConstants.INTERNAL_ACC_FINAL :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_INTERFACE) ? ClassConstants.INTERNAL_ACC_INTERFACE :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
+ strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_ANNOTATION) ? ClassConstants.INTERNAL_ACC_ANNOTATTION :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_ENUM) ? ClassConstants.INTERNAL_ACC_ENUM :
unknownAccessFlag();
@@ -543,9 +557,11 @@ public class ConfigurationParser
// Is it an annotation modifier?
if (accessFlag == ClassConstants.INTERNAL_ACC_ANNOTATTION)
{
- // Is the next word actually an annotation type?
- readNextWord("annotation type or keyword '" + ClassConstants.EXTERNAL_ACC_INTERFACE + "'", false);
+ // Already read the next word.
+ readNextWord("annotation type or keyword '" + ClassConstants.EXTERNAL_ACC_INTERFACE + "'",
+ false, false);
+ // Is the next word actually an annotation type?
if (!nextWord.equals(ClassConstants.EXTERNAL_ACC_INTERFACE) &&
!nextWord.equals(ClassConstants.EXTERNAL_ACC_ENUM) &&
!nextWord.equals(ConfigurationConstants.CLASS_KEYWORD))
@@ -554,13 +570,17 @@ public class ConfigurationParser
annotationType =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("annotation type",
- false, false, false, true, false, false, true, null));
+ false, false, false, false, true, false, false, true, null), false);
+ // Continue parsing the access modifier that we just read
+ // in the next cycle.
continue;
}
+
+ // Otherwise just handle the annotation modifier.
}
- if (strippedWord.equals(nextWord))
+ if (!negated)
{
requiredSetClassAccessFlags |= accessFlag;
}
@@ -569,7 +589,6 @@ public class ConfigurationParser
requiredUnsetClassAccessFlags |= accessFlag;
}
-
if ((requiredSetClassAccessFlags &
requiredUnsetClassAccessFlags) != 0)
{
@@ -585,16 +604,21 @@ public class ConfigurationParser
break;
}
- readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD +
- "', '" + ClassConstants.EXTERNAL_ACC_INTERFACE +
- "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true);
+ // Should we read the next word?
+ if (accessFlag != ClassConstants.INTERNAL_ACC_ANNOTATTION)
+ {
+ readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD +
+ "', '" + ClassConstants.EXTERNAL_ACC_INTERFACE +
+ "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'",
+ false, true);
+ }
}
// Parse the class name part.
String externalClassName =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("class name or interface name",
- true, false, false, true, false, false, false, null));
+ true, false, false, false, true, false, false, false, null), false);
// For backward compatibility, allow a single "*" wildcard to match any
// class.
@@ -612,7 +636,7 @@ public class ConfigurationParser
if (ConfigurationConstants.IMPLEMENTS_KEYWORD.equals(nextWord) ||
ConfigurationConstants.EXTENDS_KEYWORD.equals(nextWord))
{
- readNextWord("class name or interface name", true);
+ readNextWord("class name or interface name", false, true);
// Parse the annotation type, if any.
if (ConfigurationConstants.ANNOTATION_KEYWORD.equals(nextWord))
@@ -620,13 +644,13 @@ public class ConfigurationParser
extendsAnnotationType =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("annotation type",
- true, false, false, true, false, false, true, null));
+ true, false, false, false, true, false, false, true, null), false);
}
String externalExtendsClassName =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("class name or interface name",
- false, false, false, true, false, false, false, null));
+ false, false, false, false, true, false, false, false, null), false);
extendsClassName = ConfigurationConstants.ANY_CLASS_KEYWORD.equals(externalExtendsClassName) ?
null :
@@ -659,7 +683,8 @@ public class ConfigurationParser
while (true)
{
readNextWord("class member description" +
- " or closing '" + ConfigurationConstants.CLOSE_KEYWORD + "'", true);
+ " or closing '" + ConfigurationConstants.CLOSE_KEYWORD + "'",
+ false, true);
if (nextWord.equals(ConfigurationConstants.CLOSE_KEYWORD))
{
@@ -697,8 +722,7 @@ public class ConfigurationParser
annotationType =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("annotation type",
- true, false, false, true, false, false, true, null));
-
+ true, false, false, false, true, false, false, true, null), false);
continue;
}
@@ -716,9 +740,12 @@ public class ConfigurationParser
strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED) ? ClassConstants.INTERNAL_ACC_SYNCHRONIZED :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_VOLATILE) ? ClassConstants.INTERNAL_ACC_VOLATILE :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_TRANSIENT) ? ClassConstants.INTERNAL_ACC_TRANSIENT :
+ strippedWord.equals(ClassConstants.EXTERNAL_ACC_BRIDGE) ? ClassConstants.INTERNAL_ACC_BRIDGE :
+ strippedWord.equals(ClassConstants.EXTERNAL_ACC_VARARGS) ? ClassConstants.INTERNAL_ACC_VARARGS :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_NATIVE) ? ClassConstants.INTERNAL_ACC_NATIVE :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_STRICT) ? ClassConstants.INTERNAL_ACC_STRICT :
+ strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC :
0;
if (accessFlag == 0)
{
@@ -875,7 +902,7 @@ public class ConfigurationParser
// Parse the method arguments.
String descriptor =
ClassUtil.internalMethodDescriptor(type,
- parseCommaSeparatedList("argument", true, true, true, true, false, false, false, null));
+ parseCommaSeparatedList("argument", true, true, true, false, true, false, false, false, null));
if (!ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD.equals(nextWord))
{
@@ -921,6 +948,7 @@ public class ConfigurationParser
boolean readFirstWord,
boolean allowEmptyList,
boolean expectClosingParenthesis,
+ boolean isFileName,
boolean checkJavaIdentifiers,
boolean replaceSystemProperties,
boolean replaceExternalClassNames,
@@ -938,12 +966,12 @@ public class ConfigurationParser
if (expectClosingParenthesis || !allowEmptyList)
{
// Read the first list entry.
- readNextWord(expectedDescription);
+ readNextWord(expectedDescription, isFileName, false);
}
else
{
// Read the first list entry, if there is any.
- readNextWord();
+ readNextWord(isFileName);
// Check if the list is empty.
if (configurationEnd() ||
@@ -1005,7 +1033,7 @@ public class ConfigurationParser
}
// Read the next list entry.
- readNextWord(expectedDescription);
+ readNextWord(expectedDescription, isFileName, false);
}
return list;
@@ -1035,16 +1063,6 @@ public class ConfigurationParser
file = new File(reader.getBaseDir(), fileName);
}
- // Try to get a canonical representation.
- try
- {
- file = file.getCanonicalFile();
- }
- catch (IOException ex)
- {
- // Just keep the original representation.
- }
-
return file;
}
@@ -1096,7 +1114,7 @@ public class ConfigurationParser
private void readNextWord(String expectedDescription)
throws ParseException, IOException
{
- readNextWord(expectedDescription, false);
+ readNextWord(expectedDescription, false, false);
}
@@ -1105,10 +1123,11 @@ public class ConfigurationParser
* throwing an exception if there is no next word.
*/
private void readNextWord(String expectedDescription,
+ boolean isFileName,
boolean expectingAtCharacter)
throws ParseException, IOException
{
- readNextWord();
+ readNextWord(isFileName);
if (configurationEnd(expectingAtCharacter))
{
throw new ParseException("Expecting " + expectedDescription +
@@ -1122,7 +1141,16 @@ public class ConfigurationParser
*/
private void readNextWord() throws IOException
{
- nextWord = reader.nextWord();
+ readNextWord(false);
+ }
+
+
+ /**
+ * Reads the next word of the configuration in the 'nextWord' field.
+ */
+ private void readNextWord(boolean isFileName) throws IOException
+ {
+ nextWord = reader.nextWord(isFileName);
}
diff --git a/src/proguard/ConfigurationWriter.java b/src/proguard/ConfigurationWriter.java
index 5d112d6..cd83515 100644
--- a/src/proguard/ConfigurationWriter.java
+++ b/src/proguard/ConfigurationWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -25,7 +25,7 @@ import proguard.classfile.util.ClassUtil;
import proguard.util.ListUtil;
import java.io.*;
-import java.util.List;
+import java.util.*;
/**
@@ -44,7 +44,7 @@ public class ConfigurationWriter
private final PrintWriter writer;
- private File baseDir;
+ private File baseDir;
/**
@@ -105,7 +105,7 @@ public class ConfigurationWriter
writer.println();
// Write the other options.
- writeOption(ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION, !configuration.skipNonPublicLibraryClasses);
+ writeOption(ConfigurationConstants.SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION, configuration.skipNonPublicLibraryClasses);
writeOption(ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION, !configuration.skipNonPublicLibraryClassMembers);
writeOption(ConfigurationConstants.KEEP_DIRECTORIES_OPTION, configuration.keepDirectories);
writeOption(ConfigurationConstants.TARGET_OPTION, ClassUtil.externalClassVersion(configuration.targetClassVersion));
@@ -115,7 +115,7 @@ public class ConfigurationWriter
writeOption(ConfigurationConstants.PRINT_USAGE_OPTION, configuration.printUsage);
writeOption(ConfigurationConstants.DONT_OPTIMIZE_OPTION, !configuration.optimize);
- writeOption(ConfigurationConstants.OPTIMIZATIONS, configuration.optimize ? ListUtil.commaSeparatedString(configuration.optimizations) : null);
+ writeOption(ConfigurationConstants.OPTIMIZATIONS, configuration.optimizations);
writeOption(ConfigurationConstants.OPTIMIZATION_PASSES, configuration.optimizationPasses);
writeOption(ConfigurationConstants.ALLOW_ACCESS_MODIFICATION_OPTION, configuration.allowAccessModification);
writeOption(ConfigurationConstants.MERGE_INTERFACES_AGGRESSIVELY_OPTION, configuration.mergeInterfacesAggressively);
@@ -133,6 +133,7 @@ public class ConfigurationWriter
writeOption(ConfigurationConstants.FLATTEN_PACKAGE_HIERARCHY_OPTION, configuration.flattenPackageHierarchy, true);
writeOption(ConfigurationConstants.REPACKAGE_CLASSES_OPTION, configuration.repackageClasses, true);
writeOption(ConfigurationConstants.KEEP_ATTRIBUTES_OPTION, configuration.keepAttributes);
+ writeOption(ConfigurationConstants.KEEP_PARAMETER_NAMES_OPTION, configuration.keepParameterNames);
writeOption(ConfigurationConstants.RENAME_SOURCE_FILE_ATTRIBUTE_OPTION, configuration.newSourceFileAttribute);
writeOption(ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION, configuration.adaptClassStrings, true);
writeOption(ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION, configuration.adaptResourceFileNames);
@@ -218,15 +219,7 @@ public class ConfigurationWriter
writer.print(ConfigurationConstants.OPEN_ARGUMENTS_KEYWORD);
}
- for (int index = 0; index < filter.size(); index++)
- {
- if (index > 0)
- {
- writer.print(ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD);
- }
-
- writer.print(quotedString((String)filter.get(index)));
- }
+ writer.print(ListUtil.commaSeparatedString(filter, true));
filtered = true;
}
@@ -273,16 +266,14 @@ public class ConfigurationWriter
}
else
{
- String argumentString = ListUtil.commaSeparatedString(arguments);
-
if (replaceInternalClassNames)
{
- argumentString = ClassUtil.externalClassName(argumentString);
+ arguments = externalClassNames(arguments);
}
writer.print(optionName);
writer.print(' ');
- writer.println(quotedString(argumentString));
+ writer.println(ListUtil.commaSeparatedString(arguments, true));
}
}
}
@@ -585,6 +576,23 @@ public class ConfigurationWriter
/**
+ * Returns a list with external versions of the given list of internal
+ * class names.
+ */
+ private List externalClassNames(List internalClassNames)
+ {
+ List externalClassNames = new ArrayList(internalClassNames.size());
+
+ for (int index = 0; index < internalClassNames.size(); index++)
+ {
+ externalClassNames.add(ClassUtil.externalClassName((String)internalClassNames.get(index)));
+ }
+
+ return externalClassNames;
+ }
+
+
+ /**
* Returns a relative file name of the given file, if possible.
* The file name is also quoted, if necessary.
*/
diff --git a/src/proguard/DataEntryReaderFactory.java b/src/proguard/DataEntryReaderFactory.java
index a9724b5..5b9c711 100644
--- a/src/proguard/DataEntryReaderFactory.java
+++ b/src/proguard/DataEntryReaderFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -48,11 +48,10 @@ public class DataEntryReaderFactory
ClassPathEntry classPathEntry,
DataEntryReader reader)
{
- String entryName = classPathEntry.getName();
- boolean isJar = endsWithIgnoreCase(entryName, ".jar");
- boolean isWar = endsWithIgnoreCase(entryName, ".war");
- boolean isEar = endsWithIgnoreCase(entryName, ".ear");
- boolean isZip = endsWithIgnoreCase(entryName, ".zip");
+ boolean isJar = classPathEntry.isJar();
+ boolean isWar = classPathEntry.isWar();
+ boolean isEar = classPathEntry.isEar();
+ boolean isZip = classPathEntry.isZip();
List filter = classPathEntry.getFilter();
List jarFilter = classPathEntry.getJarFilter();
@@ -139,17 +138,4 @@ public class DataEntryReaderFactory
reader);
}
}
-
-
- /**
- * Returns whether the given string ends with the given suffix, ignoring its
- * case.
- */
- private static boolean endsWithIgnoreCase(String string, String suffix)
- {
- int stringLength = string.length();
- int suffixLength = suffix.length();
-
- return string.regionMatches(true, stringLength - suffixLength, suffix, 0, suffixLength);
- }
}
diff --git a/src/proguard/DataEntryWriterFactory.java b/src/proguard/DataEntryWriterFactory.java
index 9fbc6d0..0da890b 100644
--- a/src/proguard/DataEntryWriterFactory.java
+++ b/src/proguard/DataEntryWriterFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -65,11 +65,10 @@ public class DataEntryWriterFactory
private static DataEntryWriter createClassPathEntryWriter(ClassPathEntry classPathEntry,
DataEntryWriter alternativeWriter)
{
- String entryName = classPathEntry.getName();
- boolean isJar = endsWithIgnoreCase(entryName, ".jar");
- boolean isWar = endsWithIgnoreCase(entryName, ".war");
- boolean isEar = endsWithIgnoreCase(entryName, ".ear");
- boolean isZip = endsWithIgnoreCase(entryName, ".zip");
+ boolean isJar = classPathEntry.isJar();
+ boolean isWar = classPathEntry.isWar();
+ boolean isEar = classPathEntry.isEar();
+ boolean isZip = classPathEntry.isZip();
List filter = classPathEntry.getFilter();
List jarFilter = classPathEntry.getJarFilter();
@@ -83,7 +82,7 @@ public class DataEntryWriterFactory
isEar ? "ear" :
isZip ? "zip" :
"directory") +
- " [" + entryName + "]" +
+ " [" + classPathEntry.getName() + "]" +
(filter != null ||
jarFilter != null ||
warFilter != null ||
@@ -148,17 +147,4 @@ public class DataEntryWriterFactory
filteredJarWriter,
isJar ? jarWriter : writer);
}
-
-
- /**
- * Returns whether the given string ends with the given suffix, ignoring its
- * case.
- */
- private static boolean endsWithIgnoreCase(String string, String suffix)
- {
- int stringLength = string.length();
- int suffixLength = suffix.length();
-
- return string.regionMatches(true, stringLength - suffixLength, suffix, 0, suffixLength);
- }
}
diff --git a/src/proguard/DescriptorKeepChecker.java b/src/proguard/DescriptorKeepChecker.java
index 1dfaf1a..7849693 100644
--- a/src/proguard/DescriptorKeepChecker.java
+++ b/src/proguard/DescriptorKeepChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -23,7 +23,7 @@ package proguard;
import proguard.classfile.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
-import proguard.optimize.KeepMarker;
+import proguard.optimize.*;
import java.util.List;
@@ -64,7 +64,7 @@ implements MemberVisitor,
/**
* Checks the classes mentioned in the given keep specifications, printing
- * notes if necessary. Returns the number of notes printed.
+ * notes if necessary.
*/
public void checkClassSpecifications(List keepSpecifications)
{
@@ -85,8 +85,11 @@ implements MemberVisitor,
programClassPool.accept(classPoolvisitor);
libraryClassPool.accept(classPoolvisitor);
- // Print out notes about argument types that are not being kept.
- programClassPool.classesAccept(new AllMemberVisitor(this));
+ // Print out notes about argument types that are not being kept in
+ // class members that are being kept.
+ programClassPool.classesAccept(
+ new AllMemberVisitor(
+ new KeptMemberFilter(this)));
}
@@ -94,39 +97,42 @@ implements MemberVisitor,
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
- if (KeepMarker.isKept(programField))
- {
- referencingClass = programClass;
- referencingMember = programField;
- isField = true;
-
- // Don't check the type, because it is not required for introspection.
- //programField.referencedClassesAccept(this);
- }
+ //referencingClass = programClass;
+ //referencingMember = programField;
+ //isField = true;
+ //
+ // Don't check the type, because it is not required for introspection.
+ //programField.referencedClassesAccept(this);
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- if (KeepMarker.isKept(programMethod))
+ referencingClass = programClass;
+ referencingMember = programMethod;
+ isField = false;
+
+ // Don't check the return type, because it is not required for
+ // introspection (e.g. the return type of the special Enum methods).
+ //programMethod.referencedClassesAccept(this);
+
+ Clazz[] referencedClasses = programMethod.referencedClasses;
+ if (referencedClasses != null)
{
- referencingClass = programClass;
- referencingMember = programMethod;
- isField = false;
+ int count = referencedClasses.length;
- // Don't check the return type, because it is not required for
- // introspection (e.g. the return type of the special Enum methods).
- //programMethod.referencedClassesAccept(this);
+ // Adapt the count if the return type is a class type (not so
+ // pretty; assuming test just checks for final ';').
+ if (ClassUtil.isInternalClassType(programMethod.getDescriptor(programClass)))
+ {
+ count--;
+ }
- Clazz[] referencedClasses = programMethod.referencedClasses;
- if (referencedClasses != null)
+ for (int index = 0; index < count; index++)
{
- for (int index = 0; index < referencedClasses.length-1; index++)
+ if (referencedClasses[index] != null)
{
- if (referencedClasses[index] != null)
- {
- referencedClasses[index].accept(this);
- }
+ referencedClasses[index].accept(this);
}
}
}
diff --git a/src/proguard/DuplicateClassPrinter.java b/src/proguard/DuplicateClassPrinter.java
index 21b6aa0..9ade21b 100644
--- a/src/proguard/DuplicateClassPrinter.java
+++ b/src/proguard/DuplicateClassPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/FileWordReader.java b/src/proguard/FileWordReader.java
index fb9fa50..e0325b7 100644
--- a/src/proguard/FileWordReader.java
+++ b/src/proguard/FileWordReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -29,23 +29,17 @@ import java.net.URL;
*
* @author Eric Lafortune
*/
-public class FileWordReader extends WordReader
+public class FileWordReader extends LineWordReader
{
- private final String name;
- private LineNumberReader reader;
-
-
/**
* Creates a new FileWordReader for the given file.
*/
public FileWordReader(File file) throws IOException
{
- super(file.getParentFile());
-
- this.name = file.getPath();
- this.reader = new LineNumberReader(
- new BufferedReader(
- new FileReader(file)));
+ super(new LineNumberReader(new BufferedReader(new FileReader(file))),
+ "file '" + file.getPath() + "'",
+ file.getParentFile()
+ );
}
@@ -54,36 +48,8 @@ public class FileWordReader extends WordReader
*/
public FileWordReader(URL url) throws IOException
{
- super(null);
-
- this.name = url.toString();
- this.reader = new LineNumberReader(
- new BufferedReader(
- new InputStreamReader(url.openStream())));
- }
-
-
- // Implementations for WordReader.
-
- protected String nextLine() throws IOException
- {
- return reader.readLine();
- }
-
-
- protected String lineLocationDescription()
- {
- return "line " + reader.getLineNumber() + " of file '" + name + "'";
- }
-
-
- public void close() throws IOException
- {
- super.close();
-
- if (reader != null)
- {
- reader.close();
- }
+ super(new LineNumberReader(new BufferedReader(new InputStreamReader(url.openStream()))),
+ "file '" + url.toString() + "'",
+ null);
}
}
diff --git a/src/proguard/FullyQualifiedClassNameChecker.java b/src/proguard/FullyQualifiedClassNameChecker.java
index 06949b5..7534fb4 100644
--- a/src/proguard/FullyQualifiedClassNameChecker.java
+++ b/src/proguard/FullyQualifiedClassNameChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -42,7 +42,7 @@ implements ClassVisitor
/**
- * Creates a new DescriptorKeepChecker.
+ * Creates a new FullyQualifiedClassNameChecker.
*/
public FullyQualifiedClassNameChecker(ClassPool programClassPool,
ClassPool libraryClassPool,
@@ -56,7 +56,7 @@ implements ClassVisitor
/**
* Checks the classes mentioned in the given class specifications, printing
- * notes if necessary. Returns the number of notes printed.
+ * notes if necessary.
*/
public void checkClassSpecifications(List classSpecifications)
{
@@ -173,7 +173,8 @@ implements ClassVisitor
private static boolean containsWildCards(String string)
{
return string != null &&
- (string.indexOf('*') >= 0 ||
+ (string.indexOf('!') >= 0 ||
+ string.indexOf('*') >= 0 ||
string.indexOf('?') >= 0 ||
string.indexOf(',') >= 0 ||
string.indexOf("///") >= 0);
diff --git a/src/proguard/GPL.java b/src/proguard/GPL.java
index 272a837..9327b8b 100644
--- a/src/proguard/GPL.java
+++ b/src/proguard/GPL.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -48,9 +48,10 @@ public class GPL
{
String uniquePackageNames = uniquePackageNames(unknownPackageNames);
- System.out.println("ProGuard is released under the GNU General Public License. The authors of all");
- System.out.println("programs or plugins that link to it ("+uniquePackageNames+"...) therefore");
- System.out.println("must ensure that these programs carry the GNU General Public License as well.");
+ System.out.println("ProGuard is released under the GNU General Public License. You therefore");
+ System.out.println("must ensure that programs that link to it ("+uniquePackageNames+"...)");
+ System.out.println("carry the GNU General Public License as well. Alternatively, you can");
+ System.out.println("apply for an exception with the author of ProGuard.");
}
}
@@ -165,9 +166,14 @@ public class GPL
packageName.startsWith("org.apache.tools.maven") ||
packageName.startsWith("org.eclipse") ||
packageName.startsWith("org.netbeans") ||
+ packageName.startsWith("com.android") ||
packageName.startsWith("com.sun.kvem") ||
packageName.startsWith("net.certiv.proguarddt") ||
+ packageName.startsWith("scala") ||
+ packageName.startsWith("sbt") ||
+ packageName.startsWith("xsbt") ||
packageName.startsWith("eclipseme") ||
+ packageName.startsWith("com.neomades") ||
packageName.startsWith("jg.j2me") ||
packageName.startsWith("jg.common") ||
packageName.startsWith("jg.buildengine");
diff --git a/src/proguard/Initializer.java b/src/proguard/Initializer.java
index 41cf971..dc17b00 100644
--- a/src/proguard/Initializer.java
+++ b/src/proguard/Initializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -60,6 +60,11 @@ public class Initializer
{
int originalLibraryClassPoolSize = libraryClassPool.size();
+ // Perform a basic check on the keep options in the configuration.
+ WarningPrinter keepClassMemberNotePrinter = new WarningPrinter(System.out, configuration.note);
+
+ new KeepClassMemberChecker(keepClassMemberNotePrinter).checkClassSpecifications(configuration.keep);
+
// Construct a reduced library class pool with only those library
// classes whose hierarchies are referenced by the program classes.
// We can't do this if we later have to come up with the obfuscated
@@ -275,8 +280,12 @@ public class Initializer
{
System.err.println("Warning: there were " + classReferenceWarningCount +
" unresolved references to classes or interfaces.");
- System.err.println(" You may need to specify additional library jars (using '-libraryjars'),");
- System.err.println(" or perhaps the '-dontskipnonpubliclibraryclasses' option.");
+ System.err.println(" You may need to specify additional library jars (using '-libraryjars').");
+
+ if (configuration.skipNonPublicLibraryClasses)
+ {
+ System.err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'.");
+ }
}
int dependencyWarningCount = dependencyWarningPrinter.getWarningCount();
@@ -295,9 +304,13 @@ public class Initializer
" unresolved references to program class members.");
System.err.println(" Your input classes appear to be inconsistent.");
System.err.println(" You may need to recompile them and try again.");
- System.err.println(" Alternatively, you may have to specify the options ");
- System.err.println(" '-dontskipnonpubliclibraryclasses' and/or");
+ System.err.println(" Alternatively, you may have to specify the option ");
System.err.println(" '-dontskipnonpubliclibraryclassmembers'.");
+
+ if (configuration.skipNonPublicLibraryClasses)
+ {
+ System.err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'.");
+ }
}
if ((classReferenceWarningCount > 0 ||
diff --git a/src/proguard/InputReader.java b/src/proguard/InputReader.java
index c088324..9ee1314 100644
--- a/src/proguard/InputReader.java
+++ b/src/proguard/InputReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -227,7 +227,7 @@ public class InputReader
}
catch (IOException ex)
{
- throw new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")");
+ throw (IOException)new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")").initCause(ex);
}
}
}
diff --git a/src/proguard/KeepClassMemberChecker.java b/src/proguard/KeepClassMemberChecker.java
new file mode 100644
index 0000000..a6546d9
--- /dev/null
+++ b/src/proguard/KeepClassMemberChecker.java
@@ -0,0 +1,87 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard;
+
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+import java.util.List;
+
+/**
+ * This class checks if the user has forgotten to specify class members in
+ * some keep options in the configuration.
+ *
+ * @author Eric Lafortune
+ */
+public class KeepClassMemberChecker
+extends SimplifiedVisitor
+implements ClassVisitor
+{
+ private final WarningPrinter notePrinter;
+
+
+ /**
+ * Creates a new KeepClassMemberChecker.
+ */
+ public KeepClassMemberChecker(WarningPrinter notePrinter)
+ {
+ this.notePrinter = notePrinter;
+ }
+
+
+ /**
+ * Checks if the given class specifications try to keep class members
+ * without actually specifying any, printing notes if necessary. Returns
+ * the number of notes printed.
+ */
+ public void checkClassSpecifications(List keepClassSpecifications)
+ {
+ if (keepClassSpecifications != null)
+ {
+ for (int index = 0; index < keepClassSpecifications.size(); index++)
+ {
+ KeepClassSpecification keepClassSpecification =
+ (KeepClassSpecification)keepClassSpecifications.get(index);
+
+ if (!keepClassSpecification.markClasses &&
+ (keepClassSpecification.fieldSpecifications == null ||
+ keepClassSpecification.fieldSpecifications.size() == 0) &&
+ (keepClassSpecification.methodSpecifications == null ||
+ keepClassSpecification.methodSpecifications.size() == 0))
+ {
+ String className = keepClassSpecification.className;
+ if (className == null)
+ {
+ className = keepClassSpecification.extendsClassName;
+ }
+
+ if (className != null &&
+ notePrinter.accepts(className))
+ {
+ notePrinter.print(className,
+ "Note: the configuration doesn't specify which class members to keep for class '" +
+ ClassUtil.externalClassName(className) + "'");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/proguard/KeepClassSpecification.java b/src/proguard/KeepClassSpecification.java
index 29c0d3c..c30538a 100644
--- a/src/proguard/KeepClassSpecification.java
+++ b/src/proguard/KeepClassSpecification.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/LineWordReader.java b/src/proguard/LineWordReader.java
new file mode 100644
index 0000000..b8c9126
--- /dev/null
+++ b/src/proguard/LineWordReader.java
@@ -0,0 +1,74 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard;
+
+import java.io.*;
+
+
+/**
+ * A <code>WordReader</code> that returns words from a line number reader.
+ *
+ * @author Eric Lafortune
+ */
+public class LineWordReader extends WordReader
+{
+ private final LineNumberReader reader;
+ private final String description;
+
+
+ /**
+ * Creates a new LineWordReader for the given input.
+ */
+ public LineWordReader(LineNumberReader lineNumberReader,
+ String description,
+ File baseDir) throws IOException
+ {
+ super(baseDir);
+
+ this.reader = lineNumberReader;
+ this.description = description;
+ }
+
+
+ // Implementations for WordReader.
+
+ protected String nextLine() throws IOException
+ {
+ return reader.readLine();
+ }
+
+
+ protected String lineLocationDescription()
+ {
+ return "line " + reader.getLineNumber() + " of " + description;
+ }
+
+
+ public void close() throws IOException
+ {
+ super.close();
+
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+}
diff --git a/src/proguard/MemberSpecification.java b/src/proguard/MemberSpecification.java
index 1cfa962..025f3b8 100644
--- a/src/proguard/MemberSpecification.java
+++ b/src/proguard/MemberSpecification.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/OutputWriter.java b/src/proguard/OutputWriter.java
index 10c18fb..39dd1ad 100644
--- a/src/proguard/OutputWriter.java
+++ b/src/proguard/OutputWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -63,13 +63,12 @@ public class OutputWriter
"] must be specified after an input jar, or it will be empty.");
}
- // Perform some checks on the output jars.
+ // Check if the first of two subsequent the output jars has a filter.
for (int index = 0; index < programJars.size() - 1; index++)
{
ClassPathEntry entry = programJars.get(index);
if (entry.isOutput())
{
- // Check if all but the last output jars have filters.
if (entry.getFilter() == null &&
entry.getJarFilter() == null &&
entry.getWarFilter() == null &&
@@ -78,10 +77,17 @@ public class OutputWriter
programJars.get(index + 1).isOutput())
{
throw new IOException("The output jar [" + entry.getName() +
- "] must have a filter, or all subsequent jars will be empty.");
+ "] must have a filter, or all subsequent output jars will be empty.");
}
+ }
+ }
- // Check if the output jar name is different from the input jar names.
+ // Check if the output jar names are different from the input jar names.
+ for (int outIndex = 0; outIndex < programJars.size() - 1; outIndex++)
+ {
+ ClassPathEntry entry = programJars.get(outIndex);
+ if (entry.isOutput())
+ {
for (int inIndex = 0; inIndex < programJars.size(); inIndex++)
{
ClassPathEntry otherEntry = programJars.get(inIndex);
@@ -96,6 +102,40 @@ public class OutputWriter
}
}
+ // Check for potential problems with mixed-case class names on
+ // case-insensitive file systems.
+ if (configuration.obfuscate &&
+ configuration.useMixedCaseClassNames &&
+ configuration.classObfuscationDictionary == null &&
+ (configuration.note == null ||
+ !configuration.note.isEmpty()))
+ {
+ String os = System.getProperty("os.name").toLowerCase();
+ if (os.startsWith("windows") ||
+ os.startsWith("mac os"))
+ {
+ // Go over all program class path entries.
+ for (int index = 0; index < programJars.size(); index++)
+ {
+ // Is it an output directory?
+ ClassPathEntry entry = programJars.get(index);
+ if (entry.isOutput() &&
+ !entry.isJar() &&
+ !entry.isWar() &&
+ !entry.isEar() &&
+ !entry.isZip())
+ {
+ System.out.println("Note: you're writing the processed class files to a directory [" + entry.getName() +"].");
+ System.out.println(" This will likely cause problems with obfuscated mixed-case class names.");
+ System.out.println(" You should consider writing the output to a jar file, or otherwise");
+ System.out.println(" specify '-dontusemixedclassnames'.");
+
+ break;
+ }
+ }
+ }
+ }
+
int firstInputIndex = 0;
int lastInputIndex = 0;
@@ -166,7 +206,7 @@ public class OutputWriter
{
resourceRewriter =
new NameFilter(configuration.adaptResourceFileContents,
- new NameFilter("META-INF/**",
+ new NameFilter("META-INF/MANIFEST.MF,META-INF/*.SF",
new ManifestRewriter(programClassPool, writer),
new DataEntryRewriter(programClassPool, writer)),
resourceRewriter);
@@ -221,7 +261,7 @@ public class OutputWriter
}
catch (IOException ex)
{
- throw new IOException("Can't write [" + classPath.get(fromOutputIndex).getName() + "] (" + ex.getMessage() + ")");
+ throw (IOException)new IOException("Can't write [" + classPath.get(fromOutputIndex).getName() + "] (" + ex.getMessage() + ")").initCause(ex);
}
}
@@ -232,25 +272,25 @@ public class OutputWriter
*/
private static Map createPackagePrefixMap(ClassPool classPool)
{
- Map PackagePrefixMap = new HashMap();
+ Map packagePrefixMap = new HashMap();
Iterator iterator = classPool.classNames();
while (iterator.hasNext())
{
String className = (String)iterator.next();
- String PackagePrefix = ClassUtil.internalPackagePrefix(className);
+ String packagePrefix = ClassUtil.internalPackagePrefix(className);
- String mappedNewPackagePrefix = (String)PackagePrefixMap.get(PackagePrefix);
+ String mappedNewPackagePrefix = (String)packagePrefixMap.get(packagePrefix);
if (mappedNewPackagePrefix == null ||
- !mappedNewPackagePrefix.equals(PackagePrefix))
+ !mappedNewPackagePrefix.equals(packagePrefix))
{
String newClassName = classPool.getClass(className).getName();
String newPackagePrefix = ClassUtil.internalPackagePrefix(newClassName);
- PackagePrefixMap.put(PackagePrefix, newPackagePrefix);
+ packagePrefixMap.put(packagePrefix, newPackagePrefix);
}
}
- return PackagePrefixMap;
+ return packagePrefixMap;
}
}
diff --git a/src/proguard/ParseException.java b/src/proguard/ParseException.java
index 9294200..2f3af01 100644
--- a/src/proguard/ParseException.java
+++ b/src/proguard/ParseException.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ProGuard.java b/src/proguard/ProGuard.java
index 8c30e10..913207a 100644
--- a/src/proguard/ProGuard.java
+++ b/src/proguard/ProGuard.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -24,7 +24,7 @@ import proguard.classfile.ClassPool;
import proguard.classfile.editor.ClassElementSorter;
import proguard.classfile.visitor.*;
import proguard.obfuscate.Obfuscator;
-import proguard.optimize.Optimizer;
+import proguard.optimize.*;
import proguard.preverify.*;
import proguard.shrink.Shrinker;
@@ -37,7 +37,7 @@ import java.io.*;
*/
public class ProGuard
{
- public static final String VERSION = "ProGuard, version 4.4";
+ public static final String VERSION = "ProGuard, version 4.7";
private final Configuration configuration;
private ClassPool programClassPool = new ClassPool();
@@ -77,7 +77,8 @@ public class ProGuard
readInput();
- if (configuration.shrink ||
+ if (configuration.printSeeds != null ||
+ configuration.shrink ||
configuration.optimize ||
configuration.obfuscate ||
configuration.preverify)
@@ -236,30 +237,10 @@ public class ProGuard
System.out.println("Printing kept classes, fields, and methods...");
}
- // Check if we have at least some keep commands.
- if (configuration.keep == null)
- {
- throw new IOException("You have to specify '-keep' options for the shrinking step.");
- }
-
PrintStream ps = createPrintStream(configuration.printSeeds);
try
{
- // Create a visitor for printing out the seeds. We're printing out
- // the program elements that are preserved against shrinking,
- // optimization, or obfuscation.
- SimpleClassPrinter printer = new SimpleClassPrinter(false, ps);
- ClassPoolVisitor classPoolvisitor =
- ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
- new ProgramClassFilter(printer),
- new ProgramMemberFilter(printer),
- true,
- true,
- true);
-
- // Print out the seeds.
- programClassPool.accept(classPoolvisitor);
- libraryClassPool.accept(classPoolvisitor);
+ new SeedPrinter(ps).write(configuration, programClassPool, libraryClassPool);
}
finally
{
@@ -445,14 +426,26 @@ public class ProGuard
/**
- * Returns the absolute file name for the given file, or the standard output
+ * Returns the canonical file name for the given file, or "standard output"
* if the file name is empty.
*/
private String fileName(File file)
{
- return isFile(file) ?
- file.getAbsolutePath() :
- "standard output";
+ if (isFile(file))
+ {
+ try
+ {
+ return file.getCanonicalPath();
+ }
+ catch (IOException ex)
+ {
+ return file.getPath();
+ }
+ }
+ else
+ {
+ return "standard output";
+ }
}
diff --git a/src/proguard/SeedPrinter.java b/src/proguard/SeedPrinter.java
new file mode 100644
index 0000000..aee8f60
--- /dev/null
+++ b/src/proguard/SeedPrinter.java
@@ -0,0 +1,97 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard;
+
+import proguard.classfile.ClassPool;
+import proguard.classfile.attribute.visitor.AllAttributeVisitor;
+import proguard.classfile.constant.visitor.AllConstantVisitor;
+import proguard.classfile.instruction.visitor.AllInstructionVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+import proguard.optimize.*;
+import proguard.util.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * This class prints out the seeds specified by keep options.
+ *
+ * @author Eric Lafortune
+ */
+public class SeedPrinter
+{
+ private final PrintStream ps;
+
+
+ /**
+ * Creates a new ConfigurationWriter for the given PrintStream.
+ */
+ public SeedPrinter(PrintStream ps) throws IOException
+ {
+ this.ps = ps;
+ }
+
+
+ /**
+ * Prints out the seeds for the classes in the given program class pool.
+ * @param configuration the configuration containing the keep options.
+ * @throws IOException if an IO error occurs while writing the configuration.
+ */
+ public void write(Configuration configuration,
+ ClassPool programClassPool,
+ ClassPool libraryClassPool) throws IOException
+ {
+ // Check if we have at least some keep commands.
+ if (configuration.keep == null)
+ {
+ throw new IOException("You have to specify '-keep' options for the shrinking step.");
+ }
+
+ // Clean up any old visitor info.
+ programClassPool.classesAccept(new ClassCleaner());
+ libraryClassPool.classesAccept(new ClassCleaner());
+
+ // Create a visitor for printing out the seeds. We're printing out
+ // the program elements that are preserved against shrinking,
+ // optimization, or obfuscation.
+ KeepMarker keepMarker = new KeepMarker();
+ ClassPoolVisitor classPoolvisitor =
+ ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
+ keepMarker,
+ keepMarker,
+ true,
+ true,
+ true);
+ // Mark the seeds.
+ programClassPool.accept(classPoolvisitor);
+ libraryClassPool.accept(classPoolvisitor);
+
+ // Print out the seeds.
+ SimpleClassPrinter printer = new SimpleClassPrinter(false, ps);
+ programClassPool.classesAcceptAlphabetically(new MultiClassVisitor(
+ new ClassVisitor[]
+ {
+ new KeptClassFilter(printer),
+ new AllMemberVisitor(new KeptMemberFilter(printer))
+ }));
+ }
+} \ No newline at end of file
diff --git a/src/proguard/SubclassedClassFilter.java b/src/proguard/SubclassedClassFilter.java
index 27cac11..78afb7f 100644
--- a/src/proguard/SubclassedClassFilter.java
+++ b/src/proguard/SubclassedClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/Targeter.java b/src/proguard/Targeter.java
index 5067205..16583bf 100644
--- a/src/proguard/Targeter.java
+++ b/src/proguard/Targeter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/UpToDateChecker.java b/src/proguard/UpToDateChecker.java
index 9fa5d16..c743af9 100644
--- a/src/proguard/UpToDateChecker.java
+++ b/src/proguard/UpToDateChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -47,107 +47,186 @@ public class UpToDateChecker
*/
public boolean check()
{
- long inputLastModified = configuration.lastModified;
- long outputLastModified = Long.MAX_VALUE;
+ try
+ {
+ ModificationTimeChecker checker = new ModificationTimeChecker();
- ClassPath programJars = configuration.programJars;
- ClassPath libraryJars = configuration.libraryJars;
+ checker.updateInputModificationTime(configuration.lastModified);
- // Check the dates of the program jars, if any.
- if (programJars != null)
- {
- for (int index = 0; index < programJars.size(); index++)
+ ClassPath programJars = configuration.programJars;
+ ClassPath libraryJars = configuration.libraryJars;
+
+ // Check the dates of the program jars, if any.
+ if (programJars != null)
{
- // Break early, if possible.
- if (inputLastModified >= outputLastModified)
+ for (int index = 0; index < programJars.size(); index++)
{
- break;
- }
+ // Update the input and output modification times.
+ ClassPathEntry classPathEntry = programJars.get(index);
- // Update the input and output modification times.
- ClassPathEntry classPathEntry = programJars.get(index);
- if (classPathEntry.isOutput())
- {
- long lastModified = lastModified(classPathEntry.getFile(), true);
- if (outputLastModified > lastModified)
- {
- outputLastModified = lastModified;
- }
- }
- else
- {
- long lastModified = lastModified(classPathEntry.getFile(), false);
- if (inputLastModified < lastModified)
- {
- inputLastModified = lastModified;
- }
+ checker.updateModificationTime(classPathEntry.getFile(),
+ classPathEntry.isOutput());
}
}
- }
- // Check the dates of the library jars, if any.
- if (libraryJars != null)
- {
- for (int index = 0; index < libraryJars.size(); index++)
+ // Check the dates of the library jars, if any.
+ if (libraryJars != null)
{
- // Break early, if possible.
- if (inputLastModified >= outputLastModified)
+ for (int index = 0; index < libraryJars.size(); index++)
{
- break;
- }
+ // Update the input modification time.
+ ClassPathEntry classPathEntry = libraryJars.get(index);
- // Update the input modification time.
- ClassPathEntry classPathEntry = libraryJars.get(index);
- long lastModified = lastModified(classPathEntry.getFile(), false);
- if (inputLastModified < lastModified)
- {
- inputLastModified = lastModified;
+ checker.updateModificationTime(classPathEntry.getFile(),
+ false);
}
}
- }
- boolean outputUpToDate = inputLastModified < outputLastModified;
- if (outputUpToDate)
+ // Check the dates of the auxiliary input files.
+ checker.updateInputModificationTime(configuration.applyMapping);
+ checker.updateInputModificationTime(configuration.obfuscationDictionary);
+ checker.updateInputModificationTime(configuration.classObfuscationDictionary);
+ checker.updateInputModificationTime(configuration.packageObfuscationDictionary);
+
+ // Check the dates of the auxiliary output files.
+ checker.updateOutputModificationTime(configuration.printSeeds);
+ checker.updateOutputModificationTime(configuration.printUsage);
+ checker.updateOutputModificationTime(configuration.printMapping);
+ checker.updateOutputModificationTime(configuration.printConfiguration);
+ checker.updateOutputModificationTime(configuration.dump);
+ }
+ catch (IllegalStateException e)
{
- System.out.println("The output is up to date");
+ // The output is outdated.
+ return false;
}
- return outputUpToDate;
+ System.out.println("The output seems up to date");
+
+ return true;
}
/**
- * Returns the minimum or maximum modification time of the given file or
- * of the files in the given directory (recursively).
+ * This class maintains the modification times of input and output.
+ * The methods throw an IllegalStateException if the output appears
+ * outdated.
*/
- private long lastModified(File file, boolean minimum)
- {
- // Is it a directory?
- if (file.isDirectory())
+ private static class ModificationTimeChecker {
+
+ private long inputModificationTime = Long.MIN_VALUE;
+ private long outputModificationTime = Long.MAX_VALUE;
+
+
+ /**
+ * Updates the input modification time based on the given file or
+ * directory (recursively).
+ */
+ public void updateInputModificationTime(File file)
{
- // Ignore the directory's modification time; just recurse on its files.
- File[] files = file.listFiles();
+ if (file != null)
+ {
+ updateModificationTime(file, false);
+ }
+ }
- // Still, an empty output directory is probably a sign that it is
- // not up to date.
- long lastModified = files.length != 0 && minimum ?
- Long.MAX_VALUE : 0L;
- for (int index = 0; index < files.length; index++)
+ /**
+ * Updates the input modification time based on the given file or
+ * directory (recursively).
+ */
+ public void updateOutputModificationTime(File file)
+ {
+ if (file != null && file.getName().length() > 0)
{
- long fileLastModified = lastModified(files[index], minimum);
- if ((lastModified < fileLastModified) ^ minimum)
+ updateModificationTime(file, true);
+ }
+ }
+
+
+ /**
+ * Updates the specified modification time based on the given file or
+ * directory (recursively).
+ */
+ public void updateModificationTime(File file, boolean isOutput)
+ {
+ // Is it a directory?
+ if (file.isDirectory())
+ {
+ // Ignore the directory's modification time; just recurse on
+ // its files.
+ File[] files = file.listFiles();
+
+ // Still, an empty output directory is probably a sign that it
+ // is not up to date.
+ if (files.length == 0 && isOutput)
{
- lastModified = fileLastModified;
+ updateOutputModificationTime(Long.MIN_VALUE);
}
+
+ for (int index = 0; index < files.length; index++)
+ {
+ updateModificationTime(files[index], isOutput);
+ }
+ }
+ else
+ {
+ // Update with the file's modification time.
+ updateModificationTime(file.lastModified(), isOutput);
}
+ }
+
- return lastModified;
+ /**
+ * Updates the specified modification time.
+ */
+ public void updateModificationTime(long time, boolean isOutput)
+ {
+ if (isOutput)
+ {
+ updateOutputModificationTime(time);
+ }
+ else
+ {
+ updateInputModificationTime(time);
+ }
}
- else
+
+
+ /**
+ * Updates the input modification time.
+ */
+ public void updateInputModificationTime(long time)
{
- // Return the file's modification time.
- return file.lastModified();
+ if (inputModificationTime < time)
+ {
+ inputModificationTime = time;
+
+ checkModificationTimes();
+ }
+ }
+
+
+ /**
+ * Updates the output modification time.
+ */
+ public void updateOutputModificationTime(long time)
+ {
+ if (outputModificationTime > time)
+ {
+ outputModificationTime = time;
+
+ checkModificationTimes();
+ }
+ }
+
+
+ private void checkModificationTimes()
+ {
+ if (inputModificationTime > outputModificationTime)
+ {
+ throw new IllegalStateException("The output is outdated");
+ }
}
}
}
diff --git a/src/proguard/WordReader.java b/src/proguard/WordReader.java
index d73505a..4e7a511 100644
--- a/src/proguard/WordReader.java
+++ b/src/proguard/WordReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -105,9 +105,11 @@ public abstract class WordReader
* Reads a word from this WordReader, or from one of its active included
* WordReader objects.
*
+ * @param isFileName return a complete line (or argument), if the word
+ * isn't an option (it doesn't start with '-').
* @return the read word.
*/
- public String nextWord() throws IOException
+ public String nextWord(boolean isFileName) throws IOException
{
currentWord = null;
@@ -115,7 +117,7 @@ public abstract class WordReader
if (includeWordReader != null)
{
// Does the included word reader still produce a word?
- currentWord = includeWordReader.nextWord();
+ currentWord = includeWordReader.nextWord(isFileName);
if (currentWord != null)
{
// Return it if so.
@@ -129,12 +131,22 @@ public abstract class WordReader
// Get a word from this reader.
- // Skip leading whitespace.
- while (currentLine != null &&
- currentIndex < currentLineLength &&
- Character.isWhitespace(currentLine.charAt(currentIndex)))
+ // Skip any whitespace and comments left on the current line.
+ if (currentLine != null)
{
- currentIndex++;
+ // Skip any leading whitespace.
+ while (currentIndex < currentLineLength &&
+ Character.isWhitespace(currentLine.charAt(currentIndex)))
+ {
+ currentIndex++;
+ }
+
+ // Skip any comments.
+ if (currentIndex < currentLineLength &&
+ isComment(currentLine.charAt(currentIndex)))
+ {
+ currentIndex = currentLineLength;
+ }
}
// Make sure we have a non-blank line.
@@ -146,29 +158,28 @@ public abstract class WordReader
return null;
}
- // Trim off any comments.
- int comments_start = currentLine.indexOf(COMMENT_CHARACTER);
- if (comments_start >= 0)
+ currentLineLength = currentLine.length();
+
+ // Skip any leading whitespace.
+ currentIndex = 0;
+ while (currentIndex < currentLineLength &&
+ Character.isWhitespace(currentLine.charAt(currentIndex)))
{
- currentLineLength = comments_start;
+ currentIndex++;
+ }
+ // Remember any leading comments.
+ if (currentIndex < currentLineLength &&
+ isComment(currentLine.charAt(currentIndex)))
+ {
// Remember the comments.
- String comment = currentLine.substring(comments_start + 1);
+ String comment = currentLine.substring(currentIndex + 1);
currentComments = currentComments == null ?
comment :
currentComments + '\n' + comment;
- }
- else
- {
- currentLineLength = currentLine.length();
- }
- // Skip leading whitespace.
- currentIndex = 0;
- while (currentIndex < currentLineLength &&
- Character.isWhitespace(currentLine.charAt(currentIndex)))
- {
- currentIndex++;
+ // Skip the comments.
+ currentIndex = currentLineLength;
}
}
@@ -178,12 +189,7 @@ public abstract class WordReader
char startChar = currentLine.charAt(startIndex);
- if (isDelimiter(startChar))
- {
- // The next word is a single delimiting character.
- endIndex = ++currentIndex;
- }
- else if (isQuote(startChar))
+ if (isQuote(startChar))
{
// The next word is starting with a quote character.
// Skip the opening quote.
@@ -205,6 +211,39 @@ public abstract class WordReader
endIndex = currentIndex++;
}
+ else if (isFileName &&
+ !isOption(startChar))
+ {
+ // The next word is a (possibly optional) file name.
+ // Find the end of the line, the first path separator, the first
+ // option, or the first comment.
+ while (currentIndex < currentLineLength)
+ {
+ char currentCharacter = currentLine.charAt(currentIndex);
+ if (isFileDelimiter(currentCharacter) ||
+ (isOption(currentCharacter) ||
+ isComment(currentCharacter)) &&
+ Character.isWhitespace(currentLine.charAt(currentIndex-1))) {
+ break;
+ }
+
+ currentIndex++;
+ }
+
+ endIndex = currentIndex;
+
+ // Trim any trailing whitespace.
+ while (endIndex > startIndex &&
+ Character.isWhitespace(currentLine.charAt(endIndex-1)))
+ {
+ endIndex--;
+ }
+ }
+ else if (isDelimiter(startChar))
+ {
+ // The next word is a single delimiting character.
+ endIndex = ++currentIndex;
+ }
else
{
// The next word is a simple character string.
@@ -213,9 +252,9 @@ public abstract class WordReader
while (currentIndex < currentLineLength)
{
char currentCharacter = currentLine.charAt(currentIndex);
- if (isDelimiter(currentCharacter) ||
- Character.isWhitespace(currentCharacter))
- {
+ if (isDelimiter(currentCharacter) ||
+ Character.isWhitespace(currentCharacter) ||
+ isComment(currentCharacter)) {
break;
}
@@ -305,6 +344,18 @@ public abstract class WordReader
// Small utility methods.
+ private boolean isOption(char character)
+ {
+ return character == '-';
+ }
+
+
+ private boolean isComment(char character)
+ {
+ return character == COMMENT_CHARACTER;
+ }
+
+
private boolean isDelimiter(char character)
{
return character == '@' ||
@@ -318,6 +369,16 @@ public abstract class WordReader
}
+ private boolean isFileDelimiter(char character)
+ {
+ return character == '(' ||
+ character == ')' ||
+ character == ',' ||
+ character == ';' ||
+ character == File.pathSeparatorChar;
+ }
+
+
private boolean isQuote(char character)
{
return character == '\'' ||
diff --git a/src/proguard/ant/ClassPathElement.java b/src/proguard/ant/ClassPathElement.java
index b5c2df4..53084d3 100644
--- a/src/proguard/ant/ClassPathElement.java
+++ b/src/proguard/ant/ClassPathElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/ClassSpecificationElement.java b/src/proguard/ant/ClassSpecificationElement.java
index f4ea2ff..81b0c1b 100644
--- a/src/proguard/ant/ClassSpecificationElement.java
+++ b/src/proguard/ant/ClassSpecificationElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -222,6 +222,7 @@ public class ClassSpecificationElement extends DataType
strippedToken.equals(ClassConstants.EXTERNAL_ACC_PUBLIC) ? ClassConstants.INTERNAL_ACC_PUBLIC :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_FINAL) ? ClassConstants.INTERNAL_ACC_FINAL :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
+ strippedToken.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_ANNOTATION) ? ClassConstants.INTERNAL_ACC_ANNOTATTION :
0;
diff --git a/src/proguard/ant/ConfigurationElement.java b/src/proguard/ant/ConfigurationElement.java
index 76e9418..f283b8d 100644
--- a/src/proguard/ant/ConfigurationElement.java
+++ b/src/proguard/ant/ConfigurationElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/ConfigurationTask.java b/src/proguard/ant/ConfigurationTask.java
index 0d2f04f..6c4d48a 100644
--- a/src/proguard/ant/ConfigurationTask.java
+++ b/src/proguard/ant/ConfigurationTask.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -293,7 +293,8 @@ public class ConfigurationTask extends Task
{
String arg = getProject().replaceProperties(text);
- ConfigurationParser parser = new ConfigurationParser(new String[] { arg },
+ ConfigurationParser parser = new ConfigurationParser(arg,
+ "embedded configuration",
getProject().getBaseDir());
try
diff --git a/src/proguard/ant/FilterElement.java b/src/proguard/ant/FilterElement.java
index d792c5d..1174bd5 100644
--- a/src/proguard/ant/FilterElement.java
+++ b/src/proguard/ant/FilterElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/KeepSpecificationElement.java b/src/proguard/ant/KeepSpecificationElement.java
index e36b744..2ac61e8 100644
--- a/src/proguard/ant/KeepSpecificationElement.java
+++ b/src/proguard/ant/KeepSpecificationElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/MemberSpecificationElement.java b/src/proguard/ant/MemberSpecificationElement.java
index d4bb4a9..789cc5e 100644
--- a/src/proguard/ant/MemberSpecificationElement.java
+++ b/src/proguard/ant/MemberSpecificationElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -195,9 +195,12 @@ public class MemberSpecificationElement extends DataType
strippedToken.equals(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED) ? ClassConstants.INTERNAL_ACC_SYNCHRONIZED :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_VOLATILE) ? ClassConstants.INTERNAL_ACC_VOLATILE :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_TRANSIENT) ? ClassConstants.INTERNAL_ACC_TRANSIENT :
+ strippedToken.equals(ClassConstants.EXTERNAL_ACC_BRIDGE) ? ClassConstants.INTERNAL_ACC_BRIDGE :
+ strippedToken.equals(ClassConstants.EXTERNAL_ACC_VARARGS) ? ClassConstants.INTERNAL_ACC_VARARGS :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_NATIVE) ? ClassConstants.INTERNAL_ACC_NATIVE :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_STRICT) ? ClassConstants.INTERNAL_ACC_STRICT :
+ strippedToken.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC :
0;
if (accessFlag == 0)
diff --git a/src/proguard/ant/ProGuardTask.java b/src/proguard/ant/ProGuardTask.java
index b7fc361..982c2dd 100644
--- a/src/proguard/ant/ProGuardTask.java
+++ b/src/proguard/ant/ProGuardTask.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -215,6 +215,12 @@ public class ProGuardTask extends ConfigurationTask
}
+ public void setKeepparameternames(boolean keepParameterNames)
+ {
+ configuration.keepParameterNames = keepParameterNames;
+ }
+
+
public void setRenamesourcefileattribute(String newSourceFileAttribute)
{
configuration.newSourceFileAttribute = newSourceFileAttribute;
@@ -241,13 +247,39 @@ public class ProGuardTask extends ConfigurationTask
public void setNote(boolean note)
{
- configuration.note = note ? null : new ArrayList();
+ if (note)
+ {
+ // Switch on notes if they were completely disabled.
+ if (configuration.note != null &&
+ configuration.note.isEmpty())
+ {
+ configuration.note = null;
+ }
+ }
+ else
+ {
+ // Switch off notes.
+ configuration.note = new ArrayList();
+ }
}
public void setWarn(boolean warn)
{
- configuration.warn = warn ? null : new ArrayList();
+ if (warn)
+ {
+ // Switch on warnings if they were completely disabled.
+ if (configuration.warn != null &&
+ configuration.warn.isEmpty())
+ {
+ configuration.warn = null;
+ }
+ }
+ else
+ {
+ // Switch off warnings.
+ configuration.warn = new ArrayList();
+ }
}
diff --git a/src/proguard/classfile/ClassConstants.java b/src/proguard/classfile/ClassConstants.java
index 3b243e0..081305b 100644
--- a/src/proguard/classfile/ClassConstants.java
+++ b/src/proguard/classfile/ClassConstants.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -43,6 +43,8 @@ public interface ClassConstants
public static final int INTERNAL_CLASS_VERSION_1_5_MINOR = 0;
public static final int INTERNAL_CLASS_VERSION_1_6_MAJOR = 50;
public static final int INTERNAL_CLASS_VERSION_1_6_MINOR = 0;
+ public static final int INTERNAL_CLASS_VERSION_1_7_MAJOR = 51;
+ public static final int INTERNAL_CLASS_VERSION_1_7_MINOR = 0;
public static final int INTERNAL_CLASS_VERSION_1_0 = (INTERNAL_CLASS_VERSION_1_0_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_0_MINOR;
public static final int INTERNAL_CLASS_VERSION_1_2 = (INTERNAL_CLASS_VERSION_1_2_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_2_MINOR;
@@ -50,6 +52,7 @@ public interface ClassConstants
public static final int INTERNAL_CLASS_VERSION_1_4 = (INTERNAL_CLASS_VERSION_1_4_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_4_MINOR;
public static final int INTERNAL_CLASS_VERSION_1_5 = (INTERNAL_CLASS_VERSION_1_5_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_5_MINOR;
public static final int INTERNAL_CLASS_VERSION_1_6 = (INTERNAL_CLASS_VERSION_1_6_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_6_MINOR;
+ public static final int INTERNAL_CLASS_VERSION_1_7 = (INTERNAL_CLASS_VERSION_1_7_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_7_MINOR;
public static final String EXTERNAL_CLASS_VERSION_1_0 = "1.0";
public static final String EXTERNAL_CLASS_VERSION_1_1 = "1.1";
@@ -58,8 +61,10 @@ public interface ClassConstants
public static final String EXTERNAL_CLASS_VERSION_1_4 = "1.4";
public static final String EXTERNAL_CLASS_VERSION_1_5 = "1.5";
public static final String EXTERNAL_CLASS_VERSION_1_6 = "1.6";
+ public static final String EXTERNAL_CLASS_VERSION_1_7 = "1.7";
public static final String EXTERNAL_CLASS_VERSION_1_5_ALIAS = "5";
public static final String EXTERNAL_CLASS_VERSION_1_6_ALIAS = "6";
+ public static final String EXTERNAL_CLASS_VERSION_1_7_ALIAS = "7";
public static final int INTERNAL_ACC_PUBLIC = 0x0001;
public static final int INTERNAL_ACC_PRIVATE = 0x0002;
@@ -119,10 +124,13 @@ public interface ClassConstants
public static final String EXTERNAL_ACC_SYNCHRONIZED = "synchronized";
public static final String EXTERNAL_ACC_VOLATILE = "volatile";
public static final String EXTERNAL_ACC_TRANSIENT = "transient";
+ public static final String EXTERNAL_ACC_BRIDGE = "bridge";
+ public static final String EXTERNAL_ACC_VARARGS = "varargs";
public static final String EXTERNAL_ACC_NATIVE = "native";
public static final String EXTERNAL_ACC_INTERFACE = "interface";
public static final String EXTERNAL_ACC_ABSTRACT = "abstract";
public static final String EXTERNAL_ACC_STRICT = "strictfp";
+ public static final String EXTERNAL_ACC_SYNTHETIC = "synthetic";
public static final String EXTERNAL_ACC_ANNOTATION = "@";
public static final String EXTERNAL_ACC_ENUM = "enum";
@@ -137,7 +145,21 @@ public interface ClassConstants
public static final int CONSTANT_Methodref = 10;
public static final int CONSTANT_InterfaceMethodref = 11;
public static final int CONSTANT_NameAndType = 12;
+ public static final int CONSTANT_MethodHandle = 15;
+ public static final int CONSTANT_MethodType = 16;
+ public static final int CONSTANT_InvokeDynamic = 18;
+ public static final int REF_getField = 1;
+ public static final int REF_getStatic = 2;
+ public static final int REF_putField = 3;
+ public static final int REF_putStatic = 4;
+ public static final int REF_invokeVirtual = 5;
+ public static final int REF_invokeStatic = 6;
+ public static final int REF_invokeSpecial = 7;
+ public static final int REF_newInvokeSpecial = 8;
+ public static final int REF_invokeInterface = 9;
+
+ public static final String ATTR_BootstrapMethods = "BootstrapMethods";
public static final String ATTR_SourceFile = "SourceFile";
public static final String ATTR_SourceDir = "SourceDir";
public static final String ATTR_InnerClasses = "InnerClasses";
@@ -179,32 +201,48 @@ public interface ClassConstants
public static final char INTERNAL_METHOD_ARGUMENTS_OPEN = '(';
public static final char INTERNAL_METHOD_ARGUMENTS_CLOSE = ')';
- public static final String INTERNAL_PACKAGE_JAVA_LANG = "java/lang/";
- public static final String INTERNAL_NAME_JAVA_LANG_OBJECT = "java/lang/Object";
- public static final String INTERNAL_TYPE_JAVA_LANG_OBJECT = "Ljava/lang/Object;";
- public static final String INTERNAL_NAME_JAVA_LANG_CLONEABLE = "java/lang/Cloneable";
- public static final String INTERNAL_NAME_JAVA_LANG_THROWABLE = "java/lang/Throwable";
- public static final String INTERNAL_NAME_JAVA_LANG_CLASS = "java/lang/Class";
- public static final String INTERNAL_NAME_JAVA_LANG_STRING = "java/lang/String";
- public static final String INTERNAL_NAME_JAVA_IO_SERIALIZABLE = "java/io/Serializable";
+ public static final String INTERNAL_PACKAGE_JAVA_LANG = "java/lang/";
+ public static final String INTERNAL_NAME_JAVA_LANG_OBJECT = "java/lang/Object";
+ public static final String INTERNAL_TYPE_JAVA_LANG_OBJECT = "Ljava/lang/Object;";
+ public static final String INTERNAL_NAME_JAVA_LANG_CLONEABLE = "java/lang/Cloneable";
+ public static final String INTERNAL_NAME_JAVA_LANG_THROWABLE = "java/lang/Throwable";
+ public static final String INTERNAL_NAME_JAVA_LANG_CLASS = "java/lang/Class";
+ public static final String INTERNAL_NAME_JAVA_LANG_STRING = "java/lang/String";
+ public static final String INTERNAL_NAME_JAVA_LANG_STRING_BUFFER = "java/lang/StringBuffer";
+ public static final String INTERNAL_NAME_JAVA_LANG_STRING_BUILDER = "java/lang/StringBuilder";
+ public static final String INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE = "java/lang/invoke/MethodHandle";
+ public static final String INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE = "java/lang/invoke/MethodType";
+ public static final String INTERNAL_NAME_JAVA_IO_SERIALIZABLE = "java/io/Serializable";
+
+ public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_INTEGER_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicIntegerFieldUpdater";
+ public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_LONG_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicLongFieldUpdater";
+ public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_REFERENCE_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicReferenceFieldUpdater";
public static final String INTERNAL_METHOD_NAME_INIT = "<init>";
public static final String INTERNAL_METHOD_TYPE_INIT = "()V";
public static final String INTERNAL_METHOD_NAME_CLINIT = "<clinit>";
public static final String INTERNAL_METHOD_TYPE_CLINIT = "()V";
- public static final String INTERNAL_METHOD_NAME_CLASS_FOR_NAME = "forName";
- public static final String INTERNAL_METHOD_TYPE_CLASS_FOR_NAME = "(Ljava/lang/String;)Ljava/lang/Class;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_COMPONENT_TYPE = "getComponentType";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_COMPONENT_TYPE = "()Ljava/lang/Class;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_FIELD = "getField";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_FIELD = "getDeclaredField";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_METHOD = "getMethod";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_METHOD = "getDeclaredMethod";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_FOR_NAME = "forName";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_FOR_NAME = "(Ljava/lang/String;)Ljava/lang/Class;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_COMPONENT_TYPE = "getComponentType";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_COMPONENT_TYPE = "()Ljava/lang/Class;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_FIELD = "getField";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_FIELD = "getDeclaredField";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;";
+ public static final String INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_CONSTRUCTOR = "getConstructor";
+ public static final String INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_CONSTRUCTOR = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;";
+ public static final String INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_DECLARED_CONSTRUCTOR = "getDeclaredConstructor";
+ public static final String INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_DECLARED_CONSTRUCTOR = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_METHOD = "getMethod";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_METHOD = "getDeclaredMethod";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
+ public static final String INTERNAL_METHOD_NAME_NEW_UPDATER = "newUpdater";
+ public static final String INTERNAL_METHOD_TYPE_NEW_INTEGER_UPDATER = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicIntegerFieldUpdater;";
+ public static final String INTERNAL_METHOD_TYPE_NEW_LONG_UPDATER = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;";
+ public static final String INTERNAL_METHOD_TYPE_NEW_REFERENCE_UPDATER = "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;";
public static final String INTERNAL_METHOD_NAME_DOT_CLASS_JAVAC = "class$";
public static final String INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC = "(Ljava/lang/String;)Ljava/lang/Class;";
@@ -214,6 +252,29 @@ public interface ClassConstants
public static final String INTERNAL_METHOD_NAME_NEW_INSTANCE = "newInstance";
public static final String INTERNAL_METHOD_TYPE_NEW_INSTANCE = "()Ljava/lang/Object;";
+ public static final String INTERNAL_METHOD_NAME_EQUALS = "equals";
+ public static final String INTERNAL_METHOD_TYPE_EQUALS = "(Ljava/lang/Object;)Z";
+ public static final String INTERNAL_METHOD_NAME_LENGTH = "length";
+ public static final String INTERNAL_METHOD_TYPE_LENGTH = "()I";
+ public static final String INTERNAL_METHOD_NAME_APPEND = "append";
+ public static final String INTERNAL_METHOD_TYPE_STRING_VOID = "(Ljava/lang/String;)V";
+ public static final String INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUFFER = "(Z)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_CHAR_STRING_BUFFER = "(C)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_INT_STRING_BUFFER = "(I)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_LONG_STRING_BUFFER = "(J)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_FLOAT_STRING_BUFFER = "(F)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUFFER = "(D)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_STRING_STRING_BUFFER = "(Ljava/lang/String;)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUILDER = "(Z)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_CHAR_STRING_BUILDER = "(C)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_INT_STRING_BUILDER = "(I)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_LONG_STRING_BUILDER = "(J)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_FLOAT_STRING_BUILDER = "(F)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUILDER = "(D)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_STRING_STRING_BUILDER = "(Ljava/lang/String;)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_NAME_TOSTRING = "toString";
+ public static final String INTERNAL_METHOD_TYPE_TOSTRING = "()Ljava/lang/String;";
+
public static final char INTERNAL_TYPE_VOID = 'V';
public static final char INTERNAL_TYPE_BOOLEAN = 'Z';
public static final char INTERNAL_TYPE_BYTE = 'B';
diff --git a/src/proguard/classfile/ClassPool.java b/src/proguard/classfile/ClassPool.java
index 57728a5..c5defe8 100644
--- a/src/proguard/classfile/ClassPool.java
+++ b/src/proguard/classfile/ClassPool.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -26,14 +26,16 @@ import proguard.classfile.visitor.*;
import java.util.*;
/**
- * This is a set of representations of classes. They can be enumerated or
+ * This is a set of representations of classes. They can be enumerated or
* retrieved by name. They can also be accessed by means of class visitors.
*
* @author Eric Lafortune
*/
public class ClassPool
{
- private final Map classes = new HashMap();
+ // We're using a sorted tree map instead of a hash map to store the classes,
+ // in order to make the processing more deterministic.
+ private final Map classes = new TreeMap();
/**
@@ -66,11 +68,11 @@ public class ClassPool
/**
* Returns a Clazz from the class pool based on its name. Returns
* <code>null</code> if the class with the given name is not in the class
- * pool. Returns the base class if the class name is an array type.
+ * pool.
*/
public Clazz getClass(String className)
{
- return (Clazz)classes.get(ClassUtil.internalClassNameFromClassType(className));
+ return (Clazz)classes.get(className);
}
@@ -122,8 +124,11 @@ public class ClassPool
*/
public void classesAcceptAlphabetically(ClassVisitor classVisitor)
{
- TreeMap sortedClasses = new TreeMap(classes);
- Iterator iterator = sortedClasses.values().iterator();
+ // We're already using a tree map.
+ //TreeMap sortedClasses = new TreeMap(classes);
+ //Iterator iterator = sortedClasses.values().iterator();
+
+ Iterator iterator = classes.values().iterator();
while (iterator.hasNext())
{
Clazz clazz = (Clazz)iterator.next();
diff --git a/src/proguard/classfile/Clazz.java b/src/proguard/classfile/Clazz.java
index da37d9a..3dfdcd0 100644
--- a/src/proguard/classfile/Clazz.java
+++ b/src/proguard/classfile/Clazz.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -90,6 +90,16 @@ public interface Clazz extends VisitorAccepter
*/
public String getType(int constantIndex);
+ /**
+ * Returns the name of the RefConstant at the specified index.
+ */
+ public String getRefName(int constantIndex);
+
+ /**
+ * Returns the type of the RefConstant at the specified index.
+ */
+ public String getRefType(int constantIndex);
+
// Methods pertaining to related classes.
@@ -116,12 +126,26 @@ public interface Clazz extends VisitorAccepter
public boolean extends_(Clazz clazz);
/**
+ * Returns whether this class extends the specified class.
+ * A class is always considered to extend itself.
+ * Interfaces are considered to only extend the root Object class.
+ */
+ public boolean extends_(String className);
+
+ /**
* Returns whether this class implements the given class.
* A class is always considered to implement itself.
* Interfaces are considered to implement all their superinterfaces.
*/
public boolean extendsOrImplements(Clazz clazz);
+ /**
+ * Returns whether this class implements the specified class.
+ * A class is always considered to implement itself.
+ * Interfaces are considered to implement all their superinterfaces.
+ */
+ public boolean extendsOrImplements(String className);
+
// Methods for getting specific class members.
@@ -229,4 +253,9 @@ public interface Clazz extends VisitorAccepter
* Lets the given attribute info visitor visit all attributes of this class.
*/
public void attributesAccept(AttributeVisitor attributeVisitor);
+
+ /**
+ * Lets the given attribute info visitor visit the specified attribute.
+ */
+ public void attributeAccept(String name, AttributeVisitor attributeVisitor);
}
diff --git a/src/proguard/classfile/Field.java b/src/proguard/classfile/Field.java
index ba1315a..c30321d 100644
--- a/src/proguard/classfile/Field.java
+++ b/src/proguard/classfile/Field.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/LibraryClass.java b/src/proguard/classfile/LibraryClass.java
index 0a27593..625d088 100644
--- a/src/proguard/classfile/LibraryClass.java
+++ b/src/proguard/classfile/LibraryClass.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -137,6 +137,17 @@ public class LibraryClass implements Clazz
}
+ public String getRefName(int constantIndex)
+ {
+ throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
+ }
+
+ public String getRefType(int constantIndex)
+ {
+ throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
+ }
+
+
public void addSubClass(Clazz clazz)
{
if (subClasses == null)
@@ -179,6 +190,18 @@ public class LibraryClass implements Clazz
}
+ public boolean extends_(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ return superClass != null &&
+ superClass.extends_(className);
+ }
+
+
public boolean extendsOrImplements(Clazz clazz)
{
if (this.equals(clazz))
@@ -209,6 +232,36 @@ public class LibraryClass implements Clazz
}
+ public boolean extendsOrImplements(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ if (superClass != null &&
+ superClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+
+ if (interfaceClasses != null)
+ {
+ for (int index = 0; index < interfaceClasses.length; index++)
+ {
+ Clazz interfaceClass = interfaceClasses[index];
+ if (interfaceClass != null &&
+ interfaceClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+
public Field findField(String name, String descriptor)
{
for (int index = 0; index < fields.length; index++)
@@ -467,6 +520,12 @@ public class LibraryClass implements Clazz
}
+ public void attributeAccept(String name, AttributeVisitor attributeVisitor)
+ {
+ throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store attributes");
+ }
+
+
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
diff --git a/src/proguard/classfile/LibraryField.java b/src/proguard/classfile/LibraryField.java
index 2908c37..e9c8469 100644
--- a/src/proguard/classfile/LibraryField.java
+++ b/src/proguard/classfile/LibraryField.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/LibraryMember.java b/src/proguard/classfile/LibraryMember.java
index 41ccb60..ef5a4d7 100644
--- a/src/proguard/classfile/LibraryMember.java
+++ b/src/proguard/classfile/LibraryMember.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/LibraryMethod.java b/src/proguard/classfile/LibraryMethod.java
index a49a5f1..cd95ea6 100644
--- a/src/proguard/classfile/LibraryMethod.java
+++ b/src/proguard/classfile/LibraryMethod.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/Member.java b/src/proguard/classfile/Member.java
index 1400b9c..2e984c2 100644
--- a/src/proguard/classfile/Member.java
+++ b/src/proguard/classfile/Member.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/Method.java b/src/proguard/classfile/Method.java
index ebcae2b..ec8f2b5 100644
--- a/src/proguard/classfile/Method.java
+++ b/src/proguard/classfile/Method.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/ProgramClass.java b/src/proguard/classfile/ProgramClass.java
index 9d0fc0c..e3caddb 100644
--- a/src/proguard/classfile/ProgramClass.java
+++ b/src/proguard/classfile/ProgramClass.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -117,8 +117,7 @@ public class ProgramClass implements Clazz
}
catch (ClassCastException ex)
{
- new ClassPrinter().visitProgramClass(this);
- throw new ClassCastException("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -130,7 +129,7 @@ public class ProgramClass implements Clazz
}
catch (ClassCastException ex)
{
- throw new ClassCastException("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -142,7 +141,7 @@ public class ProgramClass implements Clazz
}
catch (ClassCastException ex)
{
- throw new ClassCastException("Expected ClassConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected ClassConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -154,7 +153,7 @@ public class ProgramClass implements Clazz
}
catch (ClassCastException ex)
{
- throw new ClassCastException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -166,7 +165,32 @@ public class ProgramClass implements Clazz
}
catch (ClassCastException ex)
{
- throw new ClassCastException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+
+ public String getRefName(int constantIndex)
+ {
+ try
+ {
+ return ((RefConstant)constantPool[constantIndex]).getName(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+ public String getRefType(int constantIndex)
+ {
+ try
+ {
+ return ((RefConstant)constantPool[constantIndex]).getType(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -216,6 +240,19 @@ public class ProgramClass implements Clazz
}
+ public boolean extends_(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ Clazz superClass = getSuperClass();
+ return superClass != null &&
+ superClass.extends_(className);
+ }
+
+
public boolean extendsOrImplements(Clazz clazz)
{
if (this.equals(clazz))
@@ -244,6 +281,34 @@ public class ProgramClass implements Clazz
}
+ public boolean extendsOrImplements(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ Clazz superClass = getSuperClass();
+ if (superClass != null &&
+ superClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+
+ for (int index = 0; index < u2interfacesCount; index++)
+ {
+ Clazz interfaceClass = getInterface(index);
+ if (interfaceClass != null &&
+ interfaceClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
public Field findField(String name, String descriptor)
{
for (int index = 0; index < u2fieldsCount; index++)
@@ -472,6 +537,19 @@ public class ProgramClass implements Clazz
}
+ public void attributeAccept(String name, AttributeVisitor attributeVisitor)
+ {
+ for (int index = 0; index < u2attributesCount; index++)
+ {
+ Attribute attribute = attributes[index];
+ if (attribute.getAttributeName(this).equals(name))
+ {
+ attribute.accept(this, attributeVisitor);
+ }
+ }
+ }
+
+
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
diff --git a/src/proguard/classfile/ProgramField.java b/src/proguard/classfile/ProgramField.java
index 5991b00..761fe95 100644
--- a/src/proguard/classfile/ProgramField.java
+++ b/src/proguard/classfile/ProgramField.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/ProgramMember.java b/src/proguard/classfile/ProgramMember.java
index ea6f46d..86d12d9 100644
--- a/src/proguard/classfile/ProgramMember.java
+++ b/src/proguard/classfile/ProgramMember.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/ProgramMethod.java b/src/proguard/classfile/ProgramMethod.java
index 943c3d6..39e720f 100644
--- a/src/proguard/classfile/ProgramMethod.java
+++ b/src/proguard/classfile/ProgramMethod.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/VisitorAccepter.java b/src/proguard/classfile/VisitorAccepter.java
index e38f888..551d025 100644
--- a/src/proguard/classfile/VisitorAccepter.java
+++ b/src/proguard/classfile/VisitorAccepter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/Attribute.java b/src/proguard/classfile/attribute/Attribute.java
index 2e16e22..0eaafbb 100644
--- a/src/proguard/classfile/attribute/Attribute.java
+++ b/src/proguard/classfile/attribute/Attribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/BootstrapMethodInfo.java b/src/proguard/classfile/attribute/BootstrapMethodInfo.java
new file mode 100755
index 0000000..c593251
--- /dev/null
+++ b/src/proguard/classfile/attribute/BootstrapMethodInfo.java
@@ -0,0 +1,89 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.attribute;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+
+/**
+ * Representation of a bootstrap method.
+ *
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodInfo implements VisitorAccepter
+{
+ public int u2methodHandleIndex;
+ public int u2methodArgumentCount;
+ public int[] u2methodArguments;
+
+ /**
+ * An extra field in which visitors can store information.
+ */
+ public Object visitorInfo;
+
+
+ /**
+ * Creates an uninitialized BootstrapMethodInfo.
+ */
+ public BootstrapMethodInfo()
+ {
+ }
+
+
+ /**
+ * Creates an initialized BootstrapMethodInfo.
+ */
+ public BootstrapMethodInfo(int u2methodHandleIndex,
+ int u2methodArgumentCount,
+ int[] u2methodArguments)
+ {
+ this.u2methodHandleIndex = u2methodHandleIndex;
+ this.u2methodArgumentCount = u2methodArgumentCount;
+ this.u2methodArguments = u2methodArguments;
+ }
+
+
+ /**
+ * Applies the given constant pool visitor to the argument constants of the
+ * bootstrap method.
+ */
+ public void methodArgumentsAccept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ for (int index = 0; index < u2methodArgumentCount; index++)
+ {
+ clazz.constantPoolEntryAccept(u2methodArguments[index],
+ constantVisitor);
+ }
+ }
+
+
+ // Implementations for VisitorAccepter.
+
+ public Object getVisitorInfo()
+ {
+ return visitorInfo;
+ }
+
+ public void setVisitorInfo(Object visitorInfo)
+ {
+ this.visitorInfo = visitorInfo;
+ }
+}
diff --git a/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java b/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java
new file mode 100755
index 0000000..b8ec9bd
--- /dev/null
+++ b/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java
@@ -0,0 +1,95 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.attribute;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+
+/**
+ * This Attribute represents a bootstrap methods attribute.
+ *
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodsAttribute extends Attribute
+{
+ public int u2bootstrapMethodsCount;
+ public BootstrapMethodInfo[] bootstrapMethods;
+
+
+ /**
+ * Creates an uninitialized BootstrapMethodsAttribute.
+ */
+ public BootstrapMethodsAttribute()
+ {
+ }
+
+
+ /**
+ * Creates an initialized BootstrapMethodsAttribute.
+ */
+ public BootstrapMethodsAttribute(int u2attributeNameIndex,
+ int u2bootstrapMethodsCount,
+ BootstrapMethodInfo[] bootstrapMethods)
+ {
+ super(u2attributeNameIndex);
+
+ this.u2bootstrapMethodsCount = u2bootstrapMethodsCount;
+ this.bootstrapMethods = bootstrapMethods;
+ }
+
+
+ // Implementations for Attribute.
+
+ public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
+ {
+ attributeVisitor.visitBootstrapMethodsAttribute(clazz, this);
+ }
+
+
+ /**
+ * Applies the given constant pool visitor to all bootstrap method info
+ * entries.
+ */
+ public void bootstrapMethodEntriesAccept(Clazz clazz, BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor)
+ {
+ for (int index = 0; index < u2bootstrapMethodsCount; index++)
+ {
+ // We don't need double dispatching here, since there is only one
+ // type of BootstrapMethodInfo.
+ bootstrapMethodInfoVisitor.visitBootstrapMethodInfo(clazz, bootstrapMethods[index]);
+ }
+ }
+
+
+ /**
+ * Applies the given constant pool visitor to the specified bootstrap method
+ * info entry.
+ */
+ public void bootstrapMethodEntryAccept(Clazz clazz,
+ int bootstrapMethodIndex,
+ BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor)
+ {
+ // We don't need double dispatching here, since there is only one
+ // type of BootstrapMethodInfo.
+ bootstrapMethodInfoVisitor.visitBootstrapMethodInfo(clazz, bootstrapMethods[bootstrapMethodIndex]);
+ }
+}
diff --git a/src/proguard/classfile/attribute/CodeAttribute.java b/src/proguard/classfile/attribute/CodeAttribute.java
index 92ff9ea..9d5a254 100644
--- a/src/proguard/classfile/attribute/CodeAttribute.java
+++ b/src/proguard/classfile/attribute/CodeAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/ConstantValueAttribute.java b/src/proguard/classfile/attribute/ConstantValueAttribute.java
index 3ae991e..737ade0 100644
--- a/src/proguard/classfile/attribute/ConstantValueAttribute.java
+++ b/src/proguard/classfile/attribute/ConstantValueAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/DeprecatedAttribute.java b/src/proguard/classfile/attribute/DeprecatedAttribute.java
index 4180950..d440242 100644
--- a/src/proguard/classfile/attribute/DeprecatedAttribute.java
+++ b/src/proguard/classfile/attribute/DeprecatedAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/EnclosingMethodAttribute.java b/src/proguard/classfile/attribute/EnclosingMethodAttribute.java
index 9275b3a..befd585 100644
--- a/src/proguard/classfile/attribute/EnclosingMethodAttribute.java
+++ b/src/proguard/classfile/attribute/EnclosingMethodAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/ExceptionInfo.java b/src/proguard/classfile/attribute/ExceptionInfo.java
index 082efab..5f605cf 100644
--- a/src/proguard/classfile/attribute/ExceptionInfo.java
+++ b/src/proguard/classfile/attribute/ExceptionInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/ExceptionsAttribute.java b/src/proguard/classfile/attribute/ExceptionsAttribute.java
index d22c4a6..8dfd096 100644
--- a/src/proguard/classfile/attribute/ExceptionsAttribute.java
+++ b/src/proguard/classfile/attribute/ExceptionsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -69,12 +69,12 @@ public class ExceptionsAttribute extends Attribute
* Applies the given constant pool visitor to all exception class pool info
* entries.
*/
- public void exceptionEntriesAccept(ProgramClass programClass, ConstantVisitor constantVisitor)
+ public void exceptionEntriesAccept(Clazz clazz, ConstantVisitor constantVisitor)
{
for (int index = 0; index < u2exceptionIndexTableLength; index++)
{
- programClass.constantPoolEntryAccept(u2exceptionIndexTable[index],
- constantVisitor);
+ clazz.constantPoolEntryAccept(u2exceptionIndexTable[index],
+ constantVisitor);
}
}
}
diff --git a/src/proguard/classfile/attribute/InnerClassesAttribute.java b/src/proguard/classfile/attribute/InnerClassesAttribute.java
index 2f7e310..135c61c 100644
--- a/src/proguard/classfile/attribute/InnerClassesAttribute.java
+++ b/src/proguard/classfile/attribute/InnerClassesAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/InnerClassesInfo.java b/src/proguard/classfile/attribute/InnerClassesInfo.java
index 1bdd6c3..87f9768 100644
--- a/src/proguard/classfile/attribute/InnerClassesInfo.java
+++ b/src/proguard/classfile/attribute/InnerClassesInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -74,8 +74,7 @@ public class InnerClassesInfo implements VisitorAccepter
{
if (u2innerClassIndex != 0)
{
- clazz.constantPoolEntryAccept(u2innerClassIndex,
- constantVisitor);
+ clazz.constantPoolEntryAccept(u2innerClassIndex, constantVisitor);
}
}
@@ -88,8 +87,7 @@ public class InnerClassesInfo implements VisitorAccepter
{
if (u2outerClassIndex != 0)
{
- clazz.constantPoolEntryAccept(u2outerClassIndex,
- constantVisitor);
+ clazz.constantPoolEntryAccept(u2outerClassIndex, constantVisitor);
}
}
@@ -102,8 +100,7 @@ public class InnerClassesInfo implements VisitorAccepter
{
if (u2innerNameIndex != 0)
{
- clazz.constantPoolEntryAccept(u2innerNameIndex,
- constantVisitor);
+ clazz.constantPoolEntryAccept(u2innerNameIndex, constantVisitor);
}
}
diff --git a/src/proguard/classfile/attribute/LineNumberInfo.java b/src/proguard/classfile/attribute/LineNumberInfo.java
index f58083a..6ad7ed2 100644
--- a/src/proguard/classfile/attribute/LineNumberInfo.java
+++ b/src/proguard/classfile/attribute/LineNumberInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/LineNumberTableAttribute.java b/src/proguard/classfile/attribute/LineNumberTableAttribute.java
index 4d507d9..b9056d9 100644
--- a/src/proguard/classfile/attribute/LineNumberTableAttribute.java
+++ b/src/proguard/classfile/attribute/LineNumberTableAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/LocalVariableInfo.java b/src/proguard/classfile/attribute/LocalVariableInfo.java
index 4e54c22..589bb7a 100644
--- a/src/proguard/classfile/attribute/LocalVariableInfo.java
+++ b/src/proguard/classfile/attribute/LocalVariableInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -28,7 +28,7 @@ import proguard.classfile.visitor.ClassVisitor;
*
* @author Eric Lafortune
*/
-public class LocalVariableInfo
+public class LocalVariableInfo implements Comparable
{
public int u2startPC;
public int u2length;
@@ -80,4 +80,20 @@ public class LocalVariableInfo
referencedClass.accept(classVisitor);
}
}
+
+
+ // Implementations for Comparable.
+
+ public int compareTo(Object object)
+ {
+ LocalVariableInfo other = (LocalVariableInfo)object;
+
+ return
+ this.u2startPC < other.u2startPC ? -1 : this.u2startPC > other.u2startPC ? 1 :
+ this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 :
+ this.u2index < other.u2index ? -1 : this.u2index > other.u2index ? 1 :
+ this.u2descriptorIndex < other.u2descriptorIndex ? -1 : this.u2descriptorIndex > other.u2descriptorIndex ? 1 :
+ this.u2nameIndex < other.u2nameIndex ? -1 : this.u2nameIndex > other.u2nameIndex ? 1 :
+ 0;
+ }
}
diff --git a/src/proguard/classfile/attribute/LocalVariableTableAttribute.java b/src/proguard/classfile/attribute/LocalVariableTableAttribute.java
index 9c3f115..02eae2a 100644
--- a/src/proguard/classfile/attribute/LocalVariableTableAttribute.java
+++ b/src/proguard/classfile/attribute/LocalVariableTableAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/LocalVariableTypeInfo.java b/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
index 1b71f35..3a77e3d 100644
--- a/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
+++ b/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -28,7 +28,7 @@ import proguard.classfile.visitor.ClassVisitor;
*
* @author Eric Lafortune
*/
-public class LocalVariableTypeInfo
+public class LocalVariableTypeInfo implements Comparable
{
public int u2startPC;
public int u2length;
@@ -88,4 +88,20 @@ public class LocalVariableTypeInfo
}
}
}
+
+
+ // Implementations for Comparable.
+
+ public int compareTo(Object object)
+ {
+ LocalVariableTypeInfo other = (LocalVariableTypeInfo)object;
+
+ return
+ this.u2startPC < other.u2startPC ? -1 : this.u2startPC > other.u2startPC ? 1 :
+ this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 :
+ this.u2index < other.u2index ? -1 : this.u2index > other.u2index ? 1 :
+ this.u2signatureIndex < other.u2signatureIndex ? -1 : this.u2signatureIndex > other.u2signatureIndex ? 1 :
+ this.u2nameIndex < other.u2nameIndex ? -1 : this.u2nameIndex > other.u2nameIndex ? 1 :
+ 0;
+ }
}
diff --git a/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java b/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java
index fd856fe..3a2ab75 100644
--- a/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java
+++ b/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/SignatureAttribute.java b/src/proguard/classfile/attribute/SignatureAttribute.java
index c7585fe..2b59775 100644
--- a/src/proguard/classfile/attribute/SignatureAttribute.java
+++ b/src/proguard/classfile/attribute/SignatureAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/SourceDirAttribute.java b/src/proguard/classfile/attribute/SourceDirAttribute.java
index a26e8b1..f9e4005 100644
--- a/src/proguard/classfile/attribute/SourceDirAttribute.java
+++ b/src/proguard/classfile/attribute/SourceDirAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/SourceFileAttribute.java b/src/proguard/classfile/attribute/SourceFileAttribute.java
index 24269b7..b28e139 100644
--- a/src/proguard/classfile/attribute/SourceFileAttribute.java
+++ b/src/proguard/classfile/attribute/SourceFileAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/SyntheticAttribute.java b/src/proguard/classfile/attribute/SyntheticAttribute.java
index 6ccb1b5..cbb7e30 100644
--- a/src/proguard/classfile/attribute/SyntheticAttribute.java
+++ b/src/proguard/classfile/attribute/SyntheticAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/UnknownAttribute.java b/src/proguard/classfile/attribute/UnknownAttribute.java
index 2f138bd..11f6029 100644
--- a/src/proguard/classfile/attribute/UnknownAttribute.java
+++ b/src/proguard/classfile/attribute/UnknownAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/Annotation.java b/src/proguard/classfile/attribute/annotation/Annotation.java
index 41bb8e3..248c8f3 100644
--- a/src/proguard/classfile/attribute/annotation/Annotation.java
+++ b/src/proguard/classfile/attribute/annotation/Annotation.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java b/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java
index b378cd2..9ac7eae 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java b/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
index 29129d0..0cfefac 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java
index 8117077..1786f15 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/ArrayElementValue.java b/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
index 25b8b9f..f2bf911 100644
--- a/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/ClassElementValue.java b/src/proguard/classfile/attribute/annotation/ClassElementValue.java
index ba51641..b174695 100644
--- a/src/proguard/classfile/attribute/annotation/ClassElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ClassElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/ConstantElementValue.java b/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
index 3ebe5e5..f8bfc7f 100644
--- a/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/ElementValue.java b/src/proguard/classfile/attribute/annotation/ElementValue.java
index 39f8953..415aa6a 100644
--- a/src/proguard/classfile/attribute/annotation/ElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java b/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
index d46bb7f..c6fbb52 100644
--- a/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java
index 3c700c8..0aca20f 100644
--- a/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java
index 9c8180c..4494b4c 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java
index 7e41656..5696a37 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java
index 380c52e..e25d868 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java
index 626fbda..722792e 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java
index bce7170..4af6946 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java
index 7a1d7c6..4582728 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java
index c206c16..c3e5eb0 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java
index d869fd2..6068dfb 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java
index 16b2a56..b079628 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java
index 112084a..0f89b06 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/DoubleType.java b/src/proguard/classfile/attribute/preverification/DoubleType.java
index d574dcb..4cc614d 100644
--- a/src/proguard/classfile/attribute/preverification/DoubleType.java
+++ b/src/proguard/classfile/attribute/preverification/DoubleType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/FloatType.java b/src/proguard/classfile/attribute/preverification/FloatType.java
index 2f24720..2559d53 100644
--- a/src/proguard/classfile/attribute/preverification/FloatType.java
+++ b/src/proguard/classfile/attribute/preverification/FloatType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/FullFrame.java b/src/proguard/classfile/attribute/preverification/FullFrame.java
index adf5684..39cc7f6 100644
--- a/src/proguard/classfile/attribute/preverification/FullFrame.java
+++ b/src/proguard/classfile/attribute/preverification/FullFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/IntegerType.java b/src/proguard/classfile/attribute/preverification/IntegerType.java
index 55e3abe..3dc6382 100644
--- a/src/proguard/classfile/attribute/preverification/IntegerType.java
+++ b/src/proguard/classfile/attribute/preverification/IntegerType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/LessZeroFrame.java b/src/proguard/classfile/attribute/preverification/LessZeroFrame.java
index fcc8e0a..e995346 100644
--- a/src/proguard/classfile/attribute/preverification/LessZeroFrame.java
+++ b/src/proguard/classfile/attribute/preverification/LessZeroFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/LongType.java b/src/proguard/classfile/attribute/preverification/LongType.java
index 9b14dd6..a2f3eaa 100644
--- a/src/proguard/classfile/attribute/preverification/LongType.java
+++ b/src/proguard/classfile/attribute/preverification/LongType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java b/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java
index 881f188..1a375f1 100644
--- a/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java
+++ b/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/NullType.java b/src/proguard/classfile/attribute/preverification/NullType.java
index f35cefd..4832751 100644
--- a/src/proguard/classfile/attribute/preverification/NullType.java
+++ b/src/proguard/classfile/attribute/preverification/NullType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/ObjectType.java b/src/proguard/classfile/attribute/preverification/ObjectType.java
index fbdeec7..acc45e1 100644
--- a/src/proguard/classfile/attribute/preverification/ObjectType.java
+++ b/src/proguard/classfile/attribute/preverification/ObjectType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/SameOneFrame.java b/src/proguard/classfile/attribute/preverification/SameOneFrame.java
index db6747b..7d5db73 100644
--- a/src/proguard/classfile/attribute/preverification/SameOneFrame.java
+++ b/src/proguard/classfile/attribute/preverification/SameOneFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/SameZeroFrame.java b/src/proguard/classfile/attribute/preverification/SameZeroFrame.java
index 64b17f5..ffde7f5 100644
--- a/src/proguard/classfile/attribute/preverification/SameZeroFrame.java
+++ b/src/proguard/classfile/attribute/preverification/SameZeroFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/StackMapAttribute.java b/src/proguard/classfile/attribute/preverification/StackMapAttribute.java
index db53ff1..fe0e010 100644
--- a/src/proguard/classfile/attribute/preverification/StackMapAttribute.java
+++ b/src/proguard/classfile/attribute/preverification/StackMapAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/StackMapFrame.java b/src/proguard/classfile/attribute/preverification/StackMapFrame.java
index aa3e1f2..999863b 100644
--- a/src/proguard/classfile/attribute/preverification/StackMapFrame.java
+++ b/src/proguard/classfile/attribute/preverification/StackMapFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java b/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java
index 0cddf70..7a2be14 100644
--- a/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java
+++ b/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/TopType.java b/src/proguard/classfile/attribute/preverification/TopType.java
index bde8dda..27321bc 100644
--- a/src/proguard/classfile/attribute/preverification/TopType.java
+++ b/src/proguard/classfile/attribute/preverification/TopType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/UninitializedThisType.java b/src/proguard/classfile/attribute/preverification/UninitializedThisType.java
index dc4654f..1a9bf83 100644
--- a/src/proguard/classfile/attribute/preverification/UninitializedThisType.java
+++ b/src/proguard/classfile/attribute/preverification/UninitializedThisType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/UninitializedType.java b/src/proguard/classfile/attribute/preverification/UninitializedType.java
index a495f1f..4b2963c 100644
--- a/src/proguard/classfile/attribute/preverification/UninitializedType.java
+++ b/src/proguard/classfile/attribute/preverification/UninitializedType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/VerificationType.java b/src/proguard/classfile/attribute/preverification/VerificationType.java
index f33d511..720f221 100644
--- a/src/proguard/classfile/attribute/preverification/VerificationType.java
+++ b/src/proguard/classfile/attribute/preverification/VerificationType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java b/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java
index f8ef7e0..c99ee7d 100644
--- a/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java
+++ b/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java b/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java
index 7db246c..1b4ffad 100644
--- a/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java
+++ b/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java b/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java
index e9931f8..703e8c4 100644
--- a/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java
+++ b/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java b/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java
index 61b0f1a..8c4555d 100644
--- a/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java
new file mode 100644
index 0000000..fbc9189
--- /dev/null
+++ b/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java
@@ -0,0 +1,55 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.attribute.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This AttributeVisitor lets a given BootstrapMethodInfoVisitor visit all
+ * bootstrap method objects of the BootstrapMethodsAttribute objects it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class AllBootstrapMethodInfoVisitor
+extends SimplifiedVisitor
+implements AttributeVisitor
+{
+ private final BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor;
+
+
+ public AllBootstrapMethodInfoVisitor(BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor)
+ {
+ this.bootstrapMethodInfoVisitor = bootstrapMethodInfoVisitor;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, bootstrapMethodInfoVisitor);
+ }
+}
diff --git a/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java
index 839e104..e502123 100644
--- a/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java
new file mode 100644
index 0000000..3e1f0a7
--- /dev/null
+++ b/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java
@@ -0,0 +1,55 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.attribute.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This AttributeVisitor lets a given InnerClassesInfoVisitor visit all
+ * InnerClassessInfo objects of the InnerClassesAttribute objects it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class AllInnerClassesInfoVisitor
+extends SimplifiedVisitor
+implements AttributeVisitor
+{
+ private final InnerClassesInfoVisitor innerClassesInfoVisitor;
+
+
+ public AllInnerClassesInfoVisitor(InnerClassesInfoVisitor innerClassesInfoVisitor)
+ {
+ this.innerClassesInfoVisitor = innerClassesInfoVisitor;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
+ {
+ innerClassesAttribute.innerClassEntriesAccept(clazz, innerClassesInfoVisitor);
+ }
+} \ No newline at end of file
diff --git a/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java b/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java
index aa81ce0..9906483 100644
--- a/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java
+++ b/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -24,7 +24,7 @@ import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.preverification.*;
-import proguard.util.StringMatcher;
+import proguard.util.*;
/**
* This AttributeVisitor delegates its visits another AttributeVisitor, but
@@ -41,7 +41,21 @@ implements AttributeVisitor
/**
- * Creates a new AttributeNameFilter.
+ * Creates a new AttributeNameFilter based on a given name.
+ * @param name the string matcher that will check the attribute
+ * names.
+ * @param attributeVisitor the <code>AttributeVisitor</code> to which
+ * visits will be delegated.
+ */
+ public AttributeNameFilter(String name,
+ AttributeVisitor attributeVisitor)
+ {
+ this(new FixedStringMatcher(name), attributeVisitor);
+ }
+
+
+ /**
+ * Creates a new AttributeNameFilter based on a given string matcher.
* @param stringMatcher the string matcher that will check the attribute
* names.
* @param attributeVisitor the <code>AttributeVisitor</code> to which
@@ -66,6 +80,15 @@ implements AttributeVisitor
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (accepted(clazz, bootstrapMethodsAttribute))
+ {
+ bootstrapMethodsAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
if (accepted(clazz, sourceFileAttribute))
diff --git a/src/proguard/classfile/attribute/visitor/AttributeVisitor.java b/src/proguard/classfile/attribute/visitor/AttributeVisitor.java
index e8f226b..bb7ee34 100644
--- a/src/proguard/classfile/attribute/visitor/AttributeVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/AttributeVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -35,11 +35,12 @@ public interface AttributeVisitor
{
// Attributes that are attached to classes.
- public void visitUnknownAttribute( Clazz clazz, UnknownAttribute unknownAttribute);
- public void visitSourceFileAttribute( Clazz clazz, SourceFileAttribute sourceFileAttribute);
- public void visitSourceDirAttribute( Clazz clazz, SourceDirAttribute sourceDirAttribute);
- public void visitInnerClassesAttribute( Clazz clazz, InnerClassesAttribute innerClassesAttribute);
- public void visitEnclosingMethodAttribute( Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute);
+ public void visitUnknownAttribute( Clazz clazz, UnknownAttribute unknownAttribute);
+ public void visitBootstrapMethodsAttribute( Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute);
+ public void visitSourceFileAttribute( Clazz clazz, SourceFileAttribute sourceFileAttribute);
+ public void visitSourceDirAttribute( Clazz clazz, SourceDirAttribute sourceDirAttribute);
+ public void visitInnerClassesAttribute( Clazz clazz, InnerClassesAttribute innerClassesAttribute);
+ public void visitEnclosingMethodAttribute( Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute);
// Attributes that are attached to classes, fields, and methods.
diff --git a/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java b/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
new file mode 100755
index 0000000..4828d7f
--- /dev/null
+++ b/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
@@ -0,0 +1,40 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.attribute.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+
+import java.beans.MethodDescriptor;
+
+
+/**
+ * This interface specifies the methods for a visitor of
+ * <code>BootstrapMethodInfo</code> objects. Note that there is only a single
+ * implementation of <code>BootstrapMethodInfo</code>, such that this interface
+ * is not strictly necessary as a visitor.
+ *
+ * @author Eric Lafortune
+ */
+public interface BootstrapMethodInfoVisitor
+{
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo);
+}
diff --git a/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java b/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java
index 7c85e53..a96d4bf 100644
--- a/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java b/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java
index 91267b0..8f033bf 100644
--- a/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java
index e59ed7b..32efa63 100644
--- a/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java
index 8647cb3..d00e184 100644
--- a/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java
index 9ad38e0..7018fea 100644
--- a/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java b/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java
index 870ba94..4156654 100644
--- a/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -85,6 +85,15 @@ public class MultiAttributeVisitor implements AttributeVisitor
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ for (int index = 0; index < attributeVisitors.length; index++)
+ {
+ attributeVisitors[index].visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute);
+ }
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
diff --git a/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java b/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java
new file mode 100644
index 0000000..1b0460f
--- /dev/null
+++ b/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java
@@ -0,0 +1,293 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.attribute.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.preverification.*;
+import proguard.util.StringMatcher;
+
+/**
+ * This AttributeVisitor delegates its visits another AttributeVisitor, but
+ * only when the visited attribute is not empty. For instance, a local variable
+ * table without variables is empty.
+ *
+ * @author Eric Lafortune
+ */
+public class NonEmptyAttributeFilter
+implements AttributeVisitor
+{
+ private final AttributeVisitor attributeVisitor;
+
+
+ /**
+ * Creates a new NonEmptyAttributeFilter.
+ * @param attributeVisitor the <code>AttributeVisitor</code> to which
+ * visits will be delegated.
+ */
+ public NonEmptyAttributeFilter(AttributeVisitor attributeVisitor)
+ {
+ this.attributeVisitor = attributeVisitor;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
+ {
+ unknownAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (bootstrapMethodsAttribute.u2bootstrapMethodsCount > 0)
+ {
+ bootstrapMethodsAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
+ public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
+ {
+ sourceFileAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
+ {
+ sourceDirAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
+ {
+ if (innerClassesAttribute.u2classesCount > 0)
+ {
+ innerClassesAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
+ public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
+ {
+ enclosingMethodAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
+ {
+ deprecatedAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
+ {
+ deprecatedAttribute.accept(clazz, field, attributeVisitor);
+ }
+
+
+ public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
+ {
+ deprecatedAttribute.accept(clazz, method, attributeVisitor);
+ }
+
+
+ public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
+ {
+ syntheticAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
+ {
+ syntheticAttribute.accept(clazz, field, attributeVisitor);
+ }
+
+
+ public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
+ {
+ syntheticAttribute.accept(clazz, method, attributeVisitor);
+ }
+
+
+ public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
+ {
+ signatureAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute)
+ {
+ signatureAttribute.accept(clazz, field, attributeVisitor);
+ }
+
+
+ public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute)
+ {
+ signatureAttribute.accept(clazz, method, attributeVisitor);
+ }
+
+
+ public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
+ {
+ constantValueAttribute.accept(clazz, field, attributeVisitor);
+ }
+
+
+ public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
+ {
+ if (exceptionsAttribute.u2exceptionIndexTableLength > 0)
+ {
+ exceptionsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ codeAttribute.accept(clazz, method, attributeVisitor);
+ }
+
+
+ public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
+ {
+ if (stackMapAttribute.u2stackMapFramesCount > 0)
+ {
+ stackMapAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
+ {
+ if (stackMapTableAttribute.u2stackMapFramesCount > 0)
+ {
+ stackMapTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
+ {
+ if (lineNumberTableAttribute.u2lineNumberTableLength > 0)
+ {
+ lineNumberTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ if (localVariableTableAttribute.u2localVariableTableLength > 0)
+ {
+ localVariableTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ if (localVariableTypeTableAttribute.u2localVariableTypeTableLength > 0)
+ {
+ localVariableTypeTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
+ {
+ if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeVisibleAnnotationsAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
+ {
+ if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeVisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
+ {
+ if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeVisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
+ {
+ if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeInvisibleAnnotationsAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
+ {
+ if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeInvisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
+ {
+ if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeInvisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
+ {
+ if (runtimeVisibleParameterAnnotationsAttribute.u2parametersCount > 0)
+ {
+ runtimeVisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
+ {
+ if (runtimeInvisibleParameterAnnotationsAttribute.u2parametersCount > 0)
+ {
+ runtimeInvisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
+ {
+ annotationDefaultAttribute.accept(clazz, method, attributeVisitor);
+ }
+}
diff --git a/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java b/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java
index 92099f9..e392ee7 100644
--- a/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java
+++ b/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -80,6 +80,15 @@ implements AttributeVisitor
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (requiredAttributeVisitor != null)
+ {
+ bootstrapMethodsAttribute.accept(clazz, requiredAttributeVisitor);
+ }
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
if (optionalAttributeVisitor != null)
diff --git a/src/proguard/classfile/attribute/visitor/StackSizeComputer.java b/src/proguard/classfile/attribute/visitor/StackSizeComputer.java
index 401f188..c4711d1 100644
--- a/src/proguard/classfile/attribute/visitor/StackSizeComputer.java
+++ b/src/proguard/classfile/attribute/visitor/StackSizeComputer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -27,6 +27,8 @@ import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor computes the stack sizes at all instruction offsets
* of the code attributes that it visits.
@@ -140,10 +142,7 @@ implements AttributeVisitor,
}
else
{
- for (int index = 0; index < codeLength; index++)
- {
- evaluated[index] = false;
- }
+ Arrays.fill(evaluated, 0, codeLength, false);
}
// The initial stack is always empty.
diff --git a/src/proguard/classfile/constant/ClassConstant.java b/src/proguard/classfile/constant/ClassConstant.java
index d217bf6..b9089d2 100644
--- a/src/proguard/classfile/constant/ClassConstant.java
+++ b/src/proguard/classfile/constant/ClassConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/Constant.java b/src/proguard/classfile/constant/Constant.java
index 30ce5df..ec25a67 100644
--- a/src/proguard/classfile/constant/Constant.java
+++ b/src/proguard/classfile/constant/Constant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/DoubleConstant.java b/src/proguard/classfile/constant/DoubleConstant.java
index 61779b5..08827c2 100644
--- a/src/proguard/classfile/constant/DoubleConstant.java
+++ b/src/proguard/classfile/constant/DoubleConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/FieldrefConstant.java b/src/proguard/classfile/constant/FieldrefConstant.java
index d4afce5..ddd6fb1 100644
--- a/src/proguard/classfile/constant/FieldrefConstant.java
+++ b/src/proguard/classfile/constant/FieldrefConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/FloatConstant.java b/src/proguard/classfile/constant/FloatConstant.java
index 578f567..e98aec2 100644
--- a/src/proguard/classfile/constant/FloatConstant.java
+++ b/src/proguard/classfile/constant/FloatConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/IntegerConstant.java b/src/proguard/classfile/constant/IntegerConstant.java
index 8a476c6..bd6afa0 100644
--- a/src/proguard/classfile/constant/IntegerConstant.java
+++ b/src/proguard/classfile/constant/IntegerConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/InterfaceMethodrefConstant.java b/src/proguard/classfile/constant/InterfaceMethodrefConstant.java
index ddee42f..80fe817 100644
--- a/src/proguard/classfile/constant/InterfaceMethodrefConstant.java
+++ b/src/proguard/classfile/constant/InterfaceMethodrefConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/InvokeDynamicConstant.java b/src/proguard/classfile/constant/InvokeDynamicConstant.java
new file mode 100755
index 0000000..bbff88d
--- /dev/null
+++ b/src/proguard/classfile/constant/InvokeDynamicConstant.java
@@ -0,0 +1,148 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.constant;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.visitor.*;
+import proguard.classfile.visitor.*;
+
+/**
+ * This Constant represents an invoke dynamic constant in the constant pool.
+ *
+ * @author Eric Lafortune
+ */
+public class InvokeDynamicConstant extends Constant
+{
+ public int u2bootstrapMethodAttributeIndex;
+ public int u2nameAndTypeIndex;
+
+ /**
+ * An extra field pointing to the Clazz objects referenced in the
+ * descriptor string. This field is filled out by the <code>{@link
+ * proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}</code>.
+ * References to primitive types are ignored.
+ */
+ public Clazz[] referencedClasses;
+
+
+ /**
+ * Creates an uninitialized InvokeDynamicConstant.
+ */
+ public InvokeDynamicConstant()
+ {
+ }
+
+
+ /**
+ * Creates a new InvokeDynamicConstant with the given bootstrap method
+ * and name-and-type indices.
+ * @param u2bootstrapMethodAttributeIndex the index of the bootstrap method
+ * entry in the bootstrap methods
+ * attribute.
+ * @param u2nameAndTypeIndex the index of the name and type
+ * entry in the constant pool.
+ * @param referencedClasses the classes referenced by the
+ * type.
+ */
+ public InvokeDynamicConstant(int u2bootstrapMethodAttributeIndex,
+ int u2nameAndTypeIndex,
+ Clazz[] referencedClasses)
+ {
+ this.u2bootstrapMethodAttributeIndex = u2bootstrapMethodAttributeIndex;
+ this.u2nameAndTypeIndex = u2nameAndTypeIndex;
+ this.referencedClasses = referencedClasses;
+ }
+
+
+ /**
+ * Returns the index of the bootstrap method in the bootstrap methods
+ * attribute of the class.
+ */
+ public int getBootstrapMethodAttributeIndex()
+ {
+ return u2bootstrapMethodAttributeIndex;
+ }
+
+ /**
+ * Returns the name-and-type index.
+ */
+ public int getNameAndTypeIndex()
+ {
+ return u2nameAndTypeIndex;
+ }
+
+ /**
+ * Returns the method name.
+ */
+ public String getName(Clazz clazz)
+ {
+ return clazz.getName(u2nameAndTypeIndex);
+ }
+
+ /**
+ * Returns the method type.
+ */
+ public String getType(Clazz clazz)
+ {
+ return clazz.getType(u2nameAndTypeIndex);
+ }
+
+
+ /**
+ * Lets the Clazz objects referenced in the descriptor string
+ * accept the given visitor.
+ */
+ public void referencedClassesAccept(ClassVisitor classVisitor)
+ {
+ if (referencedClasses != null)
+ {
+ for (int index = 0; index < referencedClasses.length; index++)
+ {
+ if (referencedClasses[index] != null)
+ {
+ referencedClasses[index].accept(classVisitor);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Lets the bootstrap method handle constant accept the given visitor.
+ */
+ public void bootstrapMethodHandleAccept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ new BootstrapMethodHandleTraveler(constantVisitor).visitInvokeDynamicConstant(clazz, this);
+ }
+
+
+ // Implementations for Constant.
+
+ public int getTag()
+ {
+ return ClassConstants.CONSTANT_InvokeDynamic;
+ }
+
+ public void accept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ constantVisitor.visitInvokeDynamicConstant(clazz, this);
+ }
+}
diff --git a/src/proguard/classfile/constant/LongConstant.java b/src/proguard/classfile/constant/LongConstant.java
index ea66e07..2d55e6a 100644
--- a/src/proguard/classfile/constant/LongConstant.java
+++ b/src/proguard/classfile/constant/LongConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/MethodHandleConstant.java b/src/proguard/classfile/constant/MethodHandleConstant.java
new file mode 100755
index 0000000..c2e068e
--- /dev/null
+++ b/src/proguard/classfile/constant/MethodHandleConstant.java
@@ -0,0 +1,124 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.constant;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+
+/**
+ * This Constant represents a method handle constant in the constant pool.
+ *
+ * @author Eric Lafortune
+ */
+public class MethodHandleConstant extends Constant
+{
+ public int u1referenceKind;
+ public int u2referenceIndex;
+
+
+ /**
+ * An extra field pointing to the java.lang.invoke.MethodHandle Clazz object.
+ * This field is typically filled out by the <code>{@link
+ * proguard.classfile.util.ClassReferenceInitializer
+ * ClassReferenceInitializer}</code>..
+ */
+ public Clazz javaLangInvokeMethodHandleClass;
+
+
+ /**
+ * Creates an uninitialized MethodHandleConstant.
+ */
+ public MethodHandleConstant()
+ {
+ }
+
+
+ /**
+ * Creates a new MethodHandleConstant with the given type and method ref
+ * index.
+ * @param u1referenceKind the reference kind.
+ * @param u2referenceIndex the index of the field ref constant, interface
+ * method ref constant, or method ref constant in
+ * the constant pool.
+ */
+ public MethodHandleConstant(int u1referenceKind, int u2referenceIndex)
+ {
+ this.u1referenceKind = u1referenceKind;
+ this.u2referenceIndex = u2referenceIndex;
+ }
+
+
+ /**
+ * Returns the kind of reference to which this constant is pointing.
+ * @return One of
+ * {@link ClassConstants#REF_getField },
+ * {@link ClassConstants#REF_getStatic },
+ * {@link ClassConstants#REF_putField },
+ * {@link ClassConstants#REF_putStatic },
+ * {@link ClassConstants#REF_invokeVirtual },
+ * {@link ClassConstants#REF_invokeStatic },
+ * {@link ClassConstants#REF_invokeSpecial },
+ * {@link ClassConstants#REF_newInvokeSpecial}, or
+ * {@link ClassConstants#REF_invokeInterface }.
+ */
+ public int getReferenceKind()
+ {
+ return u1referenceKind;
+ }
+
+ /**
+ * Returns the field ref, interface method ref, or method ref index.
+ */
+ public int getReferenceIndex()
+ {
+ return u2referenceIndex;
+ }
+
+
+ /**
+ * Returns the method/field name.
+ */
+ public String getName(Clazz clazz)
+ {
+ return clazz.getRefName(u2referenceIndex);
+ }
+
+ /**
+ * Returns the type.
+ */
+ public String getType(Clazz clazz)
+ {
+ return clazz.getRefType(u2referenceIndex);
+ }
+
+
+ // Implementations for Constant.
+
+ public int getTag()
+ {
+ return ClassConstants.CONSTANT_MethodHandle;
+ }
+
+ public void accept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ constantVisitor.visitMethodHandleConstant(clazz, this);
+ }
+}
diff --git a/src/proguard/classfile/constant/MethodTypeConstant.java b/src/proguard/classfile/constant/MethodTypeConstant.java
new file mode 100644
index 0000000..29f79d7
--- /dev/null
+++ b/src/proguard/classfile/constant/MethodTypeConstant.java
@@ -0,0 +1,93 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.constant;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+
+/**
+ * This Constant represents a method handle constant in the constant pool.
+ *
+ * @author Eric Lafortune
+ */
+public class MethodTypeConstant extends Constant
+{
+ public int u2descriptorIndex;
+
+
+ /**
+ * An extra field pointing to the java.lang.invoke.MethodType Clazz object.
+ * This field is typically filled out by the <code>{@link
+ * proguard.classfile.util.ClassReferenceInitializer
+ * ClassReferenceInitializer}</code>..
+ */
+ public Clazz javaLangInvokeMethodTypeClass;
+
+
+ /**
+ * Creates an uninitialized MethodTypeConstant.
+ */
+ public MethodTypeConstant()
+ {
+ }
+
+
+ /**
+ * Creates a new MethodTypeConstant with the given descriptor index.
+ * @param u2descriptorIndex the index of the descriptor in the constant
+ * pool.
+ */
+ public MethodTypeConstant(int u2descriptorIndex)
+ {
+ this.u2descriptorIndex = u2descriptorIndex;
+ }
+
+
+ /**
+ * Returns the descriptor index.
+ */
+ public int getDescriptorIndex()
+ {
+ return u2descriptorIndex;
+ }
+
+
+ /**
+ * Returns the type.
+ */
+ public String getType(Clazz clazz)
+ {
+ return clazz.getString(u2descriptorIndex);
+ }
+
+
+ // Implementations for Constant.
+
+ public int getTag()
+ {
+ return ClassConstants.CONSTANT_MethodType;
+ }
+
+ public void accept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ constantVisitor.visitMethodTypeConstant(clazz, this);
+ }
+}
diff --git a/src/proguard/classfile/constant/MethodrefConstant.java b/src/proguard/classfile/constant/MethodrefConstant.java
index 858eec9..a69c04e 100644
--- a/src/proguard/classfile/constant/MethodrefConstant.java
+++ b/src/proguard/classfile/constant/MethodrefConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/NameAndTypeConstant.java b/src/proguard/classfile/constant/NameAndTypeConstant.java
index e83d2f1..f8f814a 100644
--- a/src/proguard/classfile/constant/NameAndTypeConstant.java
+++ b/src/proguard/classfile/constant/NameAndTypeConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/RefConstant.java b/src/proguard/classfile/constant/RefConstant.java
index 4e4d019..c0531f6 100644
--- a/src/proguard/classfile/constant/RefConstant.java
+++ b/src/proguard/classfile/constant/RefConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/StringConstant.java b/src/proguard/classfile/constant/StringConstant.java
index 9a8d453..923c6dd 100644
--- a/src/proguard/classfile/constant/StringConstant.java
+++ b/src/proguard/classfile/constant/StringConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/Utf8Constant.java b/src/proguard/classfile/constant/Utf8Constant.java
index ae419c9..27ef218 100644
--- a/src/proguard/classfile/constant/Utf8Constant.java
+++ b/src/proguard/classfile/constant/Utf8Constant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/visitor/AllConstantVisitor.java b/src/proguard/classfile/constant/visitor/AllConstantVisitor.java
index d2d3c2c..2b89657 100644
--- a/src/proguard/classfile/constant/visitor/AllConstantVisitor.java
+++ b/src/proguard/classfile/constant/visitor/AllConstantVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java b/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java
new file mode 100644
index 0000000..6b02b73
--- /dev/null
+++ b/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java
@@ -0,0 +1,100 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.constant.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+import proguard.optimize.info.MethodOptimizationInfo;
+
+/**
+ * This ConstantVisitor and BootstrapMethodInfoVisitor travels from any invoke
+ * dynamic constants or bootstrap method info entries that it visits to their
+ * bootstrap method handle constants, and applies a given constant visitor.
+ *
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodHandleTraveler
+extends SimplifiedVisitor
+implements ConstantVisitor,
+ AttributeVisitor,
+ BootstrapMethodInfoVisitor
+{
+ private ConstantVisitor bootstrapMethodHandleVisitor;
+
+ // Field serving as a method argument.
+ int bootstrapMethodAttributeIndex;
+
+
+ /**
+ * Creates a new BootstrapMethodHandleVisitor that will delegate to the
+ * given constant visitor.
+ */
+ public BootstrapMethodHandleTraveler(ConstantVisitor bootstrapMethodHandleVisitor)
+ {
+ this.bootstrapMethodHandleVisitor = bootstrapMethodHandleVisitor;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Pass the method index.
+ bootstrapMethodAttributeIndex =
+ invokeDynamicConstant.u2bootstrapMethodAttributeIndex;
+
+ // Delegate to the bootstrap method.
+ clazz.attributesAccept(this);
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Check bootstrap methods.
+ bootstrapMethodsAttribute.bootstrapMethodEntryAccept(clazz,
+ bootstrapMethodAttributeIndex,
+ this);
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ // Check bootstrap method.
+ clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex,
+ bootstrapMethodHandleVisitor);
+ }
+}
diff --git a/src/proguard/classfile/constant/visitor/ConstantTagFilter.java b/src/proguard/classfile/constant/visitor/ConstantTagFilter.java
new file mode 100644
index 0000000..bfa7149
--- /dev/null
+++ b/src/proguard/classfile/constant/visitor/ConstantTagFilter.java
@@ -0,0 +1,86 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.constant.visitor;
+
+import proguard.classfile.Clazz;
+import proguard.classfile.constant.*;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This <code>ConstantVisitor</code> delegates its visits to one or more
+ * specified types of constants.
+ *
+ * @author Eric Lafortune
+ */
+public class ConstantTagFilter
+extends SimplifiedVisitor
+implements ConstantVisitor
+{
+ private final int constantTagMask;
+ private final ConstantVisitor constantVisitor;
+
+
+ /**
+ * Creates a new ConstantTagFilter.
+ * @param constantTag the type of constants for which visits will be
+ * delegated.
+ * @param constantVisitor the <code>ConstantVisitor</code> to which visits
+ * will be delegated.
+ */
+ public ConstantTagFilter(int constantTag,
+ ConstantVisitor constantVisitor)
+ {
+ this.constantTagMask = 1 << constantTag;
+ this.constantVisitor = constantVisitor;
+ }
+
+
+ /**
+ * Creates a new ConstantTagFilter.
+ * @param constantTags the types of constants for which visits will be
+ * delegated.
+ * @param constantVisitor the <code>ConstantVisitor</code> to which visits
+ * will be delegated.
+ */
+ public ConstantTagFilter(int[] constantTags,
+ ConstantVisitor constantVisitor)
+ {
+ int constantTagMask = 0;
+ for (int index = 0; index < constantTags.length; index++)
+ {
+ constantTagMask |= 1 << constantTags[index];
+ }
+
+ this.constantTagMask = constantTagMask;
+ this.constantVisitor = constantVisitor;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant)
+ {
+ if (((1 << constant.getTag()) & constantTagMask) != 0)
+ {
+ constant.accept(clazz, constantVisitor);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/proguard/classfile/constant/visitor/ConstantVisitor.java b/src/proguard/classfile/constant/visitor/ConstantVisitor.java
index 6cae352..2cec804 100644
--- a/src/proguard/classfile/constant/visitor/ConstantVisitor.java
+++ b/src/proguard/classfile/constant/visitor/ConstantVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -38,9 +38,12 @@ public interface ConstantVisitor
public void visitDoubleConstant( Clazz clazz, DoubleConstant doubleConstant);
public void visitStringConstant( Clazz clazz, StringConstant stringConstant);
public void visitUtf8Constant( Clazz clazz, Utf8Constant utf8Constant);
+ public void visitInvokeDynamicConstant( Clazz clazz, InvokeDynamicConstant invokeDynamicConstant);
+ public void visitMethodHandleConstant( Clazz clazz, MethodHandleConstant methodHandleConstant);
public void visitFieldrefConstant( Clazz clazz, FieldrefConstant fieldrefConstant);
public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant);
public void visitMethodrefConstant( Clazz clazz, MethodrefConstant methodrefConstant);
public void visitClassConstant( Clazz clazz, ClassConstant classConstant);
+ public void visitMethodTypeConstant( Clazz clazz, MethodTypeConstant methodTypeConstant);
public void visitNameAndTypeConstant( Clazz clazz, NameAndTypeConstant nameAndTypeConstant);
}
diff --git a/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java b/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java
index fbb3e52..0477631 100644
--- a/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java
+++ b/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -44,16 +44,16 @@ implements ConstantVisitor
/**
- * Creates a new ClassNameFilter.
+ * Creates a new ExceptClassConstantFilter.
* @param exceptClassName the name of the class that will not be visited.
* @param constantVisitor the <code>ConstantVisitor</code> to which visits
* will be delegated.
*/
- public ExceptClassConstantFilter(String exceptClassName,
- ConstantVisitor constantVisitor)
+ public ExceptClassConstantFilter(String exceptClassName,
+ ConstantVisitor constantVisitor)
{
- this.exceptClassName = exceptClassName;
- this.constantVisitor = constantVisitor;
+ this.exceptClassName = exceptClassName;
+ this.constantVisitor = constantVisitor;
}
diff --git a/src/proguard/classfile/visitor/ClassForNameClassVisitor.java b/src/proguard/classfile/constant/visitor/MethodrefTraveler.java
index ee028f8..49c0917 100644
--- a/src/proguard/classfile/visitor/ClassForNameClassVisitor.java
+++ b/src/proguard/classfile/constant/visitor/MethodrefTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -18,38 +18,32 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-package proguard.classfile.visitor;
+package proguard.classfile.constant.visitor;
import proguard.classfile.Clazz;
+import proguard.classfile.attribute.*;
import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
-
/**
- * This ConstantVisitor lets a given <code>ClassVisitor</code> visit all
- * constant classes involved in any <code>Class.forName</code> constructs that
- * it visits.
- *
- * @see DotClassClassVisitor
+ * This ConstantVisitor travels from any method handle constants that it visits
+ * to their methodref constants, and applies a given constant visitor.
*
* @author Eric Lafortune
*/
-public class ClassForNameClassVisitor
+public class MethodrefTraveler
extends SimplifiedVisitor
implements ConstantVisitor
{
- private final ClassVisitor classVisitor;
+ private ConstantVisitor methodrefConstantVisitor;
/**
- * Creates a new ClassHierarchyTraveler.
- * @param classVisitor the <code>ClassVisitor</code> to which visits will
- * be delegated.
+ * Creates a new v that will delegate to the given constant visitor.
*/
- public ClassForNameClassVisitor(ClassVisitor classVisitor)
+ public MethodrefTraveler(ConstantVisitor methodrefConstantVisitor)
{
- this.classVisitor = classVisitor;
+ this.methodrefConstantVisitor = methodrefConstantVisitor;
}
@@ -58,9 +52,9 @@ implements ConstantVisitor
public void visitAnyConstant(Clazz clazz, Constant constant) {}
- public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
{
- // Visit the referenced class from the Class.forName construct, if any.
- stringConstant.referencedClassAccept(classVisitor);
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex,
+ methodrefConstantVisitor);
}
}
diff --git a/src/proguard/classfile/editor/AccessFixer.java b/src/proguard/classfile/editor/AccessFixer.java
index 7d6274e..8ff08f3 100644
--- a/src/proguard/classfile/editor/AccessFixer.java
+++ b/src/proguard/classfile/editor/AccessFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,6 +21,8 @@
package proguard.classfile.editor;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.*;
@@ -61,12 +63,26 @@ implements ConstantVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Check the bootstrap method.
+ invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Check the method reference.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
referencingClass = clazz;
// Remember the specified class, since it might be different from
- // the referenced class that acutally contains the class member.
+ // the referenced class that actually contains the class member.
clazz.constantPoolEntryAccept(refConstant.u2classIndex, referencedClassFinder);
// Make sure the access flags of the referenced class member are
@@ -91,8 +107,8 @@ implements ConstantVisitor,
public void visitProgramClass(ProgramClass programClass)
{
- int currentAccessFlags = programClass.getAccessFlags();
- int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+ int currentAccessFlags = programClass.getAccessFlags();
+ int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
// Compute the required access level.
Clazz referencingClass = this.referencingClass;
@@ -117,8 +133,8 @@ implements ConstantVisitor,
public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
- int currentAccessFlags = programMember.getAccessFlags();
- int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+ int currentAccessFlags = programMember.getAccessFlags();
+ int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
// Compute the required access level.
int requiredAccessLevel =
diff --git a/src/proguard/classfile/editor/AnnotationAdder.java b/src/proguard/classfile/editor/AnnotationAdder.java
index 359164a..3c35608 100644
--- a/src/proguard/classfile/editor/AnnotationAdder.java
+++ b/src/proguard/classfile/editor/AnnotationAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/AnnotationsAttributeEditor.java b/src/proguard/classfile/editor/AnnotationsAttributeEditor.java
index bf8852c..5537f5e 100644
--- a/src/proguard/classfile/editor/AnnotationsAttributeEditor.java
+++ b/src/proguard/classfile/editor/AnnotationsAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/AttributeAdder.java b/src/proguard/classfile/editor/AttributeAdder.java
index 2b610b7..a7f8dc3 100644
--- a/src/proguard/classfile/editor/AttributeAdder.java
+++ b/src/proguard/classfile/editor/AttributeAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -256,7 +256,7 @@ implements AttributeVisitor
CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer();
- codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);
+ codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength + 32);
// Add the instructions.
codeAttribute.instructionsAccept(clazz,
diff --git a/src/proguard/classfile/editor/AttributeSorter.java b/src/proguard/classfile/editor/AttributeSorter.java
index d8e3367..dcae85e 100644
--- a/src/proguard/classfile/editor/AttributeSorter.java
+++ b/src/proguard/classfile/editor/AttributeSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/AttributesEditor.java b/src/proguard/classfile/editor/AttributesEditor.java
index 10846cc..91c0080 100644
--- a/src/proguard/classfile/editor/AttributesEditor.java
+++ b/src/proguard/classfile/editor/AttributesEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/BridgeMethodFixer.java b/src/proguard/classfile/editor/BridgeMethodFixer.java
new file mode 100644
index 0000000..010c8a2
--- /dev/null
+++ b/src/proguard/classfile/editor/BridgeMethodFixer.java
@@ -0,0 +1,117 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.editor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+
+/**
+ * This MemberVisitor fixes all inappropriate bridge access flags of the
+ * program methods that it visits, checking whether the methods to which they
+ * bridge have the same name. Some compilers, like in Eclipse and in later
+ * versions of JDK 1.6, complain if they can't find the method with the same
+ * name.
+ *
+ * @author Eric Lafortune
+ */
+public class BridgeMethodFixer
+extends SimplifiedVisitor
+implements MemberVisitor,
+ AttributeVisitor,
+ InstructionVisitor,
+ ConstantVisitor
+{
+ private static final boolean DEBUG = false;
+
+
+ // Return values for the visitor methods.
+ private String bridgedMethodName;
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if ((programMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_BRIDGE) != 0)
+ {
+ programMethod.attributesAccept(programClass, this);
+ }
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ // Go over the instructions of the bridge method.
+ codeAttribute.instructionsAccept(clazz, method, this);
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
+ {
+ switch (constantInstruction.opcode)
+ {
+ case InstructionConstants.OP_INVOKEVIRTUAL:
+ case InstructionConstants.OP_INVOKESPECIAL:
+ case InstructionConstants.OP_INVOKESTATIC:
+ case InstructionConstants.OP_INVOKEINTERFACE:
+ // Get the name of the bridged method.
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+
+ // Check if the name is different.
+ if (!method.getName(clazz).equals(bridgedMethodName))
+ {
+ if (DEBUG)
+ {
+ System.out.println("BridgeMethodFixer: ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"] does not bridge to ["+bridgedMethodName+"]");
+ }
+
+ // Clear the bridge flag.
+ ((ProgramMethod)method).u2accessFlags &= ~ClassConstants.INTERNAL_ACC_BRIDGE;
+ }
+ break;
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ bridgedMethodName = refConstant.getName(clazz);
+ }
+} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/ClassEditor.java b/src/proguard/classfile/editor/ClassEditor.java
index e503ea3..f51ae45 100644
--- a/src/proguard/classfile/editor/ClassEditor.java
+++ b/src/proguard/classfile/editor/ClassEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ClassElementSorter.java b/src/proguard/classfile/editor/ClassElementSorter.java
index 3256c88..c5eb366 100644
--- a/src/proguard/classfile/editor/ClassElementSorter.java
+++ b/src/proguard/classfile/editor/ClassElementSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ClassMemberSorter.java b/src/proguard/classfile/editor/ClassMemberSorter.java
index f31fcd0..61d69b2 100644
--- a/src/proguard/classfile/editor/ClassMemberSorter.java
+++ b/src/proguard/classfile/editor/ClassMemberSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ClassReferenceFixer.java b/src/proguard/classfile/editor/ClassReferenceFixer.java
index 9857903..808d339 100644
--- a/src/proguard/classfile/editor/ClassReferenceFixer.java
+++ b/src/proguard/classfile/editor/ClassReferenceFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/CodeAttributeComposer.java b/src/proguard/classfile/editor/CodeAttributeComposer.java
index e783203..a645f57 100644
--- a/src/proguard/classfile/editor/CodeAttributeComposer.java
+++ b/src/proguard/classfile/editor/CodeAttributeComposer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -29,6 +29,8 @@ import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor accumulates instructions and exceptions, and then
* copies them into code attributes that it visits.
@@ -49,7 +51,7 @@ implements AttributeVisitor,
//*
private static final boolean DEBUG = false;
/*/
- public static boolean DEBUG = true;
+ public static boolean DEBUG = false;
//*/
@@ -313,7 +315,7 @@ implements AttributeVisitor,
int handlerPC = -exceptionInfo.u2handlerPC;
if (handlerPC > 0)
{
- if (remappableInstructionOffset(handlerPC))
+ if (remappableExceptionHandler(handlerPC))
{
exceptionInfo.u2handlerPC = remapInstructionOffset(handlerPC);
}
@@ -490,7 +492,7 @@ implements AttributeVisitor,
int handlerPC = exceptionInfo.u2handlerPC;
exceptionInfo.u2handlerPC =
!allowExternalExceptionHandlers ||
- remappableInstructionOffset(handlerPC) ?
+ remappableExceptionHandler(handlerPC) ?
remapInstructionOffset(handlerPC) :
-handlerPC;
}
@@ -674,13 +676,21 @@ implements AttributeVisitor,
/**
- * Returns whether the given old instruction offset can be remapped at the
+ * Returns whether the given old exception handler can be remapped in the
+ * current code fragment.
*/
- private boolean remappableInstructionOffset(int oldInstructionOffset)
+ private boolean remappableExceptionHandler(int oldInstructionOffset)
{
- return
- oldInstructionOffset <= codeFragmentLengths[level] &&
- instructionOffsetMap[level][oldInstructionOffset] > INVALID;
+ if (oldInstructionOffset > codeFragmentLengths[level])
+ {
+ return false;
+ }
+
+ int newInstructionOffset =
+ instructionOffsetMap[level][oldInstructionOffset];
+
+ return newInstructionOffset > INVALID &&
+ newInstructionOffset < codeLength;
}
@@ -703,10 +713,7 @@ implements AttributeVisitor,
}
// Clear the unused array entries.
- for (int index = newIndex; index < exceptionInfoCount; index++)
- {
- exceptionInfos[index] = null;
- }
+ Arrays.fill(exceptionInfos, newIndex, exceptionInfoCount, null);
return newIndex;
}
@@ -734,10 +741,7 @@ implements AttributeVisitor,
}
// Clear the unused array entries.
- for (int index = newIndex; index < lineNumberInfoCount; index++)
- {
- lineNumberInfos[index] = null;
- }
+ Arrays.fill(lineNumberInfos, newIndex, lineNumberInfoCount, null);
return newIndex;
}
@@ -764,10 +768,7 @@ implements AttributeVisitor,
}
// Clear the unused array entries.
- for (int index = newIndex; index < localVariableInfoCount; index++)
- {
- localVariableInfos[index] = null;
- }
+ Arrays.fill(localVariableInfos, newIndex, localVariableInfoCount, null);
return newIndex;
}
@@ -794,10 +795,7 @@ implements AttributeVisitor,
}
// Clear the unused array entries.
- for (int index = newIndex; index < localVariableTypeInfoCount; index++)
- {
- localVariableTypeInfos[index] = null;
- }
+ Arrays.fill(localVariableTypeInfos, newIndex, localVariableTypeInfoCount, null);
return newIndex;
}
diff --git a/src/proguard/classfile/editor/CodeAttributeEditor.java b/src/proguard/classfile/editor/CodeAttributeEditor.java
index 9658c98..82ed29e 100644
--- a/src/proguard/classfile/editor/CodeAttributeEditor.java
+++ b/src/proguard/classfile/editor/CodeAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -28,7 +28,8 @@ import proguard.classfile.attribute.visitor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
-import proguard.classfile.visitor.ClassPrinter;
+
+import java.util.Arrays;
/**
* This AttributeVisitor accumulates specified changes to code, and then applies
@@ -105,13 +106,10 @@ implements AttributeVisitor,
}
else
{
- for (int index = 0; index < codeLength; index++)
- {
- preInsertions[index] = null;
- replacements[index] = null;
- postInsertions[index] = null;
- deleted[index] = false;
- }
+ Arrays.fill(preInsertions, 0, codeLength, null);
+ Arrays.fill(replacements, 0, codeLength, null);
+ Arrays.fill(postInsertions, 0, codeLength, null);
+ Arrays.fill(deleted, 0, codeLength, false);
}
modified = false;
@@ -328,52 +326,51 @@ implements AttributeVisitor,
{
if (DEBUG)
{
- System.out.println("CodeAttributeEditor: ["+clazz.getName()+"."+method.getName(clazz)+"]");
+ System.out.println("CodeAttributeEditor: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
}
- // Avoid doing any work if nothing is changing anyway.
- if (!modified)
+ // Do we have to update the code?
+ if (modified)
{
- return;
- }
-
- // Check if we can perform a faster simple replacement of instructions.
- if (canPerformSimpleReplacements(codeAttribute))
- {
- // Simply overwrite the instructions.
- performSimpleReplacements(codeAttribute);
+ // Can we perform a faster simple replacement of instructions?
+ if (canPerformSimpleReplacements(codeAttribute))
+ {
+ if (DEBUG)
+ {
+ System.out.println(" Simple editing");
+ }
- // Update the maximum stack size and local variable frame size.
- updateFrameSizes(clazz, method, codeAttribute);
- }
- else
- {
- // Move and remap the instructions.
- codeAttribute.u4codeLength =
- updateInstructions(clazz, method, codeAttribute);
+ // Simply overwrite the instructions.
+ performSimpleReplacements(codeAttribute);
+ }
+ else
+ {
+ if (DEBUG)
+ {
+ System.out.println(" Full editing");
+ }
- // Remap the exception table.
- codeAttribute.exceptionsAccept(clazz, method, this);
+ // Move and remap the instructions.
+ codeAttribute.u4codeLength =
+ updateInstructions(clazz, method, codeAttribute);
- // Remove exceptions with empty code blocks.
- codeAttribute.u2exceptionTableLength =
- removeEmptyExceptions(codeAttribute.exceptionTable,
- codeAttribute.u2exceptionTableLength);
+ // Remap the exception table.
+ codeAttribute.exceptionsAccept(clazz, method, this);
- // Update the maximum stack size and local variable frame size.
- updateFrameSizes(clazz, method, codeAttribute);
+ // Remove exceptions with empty code blocks.
+ codeAttribute.u2exceptionTableLength =
+ removeEmptyExceptions(codeAttribute.exceptionTable,
+ codeAttribute.u2exceptionTableLength);
- // Remap the line number table and the local variable table.
- codeAttribute.attributesAccept(clazz, method, this);
+ // Remap the line number table and the local variable tables.
+ codeAttribute.attributesAccept(clazz, method, this);
+ }
// Make sure instructions are widened if necessary.
instructionWriter.visitCodeAttribute(clazz, method, codeAttribute);
}
- }
-
- private void updateFrameSizes(Clazz clazz, Method method, CodeAttribute codeAttribute)
- {
+ // Update the maximum stack size and local variable frame size.
if (updateFrameSizes)
{
stackSizeUpdater.visitCodeAttribute(clazz, method, codeAttribute);
@@ -415,12 +412,6 @@ implements AttributeVisitor,
{
// Remap all local variable table entries.
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
-
- // Remove local variables with empty code blocks.
- localVariableTableAttribute.u2localVariableTableLength =
- removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable,
- localVariableTableAttribute.u2localVariableTableLength,
- codeAttribute.u2maxLocals);
}
@@ -428,12 +419,6 @@ implements AttributeVisitor,
{
// Remap all local variable table entries.
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
-
- // Remove local variables with empty code blocks.
- localVariableTypeTableAttribute.u2localVariableTypeTableLength =
- removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
- localVariableTypeTableAttribute.u2localVariableTypeTableLength,
- codeAttribute.u2maxLocals);
}
@@ -912,10 +897,12 @@ implements AttributeVisitor,
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
// Remap the code offset and length.
- // TODO: The local variable frame might not be strictly preserved.
- localVariableInfo.u2length = remapBranchOffset(localVariableInfo.u2startPC,
- localVariableInfo.u2length);
- localVariableInfo.u2startPC = remapInstructionOffset(localVariableInfo.u2startPC);
+ int newStartPC = remapInstructionOffset(localVariableInfo.u2startPC);
+ int newEndPC = remapInstructionOffset(localVariableInfo.u2startPC +
+ localVariableInfo.u2length);
+
+ localVariableInfo.u2length = newEndPC - newStartPC;
+ localVariableInfo.u2startPC = newStartPC;
}
@@ -924,10 +911,12 @@ implements AttributeVisitor,
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
// Remap the code offset and length.
- // TODO: The local variable frame might not be strictly preserved.
- localVariableTypeInfo.u2length = remapBranchOffset(localVariableTypeInfo.u2startPC,
- localVariableTypeInfo.u2length);
- localVariableTypeInfo.u2startPC = remapInstructionOffset(localVariableTypeInfo.u2startPC);
+ int newStartPC = remapInstructionOffset(localVariableTypeInfo.u2startPC);
+ int newEndPC = remapInstructionOffset(localVariableTypeInfo.u2startPC +
+ localVariableTypeInfo.u2length);
+
+ localVariableTypeInfo.u2length = newEndPC - newStartPC;
+ localVariableTypeInfo.u2startPC = newStartPC;
}
@@ -1017,54 +1006,6 @@ implements AttributeVisitor,
}
- /**
- * Returns the given list of local variables, without the ones that have empty
- * code blocks or that exceed the actual number of local variables.
- */
- private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos,
- int localVariableInfoCount,
- int maxLocals)
- {
- // Overwrite all empty local variable entries.
- int newIndex = 0;
- for (int index = 0; index < localVariableInfoCount; index++)
- {
- LocalVariableInfo localVariableInfo = localVariableInfos[index];
- if (localVariableInfo.u2length > 0 &&
- localVariableInfo.u2index < maxLocals)
- {
- localVariableInfos[newIndex++] = localVariableInfo;
- }
- }
-
- return newIndex;
- }
-
-
- /**
- * Returns the given list of local variable types, without the ones that
- * have empty code blocks or that exceed the actual number of local variables.
- */
- private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
- int localVariableTypeInfoCount,
- int maxLocals)
- {
- // Overwrite all empty local variable type entries.
- int newIndex = 0;
- for (int index = 0; index < localVariableTypeInfoCount; index++)
- {
- LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];
- if (localVariableTypeInfo.u2length > 0 &&
- localVariableTypeInfo.u2index < maxLocals)
- {
- localVariableTypeInfos[newIndex++] = localVariableTypeInfo;
- }
- }
-
- return newIndex;
- }
-
-
private class CompositeInstruction
extends Instruction
{
diff --git a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java
index 9962ea5..eedc045 100644
--- a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java
+++ b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ComparableConstant.java b/src/proguard/classfile/editor/ComparableConstant.java
index bb81221..ba5f3b1 100644
--- a/src/proguard/classfile/editor/ComparableConstant.java
+++ b/src/proguard/classfile/editor/ComparableConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -39,7 +39,7 @@ class ComparableConstant
extends SimplifiedVisitor
implements Comparable, ConstantVisitor
{
- private static final int[] PRIORITIES = new int[13];
+ private static final int[] PRIORITIES = new int[19];
static
{
PRIORITIES[ClassConstants.CONSTANT_Integer] = 0; // Possibly byte index (ldc).
@@ -47,12 +47,15 @@ implements Comparable, ConstantVisitor
PRIORITIES[ClassConstants.CONSTANT_String] = 2;
PRIORITIES[ClassConstants.CONSTANT_Class] = 3;
PRIORITIES[ClassConstants.CONSTANT_Long] = 4; // Always wide index (ldc2_w).
- PRIORITIES[ClassConstants.CONSTANT_Double] = 5;
- PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index.
- PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7;
- PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8;
- PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 9;
- PRIORITIES[ClassConstants.CONSTANT_Utf8] = 10;
+ PRIORITIES[ClassConstants.CONSTANT_Double] = 5; // Always wide index (ldc2_w).
+ PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index (getfield,...).
+ PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7; // Always wide index (invokespecial,...).
+ PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8; // Always wide index (invokeinterface).
+ PRIORITIES[ClassConstants.CONSTANT_InvokeDynamic] = 9; // Always wide index (invokedynamic).
+ PRIORITIES[ClassConstants.CONSTANT_MethodHandle] = 10;
+ PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 11;
+ PRIORITIES[ClassConstants.CONSTANT_MethodType] = 12;
+ PRIORITIES[ClassConstants.CONSTANT_Utf8] = 13;
}
private final Clazz clazz;
@@ -122,26 +125,32 @@ implements Comparable, ConstantVisitor
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
- // In JDK 1.4, we can use Integer.compare(a,b).
- result = new Integer(integerConstant.getValue()).compareTo(new Integer(((IntegerConstant)otherConstant).getValue()));
+ int value = integerConstant.getValue();
+ int otherValue = ((IntegerConstant)otherConstant).getValue();
+ result = value < otherValue ? -1 :
+ value == otherValue ? 0 :
+ 1;
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
- // In JDK 1.4, we can use Long.compare(a,b).
- result = new Long(longConstant.getValue()).compareTo(new Long(((LongConstant)otherConstant).getValue()));
+ long value = longConstant.getValue();
+ long otherValue = ((LongConstant)otherConstant).getValue();
+ result = value < otherValue ? -1 :
+ value == otherValue ? 0 :
+ 1;
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
- // In JDK 1.4, we can use Float.compare(a,b).
- result = new Float(floatConstant.getValue()).compareTo(new Float(((FloatConstant)otherConstant).getValue()));
+ result = Float.compare(floatConstant.getValue(),
+ ((FloatConstant)otherConstant).getValue());
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
- {
- // In JDK 1.4, we can use Double.compare(a,b).
- result = new Double(doubleConstant.getValue()).compareTo(new Double(((DoubleConstant)otherConstant).getValue()));
+ {
+ result = Double.compare(doubleConstant.getValue(),
+ ((DoubleConstant)otherConstant).getValue());
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
@@ -154,6 +163,38 @@ implements Comparable, ConstantVisitor
result = utf8Constant.getString().compareTo(((Utf8Constant)otherConstant).getString());
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ InvokeDynamicConstant otherInvokeDynamicConstant = (InvokeDynamicConstant)otherConstant;
+
+ int index = invokeDynamicConstant.getBootstrapMethodAttributeIndex();
+ int otherIndex = otherInvokeDynamicConstant.getBootstrapMethodAttributeIndex();
+
+ result = index < otherIndex ? -1 :
+ index > otherIndex ? 1 :
+ (invokeDynamicConstant.getName(clazz) + ' ' +
+ invokeDynamicConstant.getType(clazz))
+ .compareTo
+ (otherInvokeDynamicConstant.getName(clazz) + ' ' +
+ otherInvokeDynamicConstant.getType(clazz));
+ }
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ MethodHandleConstant otherMethodHandleConstant = (MethodHandleConstant)otherConstant;
+
+ int kind = methodHandleConstant.getReferenceKind();
+ int otherKind = methodHandleConstant.getReferenceKind();
+
+ result = kind < otherKind ? -1 :
+ kind > otherKind ? 1 :
+ (methodHandleConstant.getName(clazz) + ' ' +
+ methodHandleConstant.getType(clazz))
+ .compareTo
+ (otherMethodHandleConstant.getName(clazz) + ' ' +
+ otherMethodHandleConstant.getType(clazz));
+ }
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
RefConstant otherRefConstant = (RefConstant)otherConstant;
@@ -171,6 +212,14 @@ implements Comparable, ConstantVisitor
result = classConstant.getName(clazz).compareTo(((ClassConstant)otherConstant).getName(clazz));
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant MethodTypeConstant)
+ {
+ MethodTypeConstant otherMethodTypeConstant = (MethodTypeConstant)otherConstant;
+ result = MethodTypeConstant.getType(clazz)
+ .compareTo
+ (otherMethodTypeConstant.getType(clazz));
+ }
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
NameAndTypeConstant otherNameAndTypeConstant = (NameAndTypeConstant)otherConstant;
diff --git a/src/proguard/classfile/editor/ConstantAdder.java b/src/proguard/classfile/editor/ConstantAdder.java
index 2b74f5f..14edbce 100644
--- a/src/proguard/classfile/editor/ConstantAdder.java
+++ b/src/proguard/classfile/editor/ConstantAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -23,6 +23,7 @@ package proguard.classfile.editor;
import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.util.ListUtil;
/**
* This ConstantVisitor adds all constants that it visits to the constant pool
@@ -128,6 +129,43 @@ implements ConstantVisitor
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // First add the name and type constant.
+ clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this);
+
+ // Copy the referenced classes.
+ Clazz[] referencedClasses = invokeDynamicConstant.referencedClasses;
+ Clazz[] referencedClassesCopy = null;
+ if (referencedClasses != null)
+ {
+ referencedClassesCopy = new Clazz[referencedClasses.length];
+ System.arraycopy(referencedClasses, 0,
+ referencedClassesCopy, 0,
+ referencedClasses.length);
+ }
+
+ // Then add the actual invoke dynamic constant.
+ constantIndex =
+ constantPoolEditor.addInvokeDynamicConstant(invokeDynamicConstant.getBootstrapMethodAttributeIndex(),
+ constantIndex,
+ referencedClassesCopy);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // First add the field ref, interface method ref, or method ref
+ // constant.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+
+ // Then add the actual method handle constant.
+ constantIndex =
+ constantPoolEditor.addMethodHandleConstant(methodHandleConstant.getReferenceKind(),
+ constantIndex);
+ }
+
+
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
// First add the referenced class constant, with its own referenced class.
@@ -185,6 +223,13 @@ implements ConstantVisitor
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ constantIndex =
+ constantPoolEditor.addMethodTypeConstant(methodTypeConstant.getType(clazz));
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
constantIndex =
diff --git a/src/proguard/classfile/editor/ConstantPoolEditor.java b/src/proguard/classfile/editor/ConstantPoolEditor.java
index 8663dee..6ba4857 100644
--- a/src/proguard/classfile/editor/ConstantPoolEditor.java
+++ b/src/proguard/classfile/editor/ConstantPoolEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -199,6 +199,93 @@ public class ConstantPoolEditor
/**
+ * Finds or creates a InvokeDynamicConstant constant pool entry with the
+ * given bootstrap method constant pool entry index, method name, and
+ * descriptor.
+ * @return the constant pool index of the InvokeDynamicConstant.
+ */
+ public int addInvokeDynamicConstant(int bootstrapMethodIndex,
+ String name,
+ String descriptor,
+ Clazz[] referencedClasses)
+ {
+ return addInvokeDynamicConstant(bootstrapMethodIndex,
+ addNameAndTypeConstant(name, descriptor),
+ referencedClasses);
+ }
+
+
+ /**
+ * Finds or creates a InvokeDynamicConstant constant pool entry with the given
+ * class constant pool entry index and name and type constant pool entry
+ * index.
+ * @return the constant pool index of the InvokeDynamicConstant.
+ */
+ public int addInvokeDynamicConstant(int bootstrapMethodIndex,
+ int nameAndTypeIndex,
+ Clazz[] referencedClasses)
+ {
+ int constantPoolCount = targetClass.u2constantPoolCount;
+ Constant[] constantPool = targetClass.constantPool;
+
+ // Check if the entry already exists.
+ for (int index = 1; index < constantPoolCount; index++)
+ {
+ Constant constant = constantPool[index];
+
+ if (constant != null &&
+ constant.getTag() == ClassConstants.CONSTANT_InvokeDynamic)
+ {
+ InvokeDynamicConstant invokeDynamicConstant = (InvokeDynamicConstant)constant;
+ if (invokeDynamicConstant.u2bootstrapMethodAttributeIndex == bootstrapMethodIndex &&
+ invokeDynamicConstant.u2nameAndTypeIndex == nameAndTypeIndex)
+ {
+ return index;
+ }
+ }
+ }
+
+ return addConstant(new InvokeDynamicConstant(bootstrapMethodIndex,
+ nameAndTypeIndex,
+ referencedClasses));
+ }
+
+
+ /**
+ * Finds or creates a MethodHandleConstant constant pool entry of the
+ * specified kind and with the given field ref, interface method ref,
+ * or method ref constant pool entry index.
+ * @return the constant pool index of the MethodHandleConstant.
+ */
+ public int addMethodHandleConstant(int referenceKind,
+ int referenceIndex)
+ {
+ int constantPoolCount = targetClass.u2constantPoolCount;
+ Constant[] constantPool = targetClass.constantPool;
+
+ // Check if the entry already exists.
+ for (int index = 1; index < constantPoolCount; index++)
+ {
+ Constant constant = constantPool[index];
+
+ if (constant != null &&
+ constant.getTag() == ClassConstants.CONSTANT_MethodHandle)
+ {
+ MethodHandleConstant methodHandleConstant = (MethodHandleConstant)constant;
+ if (methodHandleConstant.u1referenceKind == referenceKind &&
+ methodHandleConstant.u2referenceIndex == referenceIndex)
+ {
+ return index;
+ }
+ }
+ }
+
+ return addConstant(new MethodHandleConstant(referenceKind,
+ referenceIndex));
+ }
+
+
+ /**
* Finds or creates a FieldrefConstant constant pool entry for the given
* class and field.
* @return the constant pool index of the FieldrefConstant.
@@ -563,6 +650,36 @@ public class ConstantPoolEditor
/**
+ * Finds or creates a MethodTypeConstant constant pool entry with the given
+ * type.
+ * @return the constant pool index of the MethodTypeConstant.
+ */
+ public int addMethodTypeConstant(String type)
+ {
+ int constantPoolCount = targetClass.u2constantPoolCount;
+ Constant[] constantPool = targetClass.constantPool;
+
+ // Check if the entry already exists.
+ for (int index = 1; index < constantPoolCount; index++)
+ {
+ Constant constant = constantPool[index];
+
+ if (constant != null &&
+ constant.getTag() == ClassConstants.CONSTANT_MethodType)
+ {
+ MethodTypeConstant methodTypeConstant = (MethodTypeConstant)constant;
+ if (methodTypeConstant.getType(targetClass).equals(type))
+ {
+ return index;
+ }
+ }
+ }
+
+ return addConstant(new MethodTypeConstant(addUtf8Constant(type)));
+ }
+
+
+ /**
* Finds or creates a NameAndTypeConstant constant pool entry with the given
* name and type.
* @return the constant pool index of the NameAndTypeConstant.
diff --git a/src/proguard/classfile/editor/ConstantPoolRemapper.java b/src/proguard/classfile/editor/ConstantPoolRemapper.java
index 7430d3d..7677218 100644
--- a/src/proguard/classfile/editor/ConstantPoolRemapper.java
+++ b/src/proguard/classfile/editor/ConstantPoolRemapper.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -47,9 +47,10 @@ implements ClassVisitor,
ConstantVisitor,
MemberVisitor,
AttributeVisitor,
- InstructionVisitor,
+ BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
+ InstructionVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
LocalVariableInfoVisitor,
@@ -57,7 +58,7 @@ implements ClassVisitor,
AnnotationVisitor,
ElementValueVisitor
{
- private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor();
+ private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);
private int[] constantIndexMap;
@@ -100,40 +101,66 @@ implements ClassVisitor,
// Implementations for ConstantVisitor.
- public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
- classConstant.u2nameIndex =
- remapConstantIndex(classConstant.u2nameIndex);
+ // Nothing to do.
}
- public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
+ public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
// Nothing to do.
}
- public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
+ public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
- fieldrefConstant.u2classIndex =
- remapConstantIndex(fieldrefConstant.u2classIndex);
- fieldrefConstant.u2nameAndTypeIndex =
- remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex);
+ // Nothing to do.
}
- public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
+ public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
// Nothing to do.
}
- public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ stringConstant.u2stringIndex =
+ remapConstantIndex(stringConstant.u2stringIndex);
+ }
+
+
+ public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
// Nothing to do.
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ invokeDynamicConstant.u2nameAndTypeIndex =
+ remapConstantIndex(invokeDynamicConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ methodHandleConstant.u2referenceIndex =
+ remapConstantIndex(methodHandleConstant.u2referenceIndex);
+ }
+
+
+ public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
+ {
+ fieldrefConstant.u2classIndex =
+ remapConstantIndex(fieldrefConstant.u2classIndex);
+ fieldrefConstant.u2nameAndTypeIndex =
+ remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex);
+ }
+
+
public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
{
interfaceMethodrefConstant.u2classIndex =
@@ -143,12 +170,6 @@ implements ClassVisitor,
}
- public void visitLongConstant(Clazz clazz, LongConstant longConstant)
- {
- // Nothing to do.
- }
-
-
public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
{
methodrefConstant.u2classIndex =
@@ -158,25 +179,26 @@ implements ClassVisitor,
}
- public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
- nameAndTypeConstant.u2nameIndex =
- remapConstantIndex(nameAndTypeConstant.u2nameIndex);
- nameAndTypeConstant.u2descriptorIndex =
- remapConstantIndex(nameAndTypeConstant.u2descriptorIndex);
+ classConstant.u2nameIndex =
+ remapConstantIndex(classConstant.u2nameIndex);
}
- public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
{
- stringConstant.u2stringIndex =
- remapConstantIndex(stringConstant.u2stringIndex);
+ methodTypeConstant.u2descriptorIndex =
+ remapConstantIndex(methodTypeConstant.u2descriptorIndex);
}
- public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
+ public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
- // Nothing to do.
+ nameAndTypeConstant.u2nameIndex =
+ remapConstantIndex(nameAndTypeConstant.u2nameIndex);
+ nameAndTypeConstant.u2descriptorIndex =
+ remapConstantIndex(nameAndTypeConstant.u2descriptorIndex);
}
@@ -230,6 +252,16 @@ implements ClassVisitor,
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ bootstrapMethodsAttribute.u2attributeNameIndex =
+ remapConstantIndex(bootstrapMethodsAttribute.u2attributeNameIndex);
+
+ // Remap the constant pool references of the bootstrap method entries.
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
sourceFileAttribute.u2attributeNameIndex =
@@ -410,6 +442,19 @@ implements ClassVisitor,
}
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ bootstrapMethodInfo.u2methodHandleIndex =
+ remapConstantIndex(bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Remap the constant pool references of the bootstrap methods..
+ remapConstantIndexArray(bootstrapMethodInfo.u2methodArguments,
+ bootstrapMethodInfo.u2methodArgumentCount);
+ }
+
+
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
diff --git a/src/proguard/classfile/editor/ConstantPoolShrinker.java b/src/proguard/classfile/editor/ConstantPoolShrinker.java
new file mode 100644
index 0000000..8c8e5d6
--- /dev/null
+++ b/src/proguard/classfile/editor/ConstantPoolShrinker.java
@@ -0,0 +1,578 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.editor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.annotation.visitor.*;
+import proguard.classfile.attribute.preverification.*;
+import proguard.classfile.attribute.preverification.visitor.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+
+import java.util.Arrays;
+
+/**
+ * This ClassVisitor removes all unused entries from the constant pool.
+ *
+ * @author Eric Lafortune
+ */
+public class ConstantPoolShrinker
+extends SimplifiedVisitor
+implements ClassVisitor,
+ MemberVisitor,
+ ConstantVisitor,
+ AttributeVisitor,
+ BootstrapMethodInfoVisitor,
+ InnerClassesInfoVisitor,
+ ExceptionInfoVisitor,
+ StackMapFrameVisitor,
+ VerificationTypeVisitor,
+ LocalVariableInfoVisitor,
+ LocalVariableTypeInfoVisitor,
+ AnnotationVisitor,
+ ElementValueVisitor,
+ InstructionVisitor
+{
+ // A visitor info flag to indicate the constant is being used.
+ private static final Object USED = new Object();
+
+ private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
+ private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Mark this class's name.
+ markConstant(programClass, programClass.u2thisClass);
+
+ // Mark the superclass class constant.
+ programClass.superClassConstantAccept(this);
+
+ // Mark the interface class constants.
+ programClass.interfaceConstantsAccept(this);
+
+ // Mark the constants referenced by the class members.
+ programClass.fieldsAccept(this);
+ programClass.methodsAccept(this);
+
+ // Mark the attributes.
+ programClass.attributesAccept(this);
+
+ // Shift the used constant pool entries together, filling out the
+ // index map.
+ int newConstantPoolCount =
+ shrinkConstantPool(programClass.constantPool,
+ programClass.u2constantPoolCount);
+
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
+
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
+ {
+ // Mark the name and descriptor.
+ markConstant(programClass, programMember.u2nameIndex);
+ markConstant(programClass, programMember.u2descriptorIndex);
+
+ // Mark the attributes.
+ programMember.attributesAccept(programClass, this);
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant)
+ {
+ markAsUsed(constant);
+ }
+
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ markAsUsed(stringConstant);
+
+ markConstant(clazz, stringConstant.u2stringIndex);
+ }
+
+
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ markAsUsed(invokeDynamicConstant);
+
+ markConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex);
+
+ // Mark the bootstrap methods attribute.
+ clazz.attributesAccept(this);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ markAsUsed(methodHandleConstant);
+
+ markConstant(clazz, methodHandleConstant.u2referenceIndex);
+ }
+
+
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ markAsUsed(refConstant);
+
+ markConstant(clazz, refConstant.u2classIndex);
+ markConstant(clazz, refConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ markAsUsed(classConstant);
+
+ markConstant(clazz, classConstant.u2nameIndex);
+ }
+
+
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ markAsUsed(methodTypeConstant);
+
+ markConstant(clazz, methodTypeConstant.u2descriptorIndex);
+ }
+
+
+ public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
+ {
+ markAsUsed(nameAndTypeConstant);
+
+ markConstant(clazz, nameAndTypeConstant.u2nameIndex);
+ markConstant(clazz, nameAndTypeConstant.u2descriptorIndex);
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute)
+ {
+ markConstant(clazz, attribute.u2attributeNameIndex);
+ }
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ markConstant(clazz, bootstrapMethodsAttribute.u2attributeNameIndex);
+
+ // Mark the bootstrap method entries.
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
+ }
+
+
+ public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
+ {
+ markConstant(clazz, sourceFileAttribute.u2attributeNameIndex);
+ markConstant(clazz, sourceFileAttribute.u2sourceFileIndex);
+ }
+
+
+ public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
+ {
+ markConstant(clazz, sourceDirAttribute.u2attributeNameIndex);
+ markConstant(clazz, sourceDirAttribute.u2sourceDirIndex);
+ }
+
+
+ public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
+ {
+ markConstant(clazz, innerClassesAttribute.u2attributeNameIndex);
+
+ // Mark the outer class entries.
+ innerClassesAttribute.innerClassEntriesAccept(clazz, this);
+ }
+
+
+ public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
+ {
+ markConstant(clazz, enclosingMethodAttribute.u2attributeNameIndex);
+ markConstant(clazz, enclosingMethodAttribute.u2classIndex);
+
+ if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
+ {
+ markConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex);
+ }
+ }
+
+
+ public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
+ {
+ markConstant(clazz, signatureAttribute.u2attributeNameIndex);
+ markConstant(clazz, signatureAttribute.u2signatureIndex);
+ }
+
+
+ public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
+ {
+ markConstant(clazz, constantValueAttribute.u2attributeNameIndex);
+ markConstant(clazz, constantValueAttribute.u2constantValueIndex);
+ }
+
+
+ public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
+ {
+ markConstant(clazz, exceptionsAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the exceptions.
+ exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this);
+ }
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ markConstant(clazz, codeAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the instructions,
+ // by the exceptions, and by the attributes.
+ codeAttribute.instructionsAccept(clazz, method, this);
+ codeAttribute.exceptionsAccept(clazz, method, this);
+ codeAttribute.attributesAccept(clazz, method, this);
+ }
+
+
+ public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
+ {
+ markConstant(clazz, stackMapAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the stack map frames.
+ stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
+ {
+ markConstant(clazz, stackMapTableAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the stack map frames.
+ stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ markConstant(clazz, localVariableTableAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the local variables.
+ localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ markConstant(clazz, localVariableTypeTableAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the local variable types.
+ localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
+ {
+ markConstant(clazz, annotationsAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the annotations.
+ annotationsAttribute.annotationsAccept(clazz, this);
+ }
+
+
+ public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
+ {
+ markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the annotations.
+ parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
+ }
+
+
+ public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
+ {
+ markConstant(clazz, annotationDefaultAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the element value.
+ annotationDefaultAttribute.defaultValueAccept(clazz, this);
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ markConstant(clazz, bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Mark the constant pool entries referenced by the arguments.
+ bootstrapMethodInfo.methodArgumentsAccept(clazz, this);
+ }
+
+
+ // Implementations for InnerClassesInfoVisitor.
+
+ public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
+ {
+ innerClassesInfo.innerClassConstantAccept(clazz, this);
+ innerClassesInfo.outerClassConstantAccept(clazz, this);
+ innerClassesInfo.innerNameConstantAccept(clazz, this);
+ }
+
+
+ // Implementations for ExceptionInfoVisitor.
+
+ public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
+ {
+ if (exceptionInfo.u2catchType != 0)
+ {
+ markConstant(clazz, exceptionInfo.u2catchType);
+ }
+ }
+
+
+ // Implementations for StackMapFrameVisitor.
+
+ public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {}
+
+
+ public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
+ {
+ // Mark the constant pool entries referenced by the verification types.
+ sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
+ }
+
+
+ public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
+ {
+ // Mark the constant pool entries referenced by the verification types.
+ moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
+ }
+
+
+ public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
+ {
+ // Mark the constant pool entries referenced by the verification types.
+ fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);
+ fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);
+ }
+
+
+ // Implementations for VerificationTypeVisitor.
+
+ public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {}
+
+
+ public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
+ {
+ markConstant(clazz, objectType.u2classIndex);
+ }
+
+
+ // Implementations for LocalVariableInfoVisitor.
+
+ public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
+ {
+ markConstant(clazz, localVariableInfo.u2nameIndex);
+ markConstant(clazz, localVariableInfo.u2descriptorIndex);
+ }
+
+
+ // Implementations for LocalVariableTypeInfoVisitor.
+
+ public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
+ {
+ markConstant(clazz, localVariableTypeInfo.u2nameIndex);
+ markConstant(clazz, localVariableTypeInfo.u2signatureIndex);
+ }
+
+
+ // Implementations for AnnotationVisitor.
+
+ public void visitAnnotation(Clazz clazz, Annotation annotation)
+ {
+ markConstant(clazz, annotation.u2typeIndex);
+
+ // Mark the constant pool entries referenced by the element values.
+ annotation.elementValuesAccept(clazz, this);
+ }
+
+
+ // Implementations for ElementValueVisitor.
+
+ public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
+ {
+ if (constantElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, constantElementValue.u2elementNameIndex);
+ }
+
+ markConstant(clazz, constantElementValue.u2constantValueIndex);
+ }
+
+
+ public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
+ {
+ if (enumConstantElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, enumConstantElementValue.u2elementNameIndex);
+ }
+
+ markConstant(clazz, enumConstantElementValue.u2typeNameIndex);
+ markConstant(clazz, enumConstantElementValue.u2constantNameIndex);
+ }
+
+
+ public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
+ {
+ if (classElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, classElementValue.u2elementNameIndex);
+ }
+
+ markConstant(clazz, classElementValue.u2classInfoIndex);
+ }
+
+
+ public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
+ {
+ if (annotationElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, annotationElementValue.u2elementNameIndex);
+ }
+
+ // Mark the constant pool entries referenced by the annotation.
+ annotationElementValue.annotationAccept(clazz, this);
+ }
+
+
+ public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
+ {
+ if (arrayElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, arrayElementValue.u2elementNameIndex);
+ }
+
+ // Mark the constant pool entries referenced by the element values.
+ arrayElementValue.elementValuesAccept(clazz, annotation, this);
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
+ {
+ markConstant(clazz, constantInstruction.constantIndex);
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Marks the given constant pool entry of the given class. This includes
+ * visiting any referenced objects.
+ */
+ private void markConstant(Clazz clazz, int index)
+ {
+ clazz.constantPoolEntryAccept(index, this);
+ }
+
+
+ /**
+ * Marks the given visitor accepter as being used.
+ */
+ private void markAsUsed(Constant constant)
+ {
+ constant.setVisitorInfo(USED);
+ }
+
+
+ /**
+ * Returns whether the given visitor accepter has been marked as being used.
+ */
+ private boolean isUsed(VisitorAccepter visitorAccepter)
+ {
+ return visitorAccepter.getVisitorInfo() == USED;
+ }
+
+
+ /**
+ * Removes all constants that are not marked as being used from the given
+ * constant pool.
+ * @return the new number of entries.
+ */
+ private int shrinkConstantPool(Constant[] constantPool, int length)
+ {
+ // Create a new index map, if necessary.
+ if (constantIndexMap.length < length)
+ {
+ constantIndexMap = new int[length];
+ }
+
+ int counter = 1;
+ boolean isUsed = false;
+
+ // Shift the used constant pool entries together.
+ for (int index = 1; index < length; index++)
+ {
+ constantIndexMap[index] = counter;
+
+ Constant constant = constantPool[index];
+
+ // Don't update the flag if this is the second half of a long entry.
+ if (constant != null)
+ {
+ isUsed = isUsed(constant);
+ }
+
+ if (isUsed)
+ {
+ constantPool[counter++] = constant;
+ }
+ }
+
+ // Clear the remaining constant pool elements.
+ Arrays.fill(constantPool, counter, length, null);
+
+ return counter;
+ }
+}
diff --git a/src/proguard/classfile/editor/ConstantPoolSorter.java b/src/proguard/classfile/editor/ConstantPoolSorter.java
index faae318..8e18865 100644
--- a/src/proguard/classfile/editor/ConstantPoolSorter.java
+++ b/src/proguard/classfile/editor/ConstantPoolSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -112,10 +112,7 @@ implements ClassVisitor
System.arraycopy(newConstantPool, 0, programClass.constantPool, 0, newLength);
// Clear any remaining entries.
- for (int index = newLength; index < constantPoolCount; index++)
- {
- programClass.constantPool[index] = null;
- }
+ Arrays.fill(programClass.constantPool, newLength, constantPoolCount, null);
programClass.u2constantPoolCount = newLength;
diff --git a/src/proguard/classfile/editor/ElementValueAdder.java b/src/proguard/classfile/editor/ElementValueAdder.java
index 8cbd11d..895fd68 100644
--- a/src/proguard/classfile/editor/ElementValueAdder.java
+++ b/src/proguard/classfile/editor/ElementValueAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ElementValuesEditor.java b/src/proguard/classfile/editor/ElementValuesEditor.java
index bfc4e9f..ce9352a 100644
--- a/src/proguard/classfile/editor/ElementValuesEditor.java
+++ b/src/proguard/classfile/editor/ElementValuesEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ExceptionAdder.java b/src/proguard/classfile/editor/ExceptionAdder.java
index 1ccb1a6..ee0fb52 100644
--- a/src/proguard/classfile/editor/ExceptionAdder.java
+++ b/src/proguard/classfile/editor/ExceptionAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ExceptionInfoAdder.java b/src/proguard/classfile/editor/ExceptionInfoAdder.java
index e0cc9c5..5fd98a8 100644
--- a/src/proguard/classfile/editor/ExceptionInfoAdder.java
+++ b/src/proguard/classfile/editor/ExceptionInfoAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ExceptionsAttributeEditor.java b/src/proguard/classfile/editor/ExceptionsAttributeEditor.java
index 4509a9a..d49658a 100644
--- a/src/proguard/classfile/editor/ExceptionsAttributeEditor.java
+++ b/src/proguard/classfile/editor/ExceptionsAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/InnerClassesAccessFixer.java b/src/proguard/classfile/editor/InnerClassesAccessFixer.java
new file mode 100644
index 0000000..1d991df
--- /dev/null
+++ b/src/proguard/classfile/editor/InnerClassesAccessFixer.java
@@ -0,0 +1,83 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.editor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.visitor.InnerClassesInfoVisitor;
+import proguard.classfile.attribute.InnerClassesInfo;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+
+/**
+ * This InnerClassesInfoVisitor fixes the inner class access flags of the
+ * inner classes information that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class InnerClassesAccessFixer
+extends SimplifiedVisitor
+implements InnerClassesInfoVisitor,
+ ConstantVisitor,
+ ClassVisitor
+{
+ private int innerClassAccessFlags;
+
+
+ // Implementations for InnerClassesInfoVisitor.
+
+ public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
+ {
+ // The current access flags are the default.
+ innerClassAccessFlags = innerClassesInfo.u2innerClassAccessFlags;
+
+ // See if we can find new access flags.
+ innerClassesInfo.innerClassConstantAccept(clazz, this);
+
+ // Update the access flags.
+ innerClassesInfo.u2innerClassAccessFlags = innerClassAccessFlags;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ classConstant.referencedClassAccept(this);
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ innerClassAccessFlags =
+ AccessUtil.replaceAccessFlags(innerClassAccessFlags,
+ programClass.u2accessFlags);
+ }
+} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/InstructionAdder.java b/src/proguard/classfile/editor/InstructionAdder.java
index 60fde6d..34fb63b 100644
--- a/src/proguard/classfile/editor/InstructionAdder.java
+++ b/src/proguard/classfile/editor/InstructionAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/InstructionWriter.java b/src/proguard/classfile/editor/InstructionWriter.java
index d842358..b7da62f 100644
--- a/src/proguard/classfile/editor/InstructionWriter.java
+++ b/src/proguard/classfile/editor/InstructionWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/InterfaceAdder.java b/src/proguard/classfile/editor/InterfaceAdder.java
index e095af6..9c11d97 100644
--- a/src/proguard/classfile/editor/InterfaceAdder.java
+++ b/src/proguard/classfile/editor/InterfaceAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/InterfaceSorter.java b/src/proguard/classfile/editor/InterfaceSorter.java
index 6521369..176e13e 100644
--- a/src/proguard/classfile/editor/InterfaceSorter.java
+++ b/src/proguard/classfile/editor/InterfaceSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,10 +21,14 @@
package proguard.classfile.editor;
import proguard.classfile.*;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.ClassVisitor;
-import java.util.Arrays;
+import java.util.*;
/**
* This ClassVisitor sorts the interfaces of the program classes that it visits.
@@ -33,7 +37,8 @@ import java.util.Arrays;
*/
public class InterfaceSorter
extends SimplifiedVisitor
-implements ClassVisitor
+implements ClassVisitor,
+ AttributeVisitor
{
// Implementations for ClassVisitor.
@@ -42,26 +47,106 @@ implements ClassVisitor
int[] interfaces = programClass.u2interfaces;
int interfacesCount = programClass.u2interfacesCount;
- // Sort the interfaces.
- Arrays.sort(interfaces, 0, interfacesCount);
+ if (interfacesCount > 1)
+ {
+ // Sort the interfaces.
+ Arrays.sort(interfaces, 0, interfacesCount);
+
+ // Remove any duplicate entries.
+ int newInterfacesCount = 0;
+ int previousInterfaceIndex = 0;
+ for (int index = 0; index < interfacesCount; index++)
+ {
+ int interfaceIndex = interfaces[index];
+
+ // Isn't this a duplicate of the previous interface?
+ if (interfaceIndex != previousInterfaceIndex)
+ {
+ interfaces[newInterfacesCount++] = interfaceIndex;
+
+ // Remember the interface.
+ previousInterfaceIndex = interfaceIndex;
+ }
+ }
+
+ programClass.u2interfacesCount = newInterfacesCount;
+
+ // Update the signature, if any
+ programClass.attributesAccept(this);
+ }
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
+ {
+ // Process the generic definitions, superclass, and implemented
+ // interfaces.
+ String signature = clazz.getString(signatureAttribute.u2signatureIndex);
+
+ // Count the signature types.
+ InternalTypeEnumeration internalTypeEnumeration =
+ new InternalTypeEnumeration(signature);
- // Remove any duplicate entries.
- int newInterfacesCount = 0;
- int previousInterfaceIndex = 0;
- for (int index = 0; index < interfacesCount; index++)
+ int count = 0;
+ int interfacesCount = -1;
+ while (internalTypeEnumeration.hasMoreTypes())
{
- int interfaceIndex = interfaces[index];
+ String internalType = internalTypeEnumeration.nextType();
- // Isn't this a duplicate of the previous interface?
- if (interfaceIndex != previousInterfaceIndex)
+ count++;
+
+ if (ClassUtil.isInternalClassType(internalType))
{
- interfaces[newInterfacesCount++] = interfaceIndex;
+ interfacesCount++;
+ }
+ }
+
+ // Put the signature types in an array.
+ internalTypeEnumeration =
+ new InternalTypeEnumeration(signature);
+
+ String[] internalTypes = new String[count];
+
+ for (int index = 0; index < count; index++)
+ {
+ String internalType = internalTypeEnumeration.nextType();
+
+ internalTypes[index] = internalType;
+ }
- // Remember the interface.
- previousInterfaceIndex = interfaceIndex;
+ // Sort the interface types in the array.
+ Arrays.sort(internalTypes, count - interfacesCount, count);
+
+ // Recompose the signature types in a string.
+ StringBuffer newSignatureBuffer = new StringBuffer();
+
+ for (int index = 0; index < count; index++)
+ {
+ // Is this not an interface type, or an interface type that isn't
+ // a duplicate of the previous interface type?
+ if (index < count - interfacesCount ||
+ !internalTypes[index].equals(internalTypes[index-1]))
+ {
+ newSignatureBuffer.append(internalTypes[index]);
}
}
- programClass.u2interfacesCount = newInterfacesCount;
+ String newSignature = newSignatureBuffer.toString();
+
+ // Did the signature change?
+ if (!newSignature.equals(signature))
+ {
+ // Update the signature.
+ ((Utf8Constant)((ProgramClass)clazz).constantPool[signatureAttribute.u2signatureIndex]).setString(newSignatureBuffer.toString());
+
+ // Clear the referenced classes.
+ // TODO: Properly update the referenced classes.
+ signatureAttribute.referencedClasses = null;
+ }
}
}
diff --git a/src/proguard/classfile/editor/InterfacesEditor.java b/src/proguard/classfile/editor/InterfacesEditor.java
index d3170e1..59cdd6a 100644
--- a/src/proguard/classfile/editor/InterfacesEditor.java
+++ b/src/proguard/classfile/editor/InterfacesEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/LineNumberInfoAdder.java b/src/proguard/classfile/editor/LineNumberInfoAdder.java
index aa8c0c4..b0db7fb 100644
--- a/src/proguard/classfile/editor/LineNumberInfoAdder.java
+++ b/src/proguard/classfile/editor/LineNumberInfoAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java
index ab96b38..7497458 100644
--- a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java
+++ b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/LocalVariableInfoAdder.java b/src/proguard/classfile/editor/LocalVariableInfoAdder.java
index f285e4f..0f47933 100644
--- a/src/proguard/classfile/editor/LocalVariableInfoAdder.java
+++ b/src/proguard/classfile/editor/LocalVariableInfoAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java
index 053b628..8bb051d 100644
--- a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java
+++ b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java
index ca50f3f..a1c1379 100644
--- a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java
+++ b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java
index fe5a64d..9b1ebd5 100644
--- a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java
+++ b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/MemberAdder.java b/src/proguard/classfile/editor/MemberAdder.java
index 5f939bb..7791e3b 100644
--- a/src/proguard/classfile/editor/MemberAdder.java
+++ b/src/proguard/classfile/editor/MemberAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -26,8 +26,9 @@ import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.MemberVisitor;
/**
- * This ConstantVisitor adds all class members that it visits to the given
- * target class.
+ * This MemberVisitor copies all class members that it visits to the given
+ * target class. Their visitor info is set to the class members from which they
+ * were copied.
*
* @author Eric Lafortune
*/
@@ -45,8 +46,9 @@ implements MemberVisitor
private static final Attribute[] EMPTY_ATTRIBUTES = new Attribute[0];
- private final ProgramClass targetClass;
-// private final boolean addFields;
+ private final ProgramClass targetClass;
+// private final boolean addFields;
+ private final MemberVisitor extraMemberVisitor;
private final ConstantAdder constantAdder;
private final ClassEditor classEditor;
@@ -59,13 +61,30 @@ implements MemberVisitor
* @param targetClass the class to which all visited class members will be
* added.
*/
+ public MemberAdder(ProgramClass targetClass)
+ {
+ this(targetClass, null);
+ }
+
+
+ /**
+ * Creates a new MemberAdder that will copy methods into the given target
+ * class.
+ * @param targetClass the class to which all visited class members
+ * will be added.
+ * @param extraMemberVisitor an optional member visitor that visits each
+ * new member right after it has been added. This
+ * allows changing the visitor info, for instance.
+ */
// * @param addFields specifies whether fields should be added, or fused
// * with the present fields.
- public MemberAdder(ProgramClass targetClass)//),
-// boolean addFields)
+ public MemberAdder(ProgramClass targetClass,
+// boolean addFields,
+ MemberVisitor extraMemberVisitor)
{
- this.targetClass = targetClass;
-// this.addFields = addFields;
+ this.targetClass = targetClass;
+// this.addFields = addFields;
+ this.extraMemberVisitor = extraMemberVisitor;
constantAdder = new ConstantAdder(targetClass);
classEditor = new ClassEditor(targetClass);
@@ -150,6 +169,12 @@ implements MemberVisitor
// Add the completed field.
classEditor.addField(newProgramField);
+
+ // Visit the newly added field, if necessary.
+ if (extraMemberVisitor != null)
+ {
+ extraMemberVisitor.visitProgramField(targetClass, newProgramField);
+ }
}
@@ -240,6 +265,12 @@ implements MemberVisitor
// Add the completed method.
classEditor.addMethod(newProgramMethod);
+
+ // Visit the newly added method, if necessary.
+ if (extraMemberVisitor != null)
+ {
+ extraMemberVisitor.visitProgramMethod(targetClass, newProgramMethod);
+ }
}
diff --git a/src/proguard/classfile/editor/MemberReferenceFixer.java b/src/proguard/classfile/editor/MemberReferenceFixer.java
index 4bd8af5..6d665c1 100644
--- a/src/proguard/classfile/editor/MemberReferenceFixer.java
+++ b/src/proguard/classfile/editor/MemberReferenceFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -298,22 +298,17 @@ implements ClassVisitor,
{
Clazz referencedClass = enclosingMethodAttribute.referencedClass;
- // Does it have a new class?
- if (!enclosingMethodAttribute.getClassName(clazz).equals(referencedClass.getName()))
- {
- // Update the class index.
- enclosingMethodAttribute.u2classIndex =
- new ConstantPoolEditor((ProgramClass)clazz).addClassConstant(referencedClass);
- }
-
// Does it have a new name or type?
- if (!enclosingMethodAttribute.getName(clazz).equals(referencedMember.getName(referencedClass)) ||
- !enclosingMethodAttribute.getType(clazz).equals(referencedMember.getDescriptor(referencedClass)))
+ String newName = referencedMember.getName(referencedClass);
+ String newType = referencedMember.getDescriptor(referencedClass);
+
+ if (!enclosingMethodAttribute.getName(clazz).equals(newName) ||
+ !enclosingMethodAttribute.getType(clazz).equals(newType))
{
// Update the name and type index.
enclosingMethodAttribute.u2nameAndTypeIndex =
- new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(referencedMember.getName(referencedClass),
- referencedMember.getDescriptor(referencedClass));
+ new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(newName,
+ newType);
}
}
}
@@ -433,10 +428,9 @@ implements ClassVisitor,
Member referencedMember)
{
System.out.println("MemberReferenceFixer:");
- System.out.println(" Class file = "+clazz.getName());
- System.out.println(" Ref class = "+referencedClass.getName());
- System.out.println(" Ref member name = "+stringConstant.getString(clazz));
- System.out.println(" -> "+referencedMember.getName(referencedClass));
+ System.out.println(" ["+clazz.getName()+"]: String ["+
+ stringConstant.getString(clazz)+"] -> ["+
+ referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]");
}
@@ -446,11 +440,8 @@ implements ClassVisitor,
Member referencedMember)
{
System.out.println("MemberReferenceFixer:");
- System.out.println(" Class file = "+clazz.getName());
- System.out.println(" Ref class = "+referencedClass.getName());
- System.out.println(" Ref member name = "+refConstant.getName(clazz));
- System.out.println(" -> "+referencedMember.getName(referencedClass));
- System.out.println(" Ref descriptor = "+refConstant.getType(clazz));
- System.out.println(" -> "+referencedMember.getDescriptor(referencedClass));
+ System.out.println(" ["+clazz.getName()+"]: ["+
+ refConstant.getClassName(clazz)+"."+refConstant.getName(clazz)+" "+refConstant.getType(clazz)+"] -> ["+
+ referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]");
}
}
diff --git a/src/proguard/classfile/editor/MethodInvocationFixer.java b/src/proguard/classfile/editor/MethodInvocationFixer.java
index ef76012..f33ef1d 100644
--- a/src/proguard/classfile/editor/MethodInvocationFixer.java
+++ b/src/proguard/classfile/editor/MethodInvocationFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -28,7 +28,6 @@ import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;
-import proguard.classfile.visitor.*;
/**
* This AttributeVisitor fixes all inappropriate special/virtual/static/interface
@@ -40,9 +39,7 @@ public class MethodInvocationFixer
extends SimplifiedVisitor
implements AttributeVisitor,
InstructionVisitor,
- ConstantVisitor,
- ClassVisitor,
- MemberVisitor
+ ConstantVisitor
{
private static final boolean DEBUG = false;
@@ -88,7 +85,8 @@ implements AttributeVisitor,
clazz.constantPoolEntryAccept(constantIndex, this);
// Did we find the called class and method?
- if (referencedMethod != null)
+ if (referencedClass != null &&
+ referencedMethod != null)
{
// Do we need to update the opcode?
byte opcode = constantInstruction.opcode;
@@ -168,6 +166,7 @@ implements AttributeVisitor,
// but not a super call)?
if (opcode != InstructionConstants.OP_INVOKEVIRTUAL &&
(opcode != InstructionConstants.OP_INVOKESPECIAL ||
+ clazz.equals(referencedClass) ||
!clazz.extends_(referencedClass)))
{
// Replace the invocation by an invokevirtual instruction.
@@ -194,40 +193,30 @@ implements AttributeVisitor,
public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
{
- // Check if this is an interface method. Note that we're interested in
- // the class of the method reference, not in the class in which the
- // method was actually found.
- //refConstant.referencedClassAccept(this);
- clazz.constantPoolEntryAccept(refConstant.u2classIndex, this);
-
- // Get the referenced access flags and names.
- refConstant.referencedMemberAccept(this);
- }
-
+ // Remember the referenced class. Note that we're interested in the
+ // class of the method reference, not in the class in which the
+ // method was actually found, unless it is an array type.
+ //
+ if (ClassUtil.isInternalArrayType(refConstant.getClassName(clazz)))
+ {
+ // For an array type, the class will be java.lang.Object.
+ referencedClass = refConstant.referencedClass;
+ }
+ else
+ {
+ clazz.constantPoolEntryAccept(refConstant.u2classIndex, this);
+ }
- public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
- {
- // Check if this is an interface class.
- classConstant.referencedClassAccept(this);
+ // Remember the referenced method.
+ referencedMethodClass = refConstant.referencedClass;
+ referencedMethod = refConstant.referencedMember;
}
- // Implementations for ClassVisitor.
-
- public void visitAnyClass(Clazz clazz)
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Remember the referenced class.
- referencedClass = clazz;
- }
-
-
- // Implementations for MemberVisitor.
-
- public void visitAnyMember(Clazz clazz, Member member)
- {
- // Remember the referenced method.
- referencedMethodClass = clazz;
- referencedMethod = member;
+ referencedClass = classConstant.referencedClass;
}
diff --git a/src/proguard/obfuscate/NameAndTypeUsageMarker.java b/src/proguard/classfile/editor/NameAndTypeShrinker.java
index cc779f0..f316884 100644
--- a/src/proguard/obfuscate/NameAndTypeUsageMarker.java
+++ b/src/proguard/classfile/editor/NameAndTypeShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -18,25 +18,27 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-package proguard.obfuscate;
+package proguard.classfile.editor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.editor.ConstantPoolRemapper;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.ClassVisitor;
+import java.util.Arrays;
+
+
/**
- * This ClassVisitor marks all NameAndType constant pool entries that are
- * being used in the program classes it visits.
- *
- * @see NameAndTypeShrinker
+ * This ClassVisitor removes NameAndType constant pool entries that are not
+ * used.
*
* @author Eric Lafortune
*/
-public class NameAndTypeUsageMarker
+public class NameAndTypeShrinker
extends SimplifiedVisitor
implements ClassVisitor,
ConstantVisitor,
@@ -45,6 +47,9 @@ implements ClassVisitor,
// A visitor info flag to indicate the NameAndType constant pool entry is being used.
private static final Object USED = new Object();
+ private int[] constantIndexMap;
+ private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
+
// Implementations for ClassVisitor.
@@ -57,33 +62,37 @@ implements ClassVisitor,
// Mark the NameAndType entries referenced by all EnclosingMethod
// attributes.
programClass.attributesAccept(this);
- }
+ // Shift the used constant pool entries together, filling out the
+ // index map.
+ int newConstantPoolCount =
+ shrinkConstantPool(programClass.constantPool,
+ programClass.u2constantPoolCount);
- // Implementations for ConstantVisitor.
-
- public void visitAnyConstant(Clazz clazz, Constant constant) {}
-
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
- public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
- {
- visitRefConstant(clazz, fieldrefConstant);
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
}
- public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
- {
- visitRefConstant(clazz, interfaceMethodrefConstant);
- }
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
- public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
{
- visitRefConstant(clazz, methodrefConstant);
+ markNameAndTypeConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex);
}
- private void visitRefConstant(Clazz clazz, RefConstant refConstant)
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
markNameAndTypeConstant(clazz, refConstant.u2nameAndTypeIndex);
}
@@ -118,7 +127,7 @@ implements ClassVisitor,
* Marks the given VisitorAccepter as being used.
* In this context, the VisitorAccepter will be a NameAndTypeConstant object.
*/
- private static void markAsUsed(VisitorAccepter visitorAccepter)
+ private void markAsUsed(VisitorAccepter visitorAccepter)
{
visitorAccepter.setVisitorInfo(USED);
}
@@ -128,8 +137,52 @@ implements ClassVisitor,
* Returns whether the given VisitorAccepter has been marked as being used.
* In this context, the VisitorAccepter will be a NameAndTypeConstant object.
*/
- static boolean isUsed(VisitorAccepter visitorAccepter)
+ private boolean isUsed(VisitorAccepter visitorAccepter)
{
return visitorAccepter.getVisitorInfo() == USED;
}
+
+
+ /**
+ * Removes all NameAndType entries that are not marked as being used
+ * from the given constant pool.
+ * @return the new number of entries.
+ */
+ private int shrinkConstantPool(Constant[] constantPool, int length)
+ {
+ // Create a new index map, if necessary.
+ if (constantIndexMap == null ||
+ constantIndexMap.length < length)
+ {
+ constantIndexMap = new int[length];
+ }
+
+ int counter = 1;
+ boolean isUsed = false;
+
+ // Shift the used constant pool entries together.
+ for (int index = 1; index < length; index++)
+ {
+ constantIndexMap[index] = counter;
+
+ Constant constant = constantPool[index];
+
+ // Don't update the flag if this is the second half of a long entry.
+ if (constant != null)
+ {
+ isUsed = constant.getTag() != ClassConstants.CONSTANT_NameAndType ||
+ isUsed(constant);
+ }
+
+ if (isUsed)
+ {
+ constantPool[counter++] = constant;
+ }
+ }
+
+ // Clear the remaining constant pool elements.
+ Arrays.fill(constantPool, counter, length, null);
+
+ return counter;
+ }
}
diff --git a/src/proguard/classfile/editor/NamedAttributeDeleter.java b/src/proguard/classfile/editor/NamedAttributeDeleter.java
index 0c4d339..5ae950d 100644
--- a/src/proguard/classfile/editor/NamedAttributeDeleter.java
+++ b/src/proguard/classfile/editor/NamedAttributeDeleter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java
index 4cad6b8..c97e2c8 100644
--- a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java
+++ b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/StackSizeUpdater.java b/src/proguard/classfile/editor/StackSizeUpdater.java
index 94e0519..cc743b1 100644
--- a/src/proguard/classfile/editor/StackSizeUpdater.java
+++ b/src/proguard/classfile/editor/StackSizeUpdater.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/SubclassAdder.java b/src/proguard/classfile/editor/SubclassAdder.java
index 6b9fd64..f944ef8 100644
--- a/src/proguard/classfile/editor/SubclassAdder.java
+++ b/src/proguard/classfile/editor/SubclassAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/SubclassToAdder.java b/src/proguard/classfile/editor/SubclassToAdder.java
index deb242f..f4cdd70 100644
--- a/src/proguard/classfile/editor/SubclassToAdder.java
+++ b/src/proguard/classfile/editor/SubclassToAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/Utf8UsageMarker.java b/src/proguard/classfile/editor/Utf8Shrinker.java
index c59ebb8..b9dac44 100644
--- a/src/proguard/obfuscate/Utf8UsageMarker.java
+++ b/src/proguard/classfile/editor/Utf8Shrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -18,7 +18,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-package proguard.obfuscate;
+package proguard.classfile.editor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
@@ -28,18 +28,19 @@ import proguard.classfile.attribute.preverification.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.editor.ConstantPoolRemapper;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.*;
+import java.util.Arrays;
+
+
/**
- * This ClassVisitor marks all UTF-8 constant pool entries that are
- * being used in the program classes it visits.
- *
- * @see Utf8Shrinker
+ * This ClassVisitor removes UTF-8 constant pool entries that are not used.
*
* @author Eric Lafortune
*/
-public class Utf8UsageMarker
+public class Utf8Shrinker
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
@@ -54,6 +55,9 @@ implements ClassVisitor,
// A visitor info flag to indicate the UTF-8 constant pool entry is being used.
private static final Object USED = new Object();
+ private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
+ private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
+
// Implementations for ClassVisitor.
@@ -68,6 +72,22 @@ implements ClassVisitor,
// Mark the UTF-8 entries referenced by the attributes.
programClass.attributesAccept(this);
+
+ // Shift the used constant pool entries together, filling out the
+ // index map.
+ int newConstantPoolCount =
+ shrinkConstantPool(programClass.constantPool,
+ programClass.u2constantPoolCount);
+
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
+
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
}
@@ -375,7 +395,7 @@ implements ClassVisitor,
* Marks the given VisitorAccepter as being used.
* In this context, the VisitorAccepter will be a Utf8Constant object.
*/
- private static void markAsUsed(VisitorAccepter visitorAccepter)
+ private void markAsUsed(VisitorAccepter visitorAccepter)
{
visitorAccepter.setVisitorInfo(USED);
}
@@ -385,8 +405,51 @@ implements ClassVisitor,
* Returns whether the given VisitorAccepter has been marked as being used.
* In this context, the VisitorAccepter will be a Utf8Constant object.
*/
- static boolean isUsed(VisitorAccepter visitorAccepter)
+ private boolean isUsed(VisitorAccepter visitorAccepter)
{
return visitorAccepter.getVisitorInfo() == USED;
}
+
+
+ /**
+ * Removes all UTF-8 entries that are not marked as being used
+ * from the given constant pool.
+ * @return the new number of entries.
+ */
+ private int shrinkConstantPool(Constant[] constantPool, int length)
+ {
+ // Create a new index map, if necessary.
+ if (constantIndexMap.length < length)
+ {
+ constantIndexMap = new int[length];
+ }
+
+ int counter = 1;
+ boolean isUsed = false;
+
+ // Shift the used constant pool entries together.
+ for (int index = 1; index < length; index++)
+ {
+ constantIndexMap[index] = counter;
+
+ Constant constant = constantPool[index];
+
+ // Don't update the flag if this is the second half of a long entry.
+ if (constant != null)
+ {
+ isUsed = constant.getTag() != ClassConstants.CONSTANT_Utf8 ||
+ isUsed(constant);
+ }
+
+ if (isUsed)
+ {
+ constantPool[counter++] = constant;
+ }
+ }
+
+ // Clear the remaining constant pool elements.
+ Arrays.fill(constantPool, counter, length, null);
+
+ return counter;
+ }
}
diff --git a/src/proguard/classfile/editor/VariableCleaner.java b/src/proguard/classfile/editor/VariableCleaner.java
index 1e93c15..af51403 100644
--- a/src/proguard/classfile/editor/VariableCleaner.java
+++ b/src/proguard/classfile/editor/VariableCleaner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -22,15 +22,15 @@ package proguard.classfile.editor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
-import proguard.classfile.attribute.visitor.*;
-import proguard.classfile.instruction.*;
-import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.SimplifiedVisitor;
-import proguard.optimize.info.VariableUsageMarker;
+
+import java.util.Arrays;
/**
- * This AttributeVisitor cleans up unused variables in all attributes that it
- * visits.
+ * This AttributeVisitor cleans up variable tables in all code attributes that
+ * it visits. It trims overlapping local variables. It removes empty local
+ * variables and empty local variable tables.
*
* @author Eric Lafortune
*/
@@ -38,7 +38,8 @@ public class VariableCleaner
extends SimplifiedVisitor
implements AttributeVisitor
{
- private final VariableUsageMarker variableUsageMarker = new VariableUsageMarker();
+ private boolean deleteLocalVariableTableAttribute;
+ private boolean deleteLocalVariableTypeTableAttribute;
// Implementations for AttributeVisitor.
@@ -48,11 +49,35 @@ implements AttributeVisitor
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
- // Figure out the local variables that are used by the code.
- variableUsageMarker.visitCodeAttribute(clazz, method, codeAttribute);
+ deleteLocalVariableTableAttribute = false;
+ deleteLocalVariableTypeTableAttribute = false;
- // Clean up the variables of the attributes.
+ // Trim the local variable table and the local variable type table.
codeAttribute.attributesAccept(clazz, method, this);
+
+ // Delete the local variable table if it ended up empty.
+ if (deleteLocalVariableTableAttribute)
+ {
+ AttributesEditor editor =
+ new AttributesEditor((ProgramClass)clazz,
+ (ProgramMember)method,
+ codeAttribute,
+ true);
+
+ editor.deleteAttribute(ClassConstants.ATTR_LocalVariableTable);
+ }
+
+ // Delete the local variable type table if it ended up empty.
+ if (deleteLocalVariableTypeTableAttribute)
+ {
+ AttributesEditor editor =
+ new AttributesEditor((ProgramClass)clazz,
+ (ProgramMember)method,
+ codeAttribute,
+ true);
+
+ editor.deleteAttribute(ClassConstants.ATTR_LocalVariableTypeTable);
+ }
}
@@ -60,9 +85,20 @@ implements AttributeVisitor
{
// Clean up local variables that aren't used.
localVariableTableAttribute.u2localVariableTableLength =
- removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable,
- localVariableTableAttribute.u2localVariableTableLength,
- codeAttribute.u2maxLocals);
+ removeUnusedLocalVariables(localVariableTableAttribute.localVariableTable,
+ localVariableTableAttribute.u2localVariableTableLength,
+ codeAttribute.u2maxLocals);
+
+ // Trim the code blocks of the local variables.
+ trimLocalVariables(localVariableTableAttribute.localVariableTable,
+ localVariableTableAttribute.u2localVariableTableLength,
+ codeAttribute.u2maxLocals);
+
+ // Delete the attribute in a moment, if it is empty.
+ if (localVariableTableAttribute.u2localVariableTableLength == 0)
+ {
+ deleteLocalVariableTableAttribute = true;
+ }
}
@@ -70,9 +106,20 @@ implements AttributeVisitor
{
// Clean up local variables that aren't used.
localVariableTypeTableAttribute.u2localVariableTypeTableLength =
- removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
- localVariableTypeTableAttribute.u2localVariableTypeTableLength,
- codeAttribute.u2maxLocals);
+ removeUnusedLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
+ localVariableTypeTableAttribute.u2localVariableTypeTableLength,
+ codeAttribute.u2maxLocals);
+
+ // Trim the code blocks of the local variables.
+ trimLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
+ localVariableTypeTableAttribute.u2localVariableTypeTableLength,
+ codeAttribute.u2maxLocals);
+
+ // Delete the attribute in a moment, if it is empty.
+ if (localVariableTypeTableAttribute.u2localVariableTypeTableLength == 0)
+ {
+ deleteLocalVariableTypeTableAttribute = true;
+ }
}
@@ -80,27 +127,28 @@ implements AttributeVisitor
/**
* Returns the given list of local variables, without the ones that aren't
- * used
+ * used.
*/
- private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos,
- int localVariableInfoCount,
- int maxLocals)
+ private int removeUnusedLocalVariables(LocalVariableInfo[] localVariableInfos,
+ int localVariableInfoCount,
+ int maxLocals)
{
// Overwrite all empty local variable entries.
int newIndex = 0;
- for (int index = 0; index < localVariableInfoCount && index < maxLocals; index++)
+ for (int index = 0; index < localVariableInfoCount; index++)
{
- if (variableUsageMarker.isVariableUsed(index))
+ LocalVariableInfo localVariableInfo = localVariableInfos[index];
+
+ if (localVariableInfo.u2index >= 0 &&
+ localVariableInfo.u2index < maxLocals &&
+ localVariableInfo.u2length > 0)
{
localVariableInfos[newIndex++] = localVariableInfos[index];
}
}
// Clean up any remaining array elements.
- for (int index = newIndex; index < localVariableInfoCount; index++)
- {
- localVariableInfos[index] = null;
- }
+ Arrays.fill(localVariableInfos, newIndex, localVariableInfoCount, null);
return newIndex;
}
@@ -108,28 +156,112 @@ implements AttributeVisitor
/**
* Returns the given list of local variable types, without the ones that
- * aren't used
+ * aren't used.
*/
- private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
- int localVariableTypeInfoCount,
- int maxLocals)
+ private int removeUnusedLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
+ int localVariableTypeInfoCount,
+ int maxLocals)
{
// Overwrite all empty local variable type entries.
int newIndex = 0;
- for (int index = 0; index < localVariableTypeInfoCount && index < maxLocals; index++)
+ for (int index = 0; index < localVariableTypeInfoCount; index++)
{
- if (variableUsageMarker.isVariableUsed(index))
+ LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];
+
+ if (localVariableTypeInfo.u2index >= 0 &&
+ localVariableTypeInfo.u2index < maxLocals &&
+ localVariableTypeInfo.u2length > 0)
{
localVariableTypeInfos[newIndex++] = localVariableTypeInfos[index];
}
}
// Clean up any remaining array elements.
- for (int index = newIndex; index < localVariableTypeInfoCount; index++)
+ Arrays.fill(localVariableTypeInfos, newIndex, localVariableTypeInfoCount, null);
+
+ return newIndex;
+ }
+
+
+ /**
+ * Sorts the given list of local variables and trims their code blocks
+ * when necessary. The block is trimmed at the end, which is a bit
+ * arbitrary.
+ */
+ private void trimLocalVariables(LocalVariableInfo[] localVariableInfos,
+ int localVariableInfoCount,
+ int maxLocals)
+ {
+ // Sort the local variable entries.
+ Arrays.sort(localVariableInfos, 0, localVariableInfoCount);
+
+ int[] startPCs = createMaxArray(maxLocals);
+
+ // Trim the local variable entries, starting at the last one.
+ for (int index = localVariableInfoCount-1; index >= 0; index--)
{
- localVariableTypeInfos[index] = null;
+ LocalVariableInfo localVariableInfo = localVariableInfos[index];
+
+ // Make sure the variable's code block doesn't overlap with the
+ // next one for the same variable.
+ int maxLength = startPCs[localVariableInfo.u2index] -
+ localVariableInfo.u2startPC;
+
+ if (localVariableInfo.u2length > maxLength)
+ {
+ localVariableInfo.u2length = maxLength;
+ }
+
+ startPCs[localVariableInfo.u2index] = localVariableInfo.u2startPC;
}
+ }
- return newIndex;
+
+ /**
+ * Sorts the given list of local variable types and trims their code blocks
+ * when necessary. The block is trimmed at the end, which is a bit
+ * arbitrary.
+ */
+ private void trimLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
+ int localVariableTypeInfoCount,
+ int maxLocals)
+ {
+ // Sort the local variable entries.
+ Arrays.sort(localVariableTypeInfos, 0, localVariableTypeInfoCount);
+
+ int[] startPCs = createMaxArray(maxLocals);
+
+ // Trim the local variable entries, starting at the last one.
+ for (int index = localVariableTypeInfoCount-1; index >= 0; index--)
+ {
+ LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];
+
+ // Make sure the variable's code block doesn't overlap with the
+ // next one for the same variable.
+ int maxLength = startPCs[localVariableTypeInfo.u2index] -
+ localVariableTypeInfo.u2startPC;
+
+ if (localVariableTypeInfo.u2length > maxLength)
+ {
+ localVariableTypeInfo.u2length = maxLength;
+ }
+
+ startPCs[localVariableTypeInfo.u2index] = localVariableTypeInfo.u2startPC;
+ }
+ }
+
+
+ /**
+ * Creates an integer array of the given length, initialized with
+ * Integer.MAX_VALUE.
+ */
+ private int[] createMaxArray(int length)
+ {
+ int[] startPCs = new int[length];
+ for (int index = 0; index < length; index++)
+ {
+ startPCs[index] = Integer.MAX_VALUE;
+ }
+ return startPCs;
}
} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/VariableEditor.java b/src/proguard/classfile/editor/VariableEditor.java
index a583b49..8c99ff8 100644
--- a/src/proguard/classfile/editor/VariableEditor.java
+++ b/src/proguard/classfile/editor/VariableEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -25,6 +25,8 @@ import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor accumulates specified changes to local variables, and
* then applies these accumulated changes to the code attributes that it visits.
@@ -53,14 +55,13 @@ implements AttributeVisitor
// Try to reuse the previous array.
if (deleted.length < maxLocals)
{
+ // Create a new array.
deleted = new boolean[maxLocals];
}
else
{
- for (int index = 0; index < maxLocals; index++)
- {
- deleted[index] = false;
- }
+ // Reset the array.
+ Arrays.fill(deleted, 0, maxLocals, false);
}
modified = false;
diff --git a/src/proguard/classfile/editor/VariableRemapper.java b/src/proguard/classfile/editor/VariableRemapper.java
index 590cd4e..df26534 100644
--- a/src/proguard/classfile/editor/VariableRemapper.java
+++ b/src/proguard/classfile/editor/VariableRemapper.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -40,6 +40,9 @@ implements AttributeVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor
{
+ private static final boolean DEBUG = false;
+
+
private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor();
private int[] variableMap;
@@ -62,6 +65,19 @@ implements AttributeVisitor,
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
+ if (DEBUG)
+ {
+ System.out.println("VariableRemapper: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
+ for (int index= 0; index < codeAttribute.u2maxLocals; index++)
+ {
+ System.out.println(" v"+index+" -> "+variableMap[index]);
+ }
+ }
+
+ // Remap the variables of the attributes, before editing the code and
+ // cleaning up its local variable frame.
+ codeAttribute.attributesAccept(clazz, method, this);
+
// Initially, the code attribute editor doesn't contain any changes.
codeAttributeEditor.reset(codeAttribute.u4codeLength);
@@ -70,9 +86,6 @@ implements AttributeVisitor,
// Apply the code atribute editor.
codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);
-
- // Remap the variables of the attributes.
- codeAttribute.attributesAccept(clazz, method, this);
}
@@ -80,11 +93,6 @@ implements AttributeVisitor,
{
// Remap the variable references of the local variables.
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
-
- // Remove local variables that haven't been mapped.
- localVariableTableAttribute.u2localVariableTableLength =
- removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable,
- localVariableTableAttribute.u2localVariableTableLength);
}
@@ -92,11 +100,6 @@ implements AttributeVisitor,
{
// Remap the variable references of the local variables.
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
-
- // Remove local variables that haven't been mapped.
- localVariableTypeTableAttribute.u2localVariableTypeTableLength =
- removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
- localVariableTypeTableAttribute.u2localVariableTypeTableLength);
}
@@ -150,48 +153,4 @@ implements AttributeVisitor,
{
return variableMap[variableIndex];
}
-
-
- /**
- * Returns the given list of local variables, without the ones that have
- * been removed.
- */
- private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos,
- int localVariableInfoCount)
- {
- // Overwrite all empty local variable entries.
- int newIndex = 0;
- for (int index = 0; index < localVariableInfoCount; index++)
- {
- LocalVariableInfo localVariableInfo = localVariableInfos[index];
- if (localVariableInfo.u2index >= 0)
- {
- localVariableInfos[newIndex++] = localVariableInfo;
- }
- }
-
- return newIndex;
- }
-
-
- /**
- * Returns the given list of local variable types, without the ones that
- * have been removed.
- */
- private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
- int localVariableTypeInfoCount)
- {
- // Overwrite all empty local variable type entries.
- int newIndex = 0;
- for (int index = 0; index < localVariableTypeInfoCount; index++)
- {
- LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];
- if (localVariableTypeInfo.u2index >= 0)
- {
- localVariableTypeInfos[newIndex++] = localVariableTypeInfo;
- }
- }
-
- return newIndex;
- }
}
diff --git a/src/proguard/classfile/editor/VariableSizeUpdater.java b/src/proguard/classfile/editor/VariableSizeUpdater.java
index 18958c5..bb87151 100644
--- a/src/proguard/classfile/editor/VariableSizeUpdater.java
+++ b/src/proguard/classfile/editor/VariableSizeUpdater.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -29,7 +29,8 @@ import proguard.classfile.util.*;
/**
* This AttributeVisitor computes and updates the maximum local variable frame
- * size of the code attributes that it visits.
+ * size of the code attributes that it visits. It also cleans up the local
+ * variable tables.
*
* @author Eric Lafortune
*/
@@ -45,6 +46,9 @@ implements AttributeVisitor,
//*/
+ private VariableCleaner variableCleaner = new VariableCleaner();
+
+
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
@@ -69,6 +73,9 @@ implements AttributeVisitor,
// Go over all instructions.
codeAttribute.instructionsAccept(clazz, method, this);
+
+ // Remove the unused variables of the attributes.
+ variableCleaner.visitCodeAttribute(clazz, method, codeAttribute);
}
@@ -91,7 +98,7 @@ implements AttributeVisitor,
if (DEBUG)
{
- System.out.println("Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset));
+ System.out.println(" Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset));
}
}
}
diff --git a/src/proguard/classfile/instruction/BranchInstruction.java b/src/proguard/classfile/instruction/BranchInstruction.java
index 2baa917..54f583b 100644
--- a/src/proguard/classfile/instruction/BranchInstruction.java
+++ b/src/proguard/classfile/instruction/BranchInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/ConstantInstruction.java b/src/proguard/classfile/instruction/ConstantInstruction.java
index 6c2d1a3..900a8d5 100644
--- a/src/proguard/classfile/instruction/ConstantInstruction.java
+++ b/src/proguard/classfile/instruction/ConstantInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -93,13 +93,9 @@ implements ConstantVisitor
public byte canonicalOpcode()
{
// Remove the _w extension, if any.
- switch (opcode)
- {
- case InstructionConstants.OP_LDC_W:
- case InstructionConstants.OP_LDC2_W: return InstructionConstants.OP_LDC;
-
- default: return opcode;
- }
+ return
+ opcode == InstructionConstants.OP_LDC_W ? InstructionConstants.OP_LDC :
+ opcode;
}
public Instruction shrink()
@@ -185,7 +181,8 @@ implements ConstantVisitor
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
- // The some parameters may be popped from the stack.
+ case InstructionConstants.OP_INVOKEDYNAMIC:
+ // Some parameters may be popped from the stack.
clazz.constantPoolEntryAccept(constantIndex, this);
stackPopCount += parameterStackDelta;
break;
@@ -208,6 +205,7 @@ implements ConstantVisitor
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
// The field value or a return value may be pushed onto the stack.
clazz.constantPoolEntryAccept(constantIndex, this);
stackPushCount += typeStackDelta;
@@ -226,8 +224,9 @@ implements ConstantVisitor
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) {}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant) {}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) {}
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) {}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant) {}
- public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) {}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) {}
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
@@ -238,21 +237,27 @@ implements ConstantVisitor
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this);
+ }
+
+
public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
{
- visitRefConstant(clazz, interfaceMethodrefConstant);
+ clazz.constantPoolEntryAccept(interfaceMethodrefConstant.u2nameAndTypeIndex, this);
}
public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
{
- visitRefConstant(clazz, methodrefConstant);
+ clazz.constantPoolEntryAccept(methodrefConstant.u2nameAndTypeIndex, this);
}
- private void visitRefConstant(Clazz clazz, RefConstant methodrefConstant)
+ public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
- String type = methodrefConstant.getType(clazz);
+ String type = nameAndTypeConstant.getType(clazz);
parameterStackDelta = ClassUtil.internalMethodParameterSize(type);
typeStackDelta = ClassUtil.internalTypeSize(ClassUtil.internalMethodReturnType(type));
@@ -285,6 +290,7 @@ implements ConstantVisitor
private int constantSize()
{
return opcode == InstructionConstants.OP_MULTIANEWARRAY ? 1 :
+ opcode == InstructionConstants.OP_INVOKEDYNAMIC ||
opcode == InstructionConstants.OP_INVOKEINTERFACE ? 2 :
0;
}
diff --git a/src/proguard/classfile/instruction/Instruction.java b/src/proguard/classfile/instruction/Instruction.java
index 8437495..77b0e20 100644
--- a/src/proguard/classfile/instruction/Instruction.java
+++ b/src/proguard/classfile/instruction/Instruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -220,7 +220,7 @@ public abstract class Instruction
false, // invokespecial
false, // invokestatic
false, // invokeinterface
- false, // unused
+ false, // invokedynamic
false, // new
false, // newarray
false, // anewarray
@@ -429,7 +429,7 @@ public abstract class Instruction
1, // invokespecial
0, // invokestatic
1, // invokeinterface
- 0, // unused
+ 0, // invokedynamic
0, // new
1, // newarray
1, // anewarray
@@ -638,7 +638,7 @@ public abstract class Instruction
0, // invokespecial
0, // invokestatic
0, // invokeinterface
- 0, // unused
+ 0, // invokedynamic
1, // new
1, // newarray
1, // anewarray
diff --git a/src/proguard/classfile/instruction/InstructionConstants.java b/src/proguard/classfile/instruction/InstructionConstants.java
index 78730b3..8ca03cc 100644
--- a/src/proguard/classfile/instruction/InstructionConstants.java
+++ b/src/proguard/classfile/instruction/InstructionConstants.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -213,22 +213,22 @@ public interface InstructionConstants
public static final byte OP_INVOKESPECIAL = -73;
public static final byte OP_INVOKESTATIC = -72;
public static final byte OP_INVOKEINTERFACE = -71;
-// public static final byte OP_UNUSED = -70;
- public static final byte OP_NEW = -69;
- public static final byte OP_NEWARRAY = -68;
- public static final byte OP_ANEWARRAY = -67;
- public static final byte OP_ARRAYLENGTH = -66;
- public static final byte OP_ATHROW = -65;
- public static final byte OP_CHECKCAST = -64;
- public static final byte OP_INSTANCEOF = -63;
- public static final byte OP_MONITORENTER = -62;
- public static final byte OP_MONITOREXIT = -61;
- public static final byte OP_WIDE = -60;
- public static final byte OP_MULTIANEWARRAY = -59;
- public static final byte OP_IFNULL = -58;
- public static final byte OP_IFNONNULL = -57;
- public static final byte OP_GOTO_W = -56;
- public static final byte OP_JSR_W = -55;
+ public static final byte OP_INVOKEDYNAMIC = -70;
+ public static final byte OP_NEW = -69;
+ public static final byte OP_NEWARRAY = -68;
+ public static final byte OP_ANEWARRAY = -67;
+ public static final byte OP_ARRAYLENGTH = -66;
+ public static final byte OP_ATHROW = -65;
+ public static final byte OP_CHECKCAST = -64;
+ public static final byte OP_INSTANCEOF = -63;
+ public static final byte OP_MONITORENTER = -62;
+ public static final byte OP_MONITOREXIT = -61;
+ public static final byte OP_WIDE = -60;
+ public static final byte OP_MULTIANEWARRAY = -59;
+ public static final byte OP_IFNULL = -58;
+ public static final byte OP_IFNONNULL = -57;
+ public static final byte OP_GOTO_W = -56;
+ public static final byte OP_JSR_W = -55;
public static final String[] NAMES =
@@ -419,7 +419,7 @@ public interface InstructionConstants
"invokespecial",
"invokestatic",
"invokeinterface",
- "unused",
+ "invokedynamic",
"new",
"newarray",
"anewarray",
diff --git a/src/proguard/classfile/instruction/InstructionFactory.java b/src/proguard/classfile/instruction/InstructionFactory.java
index f898471..288acc2 100644
--- a/src/proguard/classfile/instruction/InstructionFactory.java
+++ b/src/proguard/classfile/instruction/InstructionFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -182,6 +182,7 @@ public class InstructionFactory
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
case InstructionConstants.OP_NEW:
case InstructionConstants.OP_ANEWARRAY:
diff --git a/src/proguard/classfile/instruction/InstructionUtil.java b/src/proguard/classfile/instruction/InstructionUtil.java
index a3a328a..12d4d05 100644
--- a/src/proguard/classfile/instruction/InstructionUtil.java
+++ b/src/proguard/classfile/instruction/InstructionUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/LookUpSwitchInstruction.java b/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
index 178cce5..2da639b 100644
--- a/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
+++ b/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/SimpleInstruction.java b/src/proguard/classfile/instruction/SimpleInstruction.java
index 84e6344..83499dc 100644
--- a/src/proguard/classfile/instruction/SimpleInstruction.java
+++ b/src/proguard/classfile/instruction/SimpleInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/SwitchInstruction.java b/src/proguard/classfile/instruction/SwitchInstruction.java
index b98c2fb..11f05c4 100644
--- a/src/proguard/classfile/instruction/SwitchInstruction.java
+++ b/src/proguard/classfile/instruction/SwitchInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/TableSwitchInstruction.java b/src/proguard/classfile/instruction/TableSwitchInstruction.java
index ee81af5..a5e8c5e 100644
--- a/src/proguard/classfile/instruction/TableSwitchInstruction.java
+++ b/src/proguard/classfile/instruction/TableSwitchInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/VariableInstruction.java b/src/proguard/classfile/instruction/VariableInstruction.java
index 309f802..6cbd3de 100644
--- a/src/proguard/classfile/instruction/VariableInstruction.java
+++ b/src/proguard/classfile/instruction/VariableInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java b/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java
index 71b2cde..c355433 100644
--- a/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java
+++ b/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/visitor/InstructionCounter.java b/src/proguard/classfile/instruction/visitor/InstructionCounter.java
index 1d10980..64c0f65 100644
--- a/src/proguard/classfile/instruction/visitor/InstructionCounter.java
+++ b/src/proguard/classfile/instruction/visitor/InstructionCounter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/visitor/InstructionVisitor.java b/src/proguard/classfile/instruction/visitor/InstructionVisitor.java
index 11af131..d7d1b24 100644
--- a/src/proguard/classfile/instruction/visitor/InstructionVisitor.java
+++ b/src/proguard/classfile/instruction/visitor/InstructionVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java b/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java
index aada455..160ccd7 100644
--- a/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java
+++ b/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/io/LibraryClassReader.java b/src/proguard/classfile/io/LibraryClassReader.java
index f14471c..32bb569 100644
--- a/src/proguard/classfile/io/LibraryClassReader.java
+++ b/src/proguard/classfile/io/LibraryClassReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -277,6 +277,18 @@ implements ClassVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ dataInput.skipBytes(4);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ dataInput.skipBytes(3);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
dataInput.skipBytes(4);
@@ -289,6 +301,12 @@ implements ClassVisitor,
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ dataInput.skipBytes(2);
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
dataInput.skipBytes(4);
@@ -325,16 +343,19 @@ implements ClassVisitor,
switch (u1tag)
{
- case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
case ClassConstants.CONSTANT_Integer: return new IntegerConstant();
case ClassConstants.CONSTANT_Float: return new FloatConstant();
case ClassConstants.CONSTANT_Long: return new LongConstant();
case ClassConstants.CONSTANT_Double: return new DoubleConstant();
case ClassConstants.CONSTANT_String: return new StringConstant();
+ case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
+ case ClassConstants.CONSTANT_InvokeDynamic: return new InvokeDynamicConstant();
+ case ClassConstants.CONSTANT_MethodHandle: return new MethodHandleConstant();
case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant();
case ClassConstants.CONSTANT_Methodref: return new MethodrefConstant();
case ClassConstants.CONSTANT_InterfaceMethodref: return new InterfaceMethodrefConstant();
case ClassConstants.CONSTANT_Class: return new ClassConstant();
+ case ClassConstants.CONSTANT_MethodType : return new MethodTypeConstant();
case ClassConstants.CONSTANT_NameAndType: return new NameAndTypeConstant();
default: throw new RuntimeException("Unknown constant type ["+u1tag+"] in constant pool");
diff --git a/src/proguard/classfile/io/ProgramClassReader.java b/src/proguard/classfile/io/ProgramClassReader.java
index 476a346..01f057f 100644
--- a/src/proguard/classfile/io/ProgramClassReader.java
+++ b/src/proguard/classfile/io/ProgramClassReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -46,6 +46,7 @@ implements ClassVisitor,
MemberVisitor,
ConstantVisitor,
AttributeVisitor,
+ BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
@@ -250,6 +251,20 @@ implements ClassVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ invokeDynamicConstant.u2bootstrapMethodAttributeIndex = dataInput.readUnsignedShort();
+ invokeDynamicConstant.u2nameAndTypeIndex = dataInput.readUnsignedShort();
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ methodHandleConstant.u1referenceKind = dataInput.readUnsignedByte();
+ methodHandleConstant.u2referenceIndex = dataInput.readUnsignedShort();
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
refConstant.u2classIndex = dataInput.readUnsignedShort();
@@ -263,6 +278,12 @@ implements ClassVisitor,
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ methodTypeConstant.u2descriptorIndex = dataInput.readUnsignedShort();
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
nameAndTypeConstant.u2nameIndex = dataInput.readUnsignedShort();
@@ -281,6 +302,21 @@ implements ClassVisitor,
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Read the bootstrap methods.
+ bootstrapMethodsAttribute.u2bootstrapMethodsCount = dataInput.readUnsignedShort();
+
+ bootstrapMethodsAttribute.bootstrapMethods = new BootstrapMethodInfo[bootstrapMethodsAttribute.u2bootstrapMethodsCount];
+ for (int index = 0; index < bootstrapMethodsAttribute.u2bootstrapMethodsCount; index++)
+ {
+ BootstrapMethodInfo bootstrapMethodInfo = new BootstrapMethodInfo();
+ visitBootstrapMethodInfo(clazz, bootstrapMethodInfo);
+ bootstrapMethodsAttribute.bootstrapMethods[index] = bootstrapMethodInfo;
+ }
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
sourceFileAttribute.u2sourceFileIndex = dataInput.readUnsignedShort();
@@ -302,7 +338,7 @@ implements ClassVisitor,
for (int index = 0; index < innerClassesAttribute.u2classesCount; index++)
{
InnerClassesInfo innerClassesInfo = new InnerClassesInfo();
- this.visitInnerClassesInfo(clazz, innerClassesInfo);
+ visitInnerClassesInfo(clazz, innerClassesInfo);
innerClassesAttribute.classes[index] = innerClassesInfo;
}
}
@@ -372,7 +408,7 @@ implements ClassVisitor,
for (int index = 0; index < codeAttribute.u2exceptionTableLength; index++)
{
ExceptionInfo exceptionInfo = new ExceptionInfo();
- this.visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
+ visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
codeAttribute.exceptionTable[index] = exceptionInfo;
}
@@ -398,7 +434,7 @@ implements ClassVisitor,
for (int index = 0; index < stackMapAttribute.u2stackMapFramesCount; index++)
{
FullFrame stackMapFrame = new FullFrame();
- this.visitFullFrame(clazz, method, codeAttribute, index, stackMapFrame);
+ visitFullFrame(clazz, method, codeAttribute, index, stackMapFrame);
stackMapAttribute.stackMapFrames[index] = stackMapFrame;
}
}
@@ -428,7 +464,7 @@ implements ClassVisitor,
for (int index = 0; index < lineNumberTableAttribute.u2lineNumberTableLength; index++)
{
LineNumberInfo lineNumberInfo = new LineNumberInfo();
- this.visitLineNumberInfo(clazz, method, codeAttribute, lineNumberInfo);
+ visitLineNumberInfo(clazz, method, codeAttribute, lineNumberInfo);
lineNumberTableAttribute.lineNumberTable[index] = lineNumberInfo;
}
}
@@ -443,7 +479,7 @@ implements ClassVisitor,
for (int index = 0; index < localVariableTableAttribute.u2localVariableTableLength; index++)
{
LocalVariableInfo localVariableInfo = new LocalVariableInfo();
- this.visitLocalVariableInfo(clazz, method, codeAttribute, localVariableInfo);
+ visitLocalVariableInfo(clazz, method, codeAttribute, localVariableInfo);
localVariableTableAttribute.localVariableTable[index] = localVariableInfo;
}
}
@@ -458,7 +494,7 @@ implements ClassVisitor,
for (int index = 0; index < localVariableTypeTableAttribute.u2localVariableTypeTableLength; index++)
{
LocalVariableTypeInfo localVariableTypeInfo = new LocalVariableTypeInfo();
- this.visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeInfo);
+ visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeInfo);
localVariableTypeTableAttribute.localVariableTypeTable[index] = localVariableTypeInfo;
}
}
@@ -473,7 +509,7 @@ implements ClassVisitor,
for (int index = 0; index < annotationsAttribute.u2annotationsCount; index++)
{
Annotation annotation = new Annotation();
- this.visitAnnotation(clazz, annotation);
+ visitAnnotation(clazz, annotation);
annotationsAttribute.annotations[index] = annotation;
}
}
@@ -508,7 +544,7 @@ implements ClassVisitor,
for (int index = 0; index < u2annotationsCount; index++)
{
Annotation annotation = new Annotation();
- this.visitAnnotation(clazz, annotation);
+ visitAnnotation(clazz, annotation);
annotations[index] = annotation;
}
@@ -527,6 +563,22 @@ implements ClassVisitor,
}
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ bootstrapMethodInfo.u2methodHandleIndex = dataInput.readUnsignedShort();
+
+ // Read the bootstrap method arguments.
+ bootstrapMethodInfo.u2methodArgumentCount = dataInput.readUnsignedShort();
+ bootstrapMethodInfo.u2methodArguments = new int[bootstrapMethodInfo.u2methodArgumentCount];
+ for (int index = 0; index < bootstrapMethodInfo.u2methodArgumentCount; index++)
+ {
+ bootstrapMethodInfo.u2methodArguments[index] = dataInput.readUnsignedShort();
+ }
+ }
+
+
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
@@ -721,7 +773,7 @@ implements ClassVisitor,
{
// Read the annotation.
Annotation annotationValue = new Annotation();
- this.visitAnnotation(clazz, annotationValue);
+ visitAnnotation(clazz, annotationValue);
annotationElementValue.annotationValue = annotationValue;
}
@@ -749,16 +801,19 @@ implements ClassVisitor,
switch (u1tag)
{
- case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
case ClassConstants.CONSTANT_Integer: return new IntegerConstant();
case ClassConstants.CONSTANT_Float: return new FloatConstant();
case ClassConstants.CONSTANT_Long: return new LongConstant();
case ClassConstants.CONSTANT_Double: return new DoubleConstant();
case ClassConstants.CONSTANT_String: return new StringConstant();
+ case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
+ case ClassConstants.CONSTANT_InvokeDynamic: return new InvokeDynamicConstant();
+ case ClassConstants.CONSTANT_MethodHandle: return new MethodHandleConstant();
case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant();
case ClassConstants.CONSTANT_Methodref: return new MethodrefConstant();
case ClassConstants.CONSTANT_InterfaceMethodref: return new InterfaceMethodrefConstant();
case ClassConstants.CONSTANT_Class: return new ClassConstant();
+ case ClassConstants.CONSTANT_MethodType : return new MethodTypeConstant();
case ClassConstants.CONSTANT_NameAndType: return new NameAndTypeConstant();
default: throw new RuntimeException("Unknown constant type ["+u1tag+"] in constant pool");
@@ -771,7 +826,9 @@ implements ClassVisitor,
int u2attributeNameIndex = dataInput.readUnsignedShort();
int u4attributeLength = dataInput.readInt();
String attributeName = clazz.getString(u2attributeNameIndex);
+
Attribute attribute =
+ attributeName.equals(ClassConstants.ATTR_BootstrapMethods) ? (Attribute)new BootstrapMethodsAttribute():
attributeName.equals(ClassConstants.ATTR_SourceFile) ? (Attribute)new SourceFileAttribute():
attributeName.equals(ClassConstants.ATTR_SourceDir) ? (Attribute)new SourceDirAttribute():
attributeName.equals(ClassConstants.ATTR_InnerClasses) ? (Attribute)new InnerClassesAttribute():
diff --git a/src/proguard/classfile/io/ProgramClassWriter.java b/src/proguard/classfile/io/ProgramClassWriter.java
index e56f08a..53995d4 100644
--- a/src/proguard/classfile/io/ProgramClassWriter.java
+++ b/src/proguard/classfile/io/ProgramClassWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -57,7 +57,7 @@ implements ClassVisitor,
/**
- * Creates a new ProgramClassWriter for reading from the given DataOutput.
+ * Creates a new ProgramClassWriter for writing to the given DataOutput.
*/
public ProgramClassWriter(DataOutput dataOutput)
{
@@ -208,6 +208,20 @@ implements ClassVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ dataOutput.writeShort(invokeDynamicConstant.u2bootstrapMethodAttributeIndex);
+ dataOutput.writeShort(invokeDynamicConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ dataOutput.writeByte(methodHandleConstant.u1referenceKind);
+ dataOutput.writeShort(methodHandleConstant.u2referenceIndex);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
dataOutput.writeShort(refConstant.u2classIndex);
@@ -221,6 +235,12 @@ implements ClassVisitor,
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ dataOutput.writeShort(methodTypeConstant.u2descriptorIndex);
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
dataOutput.writeShort(nameAndTypeConstant.u2nameIndex);
@@ -263,6 +283,7 @@ implements ClassVisitor,
private class AttributeBodyWriter
extends SimplifiedVisitor
implements AttributeVisitor,
+ BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
@@ -282,6 +303,15 @@ implements ClassVisitor,
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Write the bootstrap methods.
+ dataOutput.writeShort(bootstrapMethodsAttribute.u2bootstrapMethodsCount);
+
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
dataOutput.writeShort(sourceFileAttribute.u2sourceFileIndex);
@@ -438,8 +468,7 @@ implements ClassVisitor,
for (int index = 0; index < u2annotationsCount; index++)
{
- Annotation annotation = annotations[index];
- this.visitAnnotation(clazz, annotation);
+ visitAnnotation(clazz, annotations[index]);
}
}
@@ -453,6 +482,22 @@ implements ClassVisitor,
}
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ dataOutput.writeShort(bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Write the bootstrap method arguments.
+ dataOutput.writeShort(bootstrapMethodInfo.u2methodArgumentCount);
+
+ for (int index = 0; index < bootstrapMethodInfo.u2methodArgumentCount; index++)
+ {
+ dataOutput.writeShort(bootstrapMethodInfo.u2methodArguments[index]);
+ }
+ }
+
+
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
diff --git a/src/proguard/classfile/io/RuntimeDataInput.java b/src/proguard/classfile/io/RuntimeDataInput.java
index 104b7c9..7225ec9 100644
--- a/src/proguard/classfile/io/RuntimeDataInput.java
+++ b/src/proguard/classfile/io/RuntimeDataInput.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/io/RuntimeDataOutput.java b/src/proguard/classfile/io/RuntimeDataOutput.java
index ffde3af..75d0642 100644
--- a/src/proguard/classfile/io/RuntimeDataOutput.java
+++ b/src/proguard/classfile/io/RuntimeDataOutput.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/AccessUtil.java b/src/proguard/classfile/util/AccessUtil.java
index 3ad6961..068a89e 100644
--- a/src/proguard/classfile/util/AccessUtil.java
+++ b/src/proguard/classfile/util/AccessUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/ClassReferenceInitializer.java b/src/proguard/classfile/util/ClassReferenceInitializer.java
index b1f2c27..e7709ab 100644
--- a/src/proguard/classfile/util/ClassReferenceInitializer.java
+++ b/src/proguard/classfile/util/ClassReferenceInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -166,17 +166,30 @@ implements ClassVisitor,
}
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Fill out the MethodHandle class.
+ methodHandleConstant.javaLangInvokeMethodHandleClass =
+ findClass(clazz.getName(), ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
String className = refConstant.getClassName(clazz);
+ // Methods for array types should be found in the Object class.
+ if (ClassUtil.isInternalArrayType(className))
+ {
+ className = ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT;
+ }
+
// See if we can find the referenced class.
// Unresolved references are assumed to refer to library classes
// that will not change anyway.
Clazz referencedClass = findClass(clazz.getName(), className);
- if (referencedClass != null &&
- !ClassUtil.isInternalArrayType(className))
+ if (referencedClass != null)
{
String name = refConstant.getName(clazz);
String type = refConstant.getType(clazz);
@@ -194,7 +207,7 @@ implements ClassVisitor,
if (refConstant.referencedMember == null)
{
- // We've haven't found the class member anywhere in the hierarchy.
+ // We haven't found the class member anywhere in the hierarchy.
missingMemberWarningPrinter.print(clazz.getName(),
className,
"Warning: " +
@@ -216,7 +229,7 @@ implements ClassVisitor,
// Fill out the referenced class.
classConstant.referencedClass =
- findClass(className, classConstant.getName(clazz));
+ findClass(className, ClassUtil.internalClassNameFromClassType(classConstant.getName(clazz)));
// Fill out the Class class.
classConstant.javaLangClassClass =
@@ -224,6 +237,14 @@ implements ClassVisitor,
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ // Fill out the MethodType class.
+ methodTypeConstant.javaLangInvokeMethodTypeClass =
+ findClass(clazz.getName(), ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE);
+ }
+
+
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
@@ -235,49 +256,36 @@ implements ClassVisitor,
String enclosingClassName = enclosingMethodAttribute.getClassName(clazz);
// See if we can find the referenced class.
- Clazz referencedClass = findClass(className, enclosingClassName);
+ enclosingMethodAttribute.referencedClass =
+ findClass(className, enclosingClassName);
- if (referencedClass == null)
+ if (enclosingMethodAttribute.referencedClass != null)
{
- // We couldn't find the enclosing class.
- missingClassWarningPrinter.print(className,
- enclosingClassName,
- "Warning: " +
- ClassUtil.externalClassName(className) +
- ": can't find enclosing class " +
- ClassUtil.externalClassName(enclosingClassName));
- return;
- }
-
- // Make sure there is actually an enclosed method.
- if (enclosingMethodAttribute.u2nameAndTypeIndex == 0)
- {
- return;
- }
-
- String name = enclosingMethodAttribute.getName(clazz);
- String type = enclosingMethodAttribute.getType(clazz);
+ // Is there an enclosing method? Otherwise it's just initialization
+ // code outside of the constructors.
+ if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
+ {
+ String name = enclosingMethodAttribute.getName(clazz);
+ String type = enclosingMethodAttribute.getType(clazz);
- // See if we can find the method in the referenced class.
- Method referencedMethod = referencedClass.findMethod(name, type);
+ // See if we can find the method in the referenced class.
+ enclosingMethodAttribute.referencedMethod =
+ enclosingMethodAttribute.referencedClass.findMethod(name, type);
- if (referencedMethod == null)
- {
- // We couldn't find the enclosing method.
- missingMemberWarningPrinter.print(className,
- enclosingClassName,
- "Warning: " +
- ClassUtil.externalClassName(className) +
- ": can't find enclosing method '" +
- ClassUtil.externalFullMethodDescription(enclosingClassName, 0, name, type) +
- "' in class " +
- ClassUtil.externalClassName(enclosingClassName));
- return;
+ if (enclosingMethodAttribute.referencedMethod == null)
+ {
+ // We couldn't find the enclosing method.
+ missingMemberWarningPrinter.print(className,
+ enclosingClassName,
+ "Warning: " +
+ ClassUtil.externalClassName(className) +
+ ": can't find enclosing method '" +
+ ClassUtil.externalFullMethodDescription(enclosingClassName, 0, name, type) +
+ "' in class " +
+ ClassUtil.externalClassName(enclosingClassName));
+ }
+ }
}
-
- // Save the references.
- enclosingMethodAttribute.referencedClass = referencedClass;
- enclosingMethodAttribute.referencedMethod = referencedMethod;
}
@@ -501,11 +509,17 @@ implements ClassVisitor,
*/
private Clazz findClass(String referencingClassName, String name)
{
- // Ignore any primitive array types.
- if (ClassUtil.isInternalArrayType(name) &&
- !ClassUtil.isInternalClassType(name))
+ // Is it an array type?
+ if (ClassUtil.isInternalArrayType(name))
{
- return null;
+ // Ignore any primitive array types.
+ if (!ClassUtil.isInternalClassType(name))
+ {
+ return null;
+ }
+
+ // Strip the array part.
+ name = ClassUtil.internalClassNameFromClassType(name);
}
// First look for the class in the program class pool.
diff --git a/src/proguard/classfile/util/ClassSubHierarchyInitializer.java b/src/proguard/classfile/util/ClassSubHierarchyInitializer.java
index 30fd526..304efd7 100644
--- a/src/proguard/classfile/util/ClassSubHierarchyInitializer.java
+++ b/src/proguard/classfile/util/ClassSubHierarchyInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java b/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java
index af2a209..de95250 100644
--- a/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java
+++ b/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -106,11 +106,6 @@ implements ClassVisitor,
libraryClass.interfaceClasses = interfaceClasses;
}
-
- // Discard the name Strings. From now on, we'll use the object
- // references.
- libraryClass.superClassName = null;
- libraryClass.interfaceNames = null;
}
diff --git a/src/proguard/classfile/util/ClassUtil.java b/src/proguard/classfile/util/ClassUtil.java
index 5f25f01..e92a022 100644
--- a/src/proguard/classfile/util/ClassUtil.java
+++ b/src/proguard/classfile/util/ClassUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -100,6 +100,8 @@ public class ClassUtil
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_5) ? ClassConstants.INTERNAL_CLASS_VERSION_1_5 :
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6_ALIAS) ||
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6) ? ClassConstants.INTERNAL_CLASS_VERSION_1_6 :
+ classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_7_ALIAS) ||
+ classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_7) ? ClassConstants.INTERNAL_CLASS_VERSION_1_7 :
0;
}
@@ -119,6 +121,7 @@ public class ClassUtil
case ClassConstants.INTERNAL_CLASS_VERSION_1_4: return ClassConstants.EXTERNAL_CLASS_VERSION_1_4;
case ClassConstants.INTERNAL_CLASS_VERSION_1_5: return ClassConstants.EXTERNAL_CLASS_VERSION_1_5;
case ClassConstants.INTERNAL_CLASS_VERSION_1_6: return ClassConstants.EXTERNAL_CLASS_VERSION_1_6;
+ case ClassConstants.INTERNAL_CLASS_VERSION_1_7: return ClassConstants.EXTERNAL_CLASS_VERSION_1_7;
default: return null;
}
}
@@ -132,11 +135,14 @@ public class ClassUtil
public static void checkVersionNumbers(int classVersion) throws UnsupportedOperationException
{
if (classVersion < ClassConstants.INTERNAL_CLASS_VERSION_1_0 ||
- classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_6)
+ classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_7)
{
- throw new UnsupportedOperationException("Unsupported version number ["+
+ throw new UnsupportedOperationException("Unsupported class version number ["+
internalMajorClassVersion(classVersion)+"."+
- internalMinorClassVersion(classVersion)+"] for class format");
+ internalMinorClassVersion(classVersion)+"] (maximum "+
+ ClassConstants.INTERNAL_CLASS_VERSION_1_7_MAJOR+"."+
+ ClassConstants.INTERNAL_CLASS_VERSION_1_7_MINOR+", Java "+
+ ClassConstants.EXTERNAL_CLASS_VERSION_1_7+")");
}
}
@@ -189,8 +195,25 @@ public class ClassUtil
/**
- * Converts an internal class name into an external short class name, without
- * package specification.
+ * Returns the external base type of an external array type, dropping any
+ * array brackets.
+ * @param externalArrayType the external array type,
+ * e.g. "<code>java.lang.Object[][]</code>"
+ * @return the external base type,
+ * e.g. "<code>java.lang.Object</code>".
+ */
+ public static String externalBaseType(String externalArrayType)
+ {
+ int index = externalArrayType.indexOf(ClassConstants.EXTERNAL_TYPE_ARRAY);
+ return index >= 0 ?
+ externalArrayType.substring(0, index) :
+ externalArrayType;
+ }
+
+
+ /**
+ * Returns the external short class name of an external class name, dropping
+ * the package specification.
* @param externalClassName the external class name,
* e.g. "<code>java.lang.Object</code>"
* @return the external short class name,
@@ -410,6 +433,21 @@ public class ClassUtil
/**
+ * Returns whether the given method name refers to a class initializer or
+ * an instance initializer.
+ * @param internalMethodName the internal method name,
+ * e.g. "<code><clinit></code>".
+ * @return whether the method name refers to an initializer,
+ * e.g. <code>true</code>.
+ */
+ public static boolean isInitializer(String internalMethodName)
+ {
+ return internalMethodName.equals(ClassConstants.INTERNAL_METHOD_NAME_CLINIT) ||
+ internalMethodName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT);
+ }
+
+
+ /**
* Returns the internal type of the given internal method descriptor.
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "<code>(II)Z</code>".
@@ -869,6 +907,21 @@ public class ClassUtil
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(' ');
}
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0)
+ {
+ // Only in InnerClasses attributes.
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(' ');
+ }
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0)
+ {
+ // Only in InnerClasses attributes.
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(' ');
+ }
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)
+ {
+ // Only in InnerClasses attributes.
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STATIC).append(' ');
+ }
if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_FINAL).append(' ');
@@ -889,6 +942,10 @@ public class ClassUtil
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ABSTRACT).append(' ');
}
+ else if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' ');
+ }
return string.toString();
}
@@ -950,6 +1007,10 @@ public class ClassUtil
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_TRANSIENT).append(' ');
}
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' ');
+ }
return string.toString();
}
@@ -1007,6 +1068,14 @@ public class ClassUtil
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED).append(' ');
}
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_BRIDGE) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_BRIDGE).append(' ');
+ }
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_VARARGS) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_VARARGS).append(' ');
+ }
if ((accessFlags & ClassConstants.INTERNAL_ACC_NATIVE) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_NATIVE).append(' ');
@@ -1019,6 +1088,10 @@ public class ClassUtil
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STRICT).append(' ');
}
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' ');
+ }
return string.toString();
}
diff --git a/src/proguard/classfile/util/DescriptorClassEnumeration.java b/src/proguard/classfile/util/DescriptorClassEnumeration.java
index 0bee2d5..bb08f08 100644
--- a/src/proguard/classfile/util/DescriptorClassEnumeration.java
+++ b/src/proguard/classfile/util/DescriptorClassEnumeration.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/DynamicClassReferenceInitializer.java b/src/proguard/classfile/util/DynamicClassReferenceInitializer.java
index 09ffdd0..bdf2102 100644
--- a/src/proguard/classfile/util/DynamicClassReferenceInitializer.java
+++ b/src/proguard/classfile/util/DynamicClassReferenceInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -301,7 +301,8 @@ implements InstructionVisitor,
{
// Save a reference to the corresponding class.
String externalClassName = stringConstant.getString(clazz);
- String internalClassName = ClassUtil.internalClassName(externalClassName);
+ String internalClassName = ClassUtil.internalClassName(
+ ClassUtil.externalBaseType(externalClassName));
stringConstant.referencedClass = findClass(clazz.getName(), internalClassName);
}
@@ -350,7 +351,7 @@ implements InstructionVisitor,
return;
}
- String className = methodrefConstant.getClassName(clazz);
+ String className = methodrefConstant.getClassName(clazz);
// Note that we look for the class by name, since the referenced
// class has not been initialized yet.
@@ -434,11 +435,17 @@ implements InstructionVisitor,
*/
private Clazz findClass(String referencingClassName, String name)
{
- // Ignore any primitive array types.
- if (ClassUtil.isInternalArrayType(name) &&
- !ClassUtil.isInternalClassType(name))
+ // Is it an array type?
+ if (ClassUtil.isInternalArrayType(name))
{
- return null;
+ // Ignore any primitive array types.
+ if (!ClassUtil.isInternalClassType(name))
+ {
+ return null;
+ }
+
+ // Strip the array part.
+ name = ClassUtil.internalClassNameFromClassType(name);
}
// First look for the class in the program class pool.
diff --git a/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java b/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java
index 1f57708..110dc43 100644
--- a/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java
+++ b/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -55,14 +55,20 @@ implements InstructionVisitor,
AttributeVisitor,
MemberVisitor
{
- public static final int X = InstructionSequenceMatcher.X;
- public static final int Y = InstructionSequenceMatcher.Y;
- public static final int Z = InstructionSequenceMatcher.Z;
+ /*
+ private static boolean DEBUG = true;
+ /*/
+ private static final boolean DEBUG = false;
+ //*/
- public static final int A = InstructionSequenceMatcher.A;
- public static final int B = InstructionSequenceMatcher.B;
- public static final int C = InstructionSequenceMatcher.C;
- public static final int D = InstructionSequenceMatcher.D;
+ public static final int CLASS_INDEX = InstructionSequenceMatcher.X;
+ public static final int MEMBER_NAME_INDEX = InstructionSequenceMatcher.Y;
+ public static final int TYPE_CLASS_INDEX = InstructionSequenceMatcher.Z;
+
+ public static final int PARAMETER0_CLASS_INDEX = InstructionSequenceMatcher.A;
+ public static final int PARAMETER1_CLASS_INDEX = InstructionSequenceMatcher.B;
+ public static final int PARAMETER2_CLASS_INDEX = InstructionSequenceMatcher.C;
+ public static final int PARAMETER3_CLASS_INDEX = InstructionSequenceMatcher.D;
private final Constant[] GET_FIELD_CONSTANTS = new Constant[]
@@ -85,6 +91,26 @@ implements InstructionVisitor,
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD),
};
+ private final Constant[] GET_CONSTRUCTOR_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS),
+ new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_CONSTRUCTOR),
+ new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_CONSTRUCTOR),
+ };
+
+ private final Constant[] GET_DECLARED_CONSTRUCTOR_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS),
+ new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_DECLARED_CONSTRUCTOR),
+ new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_DECLARED_CONSTRUCTOR),
+ };
+
private final Constant[] GET_METHOD_CONSTANTS = new Constant[]
{
new MethodrefConstant(1, 2, null, null),
@@ -105,19 +131,88 @@ implements InstructionVisitor,
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD),
};
+ private final Constant[] NEW_INTEGER_UPDATER_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_INTEGER_FIELD_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_INTEGER_UPDATER),
+ };
+
+ private final Constant[] NEW_LONG_UPDATER_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_LONG_FIELD_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_LONG_UPDATER),
+ };
+
+ private final Constant[] NEW_REFERENCE_UPDATER_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_REFERENCE_FIELD_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_REFERENCE_UPDATER),
+ };
+
// SomeClass.class.get[Declared]Field("someField").
private final Instruction[] CONSTANT_GET_FIELD_INSTRUCTIONS = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, X),
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
+// // SomeClass.class.get[Declared]Constructor(new Class[] {}).
+// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0 = new Instruction[]
+// {
+// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+// };
+//
+// // SomeClass.class.get[Declared]Constructor(new Class[] { A.class }).
+// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1 = new Instruction[]
+// {
+// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+// new SimpleInstruction(InstructionConstants.OP_DUP),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_AASTORE),
+// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+// };
+//
+// // SomeClass.class.get[Declared]Constructor(new Class[] { A.class, B.class }).
+// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2 = new Instruction[]
+// {
+// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_2),
+// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+// new SimpleInstruction(InstructionConstants.OP_DUP),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_AASTORE),
+// new SimpleInstruction(InstructionConstants.OP_DUP),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_AASTORE),
+// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+// };
+
// SomeClass.class.get[Declared]Method("someMethod", new Class[] {}).
private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS0 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, X),
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
@@ -126,13 +221,13 @@ implements InstructionVisitor,
// SomeClass.class.get[Declared]Method("someMethod", new Class[] { A.class }).
private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS1 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, X),
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_1),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
- new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
@@ -140,32 +235,86 @@ implements InstructionVisitor,
// SomeClass.class.get[Declared]Method("someMethod", new Class[] { A.class, B.class }).
private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS2 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, X),
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_2),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
- new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_1),
- new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
+ // AtomicIntegerFieldUpdater.newUpdater(A.class, "someField").
+ // AtomicLongFieldUpdater.newUpdater(A.class, "someField").
+ private final Instruction[] CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS = new Instruction[]
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
+ };
+
+ // AtomicReferenceFieldUpdater.newUpdater(A.class, B.class, "someField").
+ private final Instruction[] CONSTANT_NEW_REFERENCE_UPDATER_INSTRUCTIONS = new Instruction[]
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, TYPE_CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
+ };
+
// get[Declared]Field("someField").
private final Instruction[] GET_FIELD_INSTRUCTIONS = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+ };
+
+// // get[Declared]Constructor(new Class[] {}).
+// private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS0 = new Instruction[]
+// {
+// new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+// };
+
+ // get[Declared]Constructor(new Class[] { A.class }).
+ private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS1 = new Instruction[]
+ {
+ new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+ new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
+ new SimpleInstruction(InstructionConstants.OP_AASTORE),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+ };
+
+ // get[Declared]Constructor(new Class[] { A.class, B.class }).
+ private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS2 = new Instruction[]
+ {
+ new SimpleInstruction(InstructionConstants.OP_ICONST_2),
+ new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
+ new SimpleInstruction(InstructionConstants.OP_AASTORE),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX),
+ new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
// get[Declared]Method("someMethod", new Class[] {}).
private final Instruction[] GET_METHOD_INSTRUCTIONS0 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
@@ -174,12 +323,12 @@ implements InstructionVisitor,
// get[Declared]Method("someMethod", new Class[] { A.class }).
private final Instruction[] GET_METHOD_INSTRUCTIONS1 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_1),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
- new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
@@ -187,20 +336,29 @@ implements InstructionVisitor,
// get[Declared]Method("someMethod", new Class[] { A.class, B.class }).
private final Instruction[] GET_METHOD_INSTRUCTIONS2 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_2),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
- new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_1),
- new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
+ // AtomicIntegerFieldUpdater.newUpdater(..., "someField").
+ // AtomicLongFieldUpdater.newUpdater(..., "someField").
+ // AtomicReferenceFieldUpdater.newUpdater(..., "someField").
+ private final Instruction[] NEW_UPDATER_INSTRUCTIONS = new Instruction[]
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
+ };
+
private final ClassPool programClassPool;
private final ClassPool libraryClassPool;
@@ -217,6 +375,30 @@ implements InstructionVisitor,
new InstructionSequenceMatcher(GET_DECLARED_FIELD_CONSTANTS,
CONSTANT_GET_FIELD_INSTRUCTIONS);
+// private final InstructionSequenceMatcher constantGetConstructorMatcher0 =
+// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0);
+//
+// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher0 =
+// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0);
+//
+// private final InstructionSequenceMatcher constantGetConstructorMatcher1 =
+// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1);
+//
+// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher1 =
+// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1);
+//
+// private final InstructionSequenceMatcher constantGetConstructorMatcher2 =
+// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2);
+//
+// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher2 =
+// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2);
+
private final InstructionSequenceMatcher constantGetMethodMatcher0 =
new InstructionSequenceMatcher(GET_METHOD_CONSTANTS,
CONSTANT_GET_METHOD_INSTRUCTIONS0);
@@ -241,6 +423,18 @@ implements InstructionVisitor,
new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS,
CONSTANT_GET_METHOD_INSTRUCTIONS2);
+ private final InstructionSequenceMatcher constantGetIntegerUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_INTEGER_UPDATER_CONSTANTS,
+ CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS);
+
+ private final InstructionSequenceMatcher constantGetLongUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_LONG_UPDATER_CONSTANTS,
+ CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS);
+
+ private final InstructionSequenceMatcher constantGetReferenceUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_REFERENCE_UPDATER_CONSTANTS,
+ CONSTANT_NEW_REFERENCE_UPDATER_INSTRUCTIONS);
+
private final InstructionSequenceMatcher getFieldMatcher =
new InstructionSequenceMatcher(GET_FIELD_CONSTANTS,
GET_FIELD_INSTRUCTIONS);
@@ -249,6 +443,30 @@ implements InstructionVisitor,
new InstructionSequenceMatcher(GET_DECLARED_FIELD_CONSTANTS,
GET_FIELD_INSTRUCTIONS);
+// private final InstructionSequenceMatcher getConstructorMatcher0 =
+// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+// GET_CONSTRUCTOR_INSTRUCTIONS0);
+//
+// private final InstructionSequenceMatcher getDeclaredConstructorMatcher0 =
+// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+// GET_CONSTRUCTOR_INSTRUCTIONS0);
+
+ private final InstructionSequenceMatcher getConstructorMatcher1 =
+ new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+ GET_CONSTRUCTOR_INSTRUCTIONS1);
+
+ private final InstructionSequenceMatcher getDeclaredConstructorMatcher1 =
+ new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+ GET_CONSTRUCTOR_INSTRUCTIONS1);
+
+ private final InstructionSequenceMatcher getConstructorMatcher2 =
+ new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+ GET_CONSTRUCTOR_INSTRUCTIONS2);
+
+ private final InstructionSequenceMatcher getDeclaredConstructorMatcher2 =
+ new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+ GET_CONSTRUCTOR_INSTRUCTIONS2);
+
private final InstructionSequenceMatcher getMethodMatcher0 =
new InstructionSequenceMatcher(GET_METHOD_CONSTANTS,
GET_METHOD_INSTRUCTIONS0);
@@ -273,11 +491,24 @@ implements InstructionVisitor,
new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS,
GET_METHOD_INSTRUCTIONS2);
+ private final InstructionSequenceMatcher getIntegerUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_INTEGER_UPDATER_CONSTANTS,
+ NEW_UPDATER_INSTRUCTIONS);
+
+ private final InstructionSequenceMatcher getLongUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_LONG_UPDATER_CONSTANTS,
+ NEW_UPDATER_INSTRUCTIONS);
+
+ private final InstructionSequenceMatcher getReferenceUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_REFERENCE_UPDATER_CONSTANTS,
+ NEW_UPDATER_INSTRUCTIONS);
+
private final MemberFinder memberFinder = new MemberFinder();
// Fields acting as parameters for the visitors.
private Clazz referencedClass;
+ private String descriptor;
private boolean isDeclared;
private boolean isField;
@@ -307,48 +538,110 @@ implements InstructionVisitor,
// Try to match the SomeClass.class.getField("someField") construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetFieldMatcher,
- getFieldMatcher, true, false);
+ getFieldMatcher, true, false, null, null);
// Try to match the SomeClass.class.getDeclaredField("someField") construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredFieldMatcher,
- getDeclaredFieldMatcher, true, true);
+ getDeclaredFieldMatcher, true, true, null, null);
+
+// // Try to match the SomeClass.class.getConstructor(new Class[]
+// // {}) construct.
+// matchGetMember(clazz, method, codeAttribute, offset, instruction,
+// cnull, //onstantGetConstructorMatcher0,
+// getConstructorMatcher0, false, false,
+// ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+//
+// // Try to match the SomeClass.class.getDeclaredConstructor(new Class[]
+// // {}) construct.
+// matchGetMember(clazz, method, codeAttribute, offset, instruction,
+// null, //constantGetDeclaredConstructorMatcher0,
+// getDeclaredConstructorMatcher0, false, true,
+// ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+
+ // Try to match the SomeClass.class.getConstructor(new Class[]
+ // { A.class }) construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ null, //constantGetConstructorMatcher1,
+ getConstructorMatcher1, false, false,
+ ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+
+ // Try to match the SomeClass.class.getDeclaredConstructor(new Class[]
+ // { A.class }) construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ null, //constantGetDeclaredConstructorMatcher1,
+ getDeclaredConstructorMatcher1, false, true,
+ ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+
+ // Try to match the SomeClass.class.getConstructor(new Class[]
+ // { A.class, B.class }) construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ null, //constantGetConstructorMatcher2,
+ getConstructorMatcher2, false, false,
+ ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+
+ // Try to match the SomeClass.class.getDeclaredConstructor(new Class[]
+ // { A.class, B.class }) construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ null, //constantGetDeclaredConstructorMatcher2,
+ getDeclaredConstructorMatcher2, false, true,
+ ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
// Try to match the SomeClass.class.getMethod("someMethod", new Class[]
// {}) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetMethodMatcher0,
- getMethodMatcher0, false, false);
+ getMethodMatcher0, false, false, null, null);
// Try to match the SomeClass.class.getDeclaredMethod("someMethod",
- // new Class[] {}) construct.
+ // new Class[] {}) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredMethodMatcher0,
- getDeclaredMethodMatcher0, false, true);
+ getDeclaredMethodMatcher0, false, true, null, null);
// Try to match the SomeClass.class.getMethod("someMethod", new Class[]
// { A.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetMethodMatcher1,
- getMethodMatcher1, false, false);
+ getMethodMatcher1, false, false, null, null);
// Try to match the SomeClass.class.getDeclaredMethod("someMethod",
// new Class[] { A.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredMethodMatcher1,
- getDeclaredMethodMatcher1, false, true);
+ getDeclaredMethodMatcher1, false, true, null, null);
// Try to match the SomeClass.class.getMethod("someMethod", new Class[]
// { A.class, B.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetMethodMatcher2,
- getMethodMatcher2, false, false);
+ getMethodMatcher2, false, false, null, null);
// Try to match the SomeClass.class.getDeclaredMethod("someMethod",
- // new Class[] { A.class, B.class }) construct.
+ // new Class[] { A.class, B.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredMethodMatcher2,
- getDeclaredMethodMatcher2, false, true);
+ getDeclaredMethodMatcher2, false, true, null, null);
+
+ // Try to match the AtomicIntegerFieldUpdater.newUpdater(
+ // SomeClass.class, "someField") construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ constantGetIntegerUpdaterMatcher,
+ getIntegerUpdaterMatcher, true, false, null,
+ "" + ClassConstants.INTERNAL_TYPE_INT);
+
+ // Try to match the AtomicLongFieldUpdater.newUpdater(
+ // SomeClass.class, "someField") construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ constantGetLongUpdaterMatcher,
+ getLongUpdaterMatcher, true, false, null,
+ "" + ClassConstants.INTERNAL_TYPE_LONG);
+
+ // Try to match the AtomicReferenceFieldUpdater.newUpdater(
+ // SomeClass.class, SomeClass.class, "someField") construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ constantGetReferenceUpdaterMatcher,
+ getReferenceUpdaterMatcher, true, false, null, null);
}
@@ -364,26 +657,28 @@ implements InstructionVisitor,
InstructionSequenceMatcher constantSequenceMatcher,
InstructionSequenceMatcher variableSequenceMatcher,
boolean isField,
- boolean isDeclared)
+ boolean isDeclared,
+ String defaultName,
+ String defaultDescriptor)
{
- // Try to match the next instruction in the constant sequence.
- instruction.accept(clazz, method, codeAttribute, offset,
- constantSequenceMatcher);
-
- // Did we find a match to fill out the string constant?
- if (constantSequenceMatcher.isMatching())
+ if (constantSequenceMatcher != null)
{
- this.isField = isField;
- this.isDeclared = isDeclared;
-
- // Get the member's class.
- clazz.constantPoolEntryAccept(constantSequenceMatcher.matchedConstantIndex(X), this);
-
- // Fill out the matched string constant.
- clazz.constantPoolEntryAccept(constantSequenceMatcher.matchedConstantIndex(Y), this);
+ // Try to match the next instruction in the constant sequence.
+ instruction.accept(clazz, method, codeAttribute, offset,
+ constantSequenceMatcher);
- // Don't look for the dynamic construct.
- variableSequenceMatcher.reset();
+ // Did we find a match to fill out the string constant?
+ if (constantSequenceMatcher.isMatching())
+ {
+ initializeStringReference(clazz,
+ constantSequenceMatcher,
+ isField,
+ isDeclared,
+ defaultDescriptor);
+
+ // Don't look for the dynamic construct.
+ variableSequenceMatcher.reset();
+ }
}
// Try to match the next instruction in the variable sequence.
@@ -397,11 +692,41 @@ implements InstructionVisitor,
printDynamicInvocationNote(clazz,
variableSequenceMatcher,
isField,
- isDeclared);
+ isDeclared,
+ defaultName,
+ defaultDescriptor);
}
}
+ /**
+ * Initializes the reference of the matched string constant to the
+ * referenced class member and its class.
+ */
+ private void initializeStringReference(Clazz clazz,
+ InstructionSequenceMatcher constantSequenceMatcher,
+ boolean isField,
+ boolean isDeclared,
+ String defaultDescriptor)
+ {
+ this.isField = isField;
+ this.isDeclared = isDeclared;
+
+ // Get the member's class.
+ int classIndex = constantSequenceMatcher.matchedConstantIndex(CLASS_INDEX);
+ clazz.constantPoolEntryAccept(classIndex, this);
+
+ // Get the field's reference type, if applicable.
+ int typeClassIndex = constantSequenceMatcher.matchedConstantIndex(TYPE_CLASS_INDEX);
+ descriptor = typeClassIndex <= 0 ? defaultDescriptor :
+ ClassUtil.internalTypeFromClassName(clazz.getClassName(typeClassIndex));
+
+ // Fill out the matched string constant.
+ int memberNameIndex = constantSequenceMatcher.matchedConstantIndex(MEMBER_NAME_INDEX);
+ clazz.constantPoolEntryAccept(memberNameIndex, this);
+ }
+
+
// Implementations for ConstantVisitor.
/**
@@ -409,6 +734,11 @@ implements InstructionVisitor,
*/
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
+ if (DEBUG)
+ {
+ System.out.println("DynamicMemberReferenceInitializer: ["+clazz.getName()+"] matched class ["+classConstant.getName(clazz)+"]");
+ }
+
// Remember the referenced class.
referencedClass = ClassUtil.isInternalArrayType(classConstant.getName(clazz)) ?
null :
@@ -425,15 +755,20 @@ implements InstructionVisitor,
{
String name = stringConstant.getString(clazz);
+ if (DEBUG)
+ {
+ System.out.println("DynamicMemberReferenceInitializer: ["+clazz.getName()+"] matched string ["+name+"]");
+ }
+
// See if we can find the referenced class member locally, or
// somewhere in the hierarchy.
Member referencedMember = isDeclared ? isField ?
- (Member)referencedClass.findField(name, null) :
- (Member)referencedClass.findMethod(name, null) :
+ (Member)referencedClass.findField(name, descriptor) :
+ (Member)referencedClass.findMethod(name, descriptor) :
(Member)memberFinder.findMember(clazz,
referencedClass,
name,
- null,
+ descriptor,
isField);
if (referencedMember != null)
{
@@ -454,7 +789,9 @@ implements InstructionVisitor,
private void printDynamicInvocationNote(Clazz clazz,
InstructionSequenceMatcher noteSequenceMatcher,
boolean isField,
- boolean isDeclared)
+ boolean isDeclared,
+ String defaultName,
+ String defaultDescriptor)
{
// Print out a note about the dynamic invocation.
if (notePrinter != null &&
@@ -465,8 +802,9 @@ implements InstructionVisitor,
noteFieldExceptionMatcher :
noteMethodExceptionMatcher;
- int memberNameIndex = noteSequenceMatcher.matchedConstantIndex(Y);
- String memberName = clazz.getStringString(memberNameIndex);
+ int memberNameIndex = noteSequenceMatcher.matchedConstantIndex(MEMBER_NAME_INDEX);
+ String memberName = memberNameIndex <= 0 ? defaultName :
+ clazz.getStringString(memberNameIndex);
if (noteExceptionMatcher == null ||
!noteExceptionMatcher.matches(memberName))
@@ -479,7 +817,8 @@ implements InstructionVisitor,
externalMemberDescription += '(';
for (int count = 0; count < 2; count++)
{
- int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(A + count);
+ int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(
+ PARAMETER0_CLASS_INDEX + count);
if (memberArgumentIndex > 0)
{
if (count > 0)
@@ -501,7 +840,9 @@ implements InstructionVisitor,
ClassUtil.externalClassName(clazz.getName()) +
" accesses a " +
(isDeclared ? "declared " : "") +
- (isField ? "field" : "method") +
+ (isField ? "field" :
+ memberName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ?
+ "constructor" : "method") +
" '" +
externalMemberDescription +
"' dynamically");
@@ -511,9 +852,12 @@ implements InstructionVisitor,
if (isField)
{
- classVisitor =
+ classVisitor = defaultDescriptor == null ?
+ new AllFieldVisitor(
+ new MemberNameFilter(memberName, this)) :
new AllFieldVisitor(
- new MemberNameFilter(memberName, this));
+ new MemberNameFilter(memberName,
+ new MemberDescriptorFilter(defaultDescriptor, this)));
}
else
{
@@ -521,20 +865,16 @@ implements InstructionVisitor,
String methodDescriptor = "(";
for (int count = 0; count < 2; count++)
{
- int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(A + count);
+ int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(PARAMETER0_CLASS_INDEX + count);
if (memberArgumentIndex > 0)
{
- if (count > 0)
- {
- methodDescriptor += ',';
- }
String className = clazz.getClassName(memberArgumentIndex);
methodDescriptor += ClassUtil.isInternalArrayType(className) ?
className :
ClassUtil.internalTypeFromClassName(className);
}
}
- methodDescriptor += ")L///;";
+ methodDescriptor += ")L***;";
classVisitor =
new AllMethodVisitor(
@@ -571,7 +911,7 @@ implements InstructionVisitor,
System.out.println(" Maybe this is program method '" +
ClassUtil.externalFullClassDescription(0, programClass.getName()) +
" { " +
- ClassUtil.externalFullMethodDescription(null, 0, programMethod.getName(programClass), programMethod.getDescriptor(programClass)) +
+ ClassUtil.externalFullMethodDescription(programClass.getName(), 0, programMethod.getName(programClass), programMethod.getDescriptor(programClass)) +
"; }'");
}
}
@@ -597,7 +937,7 @@ implements InstructionVisitor,
System.out.println(" Maybe this is library method '" +
ClassUtil.externalFullClassDescription(0, libraryClass.getName()) +
" { " +
- ClassUtil.externalFullMethodDescription(null, 0, libraryMethod.getName(libraryClass), libraryMethod.getDescriptor(libraryClass)) +
+ ClassUtil.externalFullMethodDescription(libraryClass.getName(), 0, libraryMethod.getName(libraryClass), libraryMethod.getDescriptor(libraryClass)) +
"; }'");
}
}
diff --git a/src/proguard/classfile/util/ExternalTypeEnumeration.java b/src/proguard/classfile/util/ExternalTypeEnumeration.java
index 6371888..7edfbc9 100644
--- a/src/proguard/classfile/util/ExternalTypeEnumeration.java
+++ b/src/proguard/classfile/util/ExternalTypeEnumeration.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/InstructionSequenceMatcher.java b/src/proguard/classfile/util/InstructionSequenceMatcher.java
index 8a689d5..51eb7bc 100644
--- a/src/proguard/classfile/util/InstructionSequenceMatcher.java
+++ b/src/proguard/classfile/util/InstructionSequenceMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -27,6 +27,8 @@ import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
+import java.util.Arrays;
+
/**
* This InstructionVisitor checks whether a given pattern instruction sequence
* occurs in the instructions that are visited. The arguments of the
@@ -40,8 +42,8 @@ implements InstructionVisitor,
ConstantVisitor
{
/*
- private static boolean DEBUG = false;
- public static boolean DEBUG_MORE = false;
+ public static boolean DEBUG = true;
+ public static boolean DEBUG_MORE = true;
/*/
private static final boolean DEBUG = false;
private static final boolean DEBUG_MORE = false;
@@ -60,14 +62,15 @@ implements InstructionVisitor,
private final Constant[] patternConstants;
private final Instruction[] patternInstructions;
- private boolean matching;
- private boolean matchingAnyWildCards;
- private int patternInstructionIndex;
- private final int[] matchedInstructionOffsets;
- private int matchedArgumentFlags;
- private final int[] matchedArguments = new int[7];
- private long matchedConstantFlags;
- private final int[] matchedConstantIndices;
+ private boolean matching;
+ private int patternInstructionIndex;
+ private final int[] matchedInstructionOffsets;
+ private int matchedArgumentFlags;
+ private final int[] matchedArguments = new int[7];
+ private final long[] matchedConstantFlags;
+ private final int[] matchedConstantIndices;
+ private int constantFlags;
+ private int previousConstantFlags;
// Fields acting as a parameter and a return value for visitor methods.
private Constant patternConstant;
@@ -87,6 +90,7 @@ implements InstructionVisitor,
this.patternInstructions = patternInstructions;
matchedInstructionOffsets = new int[patternInstructions.length];
+ matchedConstantFlags = new long[(patternConstants.length + 63) / 64];
matchedConstantIndices = new int[patternConstants.length];
}
@@ -98,34 +102,55 @@ implements InstructionVisitor,
{
patternInstructionIndex = 0;
matchedArgumentFlags = 0;
- matchedConstantFlags = 0L;
- }
+ Arrays.fill(matchedConstantFlags, 0L);
- public boolean isMatching()
- {
- return matching;
+ previousConstantFlags = constantFlags;
+ constantFlags = 0;
}
- public boolean isMatchingAnyWildcards()
+ /**
+ * Returns whether the complete pattern sequence has been matched.
+ */
+ public boolean isMatching()
{
- return matchingAnyWildCards;
+ return matching;
}
+ /**
+ * Returns the number of instructions in the pattern sequence.
+ */
public int instructionCount()
{
return patternInstructions.length;
}
+ /**
+ * Returns the matched instruction offset of the specified pattern
+ * instruction.
+ */
public int matchedInstructionOffset(int index)
{
return matchedInstructionOffsets[index];
}
+ /**
+ * Returns whether the specified wildcard argument was a constant from
+ * the constant pool in the most recent match.
+ */
+ public boolean wasConstant(int argument)
+ {
+ return (previousConstantFlags & (1 << (argument - X))) != 0;
+ }
+
+
+ /**
+ * Returns the value of the specified matched argument (wildcard or not).
+ */
public int matchedArgument(int argument)
{
int argumentIndex = argument - X;
@@ -135,6 +160,9 @@ implements InstructionVisitor,
}
+ /**
+ * Returns the values of the specified matched arguments (wildcard or not).
+ */
public int[] matchedArguments(int[] arguments)
{
int[] matchedArguments = new int[arguments.length];
@@ -148,6 +176,9 @@ implements InstructionVisitor,
}
+ /**
+ * Returns the index of the specified matched constant (wildcard or not).
+ */
public int matchedConstantIndex(int constantIndex)
{
int argumentIndex = constantIndex - X;
@@ -157,6 +188,10 @@ implements InstructionVisitor,
}
+ /**
+ * Returns the value of the specified matched branch offset (wildcard or
+ * not).
+ */
public int matchedBranchOffset(int offset, int branchOffset)
{
int argumentIndex = branchOffset - X;
@@ -166,6 +201,10 @@ implements InstructionVisitor,
}
+ /**
+ * Returns the values of the specified matched jump offsets (wildcard or
+ * not).
+ */
public int[] matchedJumpOffsets(int offset, int[] jumpOffsets)
{
int[] matchedJumpOffsets = new int[jumpOffsets.length];
@@ -387,6 +426,35 @@ implements InstructionVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ InvokeDynamicConstant invokeDynamicPatternConstant = (InvokeDynamicConstant)patternConstant;
+
+ // Check the bootstrap method and the name and type.
+ matchingConstant =
+ matchingConstantIndices(clazz,
+ invokeDynamicConstant.getBootstrapMethodAttributeIndex(),
+ invokeDynamicPatternConstant.getBootstrapMethodAttributeIndex()) &&
+ matchingConstantIndices(clazz,
+ invokeDynamicConstant.getNameAndTypeIndex(),
+ invokeDynamicPatternConstant.getNameAndTypeIndex());
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ MethodHandleConstant methodHandlePatternConstant = (MethodHandleConstant)patternConstant;
+
+ // Check the handle type and the name and type.
+ matchingConstant =
+ matchingArguments(methodHandleConstant.getReferenceKind(),
+ methodHandlePatternConstant.getReferenceKind()) &&
+ matchingConstantIndices(clazz,
+ methodHandleConstant.getReferenceIndex(),
+ methodHandlePatternConstant.getReferenceIndex());
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
RefConstant refPatternConstant = (RefConstant)patternConstant;
@@ -414,6 +482,18 @@ implements InstructionVisitor,
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ MethodTypeConstant typePatternConstant = (MethodTypeConstant)patternConstant;
+
+ // Check the descriptor.
+ matchingConstant =
+ matchingConstantIndices(clazz,
+ methodTypeConstant.u2descriptorIndex,
+ typePatternConstant.u2descriptorIndex);
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
NameAndTypeConstant typePatternConstant = (NameAndTypeConstant)patternConstant;
@@ -449,11 +529,10 @@ implements InstructionVisitor,
// Check the literal argument.
return argument1 == argument2;
}
- else if ((matchedArgumentFlags & (1 << argumentIndex)) == 0)
+ else if (!isMatchingArgumentIndex(argumentIndex))
{
- // Store a wildcard argument.
- matchedArguments[argumentIndex] = argument1;
- matchedArgumentFlags |= 1 << argumentIndex;
+ // Store the wildcard argument.
+ setMatchingArgument(argumentIndex, argument1);
return true;
}
@@ -465,6 +544,28 @@ implements InstructionVisitor,
}
+ /**
+ * Marks the specified argument (by index) as matching the specified
+ * argument value.
+ */
+ private void setMatchingArgument(int argumentIndex,
+ int argument)
+ {
+ matchedArguments[argumentIndex] = argument;
+ matchedArgumentFlags |= 1 << argumentIndex;
+ }
+
+
+ /**
+ * Returns whether the specified wildcard argument (by index) has been
+ * matched.
+ */
+ private boolean isMatchingArgumentIndex(int argumentIndex)
+ {
+ return (matchedArgumentFlags & (1 << argumentIndex)) != 0;
+ }
+
+
private boolean matchingArguments(int[] arguments1,
int[] arguments2)
{
@@ -491,10 +592,13 @@ implements InstructionVisitor,
{
if (constantIndex2 >= X)
{
+ // Remember that we are trying to match a constant.
+ constantFlags |= 1 << (constantIndex2 - X);
+
// Check the constant index.
return matchingArguments(constantIndex1, constantIndex2);
}
- else if ((matchedConstantFlags & (1L << constantIndex2)) == 0)
+ else if (!isMatchingConstantIndex(constantIndex2))
{
// Check the actual constant.
matchingConstant = false;
@@ -507,8 +611,7 @@ implements InstructionVisitor,
if (matchingConstant)
{
// Store the constant index.
- matchedConstantIndices[constantIndex2] = constantIndex1;
- matchedConstantFlags |= 1L << constantIndex2;
+ setMatchingConstant(constantIndex2, constantIndex1);
}
}
@@ -522,6 +625,27 @@ implements InstructionVisitor,
}
+ /**
+ * Marks the specified constant (by index) as matching the specified
+ * constant index value.
+ */
+ private void setMatchingConstant(int constantIndex,
+ int constantIndex1)
+ {
+ matchedConstantIndices[constantIndex] = constantIndex1;
+ matchedConstantFlags[constantIndex / 64] |= 1L << constantIndex;
+ }
+
+
+ /**
+ * Returns whether the specified wildcard constant has been matched.
+ */
+ private boolean isMatchingConstantIndex(int constantIndex)
+ {
+ return (matchedConstantFlags[constantIndex / 64] & (1L << constantIndex)) != 0;
+ }
+
+
private boolean matchingBranchOffsets(int offset,
int branchOffset1,
int branchOffset2)
@@ -532,11 +656,10 @@ implements InstructionVisitor,
// Check the literal argument.
return branchOffset1 == branchOffset2;
}
- else if ((matchedArgumentFlags & (1 << argumentIndex)) == 0)
+ else if (!isMatchingArgumentIndex(argumentIndex))
{
// Store a wildcard argument.
- matchedArguments[argumentIndex] = offset + branchOffset1;
- matchedArgumentFlags |= 1 << argumentIndex;
+ setMatchingArgument(argumentIndex, offset + branchOffset1);
return true;
}
@@ -595,9 +718,6 @@ implements InstructionVisitor,
// Did we match all instructions in the sequence?
matching = patternInstructionIndex == patternInstructions.length;
- // Did we match any wildcards along the way?
- matchingAnyWildCards = matchedArgumentFlags != 0;
-
if (matching)
{
if (DEBUG)
diff --git a/src/proguard/classfile/util/InternalTypeEnumeration.java b/src/proguard/classfile/util/InternalTypeEnumeration.java
index 76f7e84..8658be3 100644
--- a/src/proguard/classfile/util/InternalTypeEnumeration.java
+++ b/src/proguard/classfile/util/InternalTypeEnumeration.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/MemberFinder.java b/src/proguard/classfile/util/MemberFinder.java
index 0fdeec0..6108b6d 100644
--- a/src/proguard/classfile/util/MemberFinder.java
+++ b/src/proguard/classfile/util/MemberFinder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/MethodLinker.java b/src/proguard/classfile/util/MethodLinker.java
index 5f2ea6f..8aed77a 100644
--- a/src/proguard/classfile/util/MethodLinker.java
+++ b/src/proguard/classfile/util/MethodLinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -26,16 +26,11 @@ import proguard.classfile.visitor.*;
import java.util.*;
/**
- * This ClassVisitor links all corresponding non-private methods in the class
- * hierarchies of all visited classes. Visited classes are typically all class
- * files that are not being subclassed. Chains of links that have been created
- * in previous invocations are merged with new chains of links, in order to
- * create a consistent set of chains.
- * <p>
- * As a MemberVisitor, it links all corresponding class members that it visits,
- * including fields and private class members.
- * <p>
- * Class initialization methods and constructors are always ignored.
+ * This ClassVisitor links all corresponding non-private, non-static,
+ * non-initializer methods in the class hierarchies of all visited classes.
+ * Visited classes are typically all class files that are not being subclassed.
+ * Chains of links that have been created in previous invocations are merged
+ * with new chains of links, in order to create a consistent set of chains.
*
* @author Eric Lafortune
*/
@@ -56,7 +51,7 @@ implements ClassVisitor,
// Collect all non-private members in this class hierarchy.
clazz.hierarchyAccept(true, true, true, false,
new AllMethodVisitor(
- new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
+ new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE | ClassConstants.INTERNAL_ACC_STATIC,
this)));
// Clean up for the next class hierarchy.
diff --git a/src/proguard/classfile/util/SimplifiedVisitor.java b/src/proguard/classfile/util/SimplifiedVisitor.java
index 87b7fe4..55b3848 100644
--- a/src/proguard/classfile/util/SimplifiedVisitor.java
+++ b/src/proguard/classfile/util/SimplifiedVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -42,7 +42,7 @@ public abstract class SimplifiedVisitor
/**
* Visits any type of class member of the given class.
*/
- public void visitAnyClass(Clazz Clazz)
+ public void visitAnyClass(Clazz clazz)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
@@ -157,6 +157,18 @@ public abstract class SimplifiedVisitor
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ visitAnyConstant(clazz, invokeDynamicConstant);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ visitAnyConstant(clazz, methodHandleConstant);
+ }
+
+
/**
* Visits any type of RefConstant of the given class.
*/
@@ -199,6 +211,12 @@ public abstract class SimplifiedVisitor
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ visitAnyConstant(clazz, methodTypeConstant);
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
visitAnyConstant(clazz, nameAndTypeConstant);
@@ -222,6 +240,12 @@ public abstract class SimplifiedVisitor
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ visitAnyAttribute(clazz, bootstrapMethodsAttribute);
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
visitAnyAttribute(clazz, sourceFileAttribute);
diff --git a/src/proguard/classfile/util/StringReferenceInitializer.java b/src/proguard/classfile/util/StringReferenceInitializer.java
index 3884a04..aff9b9f 100644
--- a/src/proguard/classfile/util/StringReferenceInitializer.java
+++ b/src/proguard/classfile/util/StringReferenceInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -62,7 +62,8 @@ implements ConstantVisitor
{
// See if we can find the referenced class.
stringConstant.referencedClass =
- findClass(ClassUtil.internalClassName(stringConstant.getString(clazz)));
+ findClass(ClassUtil.internalClassName(
+ ClassUtil.externalBaseType(stringConstant.getString(clazz))));
}
}
diff --git a/src/proguard/classfile/util/StringSharer.java b/src/proguard/classfile/util/StringSharer.java
index 56de7c5..04dc1d0 100644
--- a/src/proguard/classfile/util/StringSharer.java
+++ b/src/proguard/classfile/util/StringSharer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -64,6 +64,23 @@ implements ClassVisitor,
{
libraryClass.superClassName = superClass.getName();
}
+
+ // Replace the interface name strings by the shared name strings.
+ if (libraryClass.interfaceNames != null)
+ {
+ String[] interfaceNames = libraryClass.interfaceNames;
+ Clazz[] interfaceClasses = new Clazz[interfaceNames.length];
+
+ for (int index = 0; index < interfaceNames.length; index++)
+ {
+ // Keep a reference to the interface class.
+ Clazz interfaceClass = interfaceClasses[index];
+ if (interfaceClass != null)
+ {
+ interfaceNames[index] = interfaceClass.getName();
+ }
+ }
+ }
}
@@ -73,7 +90,7 @@ implements ClassVisitor,
public void visitAnyConstant(Clazz clazz, Constant constant) {}
- public void visitAnyStringConstant(Clazz clazz, StringConstant stringConstant)
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
Member referencedMember = stringConstant.referencedMember;
if (referencedMember != null)
diff --git a/src/proguard/classfile/util/WarningPrinter.java b/src/proguard/classfile/util/WarningPrinter.java
index 87d8978..de66bd6 100644
--- a/src/proguard/classfile/util/WarningPrinter.java
+++ b/src/proguard/classfile/util/WarningPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/AllClassVisitor.java b/src/proguard/classfile/visitor/AllClassVisitor.java
index 06aca2c..ea6272d 100644
--- a/src/proguard/classfile/visitor/AllClassVisitor.java
+++ b/src/proguard/classfile/visitor/AllClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/AllFieldVisitor.java b/src/proguard/classfile/visitor/AllFieldVisitor.java
index 8bff7d4..40af76c 100644
--- a/src/proguard/classfile/visitor/AllFieldVisitor.java
+++ b/src/proguard/classfile/visitor/AllFieldVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/AllMemberVisitor.java b/src/proguard/classfile/visitor/AllMemberVisitor.java
index 448470e..2a6f34e 100644
--- a/src/proguard/classfile/visitor/AllMemberVisitor.java
+++ b/src/proguard/classfile/visitor/AllMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/AllMethodVisitor.java b/src/proguard/classfile/visitor/AllMethodVisitor.java
index 75b919d..2526a6a 100644
--- a/src/proguard/classfile/visitor/AllMethodVisitor.java
+++ b/src/proguard/classfile/visitor/AllMethodVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/BottomClassFilter.java b/src/proguard/classfile/visitor/BottomClassFilter.java
index 8f5bdd1..6f442ac 100644
--- a/src/proguard/classfile/visitor/BottomClassFilter.java
+++ b/src/proguard/classfile/visitor/BottomClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassAccessFilter.java b/src/proguard/classfile/visitor/ClassAccessFilter.java
index a8815b6..cab208f 100644
--- a/src/proguard/classfile/visitor/ClassAccessFilter.java
+++ b/src/proguard/classfile/visitor/ClassAccessFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassCleaner.java b/src/proguard/classfile/visitor/ClassCleaner.java
index 36165ef..4dd1790 100644
--- a/src/proguard/classfile/visitor/ClassCleaner.java
+++ b/src/proguard/classfile/visitor/ClassCleaner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassCollector.java b/src/proguard/classfile/visitor/ClassCollector.java
index a69fe76..07c6a15 100644
--- a/src/proguard/classfile/visitor/ClassCollector.java
+++ b/src/proguard/classfile/visitor/ClassCollector.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassCounter.java b/src/proguard/classfile/visitor/ClassCounter.java
index c58c090..3c2dac7 100644
--- a/src/proguard/classfile/visitor/ClassCounter.java
+++ b/src/proguard/classfile/visitor/ClassCounter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassHierarchyTraveler.java b/src/proguard/classfile/visitor/ClassHierarchyTraveler.java
index 2e1755e..116b0bf 100644
--- a/src/proguard/classfile/visitor/ClassHierarchyTraveler.java
+++ b/src/proguard/classfile/visitor/ClassHierarchyTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassNameFilter.java b/src/proguard/classfile/visitor/ClassNameFilter.java
index c016a34..64f5a61 100644
--- a/src/proguard/classfile/visitor/ClassNameFilter.java
+++ b/src/proguard/classfile/visitor/ClassNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassPoolFiller.java b/src/proguard/classfile/visitor/ClassPoolFiller.java
index e1773de..c9efaa0 100644
--- a/src/proguard/classfile/visitor/ClassPoolFiller.java
+++ b/src/proguard/classfile/visitor/ClassPoolFiller.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassPoolVisitor.java b/src/proguard/classfile/visitor/ClassPoolVisitor.java
index 0b659dc..da2876f 100644
--- a/src/proguard/classfile/visitor/ClassPoolVisitor.java
+++ b/src/proguard/classfile/visitor/ClassPoolVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassPresenceFilter.java b/src/proguard/classfile/visitor/ClassPresenceFilter.java
index 429c340..bb90e22 100644
--- a/src/proguard/classfile/visitor/ClassPresenceFilter.java
+++ b/src/proguard/classfile/visitor/ClassPresenceFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassPrinter.java b/src/proguard/classfile/visitor/ClassPrinter.java
index 1da7d16..8d35ab7 100644
--- a/src/proguard/classfile/visitor/ClassPrinter.java
+++ b/src/proguard/classfile/visitor/ClassPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -48,8 +48,9 @@ implements ClassVisitor,
ConstantVisitor,
MemberVisitor,
AttributeVisitor,
- ExceptionInfoVisitor,
+ BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
+ ExceptionInfoVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
LineNumberInfoVisitor,
@@ -62,7 +63,8 @@ implements ClassVisitor,
private static final String INDENTATION = " ";
private final PrintStream ps;
- private int indentation;
+
+ private int indentation;
/**
@@ -222,10 +224,30 @@ implements ClassVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ println(visitorInfo(invokeDynamicConstant) + " InvokeDynamic [bootstrap method index = " + invokeDynamicConstant.u2bootstrapMethodAttributeIndex + "]:");
+
+ indent();
+ clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this);
+ outdent();
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ println(visitorInfo(methodHandleConstant) + " MethodHandle [kind = " + methodHandleConstant.u1referenceKind + "]:");
+
+ indent();
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ outdent();
+ }
+
+
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
println(visitorInfo(fieldrefConstant) + " Fieldref [" +
- clazz.getClassName(fieldrefConstant.u2classIndex) + "." +
+ clazz.getClassName(fieldrefConstant.u2classIndex) + "." +
clazz.getName(fieldrefConstant.u2nameAndTypeIndex) + " " +
clazz.getType(fieldrefConstant.u2nameAndTypeIndex) + "]");
}
@@ -256,6 +278,13 @@ implements ClassVisitor,
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ println(visitorInfo(methodTypeConstant) + " MethodType [" +
+ clazz.getString(methodTypeConstant.u2descriptorIndex) + "]");
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
println(visitorInfo(nameAndTypeConstant) + " NameAndType [" +
@@ -361,6 +390,17 @@ implements ClassVisitor,
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ println(visitorInfo(bootstrapMethodsAttribute) +
+ " Bootstrap methods attribute (count = " + bootstrapMethodsAttribute.u2bootstrapMethodsCount + "):");
+
+ indent();
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
+ outdent();
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
println(visitorInfo(sourceFileAttribute) +
@@ -595,6 +635,21 @@ implements ClassVisitor,
}
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ println(visitorInfo(bootstrapMethodInfo) +
+ " BootstrapMethodInfo (argument count = " +
+ bootstrapMethodInfo.u2methodArgumentCount+ "):");
+
+ indent();
+ clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this);
+ bootstrapMethodInfo.methodArgumentsAccept(clazz, this);
+ outdent();
+ }
+
+
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
@@ -603,6 +658,8 @@ implements ClassVisitor,
" InnerClassesInfo:");
indent();
+ println("Access flags: 0x" + Integer.toHexString(innerClassesInfo.u2innerClassAccessFlags) + " = " +
+ ClassUtil.externalClassAccessFlags(innerClassesInfo.u2innerClassAccessFlags));
innerClassesInfo.innerClassConstantAccept(clazz, this);
innerClassesInfo.outerClassConstantAccept(clazz, this);
innerClassesInfo.innerNameConstantAccept(clazz, this);
@@ -816,7 +873,7 @@ implements ClassVisitor,
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
- println("#" + localVariableInfo.u2index + ": " +
+ println("v" + localVariableInfo.u2index + ": " +
localVariableInfo.u2startPC + " -> " +
(localVariableInfo.u2startPC + localVariableInfo.u2length) + " [" +
clazz.getString(localVariableInfo.u2descriptorIndex) + " " +
@@ -828,7 +885,7 @@ implements ClassVisitor,
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
- println("#" + localVariableTypeInfo.u2index + ": " +
+ println("v" + localVariableTypeInfo.u2index + ": " +
localVariableTypeInfo.u2startPC + " -> " +
(localVariableTypeInfo.u2startPC + localVariableTypeInfo.u2length) + " [" +
clazz.getString(localVariableTypeInfo.u2signatureIndex) + " " +
diff --git a/src/proguard/classfile/visitor/ClassVersionFilter.java b/src/proguard/classfile/visitor/ClassVersionFilter.java
index 578cabf..4400ea3 100644
--- a/src/proguard/classfile/visitor/ClassVersionFilter.java
+++ b/src/proguard/classfile/visitor/ClassVersionFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -39,6 +39,19 @@ public class ClassVersionFilter implements ClassVisitor
/**
* Creates a new ClassVersionFilter.
* @param minimumClassVersion the minimum class version number.
+ * @param classVisitor the <code>ClassVisitor</code> to which visits
+ * will be delegated.
+ */
+ public ClassVersionFilter(int minimumClassVersion,
+ ClassVisitor classVisitor)
+ {
+ this(minimumClassVersion, Integer.MAX_VALUE, classVisitor);
+ }
+
+
+ /**
+ * Creates a new ClassVersionFilter.
+ * @param minimumClassVersion the minimum class version number.
* @param maximumClassVersion the maximum class version number.
* @param classVisitor the <code>ClassVisitor</code> to which visits
* will be delegated.
diff --git a/src/proguard/classfile/visitor/ClassVersionSetter.java b/src/proguard/classfile/visitor/ClassVersionSetter.java
index 34dfbc1..4090d44 100644
--- a/src/proguard/classfile/visitor/ClassVersionSetter.java
+++ b/src/proguard/classfile/visitor/ClassVersionSetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassVisitor.java b/src/proguard/classfile/visitor/ClassVisitor.java
index fdba2df..989910c 100644
--- a/src/proguard/classfile/visitor/ClassVisitor.java
+++ b/src/proguard/classfile/visitor/ClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java b/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java
index ec3fe68..0c8a9bc 100644
--- a/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java
+++ b/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/DotClassClassVisitor.java b/src/proguard/classfile/visitor/DotClassClassVisitor.java
index 263dbd5..8289f42 100644
--- a/src/proguard/classfile/visitor/DotClassClassVisitor.java
+++ b/src/proguard/classfile/visitor/DotClassClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -36,8 +36,6 @@ import proguard.classfile.util.SimplifiedVisitor;
* Note that before JDK 1.5, <code>.class</code> constructs are actually
* compiled differently, using <code>Class.forName</code> constructs.
*
- * @see ClassForNameClassVisitor
- *
* @author Eric Lafortune
*/
public class DotClassClassVisitor
diff --git a/src/proguard/classfile/visitor/ExceptClassFilter.java b/src/proguard/classfile/visitor/ExceptClassFilter.java
index 924485e..c9694e6 100644
--- a/src/proguard/classfile/visitor/ExceptClassFilter.java
+++ b/src/proguard/classfile/visitor/ExceptClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ExceptClassesFilter.java b/src/proguard/classfile/visitor/ExceptClassesFilter.java
index 7380c40..ae70ffe 100644
--- a/src/proguard/classfile/visitor/ExceptClassesFilter.java
+++ b/src/proguard/classfile/visitor/ExceptClassesFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ExceptionCounter.java b/src/proguard/classfile/visitor/ExceptionCounter.java
index c324129..e750b69 100644
--- a/src/proguard/classfile/visitor/ExceptionCounter.java
+++ b/src/proguard/classfile/visitor/ExceptionCounter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java b/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java
index 3911e39..27e1159 100644
--- a/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java
+++ b/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java b/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java
index e0fdec3..c77fb83 100644
--- a/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java
+++ b/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ExceptionHandlerFilter.java b/src/proguard/classfile/visitor/ExceptionHandlerFilter.java
index a90fb56..74ccbe5 100644
--- a/src/proguard/classfile/visitor/ExceptionHandlerFilter.java
+++ b/src/proguard/classfile/visitor/ExceptionHandlerFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ExceptionOffsetFilter.java b/src/proguard/classfile/visitor/ExceptionOffsetFilter.java
index e2a4fc9..d9fa3c7 100644
--- a/src/proguard/classfile/visitor/ExceptionOffsetFilter.java
+++ b/src/proguard/classfile/visitor/ExceptionOffsetFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ExceptionRangeFilter.java b/src/proguard/classfile/visitor/ExceptionRangeFilter.java
index c541b1f..b094907 100644
--- a/src/proguard/classfile/visitor/ExceptionRangeFilter.java
+++ b/src/proguard/classfile/visitor/ExceptionRangeFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java b/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java
index 6fe2e7d..574bbf1 100644
--- a/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java
+++ b/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ImplementedClassFilter.java b/src/proguard/classfile/visitor/ImplementedClassFilter.java
index 955a74e..d2b5ce0 100644
--- a/src/proguard/classfile/visitor/ImplementedClassFilter.java
+++ b/src/proguard/classfile/visitor/ImplementedClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java b/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java
index 9e9cea3..d052916 100644
--- a/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java
+++ b/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/LibraryClassFilter.java b/src/proguard/classfile/visitor/LibraryClassFilter.java
index 0e40f2f..1d00e1d 100644
--- a/src/proguard/classfile/visitor/LibraryClassFilter.java
+++ b/src/proguard/classfile/visitor/LibraryClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/LibraryMemberFilter.java b/src/proguard/classfile/visitor/LibraryMemberFilter.java
index 0ee80e5..d006d8d 100644
--- a/src/proguard/classfile/visitor/LibraryMemberFilter.java
+++ b/src/proguard/classfile/visitor/LibraryMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberAccessFilter.java b/src/proguard/classfile/visitor/MemberAccessFilter.java
index 6fd32e3..baf5173 100644
--- a/src/proguard/classfile/visitor/MemberAccessFilter.java
+++ b/src/proguard/classfile/visitor/MemberAccessFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberClassAccessFilter.java b/src/proguard/classfile/visitor/MemberClassAccessFilter.java
index 85272ff..0c5bfdd 100644
--- a/src/proguard/classfile/visitor/MemberClassAccessFilter.java
+++ b/src/proguard/classfile/visitor/MemberClassAccessFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberCollector.java b/src/proguard/classfile/visitor/MemberCollector.java
index ec68b2d..1373409 100644
--- a/src/proguard/classfile/visitor/MemberCollector.java
+++ b/src/proguard/classfile/visitor/MemberCollector.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberCounter.java b/src/proguard/classfile/visitor/MemberCounter.java
index c2da72e..f6f1204 100644
--- a/src/proguard/classfile/visitor/MemberCounter.java
+++ b/src/proguard/classfile/visitor/MemberCounter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberDescriptorFilter.java b/src/proguard/classfile/visitor/MemberDescriptorFilter.java
index bd69304..81251e0 100644
--- a/src/proguard/classfile/visitor/MemberDescriptorFilter.java
+++ b/src/proguard/classfile/visitor/MemberDescriptorFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberNameFilter.java b/src/proguard/classfile/visitor/MemberNameFilter.java
index 0fe450e..f638f09 100644
--- a/src/proguard/classfile/visitor/MemberNameFilter.java
+++ b/src/proguard/classfile/visitor/MemberNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberToClassVisitor.java b/src/proguard/classfile/visitor/MemberToClassVisitor.java
index a405cfc..b5b0385 100644
--- a/src/proguard/classfile/visitor/MemberToClassVisitor.java
+++ b/src/proguard/classfile/visitor/MemberToClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberVisitor.java b/src/proguard/classfile/visitor/MemberVisitor.java
index 01fdf71..c0d48cb 100644
--- a/src/proguard/classfile/visitor/MemberVisitor.java
+++ b/src/proguard/classfile/visitor/MemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MethodImplementationFilter.java b/src/proguard/classfile/visitor/MethodImplementationFilter.java
index 57d923a..c4af8b0 100644
--- a/src/proguard/classfile/visitor/MethodImplementationFilter.java
+++ b/src/proguard/classfile/visitor/MethodImplementationFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MethodImplementationTraveler.java b/src/proguard/classfile/visitor/MethodImplementationTraveler.java
index dc0ea36..d696215 100644
--- a/src/proguard/classfile/visitor/MethodImplementationTraveler.java
+++ b/src/proguard/classfile/visitor/MethodImplementationTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MultiClassPoolVisitor.java b/src/proguard/classfile/visitor/MultiClassPoolVisitor.java
index 044d55a..a52c1d6 100644
--- a/src/proguard/classfile/visitor/MultiClassPoolVisitor.java
+++ b/src/proguard/classfile/visitor/MultiClassPoolVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MultiClassVisitor.java b/src/proguard/classfile/visitor/MultiClassVisitor.java
index d34d91e..d8ac3d7 100644
--- a/src/proguard/classfile/visitor/MultiClassVisitor.java
+++ b/src/proguard/classfile/visitor/MultiClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MultiMemberVisitor.java b/src/proguard/classfile/visitor/MultiMemberVisitor.java
index cc4629c..609b6a9 100644
--- a/src/proguard/classfile/visitor/MultiMemberVisitor.java
+++ b/src/proguard/classfile/visitor/MultiMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/NamedClassVisitor.java b/src/proguard/classfile/visitor/NamedClassVisitor.java
index a14d04a..a0d9fc5 100644
--- a/src/proguard/classfile/visitor/NamedClassVisitor.java
+++ b/src/proguard/classfile/visitor/NamedClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/NamedFieldVisitor.java b/src/proguard/classfile/visitor/NamedFieldVisitor.java
index 76b66c6..7ccf0fe 100644
--- a/src/proguard/classfile/visitor/NamedFieldVisitor.java
+++ b/src/proguard/classfile/visitor/NamedFieldVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/NamedMethodVisitor.java b/src/proguard/classfile/visitor/NamedMethodVisitor.java
index d4611c1..3f94680 100644
--- a/src/proguard/classfile/visitor/NamedMethodVisitor.java
+++ b/src/proguard/classfile/visitor/NamedMethodVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ProgramClassFilter.java b/src/proguard/classfile/visitor/ProgramClassFilter.java
index fba3b21..98e4e15 100644
--- a/src/proguard/classfile/visitor/ProgramClassFilter.java
+++ b/src/proguard/classfile/visitor/ProgramClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ProgramMemberFilter.java b/src/proguard/classfile/visitor/ProgramMemberFilter.java
index 048a1e6..dd21cea 100644
--- a/src/proguard/classfile/visitor/ProgramMemberFilter.java
+++ b/src/proguard/classfile/visitor/ProgramMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ReferencedClassVisitor.java b/src/proguard/classfile/visitor/ReferencedClassVisitor.java
index 986c3f9..5b4ee20 100644
--- a/src/proguard/classfile/visitor/ReferencedClassVisitor.java
+++ b/src/proguard/classfile/visitor/ReferencedClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -123,6 +123,13 @@ implements ClassVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Let the visitor visit the class referenced in the reference constant.
+ invokeDynamicConstant.referencedClassesAccept(classVisitor);
+ }
+
+
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Let the visitor visit the class referenced in the class constant.
diff --git a/src/proguard/classfile/visitor/ReferencedMemberVisitor.java b/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
index c4d34b8..762cb06 100644
--- a/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
+++ b/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/SimilarMemberVisitor.java b/src/proguard/classfile/visitor/SimilarMemberVisitor.java
index 6dc06af..9df79cb 100644
--- a/src/proguard/classfile/visitor/SimilarMemberVisitor.java
+++ b/src/proguard/classfile/visitor/SimilarMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/SimpleClassPrinter.java b/src/proguard/classfile/visitor/SimpleClassPrinter.java
index a661110..b025ebf 100644
--- a/src/proguard/classfile/visitor/SimpleClassPrinter.java
+++ b/src/proguard/classfile/visitor/SimpleClassPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/SubclassFilter.java b/src/proguard/classfile/visitor/SubclassFilter.java
index 69ea1a1..cecb0b6 100644
--- a/src/proguard/classfile/visitor/SubclassFilter.java
+++ b/src/proguard/classfile/visitor/SubclassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/SubclassTraveler.java b/src/proguard/classfile/visitor/SubclassTraveler.java
index 4170341..505510d 100644
--- a/src/proguard/classfile/visitor/SubclassTraveler.java
+++ b/src/proguard/classfile/visitor/SubclassTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/VariableClassVisitor.java b/src/proguard/classfile/visitor/VariableClassVisitor.java
index 2f575c4..b9a40f1 100644
--- a/src/proguard/classfile/visitor/VariableClassVisitor.java
+++ b/src/proguard/classfile/visitor/VariableClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/VariableMemberVisitor.java b/src/proguard/classfile/visitor/VariableMemberVisitor.java
index c58cff3..7b93a62 100644
--- a/src/proguard/classfile/visitor/VariableMemberVisitor.java
+++ b/src/proguard/classfile/visitor/VariableMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/BasicBranchUnit.java b/src/proguard/evaluation/BasicBranchUnit.java
index 3a2db76..1c01888 100644
--- a/src/proguard/evaluation/BasicBranchUnit.java
+++ b/src/proguard/evaluation/BasicBranchUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/BasicInvocationUnit.java b/src/proguard/evaluation/BasicInvocationUnit.java
index bccd866..33b0d0c 100644
--- a/src/proguard/evaluation/BasicInvocationUnit.java
+++ b/src/proguard/evaluation/BasicInvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -162,6 +162,7 @@ implements InvocationUnit,
break;
case InstructionConstants.OP_INVOKESTATIC:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
isStatic = true;
break;
@@ -230,6 +231,31 @@ implements InvocationUnit,
}
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ String type = invokeDynamicConstant.getType(clazz);
+
+ // Count the number of parameters.
+ int parameterCount = ClassUtil.internalMethodParameterCount(type);
+ if (!isStatic)
+ {
+ parameterCount++;
+ }
+
+ // Pop the parameters and the class reference, in reverse order.
+ for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--)
+ {
+ stack.pop();
+ }
+
+ // Push the return value, if applicable.
+ String returnType = ClassUtil.internalMethodReturnType(type);
+ if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID)
+ {
+ stack.push(getMethodReturnValue(clazz, invokeDynamicConstant, returnType));
+ }
+ }
+
/**
* Sets the class through which the specified field is accessed.
@@ -340,6 +366,25 @@ implements InvocationUnit,
}
+ /**
+ * Returns the return value of the specified method.
+ */
+ protected Value getMethodReturnValue(Clazz clazz,
+ InvokeDynamicConstant invokeDynamicConstant,
+ String type)
+ {
+ // Try to figure out the class of the return type.
+ Clazz[] referencedClasses = invokeDynamicConstant.referencedClasses;
+
+ Clazz returnTypeClass = referencedClasses == null ? null :
+ referencedClasses[referencedClasses.length - 1];
+
+ return valueFactory.createValue(type,
+ returnTypeClass,
+ true);
+ }
+
+
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
diff --git a/src/proguard/evaluation/BranchUnit.java b/src/proguard/evaluation/BranchUnit.java
index b709807..1493b6f 100644
--- a/src/proguard/evaluation/BranchUnit.java
+++ b/src/proguard/evaluation/BranchUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/ClassConstantValueFactory.java b/src/proguard/evaluation/ClassConstantValueFactory.java
new file mode 100644
index 0000000..8214eea
--- /dev/null
+++ b/src/proguard/evaluation/ClassConstantValueFactory.java
@@ -0,0 +1,53 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.evaluation;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.evaluation.value.*;
+
+/**
+ * This class creates java.lang.Class ReferenceValue instances that correspond
+ * to specified constant pool entries.
+ *
+ * @author Eric Lafortune
+ */
+public class ClassConstantValueFactory
+extends ConstantValueFactory
+{
+ public ClassConstantValueFactory(ValueFactory valueFactory)
+ {
+ super(valueFactory);
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ // Create a Class reference instead of a reference to the class.
+ value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS,
+ classConstant.javaLangClassClass,
+ false);
+ }
+} \ No newline at end of file
diff --git a/src/proguard/evaluation/ConstantValueFactory.java b/src/proguard/evaluation/ConstantValueFactory.java
new file mode 100644
index 0000000..e76b869
--- /dev/null
+++ b/src/proguard/evaluation/ConstantValueFactory.java
@@ -0,0 +1,113 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.evaluation;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.evaluation.value.*;
+
+/**
+ * This class creates Value instance that correspond to specified constant pool
+ * entries.
+ *
+ * @author Eric Lafortune
+ */
+public class ConstantValueFactory
+extends SimplifiedVisitor
+implements ConstantVisitor
+{
+ protected final ValueFactory valueFactory;
+
+ // Field acting as a parameter for the ConstantVisitor methods.
+ protected Value value;
+
+
+ public ConstantValueFactory(ValueFactory valueFactory)
+ {
+ this.valueFactory = valueFactory;
+ }
+
+
+ /**
+ * Returns the Value of the constant pool element at the given index.
+ */
+ public Value constantValue(Clazz clazz,
+ int constantIndex)
+ {
+ // Visit the constant pool entry to get its return value.
+ clazz.constantPoolEntryAccept(constantIndex, this);
+
+ return value;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
+ {
+ value = valueFactory.createIntegerValue(integerConstant.getValue());
+ }
+
+ public void visitLongConstant(Clazz clazz, LongConstant longConstant)
+ {
+ value = valueFactory.createLongValue(longConstant.getValue());
+ }
+
+ public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
+ {
+ value = valueFactory.createFloatValue(floatConstant.getValue());
+ }
+
+ public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
+ {
+ value = valueFactory.createDoubleValue(doubleConstant.getValue());
+ }
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING,
+ stringConstant.javaLangStringClass,
+ false);
+ }
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE,
+ methodHandleConstant.javaLangInvokeMethodHandleClass,
+ false);
+ }
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ value = valueFactory.createReferenceValue(classConstant.getName(clazz),
+ classConstant.referencedClass,
+ false);
+ }
+
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE,
+ methodTypeConstant.javaLangInvokeMethodTypeClass,
+ false);
+ }
+} \ No newline at end of file
diff --git a/src/proguard/evaluation/InvocationUnit.java b/src/proguard/evaluation/InvocationUnit.java
index cb4d3c5..a8809ee 100644
--- a/src/proguard/evaluation/InvocationUnit.java
+++ b/src/proguard/evaluation/InvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/Processor.java b/src/proguard/evaluation/Processor.java
index 74afd0b..b694d66 100644
--- a/src/proguard/evaluation/Processor.java
+++ b/src/proguard/evaluation/Processor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -22,11 +22,8 @@ package proguard.evaluation;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
-import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
import proguard.evaluation.value.*;
/**
@@ -36,9 +33,7 @@ import proguard.evaluation.value.*;
* @author Eric Lafortune
*/
public class Processor
-extends SimplifiedVisitor
-implements InstructionVisitor,
- ConstantVisitor
+implements InstructionVisitor
{
private final Variables variables;
private final Stack stack;
@@ -46,9 +41,8 @@ implements InstructionVisitor,
private final BranchUnit branchUnit;
private final InvocationUnit invocationUnit;
- // Fields acting as parameters for the ConstantVisitor methods.
- private boolean handleClassConstantAsClassValue;
- private Value cpValue;
+ private final ConstantValueFactory constantValueFactory;
+ private final ClassConstantValueFactory classConstantValueFactory;
/**
@@ -69,6 +63,9 @@ implements InstructionVisitor,
this.valueFactory = valueFactory;
this.branchUnit = branchUnit;
this.invocationUnit = invocationUnit;
+
+ constantValueFactory = new ConstantValueFactory(valueFactory);
+ classConstantValueFactory = new ClassConstantValueFactory(valueFactory);
}
@@ -561,7 +558,7 @@ implements InstructionVisitor,
case InstructionConstants.OP_LDC:
case InstructionConstants.OP_LDC_W:
case InstructionConstants.OP_LDC2_W:
- stack.push(cpValue(clazz, constantIndex, true));
+ stack.push(classConstantValueFactory.constantValue(clazz, constantIndex));
break;
case InstructionConstants.OP_GETSTATIC:
@@ -572,16 +569,17 @@ implements InstructionVisitor,
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
invocationUnit.invokeMember(clazz, method, codeAttribute, offset, constantInstruction, stack);
break;
case InstructionConstants.OP_NEW:
- stack.push(cpValue(clazz, constantIndex).referenceValue());
+ stack.push(constantValueFactory.constantValue(clazz, constantIndex).referenceValue());
break;
case InstructionConstants.OP_ANEWARRAY:
{
- ReferenceValue referenceValue = cpValue(clazz, constantIndex).referenceValue();
+ ReferenceValue referenceValue = constantValueFactory.constantValue(clazz, constantIndex).referenceValue();
stack.push(valueFactory.createArrayReferenceValue(referenceValue.internalType(),
referenceValue.getReferencedClass(),
@@ -594,14 +592,14 @@ implements InstructionVisitor,
ReferenceValue castValue = stack.apop();
ReferenceValue castResultValue =
castValue.isNull() == Value.ALWAYS ? castValue :
- castValue.isNull() == Value.NEVER ? cpValue(clazz, constantIndex).referenceValue() :
- cpValue(clazz, constantIndex).referenceValue().generalize(valueFactory.createReferenceValueNull());
+ castValue.isNull() == Value.NEVER ? constantValueFactory.constantValue(clazz, constantIndex).referenceValue() :
+ constantValueFactory.constantValue(clazz, constantIndex).referenceValue().generalize(valueFactory.createReferenceValueNull());
stack.push(castResultValue);
break;
case InstructionConstants.OP_INSTANCEOF:
{
- ReferenceValue referenceValue = cpValue(clazz, constantIndex).referenceValue();
+ ReferenceValue referenceValue = constantValueFactory.constantValue(clazz, constantIndex).referenceValue();
int instanceOf = stack.apop().instanceOf(referenceValue.getType(),
referenceValue.getReferencedClass());
@@ -621,7 +619,7 @@ implements InstructionVisitor,
IntegerValue arrayLength = stack.ipop();
}
- stack.push(cpValue(clazz, constantIndex).referenceValue());
+ stack.push(constantValueFactory.constantValue(clazz, constantIndex).referenceValue());
break;
}
@@ -907,73 +905,4 @@ implements InstructionVisitor,
}
}
}
-
-
- // Implementations for ConstantVisitor.
-
- public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
- {
- cpValue = valueFactory.createIntegerValue(integerConstant.getValue());
- }
-
- public void visitLongConstant(Clazz clazz, LongConstant longConstant)
- {
- cpValue = valueFactory.createLongValue(longConstant.getValue());
- }
-
- public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
- {
- cpValue = valueFactory.createFloatValue(floatConstant.getValue());
- }
-
- public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
- {
- cpValue = valueFactory.createDoubleValue(doubleConstant.getValue());
- }
-
- public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
- {
- cpValue = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING,
- stringConstant.javaLangStringClass,
- false);
- }
-
- public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
- {
- cpValue = handleClassConstantAsClassValue ?
- valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS,
- classConstant.javaLangClassClass,
- false) :
- valueFactory.createReferenceValue(classConstant.getName(clazz),
- classConstant.referencedClass,
- false);
- }
-
-
- // Small utility methods.
-
- /**
- * Returns the Value of the constant pool element at the given index.
- */
- private Value cpValue(Clazz clazz,
- int constantIndex)
- {
- return cpValue(clazz, constantIndex, false);
- }
-
-
- /**
- * Returns the Value of the constant pool element at the given index.
- */
- private Value cpValue(Clazz clazz,
- int constantIndex,
- boolean handleClassConstantAsClassValue)
- {
- this.handleClassConstantAsClassValue = handleClassConstantAsClassValue;
-
- // Visit the constant pool entry to get its return value.
- clazz.constantPoolEntryAccept(constantIndex, this);
-
- return cpValue;
- }
}
diff --git a/src/proguard/evaluation/Stack.java b/src/proguard/evaluation/Stack.java
index 2808e62..46c1b40 100644
--- a/src/proguard/evaluation/Stack.java
+++ b/src/proguard/evaluation/Stack.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -22,6 +22,8 @@ package proguard.evaluation;
import proguard.evaluation.value.*;
+import java.util.Arrays;
+
/**
* This class represents an operand stack that contains <code>Value</code>
* objects.
@@ -163,10 +165,7 @@ public class Stack
public void clear()
{
// Clear the stack contents.
- for (int index = 0; index < currentSize; index++)
- {
- values[index] = null;
- }
+ Arrays.fill(values, 0, currentSize, null);
currentSize = 0;
}
diff --git a/src/proguard/evaluation/TracedStack.java b/src/proguard/evaluation/TracedStack.java
index c24f783..3c3def4 100644
--- a/src/proguard/evaluation/TracedStack.java
+++ b/src/proguard/evaluation/TracedStack.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/TracedVariables.java b/src/proguard/evaluation/TracedVariables.java
index 1ae6ba6..5f58f97 100644
--- a/src/proguard/evaluation/TracedVariables.java
+++ b/src/proguard/evaluation/TracedVariables.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -30,9 +30,6 @@ import proguard.evaluation.value.Value;
* stores. It then generalizes a given collected Value with the producer Value
* of each Value it loads. The producer Value and the initial collected Value
* can be set; the generalized collected Value can be retrieved.
- * <p>
- * In addition, an initialization index can be reset and retrieved, pointing
- * to the most recent variable that has been initialized by a store operation.
*
* @author Eric Lafortune
*/
@@ -43,7 +40,6 @@ public class TracedVariables extends Variables
private Value producerValue;
private Variables producerVariables;
- private int initializationIndex;
/**
@@ -78,24 +74,6 @@ public class TracedVariables extends Variables
/**
- * Resets the initialization index.
- */
- public void resetInitialization()
- {
- initializationIndex = NONE;
- }
-
-
- /**
- * Returns the most recent initialization index since it has been reset.
- */
- public int getInitializationIndex()
- {
- return initializationIndex;
- }
-
-
- /**
* Gets the producer Value for the specified variable, without disturbing it.
* @param index the variable index.
* @return the producer value of the given variable.
@@ -164,14 +142,6 @@ public class TracedVariables extends Variables
public void store(int index, Value value)
{
- // Is this store operation an initialization of the variable?
- Value previousValue = super.load(index);
- if (previousValue == null ||
- previousValue.computationalType() != value.computationalType())
- {
- initializationIndex = index;
- }
-
// Store the value itself in the variable.
super.store(index, value);
diff --git a/src/proguard/evaluation/Variables.java b/src/proguard/evaluation/Variables.java
index 4496aaa..0cf2584 100644
--- a/src/proguard/evaluation/Variables.java
+++ b/src/proguard/evaluation/Variables.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -22,6 +22,8 @@ package proguard.evaluation;
import proguard.evaluation.value.*;
+import java.util.Arrays;
+
/**
* This class represents a local variable frame that contains <code>Value</code>
* objects. Values are generalizations of all values that have been stored in
@@ -75,10 +77,7 @@ public class Variables
else
{
// Clear the variables.
- for (int index = 0; index < values.length; index++)
- {
- values[index] = null;
- }
+ Arrays.fill(values, null);
}
this.size = size;
diff --git a/src/proguard/evaluation/value/Category1Value.java b/src/proguard/evaluation/value/Category1Value.java
index b8c5db2..0d5650b 100644
--- a/src/proguard/evaluation/value/Category1Value.java
+++ b/src/proguard/evaluation/value/Category1Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/Category2Value.java b/src/proguard/evaluation/value/Category2Value.java
index 65916c7..dde0625 100644
--- a/src/proguard/evaluation/value/Category2Value.java
+++ b/src/proguard/evaluation/value/Category2Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ComparisonValue.java b/src/proguard/evaluation/value/ComparisonValue.java
index e4e2e02..55c942c 100644
--- a/src/proguard/evaluation/value/ComparisonValue.java
+++ b/src/proguard/evaluation/value/ComparisonValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -35,11 +35,11 @@ final class ComparisonValue extends SpecificIntegerValue
/**
* Creates a new comparison integer value of the two given scalar values.
*/
- public ComparisonValue(Value integerValue1,
- Value integerValue2)
+ public ComparisonValue(Value value1,
+ Value value2)
{
- this.value1 = integerValue1;
- this.value2 = integerValue2;
+ this.value1 = value1;
+ this.value2 = value2;
}
diff --git a/src/proguard/evaluation/value/CompositeDoubleValue.java b/src/proguard/evaluation/value/CompositeDoubleValue.java
index a6d48ef..d183dee 100644
--- a/src/proguard/evaluation/value/CompositeDoubleValue.java
+++ b/src/proguard/evaluation/value/CompositeDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/CompositeFloatValue.java b/src/proguard/evaluation/value/CompositeFloatValue.java
index 4df890a..ecc32bb 100644
--- a/src/proguard/evaluation/value/CompositeFloatValue.java
+++ b/src/proguard/evaluation/value/CompositeFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -36,7 +36,7 @@ final class CompositeFloatValue extends SpecificFloatValue
private final FloatValue floatValue1;
- private final byte operation;
+ private final byte operation;
private final FloatValue floatValue2;
@@ -45,11 +45,11 @@ final class CompositeFloatValue extends SpecificFloatValue
* and the given operation.
*/
public CompositeFloatValue(FloatValue floatValue1,
- byte operation,
- FloatValue floatValue2)
+ byte operation,
+ FloatValue floatValue2)
{
this.floatValue1 = floatValue1;
- this.operation = operation;
+ this.operation = operation;
this.floatValue2 = floatValue2;
}
diff --git a/src/proguard/evaluation/value/CompositeIntegerValue.java b/src/proguard/evaluation/value/CompositeIntegerValue.java
index 6d4f59c..a042fcf 100644
--- a/src/proguard/evaluation/value/CompositeIntegerValue.java
+++ b/src/proguard/evaluation/value/CompositeIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/CompositeLongValue.java b/src/proguard/evaluation/value/CompositeLongValue.java
index 7f63211..d4fa331 100644
--- a/src/proguard/evaluation/value/CompositeLongValue.java
+++ b/src/proguard/evaluation/value/CompositeLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedByteValue.java b/src/proguard/evaluation/value/ConvertedByteValue.java
index 7ab5d0a..115e7d1 100644
--- a/src/proguard/evaluation/value/ConvertedByteValue.java
+++ b/src/proguard/evaluation/value/ConvertedByteValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedCharacterValue.java b/src/proguard/evaluation/value/ConvertedCharacterValue.java
index 76568d1..88e0e25 100644
--- a/src/proguard/evaluation/value/ConvertedCharacterValue.java
+++ b/src/proguard/evaluation/value/ConvertedCharacterValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedDoubleValue.java b/src/proguard/evaluation/value/ConvertedDoubleValue.java
index a6afe34..943e2a5 100644
--- a/src/proguard/evaluation/value/ConvertedDoubleValue.java
+++ b/src/proguard/evaluation/value/ConvertedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedFloatValue.java b/src/proguard/evaluation/value/ConvertedFloatValue.java
index 33683b7..df4994d 100644
--- a/src/proguard/evaluation/value/ConvertedFloatValue.java
+++ b/src/proguard/evaluation/value/ConvertedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedIntegerValue.java b/src/proguard/evaluation/value/ConvertedIntegerValue.java
index aecb533..23ec03f 100644
--- a/src/proguard/evaluation/value/ConvertedIntegerValue.java
+++ b/src/proguard/evaluation/value/ConvertedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedLongValue.java b/src/proguard/evaluation/value/ConvertedLongValue.java
index ec97008..026bd5b 100644
--- a/src/proguard/evaluation/value/ConvertedLongValue.java
+++ b/src/proguard/evaluation/value/ConvertedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedShortValue.java b/src/proguard/evaluation/value/ConvertedShortValue.java
index ab79b49..c209d44 100644
--- a/src/proguard/evaluation/value/ConvertedShortValue.java
+++ b/src/proguard/evaluation/value/ConvertedShortValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/DoubleValue.java b/src/proguard/evaluation/value/DoubleValue.java
index e39ee5c..48d8f11 100644
--- a/src/proguard/evaluation/value/DoubleValue.java
+++ b/src/proguard/evaluation/value/DoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -342,11 +342,6 @@ public abstract class DoubleValue extends Category2Value
return this;
}
- public Value refresh()
- {
- return this;
- }
-
public final Value generalize(Value other)
{
return this.generalize(other.doubleValue());
diff --git a/src/proguard/evaluation/value/FloatValue.java b/src/proguard/evaluation/value/FloatValue.java
index b30e395..3783096 100644
--- a/src/proguard/evaluation/value/FloatValue.java
+++ b/src/proguard/evaluation/value/FloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedDoubleValue.java b/src/proguard/evaluation/value/IdentifiedDoubleValue.java
index 4009c6e..86393a7 100644
--- a/src/proguard/evaluation/value/IdentifiedDoubleValue.java
+++ b/src/proguard/evaluation/value/IdentifiedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedFloatValue.java b/src/proguard/evaluation/value/IdentifiedFloatValue.java
index 87bed64..363530b 100644
--- a/src/proguard/evaluation/value/IdentifiedFloatValue.java
+++ b/src/proguard/evaluation/value/IdentifiedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedIntegerValue.java b/src/proguard/evaluation/value/IdentifiedIntegerValue.java
index 66e88ee..57e73cb 100644
--- a/src/proguard/evaluation/value/IdentifiedIntegerValue.java
+++ b/src/proguard/evaluation/value/IdentifiedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedLongValue.java b/src/proguard/evaluation/value/IdentifiedLongValue.java
index eea1816..a0c4636 100644
--- a/src/proguard/evaluation/value/IdentifiedLongValue.java
+++ b/src/proguard/evaluation/value/IdentifiedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedReferenceValue.java b/src/proguard/evaluation/value/IdentifiedReferenceValue.java
index cb5efc1..1514d4d 100644
--- a/src/proguard/evaluation/value/IdentifiedReferenceValue.java
+++ b/src/proguard/evaluation/value/IdentifiedReferenceValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -57,6 +57,17 @@ final class IdentifiedReferenceValue extends ReferenceValue
}
+ // Implementations of binary methods of ReferenceValue.
+
+ public ReferenceValue generalize(ReferenceValue other)
+ {
+ // Remove the ID if both values don't share the same ID.
+ return this.equals(other) ?
+ this :
+ new ReferenceValue(type, referencedClass, mayBeNull).generalize(other);
+ }
+
+
// Implementations for Value.
public boolean isSpecific()
diff --git a/src/proguard/evaluation/value/IdentifiedValueFactory.java b/src/proguard/evaluation/value/IdentifiedValueFactory.java
index 2b14e72..f2a3cab 100644
--- a/src/proguard/evaluation/value/IdentifiedValueFactory.java
+++ b/src/proguard/evaluation/value/IdentifiedValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/InstructionOffsetValue.java b/src/proguard/evaluation/value/InstructionOffsetValue.java
index 10b5a6f..93d0380 100644
--- a/src/proguard/evaluation/value/InstructionOffsetValue.java
+++ b/src/proguard/evaluation/value/InstructionOffsetValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IntegerValue.java b/src/proguard/evaluation/value/IntegerValue.java
index 508c5f5..6a0775d 100644
--- a/src/proguard/evaluation/value/IntegerValue.java
+++ b/src/proguard/evaluation/value/IntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/LongValue.java b/src/proguard/evaluation/value/LongValue.java
index f7ba162..1d8f413 100644
--- a/src/proguard/evaluation/value/LongValue.java
+++ b/src/proguard/evaluation/value/LongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/NegatedDoubleValue.java b/src/proguard/evaluation/value/NegatedDoubleValue.java
index 2bc9423..6409f8c 100644
--- a/src/proguard/evaluation/value/NegatedDoubleValue.java
+++ b/src/proguard/evaluation/value/NegatedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/NegatedFloatValue.java b/src/proguard/evaluation/value/NegatedFloatValue.java
index 0ddf4ab..f0f7e40 100644
--- a/src/proguard/evaluation/value/NegatedFloatValue.java
+++ b/src/proguard/evaluation/value/NegatedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/NegatedIntegerValue.java b/src/proguard/evaluation/value/NegatedIntegerValue.java
index a89a2d9..74b857c 100644
--- a/src/proguard/evaluation/value/NegatedIntegerValue.java
+++ b/src/proguard/evaluation/value/NegatedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/NegatedLongValue.java b/src/proguard/evaluation/value/NegatedLongValue.java
index c3b22bb..3f97fd0 100644
--- a/src/proguard/evaluation/value/NegatedLongValue.java
+++ b/src/proguard/evaluation/value/NegatedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ParticularDoubleValue.java b/src/proguard/evaluation/value/ParticularDoubleValue.java
index 05bc559..383cae3 100644
--- a/src/proguard/evaluation/value/ParticularDoubleValue.java
+++ b/src/proguard/evaluation/value/ParticularDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -79,17 +79,23 @@ final class ParticularDoubleValue extends SpecificDoubleValue
public DoubleValue add(DoubleValue other)
{
- return value == 0.0 ? other : other.add(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other : other.add(this);
+ return other.add(this);
}
public DoubleValue subtract(DoubleValue other)
{
- return value == 0.0 ? other.negate() : other.subtractFrom(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other.negate() : other.subtractFrom(this);
+ return other.subtractFrom(this);
}
public DoubleValue subtractFrom(DoubleValue other)
{
- return value == 0.0 ? other : other.subtract(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other : other.subtract(this);
+ return other.subtract(this);
}
public DoubleValue multiply(DoubleValue other)
diff --git a/src/proguard/evaluation/value/ParticularFloatValue.java b/src/proguard/evaluation/value/ParticularFloatValue.java
index 59e4357..335765c 100644
--- a/src/proguard/evaluation/value/ParticularFloatValue.java
+++ b/src/proguard/evaluation/value/ParticularFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -79,17 +79,23 @@ final class ParticularFloatValue extends SpecificFloatValue
public FloatValue add(FloatValue other)
{
- return value == 0.0 ? other : other.add(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other : other.add(this);
+ return other.add(this);
}
public FloatValue subtract(FloatValue other)
{
- return value == 0.0 ? other.negate() : other.subtractFrom(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other.negate() : other.subtractFrom(this);
+ return other.subtractFrom(this);
}
public FloatValue subtractFrom(FloatValue other)
{
- return value == 0.0 ? other : other.subtract(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other : other.subtract(this);
+ return other.subtract(this);
}
public FloatValue multiply(FloatValue other)
diff --git a/src/proguard/evaluation/value/ParticularIntegerValue.java b/src/proguard/evaluation/value/ParticularIntegerValue.java
index 8a4ac1d..d6906e7 100644
--- a/src/proguard/evaluation/value/ParticularIntegerValue.java
+++ b/src/proguard/evaluation/value/ParticularIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ParticularLongValue.java b/src/proguard/evaluation/value/ParticularLongValue.java
index 61d2e04..22d9d1a 100644
--- a/src/proguard/evaluation/value/ParticularLongValue.java
+++ b/src/proguard/evaluation/value/ParticularLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ReferenceValue.java b/src/proguard/evaluation/value/ReferenceValue.java
index 418c6f8..084a1a4 100644
--- a/src/proguard/evaluation/value/ReferenceValue.java
+++ b/src/proguard/evaluation/value/ReferenceValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -280,11 +280,25 @@ public class ReferenceValue extends Category1Value
thisReferencedClass.hierarchyAccept(false, true, true, false,
new ClassCollector(thisSuperClasses));
+ int thisSuperClassesCount = thisSuperClasses.size();
+ if (thisSuperClassesCount == 0 &&
+ thisReferencedClass.getSuperName() != null)
+ {
+ throw new IllegalArgumentException("Can't find any super classes of ["+thisType+"] (not even immediate super class ["+thisReferencedClass.getSuperName()+"])");
+ }
+
// Collect the superclasses and interfaces of the other class.
Set otherSuperClasses = new HashSet();
otherReferencedClass.hierarchyAccept(false, true, true, false,
new ClassCollector(otherSuperClasses));
+ int otherSuperClassesCount = otherSuperClasses.size();
+ if (otherSuperClassesCount == 0 &&
+ otherReferencedClass.getSuperName() != null)
+ {
+ throw new IllegalArgumentException("Can't find any super classes of ["+otherType+"] (not even immediate super class ["+otherReferencedClass.getSuperName()+"])");
+ }
+
if (DEBUG)
{
System.out.println("ReferenceValue.generalize this ["+thisReferencedClass.getName()+"] with other ["+otherReferencedClass.getName()+"]");
@@ -302,7 +316,7 @@ public class ReferenceValue extends Category1Value
// Find a class that is a subclass of all common superclasses,
// or that at least has the maximum number of common superclasses.
- Clazz commonClazz = null;
+ Clazz commonClass = null;
int maximumSuperClassCount = -1;
@@ -317,31 +331,33 @@ public class ReferenceValue extends Category1Value
int superClassCount = superClassCount(commonSuperClass, thisSuperClasses);
if (maximumSuperClassCount < superClassCount ||
(maximumSuperClassCount == superClassCount &&
- commonClazz != null &&
- commonClazz.getName().compareTo(commonSuperClass.getName()) > 0))
+ commonClass != null &&
+ commonClass.getName().compareTo(commonSuperClass.getName()) > 0))
{
- commonClazz = commonSuperClass;
+ commonClass = commonSuperClass;
maximumSuperClassCount = superClassCount;
}
}
- if (commonClazz == null)
+ if (commonClass == null)
{
- throw new IllegalArgumentException("Can't find common super class of ["+thisType+"] and ["+otherType+"]");
+ throw new IllegalArgumentException("Can't find common super class of ["+
+ thisType +"] (with "+thisSuperClassesCount +" known super classes) and ["+
+ otherType+"] (with "+otherSuperClassesCount+" known super classes)");
}
if (DEBUG)
{
- System.out.println(" Best common class: ["+commonClazz.getName()+"]");
+ System.out.println(" Best common class: ["+commonClass.getName()+"]");
}
// TODO: Handle more difficult cases, with multiple global subclasses.
return new ReferenceValue(commonDimensionCount == 0 ?
- commonClazz.getName() :
- ClassUtil.internalArrayTypeFromClassName(commonClazz.getName(),
+ commonClass.getName() :
+ ClassUtil.internalArrayTypeFromClassName(commonClass.getName(),
commonDimensionCount),
- commonClazz,
+ commonClass,
mayBeNull);
}
}
@@ -402,8 +418,6 @@ public class ReferenceValue extends Category1Value
}
}
- //System.out.println("ReferenceValue.superClassCount: ["+subClass.getName()+"]: "+count);
-
return count;
}
diff --git a/src/proguard/evaluation/value/SpecificDoubleValue.java b/src/proguard/evaluation/value/SpecificDoubleValue.java
index 572d891..ea4ecc4 100644
--- a/src/proguard/evaluation/value/SpecificDoubleValue.java
+++ b/src/proguard/evaluation/value/SpecificDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -153,9 +153,12 @@ abstract class SpecificDoubleValue extends DoubleValue
public IntegerValue compare(SpecificDoubleValue other)
{
- return this.equals(other) ?
- SpecificValueFactory.INTEGER_VALUE_0 :
- new ComparisonValue(this, other);
+ return ValueFactory.INTEGER_VALUE;
+
+ // Not handling NaN properly.
+ //return this.equals(other) ?
+ // SpecificValueFactory.INTEGER_VALUE_0 :
+ // new ComparisonValue(this, other);
}
diff --git a/src/proguard/evaluation/value/SpecificFloatValue.java b/src/proguard/evaluation/value/SpecificFloatValue.java
index 3bc3679..1e55c23 100644
--- a/src/proguard/evaluation/value/SpecificFloatValue.java
+++ b/src/proguard/evaluation/value/SpecificFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -153,9 +153,12 @@ abstract class SpecificFloatValue extends FloatValue
public IntegerValue compare(SpecificFloatValue other)
{
- return this.equals(other) ?
- SpecificValueFactory.INTEGER_VALUE_0 :
- new ComparisonValue(this, other);
+ return ValueFactory.INTEGER_VALUE;
+
+ // Not handling NaN properly.
+ //return this.equals(other) ?
+ // SpecificValueFactory.INTEGER_VALUE_0 :
+ // new ComparisonValue(this, other);
}
diff --git a/src/proguard/evaluation/value/SpecificIntegerValue.java b/src/proguard/evaluation/value/SpecificIntegerValue.java
index 57c48b1..45eb013 100644
--- a/src/proguard/evaluation/value/SpecificIntegerValue.java
+++ b/src/proguard/evaluation/value/SpecificIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/SpecificLongValue.java b/src/proguard/evaluation/value/SpecificLongValue.java
index 5e12bde..32302a4 100644
--- a/src/proguard/evaluation/value/SpecificLongValue.java
+++ b/src/proguard/evaluation/value/SpecificLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/SpecificValueFactory.java b/src/proguard/evaluation/value/SpecificValueFactory.java
index 72dd1d3..145ff55 100644
--- a/src/proguard/evaluation/value/SpecificValueFactory.java
+++ b/src/proguard/evaluation/value/SpecificValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -45,6 +45,10 @@ extends ValueFactory
static final DoubleValue DOUBLE_VALUE_1 = new ParticularDoubleValue(1.0);
+ private static int POS_ZERO_FLOAT_BITS = Float.floatToIntBits(0.0f);
+ private static long POS_ZERO_DOUBLE_BITS = Double.doubleToLongBits(0.0);
+
+
// Implementations for ValueFactory.
public IntegerValue createIntegerValue(int value)
@@ -73,7 +77,9 @@ extends ValueFactory
public FloatValue createFloatValue(float value)
{
- return value == 0.0f ? FLOAT_VALUE_0 :
+ // Make sure to distinguish between +0.0 and -0.0.
+ return value == 0.0f && Float.floatToIntBits(value) == POS_ZERO_FLOAT_BITS
+ ? FLOAT_VALUE_0 :
value == 1.0f ? FLOAT_VALUE_1 :
value == 2.0f ? FLOAT_VALUE_2 :
new ParticularFloatValue(value);
@@ -82,7 +88,9 @@ extends ValueFactory
public DoubleValue createDoubleValue(double value)
{
- return value == 0.0 ? DOUBLE_VALUE_0 :
+ // Make sure to distinguish between +0.0 and -0.0.
+ return value == 0.0 && Double.doubleToLongBits(value) == POS_ZERO_DOUBLE_BITS
+ ? DOUBLE_VALUE_0 :
value == 1.0 ? DOUBLE_VALUE_1 :
new ParticularDoubleValue(value);
}
diff --git a/src/proguard/evaluation/value/TopValue.java b/src/proguard/evaluation/value/TopValue.java
index 048a1ff..ecd182e 100644
--- a/src/proguard/evaluation/value/TopValue.java
+++ b/src/proguard/evaluation/value/TopValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/UnknownDoubleValue.java b/src/proguard/evaluation/value/UnknownDoubleValue.java
index 79cc4de..96bf06a 100644
--- a/src/proguard/evaluation/value/UnknownDoubleValue.java
+++ b/src/proguard/evaluation/value/UnknownDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/UnknownFloatValue.java b/src/proguard/evaluation/value/UnknownFloatValue.java
index 3f9622a..14469f8 100644
--- a/src/proguard/evaluation/value/UnknownFloatValue.java
+++ b/src/proguard/evaluation/value/UnknownFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/UnknownIntegerValue.java b/src/proguard/evaluation/value/UnknownIntegerValue.java
index be5e79d..94fcf60 100644
--- a/src/proguard/evaluation/value/UnknownIntegerValue.java
+++ b/src/proguard/evaluation/value/UnknownIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/UnknownLongValue.java b/src/proguard/evaluation/value/UnknownLongValue.java
index 83a75dc..f183447 100644
--- a/src/proguard/evaluation/value/UnknownLongValue.java
+++ b/src/proguard/evaluation/value/UnknownLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/Value.java b/src/proguard/evaluation/value/Value.java
index e24ece1..b4f1c6a 100644
--- a/src/proguard/evaluation/value/Value.java
+++ b/src/proguard/evaluation/value/Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ValueFactory.java b/src/proguard/evaluation/value/ValueFactory.java
index 8415381..2b9e7f1 100644
--- a/src/proguard/evaluation/value/ValueFactory.java
+++ b/src/proguard/evaluation/value/ValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ClassPathPanel.java b/src/proguard/gui/ClassPathPanel.java
index 95f3d1b..6fa6154 100644
--- a/src/proguard/gui/ClassPathPanel.java
+++ b/src/proguard/gui/ClassPathPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -26,7 +26,7 @@ import proguard.util.ListUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
-import java.io.File;
+import java.io.*;
import java.util.List;
/**
@@ -141,7 +141,7 @@ class ClassPathPanel extends ListPanel
// Up to JDK 1.3.1, setSelectedFiles doesn't show in the file
// chooser, so we just use setSelectedFile first. It also sets
// the current directory.
- chooser.setSelectedFile(selectedFiles[0]);
+ chooser.setSelectedFile(selectedFiles[0].getAbsoluteFile());
chooser.setSelectedFiles(selectedFiles);
int returnValue = chooser.showOpenDialog(owner);
@@ -432,7 +432,7 @@ class ClassPathPanel extends ListPanel
filter = new StringBuffer().append('(');
}
- filter.append(ListUtil.commaSeparatedString(additionalFilter));
+ filter.append(ListUtil.commaSeparatedString(additionalFilter, true));
}
return filter;
diff --git a/src/proguard/gui/ClassSpecificationDialog.java b/src/proguard/gui/ClassSpecificationDialog.java
index 36d80d4..a9493c9 100644
--- a/src/proguard/gui/ClassSpecificationDialog.java
+++ b/src/proguard/gui/ClassSpecificationDialog.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -63,9 +63,10 @@ final class ClassSpecificationDialog extends JDialog
private final JRadioButton[] publicRadioButtons;
private final JRadioButton[] finalRadioButtons;
private final JRadioButton[] abstractRadioButtons;
- private final JRadioButton[] enumRadioButtons;
- private final JRadioButton[] annotationRadioButtons;
private final JRadioButton[] interfaceRadioButtons;
+ private final JRadioButton[] annotationRadioButtons;
+ private final JRadioButton[] enumRadioButtons;
+ private final JRadioButton[] syntheticRadioButtons;
private final JTextField annotationTypeTextField = new JTextField(20);
private final JTextField classNameTextField = new JTextField(20);
@@ -199,9 +200,10 @@ final class ClassSpecificationDialog extends JDialog
publicRadioButtons = addRadioButtonTriplet("Public", accessPanel);
finalRadioButtons = addRadioButtonTriplet("Final", accessPanel);
abstractRadioButtons = addRadioButtonTriplet("Abstract", accessPanel);
- enumRadioButtons = addRadioButtonTriplet("Enum", accessPanel);
- annotationRadioButtons = addRadioButtonTriplet("Annotation", accessPanel);
interfaceRadioButtons = addRadioButtonTriplet("Interface", accessPanel);
+ annotationRadioButtons = addRadioButtonTriplet("Annotation", accessPanel);
+ enumRadioButtons = addRadioButtonTriplet("Enum", accessPanel);
+ syntheticRadioButtons = addRadioButtonTriplet("Synthetic", accessPanel);
// Create the annotation type panel.
final JPanel annotationTypePanel = new JPanel(layout);
@@ -393,9 +395,10 @@ final class ClassSpecificationDialog extends JDialog
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_PUBLIC, publicRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
- setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
- setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_INTERFACE, interfaceRadioButtons);
+ setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
+ setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
+ setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
// Set the class and annotation text fields.
annotationTypeTextField .setText(annotationType == null ? "" : ClassUtil.externalType(annotationType));
@@ -453,9 +456,10 @@ final class ClassSpecificationDialog extends JDialog
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_PUBLIC, publicRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
- getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
- getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_INTERFACE, interfaceRadioButtons);
+ getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
+ getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
+ getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
// Get the keep class member option lists.
classSpecification.fieldSpecifications = memberSpecificationsPanel.getMemberSpecifications(true);
diff --git a/src/proguard/gui/ClassSpecificationsPanel.java b/src/proguard/gui/ClassSpecificationsPanel.java
index 2cf0b1d..50fd87b 100644
--- a/src/proguard/gui/ClassSpecificationsPanel.java
+++ b/src/proguard/gui/ClassSpecificationsPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ExtensionFileFilter.java b/src/proguard/gui/ExtensionFileFilter.java
index d67be40..581e889 100644
--- a/src/proguard/gui/ExtensionFileFilter.java
+++ b/src/proguard/gui/ExtensionFileFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/FilterBuilder.java b/src/proguard/gui/FilterBuilder.java
index e46193f..33a8527 100644
--- a/src/proguard/gui/FilterBuilder.java
+++ b/src/proguard/gui/FilterBuilder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/FilterDialog.java b/src/proguard/gui/FilterDialog.java
index 1567a31..e65620a 100644
--- a/src/proguard/gui/FilterDialog.java
+++ b/src/proguard/gui/FilterDialog.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -182,7 +182,7 @@ public class FilterDialog extends JDialog
*/
public void setFilter(List filter)
{
- filterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_FILTER);
+ filterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_FILTER);
}
@@ -202,7 +202,7 @@ public class FilterDialog extends JDialog
*/
public void setJarFilter(List filter)
{
- jarFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_JAR_FILTER);
+ jarFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_JAR_FILTER);
}
@@ -222,7 +222,7 @@ public class FilterDialog extends JDialog
*/
public void setWarFilter(List filter)
{
- warFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_WAR_FILTER);
+ warFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_WAR_FILTER);
}
@@ -242,7 +242,7 @@ public class FilterDialog extends JDialog
*/
public void setEarFilter(List filter)
{
- earFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_EAR_FILTER);
+ earFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_EAR_FILTER);
}
@@ -262,7 +262,7 @@ public class FilterDialog extends JDialog
*/
public void setZipFilter(List filter)
{
- zipFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_ZIP_FILTER);
+ zipFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_ZIP_FILTER);
}
diff --git a/src/proguard/gui/GUIResources.java b/src/proguard/gui/GUIResources.java
index 85d582c..b190119 100644
--- a/src/proguard/gui/GUIResources.java
+++ b/src/proguard/gui/GUIResources.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/GUIResources.properties b/src/proguard/gui/GUIResources.properties
index 86ab7a1..705079e 100644
--- a/src/proguard/gui/GUIResources.properties
+++ b/src/proguard/gui/GUIResources.properties
@@ -1,5 +1,5 @@
# ProGuard -- shrinking, optimization, and obfuscation of Java class files.
-# Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+# Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
#
# Tab names.
@@ -25,7 +25,7 @@ preverification = Preverification
#
# Panel titles.
#
-welcome = Welcome to ProGuard, version 4.4
+welcome = Welcome to ProGuard, version 4.7
options = Options
keepAdditional = Keep additional classes and class members
keepNamesAdditional = Keep additional class names and class member names
@@ -51,20 +51,26 @@ whyAreYouKeepingTip = \
# Info texts.
#
proGuardInfo = \
- ProGuard is a free class file shrinker, optimizer, obfuscator, and preverifier.\
- \n\n\
- With this GUI, you can create, load, modify, and save ProGuard configurations. \
- \n\
+ <html>ProGuard is a free class file shrinker, optimizer, obfuscator, and preverifier.\
+ <p>\
+ With this GUI, you can create, load, modify, and save ProGuard configurations.\
+ <br>\
You can then process your code right away, or you can run ProGuard from the \
- command line using your saved configuration. \
- \n\n\
+ command line using your saved configuration.\
+ <p>\
With the ReTrace part of this GUI you can de-obfuscate your stack traces.\
- \n\n\
+ <p>\
ProGuard and ReTrace are written and maintained by Eric Lafortune.\
- \n\n\
+ <p>\
+ Official site at Sourceforge: \
+ <a href="http://proguard.sourceforge.net/\">http://proguard.sourceforge.net/</a>\
+ <br>\
+ Professional support by Saikoa: \
+ <a href="http://www.saikoa.com/\">http://www.saikoa.com/</a>\
+ <p>\
Distributed under the GNU General Public License.\
- \n\
- Copyright (c) 2002-2009.
+ <br>\
+ Copyright &copy; 2002-2011.</html>
processingInfo = \
You can now start processing your code, \
@@ -105,6 +111,7 @@ flattenPackageHierarchy = Flatten package hierarchy
repackageClasses = Repackage classes
useMixedCaseClassNames = Use mixed-case class names
keepAttributes = Keep attributes
+keepParameterNames = Keep parameter names
renameSourceFileAttribute = Rename SourceFile attribute
adaptClassStrings = Adapt class strings
adaptResourceFileNames = Adapt resource file names
@@ -115,8 +122,8 @@ microEdition = Micro Edition
verbose = Verbose
note = Note potential mistakes in the configuration
-warn = Warn about possibly erronous input
-ignoreWarnings = Ignore warnings about possibly erronous input
+warn = Warn about possibly erroneous input
+ignoreWarnings = Ignore warnings about possibly erroneous input
skipNonPublicLibraryClasses = Skip non-public library classes
skipNonPublicLibraryClassMembers = Skip non-public library class members
keepDirectories = Keep directories
@@ -209,6 +216,9 @@ attributesTip = \
<li>"*Annotations*" is necessary for preserving annotations.\
</ul>\
The wildcard <code>*</code> and the negator <code>!</code> are allowed.</html>
+keepParameterNamesTip = \
+ <html>Keep parameter names and types in "LocalVariable*Table" attributes</br>\
+ in methods that are not obfuscated.</html>
renameSourceFileAttributeTip = \
<html>Put the given string in the "SourceFile" attribute of the processed class files.<br>\
It will appear as the file name of the classes in stack traces.</html>
@@ -246,12 +256,12 @@ noteTip = \
noteFilterTip = \
A filter matching classes for which no notes should be printed.
warnTip = \
- <html>Print out warnings about possibly erronous input.<br>\
+ <html>Print out warnings about possibly erroneous input.<br>\
<i>Only unset this option if you know what you're doing!</i></html>
warnFilterTip = \
A filter matching classes for which no warnings should be printed.
ignoreWarningsTip = \
- <html>Ignore any warnings about possibly erronous input.<br>\
+ <html>Ignore any warnings about possibly erroneous input.<br>\
<i>Only set this option if you know what you're doing!</i></html>
skipNonPublicLibraryClassesTip = \
<html>Skip reading non-public library classes, for efficiency.<br>\
@@ -495,6 +505,8 @@ code_simplification_fieldTip = \
Perform peephole optimizations for field loading and storing.
code_simplification_branchTip = \
Perform peephole optimizations for branch instructions.
+code_simplification_stringTip = \
+ Perform peephole optimizations for constant strings.
code_simplification_advancedTip = \
Simplify code based on control flow analysis and data flow analysis.
code_removal_advancedTip = \
@@ -504,7 +516,7 @@ code_removal_simpleTip = \
code_removal_variableTip = \
Remove unused variables from the local variable frame.
code_removal_exceptionTip = \
- Remove exceptions with empty catch blocks.
+ Remove exceptions with empty try blocks.
code_allocation_variableTip = \
Optimize variable allocation on the local variable frame.
diff --git a/src/proguard/gui/KeepSpecificationsPanel.java b/src/proguard/gui/KeepSpecificationsPanel.java
index 4c3c953..9834894 100644
--- a/src/proguard/gui/KeepSpecificationsPanel.java
+++ b/src/proguard/gui/KeepSpecificationsPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ListPanel.java b/src/proguard/gui/ListPanel.java
index 0132340..292b838 100644
--- a/src/proguard/gui/ListPanel.java
+++ b/src/proguard/gui/ListPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/MemberSpecificationDialog.java b/src/proguard/gui/MemberSpecificationDialog.java
index 46a3f6f..f260b8b 100644
--- a/src/proguard/gui/MemberSpecificationDialog.java
+++ b/src/proguard/gui/MemberSpecificationDialog.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -56,6 +56,7 @@ final class MemberSpecificationDialog extends JDialog
private final JRadioButton[] protectedRadioButtons;
private final JRadioButton[] staticRadioButtons;
private final JRadioButton[] finalRadioButtons;
+ private final JRadioButton[] syntheticRadioButtons;
private JRadioButton[] volatileRadioButtons;
private JRadioButton[] transientRadioButtons;
@@ -64,6 +65,8 @@ final class MemberSpecificationDialog extends JDialog
private JRadioButton[] nativeRadioButtons;
private JRadioButton[] abstractRadioButtons;
private JRadioButton[] strictRadioButtons;
+ private JRadioButton[] bridgeRadioButtons;
+ private JRadioButton[] varargsRadioButtons;
private final JTextField annotationTypeTextField = new JTextField(20);
private final JTextField nameTextField = new JTextField(20);
@@ -166,6 +169,7 @@ final class MemberSpecificationDialog extends JDialog
protectedRadioButtons = addRadioButtonTriplet("Protected", accessPanel);
staticRadioButtons = addRadioButtonTriplet("Static", accessPanel);
finalRadioButtons = addRadioButtonTriplet("Final", accessPanel);
+ syntheticRadioButtons = addRadioButtonTriplet("Synthetic", accessPanel);
if (isField)
{
@@ -178,6 +182,8 @@ final class MemberSpecificationDialog extends JDialog
nativeRadioButtons = addRadioButtonTriplet("Native", accessPanel);
abstractRadioButtons = addRadioButtonTriplet("Abstract", accessPanel);
strictRadioButtons = addRadioButtonTriplet("Strict", accessPanel);
+ bridgeRadioButtons = addRadioButtonTriplet("Bridge", accessPanel);
+ varargsRadioButtons = addRadioButtonTriplet("Varargs", accessPanel);
}
// Create the type panel.
@@ -332,12 +338,15 @@ final class MemberSpecificationDialog extends JDialog
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_PROTECTED, protectedRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_STATIC, staticRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
+ setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_VOLATILE, volatileRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_TRANSIENT, transientRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_SYNCHRONIZED, synchronizedRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_NATIVE, nativeRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_STRICT, strictRadioButtons);
+ setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_BRIDGE, bridgeRadioButtons);
+ setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_VARARGS, varargsRadioButtons);
// Set the class name text fields.
nameTextField.setText(name == null ? "*" : name);
@@ -403,12 +412,15 @@ final class MemberSpecificationDialog extends JDialog
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_PROTECTED, protectedRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_STATIC, staticRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
+ getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_VOLATILE, volatileRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_TRANSIENT, transientRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_SYNCHRONIZED, synchronizedRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_NATIVE, nativeRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_STRICT, strictRadioButtons);
+ getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_BRIDGE, bridgeRadioButtons);
+ getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_VARARGS, varargsRadioButtons);
return memberSpecification;
}
diff --git a/src/proguard/gui/MemberSpecificationsPanel.java b/src/proguard/gui/MemberSpecificationsPanel.java
index 20b2f17..4e0a5f4 100644
--- a/src/proguard/gui/MemberSpecificationsPanel.java
+++ b/src/proguard/gui/MemberSpecificationsPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/MessageDialogRunnable.java b/src/proguard/gui/MessageDialogRunnable.java
index e58f1c6..7dddae5 100644
--- a/src/proguard/gui/MessageDialogRunnable.java
+++ b/src/proguard/gui/MessageDialogRunnable.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/OptimizationsDialog.java b/src/proguard/gui/OptimizationsDialog.java
index 044c338..1dbbd1c 100644
--- a/src/proguard/gui/OptimizationsDialog.java
+++ b/src/proguard/gui/OptimizationsDialog.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ProGuardGUI.java b/src/proguard/gui/ProGuardGUI.java
index f27d698..7ff9086 100644
--- a/src/proguard/gui/ProGuardGUI.java
+++ b/src/proguard/gui/ProGuardGUI.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -33,7 +33,6 @@ import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.List;
-import java.lang.reflect.InvocationTargetException;
/**
@@ -110,6 +109,7 @@ public class ProGuardGUI extends JFrame
private final JCheckBox flattenPackageHierarchyCheckBox = new JCheckBox(msg("flattenPackageHierarchy"));
private final JCheckBox repackageClassesCheckBox = new JCheckBox(msg("repackageClasses"));
private final JCheckBox keepAttributesCheckBox = new JCheckBox(msg("keepAttributes"));
+ private final JCheckBox keepParameterNamesCheckBox = new JCheckBox(msg("keepParameterNames"));
private final JCheckBox newSourceFileAttributeCheckBox = new JCheckBox(msg("renameSourceFileAttribute"));
private final JCheckBox adaptClassStringsCheckBox = new JCheckBox(msg("adaptClassStrings"));
private final JCheckBox adaptResourceFileNamesCheckBox = new JCheckBox(msg("adaptResourceFileNames"));
@@ -202,13 +202,13 @@ public class ProGuardGUI extends JFrame
splashPanelConstraints.anchor = GridBagConstraints.NORTHWEST;
//splashPanelConstraints.insets = constraints.insets;
- GridBagConstraints welcomeTextAreaConstraints = new GridBagConstraints();
- welcomeTextAreaConstraints.gridwidth = GridBagConstraints.REMAINDER;
- welcomeTextAreaConstraints.fill = GridBagConstraints.NONE;
- welcomeTextAreaConstraints.weightx = 1.0;
- welcomeTextAreaConstraints.weighty = 0.01;
- welcomeTextAreaConstraints.anchor = GridBagConstraints.CENTER;//NORTHWEST;
- welcomeTextAreaConstraints.insets = new Insets(20, 40, 20, 40);
+ GridBagConstraints welcomePaneConstraints = new GridBagConstraints();
+ welcomePaneConstraints.gridwidth = GridBagConstraints.REMAINDER;
+ welcomePaneConstraints.fill = GridBagConstraints.NONE;
+ welcomePaneConstraints.weightx = 1.0;
+ welcomePaneConstraints.weighty = 0.01;
+ welcomePaneConstraints.anchor = GridBagConstraints.CENTER;//NORTHWEST;
+ welcomePaneConstraints.insets = new Insets(20, 40, 20, 40);
GridBagConstraints panelConstraints = new GridBagConstraints();
panelConstraints.gridwidth = GridBagConstraints.REMAINDER;
@@ -295,18 +295,19 @@ public class ProGuardGUI extends JFrame
splashPanel = new SplashPanel(splash, 0.5, 5500L);
splashPanel.setPreferredSize(new Dimension(0, 200));
- JTextArea welcomeTextArea = new JTextArea(msg("proGuardInfo"), 18, 50);
- welcomeTextArea.setOpaque(false);
- welcomeTextArea.setEditable(false);
- welcomeTextArea.setLineWrap(true);
- welcomeTextArea.setWrapStyleWord(true);
- welcomeTextArea.setPreferredSize(new Dimension(0, 0));
- welcomeTextArea.setBorder(new EmptyBorder(20, 20, 20, 20));
- addBorder(welcomeTextArea, "welcome");
+ JEditorPane welcomePane = new JEditorPane("text/html", msg("proGuardInfo"));
+ welcomePane.setPreferredSize(new Dimension(640, 350));
+ // The constant HONOR_DISPLAY_PROPERTIES isn't present yet in JDK 1.4.
+ //welcomePane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
+ welcomePane.putClientProperty("JEditorPane.honorDisplayProperties", Boolean.TRUE);
+ welcomePane.setOpaque(false);
+ welcomePane.setEditable(false);
+ welcomePane.setBorder(new EmptyBorder(20, 20, 20, 20));
+ addBorder(welcomePane, "welcome");
JPanel proGuardPanel = new JPanel(layout);
proGuardPanel.add(splashPanel, splashPanelConstraints);
- proGuardPanel.add(welcomeTextArea, welcomeTextAreaConstraints);
+ proGuardPanel.add(welcomePane, welcomePaneConstraints);
// Create the input panel.
// TODO: properly clone the ClassPath objects.
@@ -403,6 +404,7 @@ public class ProGuardGUI extends JFrame
obfuscationOptionsPanel.add(tip(repackageClassesTextField, "packageTip"), constraintsLastStretch);
obfuscationOptionsPanel.add(tip(keepAttributesCheckBox, "keepAttributesTip"), constraints);
obfuscationOptionsPanel.add(tip(keepAttributesTextField, "attributesTip"), constraintsLastStretch);
+ obfuscationOptionsPanel.add(tip(keepParameterNamesCheckBox, "keepParameterNamesTip"), constraintsLastStretch);
obfuscationOptionsPanel.add(tip(newSourceFileAttributeCheckBox, "renameSourceFileAttributeTip"), constraints);
obfuscationOptionsPanel.add(tip(newSourceFileAttributeTextField, "sourceFileAttributeTip"), constraintsLastStretch);
obfuscationOptionsPanel.add(tip(adaptClassStringsCheckBox, "adaptClassStringsTip"), constraints);
@@ -1019,6 +1021,7 @@ public class ProGuardGUI extends JFrame
flattenPackageHierarchyCheckBox .setSelected(configuration.flattenPackageHierarchy != null);
repackageClassesCheckBox .setSelected(configuration.repackageClasses != null);
keepAttributesCheckBox .setSelected(configuration.keepAttributes != null);
+ keepParameterNamesCheckBox .setSelected(configuration.keepParameterNames);
newSourceFileAttributeCheckBox .setSelected(configuration.newSourceFileAttribute != null);
adaptClassStringsCheckBox .setSelected(configuration.adaptClassStrings != null);
adaptResourceFileNamesCheckBox .setSelected(configuration.adaptResourceFileNames != null);
@@ -1041,21 +1044,26 @@ public class ProGuardGUI extends JFrame
dumpCheckBox .setSelected(configuration.dump != null);
printUsageTextField .setText(fileName(configuration.printUsage));
- optimizationsTextField .setText(configuration.optimizations == null ? OPTIMIZATIONS_DEFAULT : ListUtil.commaSeparatedString(configuration.optimizations));
+ optimizationsTextField .setText(configuration.optimizations ==
+ null ?
+ OPTIMIZATIONS_DEFAULT :
+ ListUtil.commaSeparatedString(configuration.optimizations, true));
printMappingTextField .setText(fileName(configuration.printMapping));
applyMappingTextField .setText(fileName(configuration.applyMapping));
obfuscationDictionaryTextField .setText(fileName(configuration.obfuscationDictionary));
- keepPackageNamesTextField .setText(configuration.keepPackageNames == null ? "" : ClassUtil.externalClassName(ListUtil.commaSeparatedString(configuration.keepPackageNames)));
+ classObfuscationDictionaryTextField .setText(fileName(configuration.classObfuscationDictionary));
+ packageObfuscationDictionaryTextField .setText(fileName(configuration.packageObfuscationDictionary));
+ keepPackageNamesTextField .setText(configuration.keepPackageNames == null ? "" : ClassUtil.externalClassName(ListUtil.commaSeparatedString(configuration.keepPackageNames, true)));
flattenPackageHierarchyTextField .setText(configuration.flattenPackageHierarchy);
repackageClassesTextField .setText(configuration.repackageClasses);
- keepAttributesTextField .setText(configuration.keepAttributes == null ? KEEP_ATTRIBUTE_DEFAULT : ListUtil.commaSeparatedString(configuration.keepAttributes));
+ keepAttributesTextField .setText(configuration.keepAttributes == null ? KEEP_ATTRIBUTE_DEFAULT : ListUtil.commaSeparatedString(configuration.keepAttributes, true));
newSourceFileAttributeTextField .setText(configuration.newSourceFileAttribute == null ? SOURCE_FILE_ATTRIBUTE_DEFAULT : configuration.newSourceFileAttribute);
- adaptClassStringsTextField .setText(configuration.adaptClassStrings == null ? "" : ClassUtil.externalClassName(ListUtil.commaSeparatedString(configuration.adaptClassStrings)));
- adaptResourceFileNamesTextField .setText(configuration.adaptResourceFileNames == null ? ADAPT_RESOURCE_FILE_NAMES_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileNames));
- adaptResourceFileContentsTextField .setText(configuration.adaptResourceFileContents == null ? ADAPT_RESOURCE_FILE_CONTENTS_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileContents));
- noteTextField .setText(ListUtil.commaSeparatedString(configuration.note));
- warnTextField .setText(ListUtil.commaSeparatedString(configuration.warn));
- keepDirectoriesTextField .setText(ListUtil.commaSeparatedString(configuration.keepDirectories));
+ adaptClassStringsTextField .setText(configuration.adaptClassStrings == null ? "" : ClassUtil.externalClassName(ListUtil.commaSeparatedString(configuration.adaptClassStrings, true)));
+ adaptResourceFileNamesTextField .setText(configuration.adaptResourceFileNames == null ? ADAPT_RESOURCE_FILE_NAMES_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileNames, true));
+ adaptResourceFileContentsTextField .setText(configuration.adaptResourceFileContents == null ? ADAPT_RESOURCE_FILE_CONTENTS_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileContents, true));
+ noteTextField .setText(ListUtil.commaSeparatedString(configuration.note, true));
+ warnTextField .setText(ListUtil.commaSeparatedString(configuration.warn, true));
+ keepDirectoriesTextField .setText(ListUtil.commaSeparatedString(configuration.keepDirectories, true));
printSeedsTextField .setText(fileName(configuration.printSeeds));
printConfigurationTextField .setText(fileName(configuration.printConfiguration));
dumpTextField .setText(fileName(configuration.dump));
@@ -1182,6 +1190,7 @@ public class ProGuardGUI extends JFrame
configuration.flattenPackageHierarchy = flattenPackageHierarchyCheckBox .isSelected() ? ClassUtil.internalClassName(flattenPackageHierarchyTextField .getText()) : null;
configuration.repackageClasses = repackageClassesCheckBox .isSelected() ? ClassUtil.internalClassName(repackageClassesTextField .getText()) : null;
configuration.keepAttributes = keepAttributesCheckBox .isSelected() ? ListUtil.commaSeparatedList(keepAttributesTextField .getText()) : null;
+ configuration.keepParameterNames = keepParameterNamesCheckBox .isSelected();
configuration.newSourceFileAttribute = newSourceFileAttributeCheckBox .isSelected() ? newSourceFileAttributeTextField .getText() : null;
configuration.adaptClassStrings = adaptClassStringsCheckBox .isSelected() ? adaptClassStringsTextField.getText().length() > 0 ? ListUtil.commaSeparatedList(ClassUtil.internalClassName(adaptClassStringsTextField.getText())) : new ArrayList() : null;
configuration.adaptResourceFileNames = adaptResourceFileNamesCheckBox .isSelected() ? ListUtil.commaSeparatedList(adaptResourceFileNamesTextField .getText()) : null;
@@ -1436,13 +1445,13 @@ public class ProGuardGUI extends JFrame
/**
* Loads the given stack trace into the GUI.
*/
- private void loadStackTrace(String fileName)
+ private void loadStackTrace(File file)
{
try
{
StringBuffer buffer = new StringBuffer(1024);
- Reader reader = new BufferedReader(new FileReader(fileName));
+ Reader reader = new BufferedReader(new FileReader(file));
try
{
while (true)
@@ -1467,7 +1476,7 @@ public class ProGuardGUI extends JFrame
catch (IOException ex)
{
JOptionPane.showMessageDialog(getContentPane(),
- msg("cantOpenStackTraceFile", fileName),
+ msg("cantOpenStackTraceFile", fileName(file)),
msg("warning"),
JOptionPane.ERROR_MESSAGE);
}
@@ -1600,10 +1609,8 @@ public class ProGuardGUI extends JFrame
int returnValue = fileChooser.showOpenDialog(ProGuardGUI.this);
if (returnValue == JFileChooser.APPROVE_OPTION)
{
- File selectedFile = fileChooser.getSelectedFile();
- String fileName = selectedFile.getPath();
- loadStackTrace(fileName);
+ loadStackTrace(fileChooser.getSelectedFile());
}
}
}
@@ -1641,11 +1648,37 @@ public class ProGuardGUI extends JFrame
// Small utility methods.
/**
- * Returns the file name of the given file, if any.
+ * Returns the canonical file name for the given file, or the empty string
+ * if the file name is empty.
*/
- private static String fileName(File file)
+ private String fileName(File file)
{
- return file == null ? "" : file.getAbsolutePath();
+ if (isFile(file))
+ {
+ try
+ {
+ return file.getCanonicalPath();
+ }
+ catch (IOException ex)
+ {
+ return file.getPath();
+ }
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+
+ /**
+ * Returns whether the given file is actually a file, or just a placeholder
+ * for the standard output.
+ */
+ private boolean isFile(File file)
+ {
+ return file != null &&
+ file.getPath().length() > 0;
}
@@ -1693,46 +1726,52 @@ public class ProGuardGUI extends JFrame
{
public void run()
{
- ProGuardGUI gui = new ProGuardGUI();
- gui.pack();
-
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- Dimension guiSize = gui.getSize();
- gui.setLocation((screenSize.width - guiSize.width) / 2,
- (screenSize.height - guiSize.height) / 2);
- gui.show();
-
- // Start the splash animation, unless specified otherwise.
- int argIndex = 0;
- if (argIndex < args.length &&
- NO_SPLASH_OPTION.startsWith(args[argIndex]))
- {
- gui.skipSplash();
- argIndex++;
- }
- else
- {
- gui.startSplash();
- }
-
- // Load an initial configuration, if specified.
- if (argIndex < args.length)
+ try
{
- gui.loadConfiguration(new File(args[argIndex]));
- argIndex++;
+ ProGuardGUI gui = new ProGuardGUI();
+ gui.pack();
+
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension guiSize = gui.getSize();
+ gui.setLocation((screenSize.width - guiSize.width) / 2,
+ (screenSize.height - guiSize.height) / 2);
+ gui.show();
+
+ // Start the splash animation, unless specified otherwise.
+ int argIndex = 0;
+ if (argIndex < args.length &&
+ NO_SPLASH_OPTION.startsWith(args[argIndex]))
+ {
+ gui.skipSplash();
+ argIndex++;
+ }
+ else
+ {
+ gui.startSplash();
+ }
+
+ // Load an initial configuration, if specified.
+ if (argIndex < args.length)
+ {
+ gui.loadConfiguration(new File(args[argIndex]));
+ argIndex++;
+ }
+
+ if (argIndex < args.length)
+ {
+ System.out.println(gui.getClass().getName() + ": ignoring extra arguments [" + args[argIndex] + "...]");
+ }
}
-
- if (argIndex < args.length)
+ catch (Exception e)
{
- System.out.println(gui.getClass().getName() + ": ignoring extra arguments [" + args[argIndex] + "...]");
+ System.out.println("Internal problem starting the ProGuard GUI (" + e.getMessage() + ")");
}
-
}
});
}
catch (Exception e)
{
- // Nothing.
+ System.out.println("Internal problem starting the ProGuard GUI (" + e.getMessage() + ")");
}
}
}
diff --git a/src/proguard/gui/ProGuardRunnable.java b/src/proguard/gui/ProGuardRunnable.java
index c5c5937..2a898d9 100644
--- a/src/proguard/gui/ProGuardRunnable.java
+++ b/src/proguard/gui/ProGuardRunnable.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ReTraceRunnable.java b/src/proguard/gui/ReTraceRunnable.java
index 1ca19ca..fb1f325 100644
--- a/src/proguard/gui/ReTraceRunnable.java
+++ b/src/proguard/gui/ReTraceRunnable.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/SwingUtil.java b/src/proguard/gui/SwingUtil.java
index 75d2f02..f6d2d34 100644
--- a/src/proguard/gui/SwingUtil.java
+++ b/src/proguard/gui/SwingUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/TabbedPane.java b/src/proguard/gui/TabbedPane.java
index a6460f5..033b039 100644
--- a/src/proguard/gui/TabbedPane.java
+++ b/src/proguard/gui/TabbedPane.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/TextAreaOutputStream.java b/src/proguard/gui/TextAreaOutputStream.java
index 57f983d..da263a5 100644
--- a/src/proguard/gui/TextAreaOutputStream.java
+++ b/src/proguard/gui/TextAreaOutputStream.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/BufferedSprite.java b/src/proguard/gui/splash/BufferedSprite.java
index 8427832..c82c511 100644
--- a/src/proguard/gui/splash/BufferedSprite.java
+++ b/src/proguard/gui/splash/BufferedSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/CircleSprite.java b/src/proguard/gui/splash/CircleSprite.java
index 5dc65eb..6512495 100644
--- a/src/proguard/gui/splash/CircleSprite.java
+++ b/src/proguard/gui/splash/CircleSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ClipSprite.java b/src/proguard/gui/splash/ClipSprite.java
index 55f9eac..6a8e5fe 100644
--- a/src/proguard/gui/splash/ClipSprite.java
+++ b/src/proguard/gui/splash/ClipSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ColorSprite.java b/src/proguard/gui/splash/ColorSprite.java
index 3f9bc3b..1e633fa 100644
--- a/src/proguard/gui/splash/ColorSprite.java
+++ b/src/proguard/gui/splash/ColorSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/CompositeSprite.java b/src/proguard/gui/splash/CompositeSprite.java
index 2480ead..e82f524 100644
--- a/src/proguard/gui/splash/CompositeSprite.java
+++ b/src/proguard/gui/splash/CompositeSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ConstantColor.java b/src/proguard/gui/splash/ConstantColor.java
index 94c78df..85ca451 100644
--- a/src/proguard/gui/splash/ConstantColor.java
+++ b/src/proguard/gui/splash/ConstantColor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ConstantDouble.java b/src/proguard/gui/splash/ConstantDouble.java
index 0874d6d..e903c9b 100644
--- a/src/proguard/gui/splash/ConstantDouble.java
+++ b/src/proguard/gui/splash/ConstantDouble.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ConstantFont.java b/src/proguard/gui/splash/ConstantFont.java
index 3f1ac03..c7fd8f5 100644
--- a/src/proguard/gui/splash/ConstantFont.java
+++ b/src/proguard/gui/splash/ConstantFont.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ConstantInt.java b/src/proguard/gui/splash/ConstantInt.java
index 537196d..c9e80a8 100644
--- a/src/proguard/gui/splash/ConstantInt.java
+++ b/src/proguard/gui/splash/ConstantInt.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ConstantString.java b/src/proguard/gui/splash/ConstantString.java
index 7617c3f..e67db5c 100644
--- a/src/proguard/gui/splash/ConstantString.java
+++ b/src/proguard/gui/splash/ConstantString.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ConstantTiming.java b/src/proguard/gui/splash/ConstantTiming.java
index dfde644..9b0a01c 100644
--- a/src/proguard/gui/splash/ConstantTiming.java
+++ b/src/proguard/gui/splash/ConstantTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/FontSprite.java b/src/proguard/gui/splash/FontSprite.java
index 9a554ba..19882d4 100644
--- a/src/proguard/gui/splash/FontSprite.java
+++ b/src/proguard/gui/splash/FontSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ImageSprite.java b/src/proguard/gui/splash/ImageSprite.java
index 6e7c189..28bb05f 100644
--- a/src/proguard/gui/splash/ImageSprite.java
+++ b/src/proguard/gui/splash/ImageSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/LinearColor.java b/src/proguard/gui/splash/LinearColor.java
index 3a7674d..cdd8d11 100644
--- a/src/proguard/gui/splash/LinearColor.java
+++ b/src/proguard/gui/splash/LinearColor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/LinearDouble.java b/src/proguard/gui/splash/LinearDouble.java
index 046ae84..249b8de 100644
--- a/src/proguard/gui/splash/LinearDouble.java
+++ b/src/proguard/gui/splash/LinearDouble.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/LinearInt.java b/src/proguard/gui/splash/LinearInt.java
index 8d299bc..7ee7c32 100644
--- a/src/proguard/gui/splash/LinearInt.java
+++ b/src/proguard/gui/splash/LinearInt.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/LinearTiming.java b/src/proguard/gui/splash/LinearTiming.java
index 9b26644..13799fc 100644
--- a/src/proguard/gui/splash/LinearTiming.java
+++ b/src/proguard/gui/splash/LinearTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/OverrideGraphics2D.java b/src/proguard/gui/splash/OverrideGraphics2D.java
index 4333459..6d70049 100644
--- a/src/proguard/gui/splash/OverrideGraphics2D.java
+++ b/src/proguard/gui/splash/OverrideGraphics2D.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/RectangleSprite.java b/src/proguard/gui/splash/RectangleSprite.java
index d204831..6f702f7 100644
--- a/src/proguard/gui/splash/RectangleSprite.java
+++ b/src/proguard/gui/splash/RectangleSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/SawToothTiming.java b/src/proguard/gui/splash/SawToothTiming.java
index 076d5e2..eef8995 100644
--- a/src/proguard/gui/splash/SawToothTiming.java
+++ b/src/proguard/gui/splash/SawToothTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ShadowedSprite.java b/src/proguard/gui/splash/ShadowedSprite.java
index c3504f3..e048c9f 100644
--- a/src/proguard/gui/splash/ShadowedSprite.java
+++ b/src/proguard/gui/splash/ShadowedSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/SineTiming.java b/src/proguard/gui/splash/SineTiming.java
index eb0a7cc..56779ef 100644
--- a/src/proguard/gui/splash/SineTiming.java
+++ b/src/proguard/gui/splash/SineTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/SmoothTiming.java b/src/proguard/gui/splash/SmoothTiming.java
index a985712..22e90fc 100644
--- a/src/proguard/gui/splash/SmoothTiming.java
+++ b/src/proguard/gui/splash/SmoothTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/SplashPanel.java b/src/proguard/gui/splash/SplashPanel.java
index 23a9ce4..00ac82a 100644
--- a/src/proguard/gui/splash/SplashPanel.java
+++ b/src/proguard/gui/splash/SplashPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/Sprite.java b/src/proguard/gui/splash/Sprite.java
index ada7a81..79a2747 100644
--- a/src/proguard/gui/splash/Sprite.java
+++ b/src/proguard/gui/splash/Sprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/TextSprite.java b/src/proguard/gui/splash/TextSprite.java
index bbf37d4..131b94c 100644
--- a/src/proguard/gui/splash/TextSprite.java
+++ b/src/proguard/gui/splash/TextSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/TimeSwitchSprite.java b/src/proguard/gui/splash/TimeSwitchSprite.java
index 921bef2..f8501de 100644
--- a/src/proguard/gui/splash/TimeSwitchSprite.java
+++ b/src/proguard/gui/splash/TimeSwitchSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/Timing.java b/src/proguard/gui/splash/Timing.java
index 887d737..1256a6f 100644
--- a/src/proguard/gui/splash/Timing.java
+++ b/src/proguard/gui/splash/Timing.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/TypeWriterString.java b/src/proguard/gui/splash/TypeWriterString.java
index 9f1441e..53540de 100644
--- a/src/proguard/gui/splash/TypeWriterString.java
+++ b/src/proguard/gui/splash/TypeWriterString.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableColor.java b/src/proguard/gui/splash/VariableColor.java
index 6a30062..7fc4b4d 100644
--- a/src/proguard/gui/splash/VariableColor.java
+++ b/src/proguard/gui/splash/VariableColor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableDouble.java b/src/proguard/gui/splash/VariableDouble.java
index 39302dd..dcde0bc 100644
--- a/src/proguard/gui/splash/VariableDouble.java
+++ b/src/proguard/gui/splash/VariableDouble.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableFont.java b/src/proguard/gui/splash/VariableFont.java
index a7de8d7..12fe09e 100644
--- a/src/proguard/gui/splash/VariableFont.java
+++ b/src/proguard/gui/splash/VariableFont.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableInt.java b/src/proguard/gui/splash/VariableInt.java
index 68a33af..148cf56 100644
--- a/src/proguard/gui/splash/VariableInt.java
+++ b/src/proguard/gui/splash/VariableInt.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableSizeFont.java b/src/proguard/gui/splash/VariableSizeFont.java
index e36d28c..eaef2c9 100644
--- a/src/proguard/gui/splash/VariableSizeFont.java
+++ b/src/proguard/gui/splash/VariableSizeFont.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableString.java b/src/proguard/gui/splash/VariableString.java
index 1dec23b..73d01f2 100644
--- a/src/proguard/gui/splash/VariableString.java
+++ b/src/proguard/gui/splash/VariableString.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/CascadingDataEntryWriter.java b/src/proguard/io/CascadingDataEntryWriter.java
index 15719e6..9bd657f 100644
--- a/src/proguard/io/CascadingDataEntryWriter.java
+++ b/src/proguard/io/CascadingDataEntryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ClassFilter.java b/src/proguard/io/ClassFilter.java
index bf591ab..fe35d8f 100644
--- a/src/proguard/io/ClassFilter.java
+++ b/src/proguard/io/ClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ClassReader.java b/src/proguard/io/ClassReader.java
index e21968c..c049ea0 100644
--- a/src/proguard/io/ClassReader.java
+++ b/src/proguard/io/ClassReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -109,7 +109,7 @@ public class ClassReader implements DataEntryReader
}
catch (Exception ex)
{
- throw new IOException("Can't process class ["+dataEntry.getName()+"] ("+ex.getMessage()+")");
+ throw (IOException)new IOException("Can't process class ["+dataEntry.getName()+"] ("+ex.getMessage()+")").initCause(ex);
}
}
}
diff --git a/src/proguard/io/ClassRewriter.java b/src/proguard/io/ClassRewriter.java
index bd19e1d..613bb89 100644
--- a/src/proguard/io/ClassRewriter.java
+++ b/src/proguard/io/ClassRewriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntry.java b/src/proguard/io/DataEntry.java
index af0e373..bc61704 100644
--- a/src/proguard/io/DataEntry.java
+++ b/src/proguard/io/DataEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryClassWriter.java b/src/proguard/io/DataEntryClassWriter.java
new file mode 100644
index 0000000..4cd46ff
--- /dev/null
+++ b/src/proguard/io/DataEntryClassWriter.java
@@ -0,0 +1,85 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.io;
+
+import proguard.classfile.*;
+import proguard.classfile.io.*;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+
+import java.io.*;
+
+/**
+ * This ClassVisitor writes out the ProgramClass objects that it visits to the
+ * given DataEntry, modified to have the correct name.
+ *
+ * @author Eric Lafortune
+ */
+public class DataEntryClassWriter
+extends SimplifiedVisitor
+implements ClassVisitor
+{
+ private final DataEntryWriter dataEntryWriter;
+ private final DataEntry templateDataEntry;
+
+
+ /**
+ * Creates a new DataEntryClassWriter for writing to the given
+ * DataEntryWriter, based on the given template DataEntry.
+ */
+ public DataEntryClassWriter(DataEntryWriter dataEntryWriter,
+ DataEntry templateDataEntry)
+ {
+ this.dataEntryWriter = dataEntryWriter;
+ this.templateDataEntry = templateDataEntry;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Rename the data entry if necessary.
+ String actualClassName = programClass.getName();
+ DataEntry actualDataEntry =
+ new RenamedDataEntry(templateDataEntry,
+ actualClassName + ClassConstants.CLASS_FILE_EXTENSION);
+
+ try
+ {
+ // Get the output entry corresponding to this input entry.
+ OutputStream outputStream = dataEntryWriter.getOutputStream(actualDataEntry);
+ if (outputStream != null)
+ {
+ // Write the class to the output entry.
+ DataOutputStream classOutputStream = new DataOutputStream(outputStream);
+
+ new ProgramClassWriter(classOutputStream).visitProgramClass(programClass);
+
+ classOutputStream.flush();
+ }
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Can't write program class ["+actualClassName+"] to ["+actualDataEntry+"] ("+e.getMessage()+")", e);
+ }
+ }
+}
diff --git a/src/proguard/io/DataEntryCopier.java b/src/proguard/io/DataEntryCopier.java
index faaa555..76d5bdd 100644
--- a/src/proguard/io/DataEntryCopier.java
+++ b/src/proguard/io/DataEntryCopier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryDirectoryFilter.java b/src/proguard/io/DataEntryDirectoryFilter.java
index bb36f3e..036347d 100644
--- a/src/proguard/io/DataEntryDirectoryFilter.java
+++ b/src/proguard/io/DataEntryDirectoryFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryFilter.java b/src/proguard/io/DataEntryFilter.java
index ddcd0be..92ff83e 100644
--- a/src/proguard/io/DataEntryFilter.java
+++ b/src/proguard/io/DataEntryFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryNameFilter.java b/src/proguard/io/DataEntryNameFilter.java
index d6afd2e..86a736f 100644
--- a/src/proguard/io/DataEntryNameFilter.java
+++ b/src/proguard/io/DataEntryNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryObfuscator.java b/src/proguard/io/DataEntryObfuscator.java
index aa63af1..1009548 100644
--- a/src/proguard/io/DataEntryObfuscator.java
+++ b/src/proguard/io/DataEntryObfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -75,7 +75,7 @@ public class DataEntryObfuscator implements DataEntryReader
String dataEntryName = dataEntry.getName();
// Try to find a corresponding class name by removing increasingly
- // long suffixes,
+ // long suffixes.
for (int suffixIndex = dataEntryName.length() - 1;
suffixIndex > 0;
suffixIndex--)
@@ -106,25 +106,44 @@ public class DataEntryObfuscator implements DataEntryReader
return new RenamedDataEntry(dataEntry, newDataEntryName);
}
-
- // Otherwise stop looking.
- break;
+ else
+ {
+ // Otherwise stop looking.
+ return dataEntry;
+ }
}
}
}
- // Did the package get a new name?
- String packagePrefix = ClassUtil.internalPackagePrefix(dataEntryName);
- String newPackagePrefix = (String)packagePrefixMap.get(packagePrefix);
- if (newPackagePrefix != null &&
- !packagePrefix.equals(newPackagePrefix))
+ // Try to find a corresponding package name by increasingly removing
+ // more subpackages.
+ String packagePrefix = dataEntryName;
+ do
{
- // Return a renamed data entry.
- String newDataEntryName =
- newPackagePrefix + dataEntryName.substring(packagePrefix.length());
+ // Chop off the class name or the last subpackage name.
+ packagePrefix = ClassUtil.internalPackagePrefix(packagePrefix);
- return new RenamedDataEntry(dataEntry, newDataEntryName);
+ // Is there a package corresponding to the package prefix?
+ String newPackagePrefix = (String)packagePrefixMap.get(packagePrefix);
+ if (newPackagePrefix != null)
+ {
+ // Did the package get a new name?
+ if (!packagePrefix.equals(newPackagePrefix))
+ {
+ // Return a renamed data entry.
+ String newDataEntryName =
+ newPackagePrefix + dataEntryName.substring(packagePrefix.length());
+
+ return new RenamedDataEntry(dataEntry, newDataEntryName);
+ }
+ else
+ {
+ // Otherwise stop looking.
+ return dataEntry;
+ }
+ }
}
+ while (packagePrefix.length() > 0);
return dataEntry;
}
diff --git a/src/proguard/io/DataEntryParentFilter.java b/src/proguard/io/DataEntryParentFilter.java
index fbeac4f..cf44b65 100644
--- a/src/proguard/io/DataEntryParentFilter.java
+++ b/src/proguard/io/DataEntryParentFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryPump.java b/src/proguard/io/DataEntryPump.java
index bfe22a3..a54038b 100644
--- a/src/proguard/io/DataEntryPump.java
+++ b/src/proguard/io/DataEntryPump.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryReader.java b/src/proguard/io/DataEntryReader.java
index e77f7bf..6d24b42 100644
--- a/src/proguard/io/DataEntryReader.java
+++ b/src/proguard/io/DataEntryReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryRenamer.java b/src/proguard/io/DataEntryRenamer.java
index 45c61ee..89e006a 100644
--- a/src/proguard/io/DataEntryRenamer.java
+++ b/src/proguard/io/DataEntryRenamer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -87,7 +87,7 @@ public class DataEntryRenamer implements DataEntryReader
String newName = (String)nameMap.get(name);
if (newName != null)
{
- // Add remove the directory separator if necessary.
+ // Remove the directory separator if necessary.
if (dataEntry.isDirectory() &&
newName.length() > 0)
{
@@ -101,4 +101,4 @@ public class DataEntryRenamer implements DataEntryReader
missingDataEntryReader.read(dataEntry);
}
}
-} \ No newline at end of file
+}
diff --git a/src/proguard/io/DataEntryRewriter.java b/src/proguard/io/DataEntryRewriter.java
index eefced4..d7852a5 100644
--- a/src/proguard/io/DataEntryRewriter.java
+++ b/src/proguard/io/DataEntryRewriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryWriter.java b/src/proguard/io/DataEntryWriter.java
index 9ecf79b..6db918e 100644
--- a/src/proguard/io/DataEntryWriter.java
+++ b/src/proguard/io/DataEntryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DirectoryFilter.java b/src/proguard/io/DirectoryFilter.java
index a45d1aa..f99a6c2 100644
--- a/src/proguard/io/DirectoryFilter.java
+++ b/src/proguard/io/DirectoryFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DirectoryPump.java b/src/proguard/io/DirectoryPump.java
index cab2ff3..35d5a76 100644
--- a/src/proguard/io/DirectoryPump.java
+++ b/src/proguard/io/DirectoryPump.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DirectoryWriter.java b/src/proguard/io/DirectoryWriter.java
index c6605df..c74d503 100644
--- a/src/proguard/io/DirectoryWriter.java
+++ b/src/proguard/io/DirectoryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/FileDataEntry.java b/src/proguard/io/FileDataEntry.java
index d0449ee..1a2d2d3 100644
--- a/src/proguard/io/FileDataEntry.java
+++ b/src/proguard/io/FileDataEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/FilteredDataEntryReader.java b/src/proguard/io/FilteredDataEntryReader.java
index 11da0d4..b03dd6f 100644
--- a/src/proguard/io/FilteredDataEntryReader.java
+++ b/src/proguard/io/FilteredDataEntryReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/FilteredDataEntryWriter.java b/src/proguard/io/FilteredDataEntryWriter.java
index 40a8c64..795e8c8 100644
--- a/src/proguard/io/FilteredDataEntryWriter.java
+++ b/src/proguard/io/FilteredDataEntryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/Finisher.java b/src/proguard/io/Finisher.java
index 8c4cc1e..164ef58 100644
--- a/src/proguard/io/Finisher.java
+++ b/src/proguard/io/Finisher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/JarReader.java b/src/proguard/io/JarReader.java
index f96b4aa..60a1d6d 100644
--- a/src/proguard/io/JarReader.java
+++ b/src/proguard/io/JarReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/JarWriter.java b/src/proguard/io/JarWriter.java
index 3e40cdf..946b5b8 100644
--- a/src/proguard/io/JarWriter.java
+++ b/src/proguard/io/JarWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ManifestRewriter.java b/src/proguard/io/ManifestRewriter.java
index f10307e..b28dd8d 100644
--- a/src/proguard/io/ManifestRewriter.java
+++ b/src/proguard/io/ManifestRewriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/NameFilter.java b/src/proguard/io/NameFilter.java
index 2a9fbc3..f36d663 100644
--- a/src/proguard/io/NameFilter.java
+++ b/src/proguard/io/NameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ParentDataEntryWriter.java b/src/proguard/io/ParentDataEntryWriter.java
index 4f16d12..528bb39 100644
--- a/src/proguard/io/ParentDataEntryWriter.java
+++ b/src/proguard/io/ParentDataEntryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/RenamedDataEntry.java b/src/proguard/io/RenamedDataEntry.java
index ae2d267..71b7fac 100644
--- a/src/proguard/io/RenamedDataEntry.java
+++ b/src/proguard/io/RenamedDataEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ZipDataEntry.java b/src/proguard/io/ZipDataEntry.java
index 5779fd8..3e19db1 100644
--- a/src/proguard/io/ZipDataEntry.java
+++ b/src/proguard/io/ZipDataEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/AttributeShrinker.java b/src/proguard/obfuscate/AttributeShrinker.java
index a8bc36b..ee9bc4b 100644
--- a/src/proguard/obfuscate/AttributeShrinker.java
+++ b/src/proguard/obfuscate/AttributeShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -26,6 +26,8 @@ import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.*;
+import java.util.Arrays;
+
/**
* This ClassVisitor removes attributes that are not marked as being used or
* required.
@@ -111,10 +113,7 @@ implements ClassVisitor,
}
// Clear the remaining array elements.
- for (int index = counter; index < length; index++)
- {
- array[index] = null;
- }
+ Arrays.fill(array, counter, length, null);
return counter;
}
diff --git a/src/proguard/obfuscate/AttributeUsageMarker.java b/src/proguard/obfuscate/AttributeUsageMarker.java
index e772324..297b540 100644
--- a/src/proguard/obfuscate/AttributeUsageMarker.java
+++ b/src/proguard/obfuscate/AttributeUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -26,7 +26,7 @@ import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.SimplifiedVisitor;
/**
- * This ClassVisitor marks all attributes that it visits.
+ * This AttributeVisitor marks all attributes that it visits.
*
* @see AttributeShrinker
*
diff --git a/src/proguard/obfuscate/ClassObfuscator.java b/src/proguard/obfuscate/ClassObfuscator.java
index 9af0c82..446b158 100644
--- a/src/proguard/obfuscate/ClassObfuscator.java
+++ b/src/proguard/obfuscate/ClassObfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -469,13 +469,25 @@ implements ClassVisitor,
{
// Come up with class names until we get an original one.
String newClassName;
+ String newMixedCaseClassName;
do
{
// Let the factory produce a class name.
newClassName = newPackagePrefix +
classNameFactory.nextName();
+
+ newMixedCaseClassName = mixedCaseClassName(newClassName);
+ }
+ while (classNamesToAvoid.contains(newMixedCaseClassName));
+
+ // Explicitly make sure the name isn't used again if we have a
+ // user-specified dictionary and we're not allowed to have mixed case
+ // class names -- just to protect against problematic dictionaries.
+ if (this.classNameFactory != null &&
+ !useMixedCaseClassNames)
+ {
+ classNamesToAvoid.add(newMixedCaseClassName);
}
- while (classNamesToAvoid.contains(mixedCaseClassName(newClassName)));
return newClassName;
}
diff --git a/src/proguard/obfuscate/ClassRenamer.java b/src/proguard/obfuscate/ClassRenamer.java
index 143e3fb..a967d36 100644
--- a/src/proguard/obfuscate/ClassRenamer.java
+++ b/src/proguard/obfuscate/ClassRenamer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/DictionaryNameFactory.java b/src/proguard/obfuscate/DictionaryNameFactory.java
index f262664..393c648 100644
--- a/src/proguard/obfuscate/DictionaryNameFactory.java
+++ b/src/proguard/obfuscate/DictionaryNameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MapCleaner.java b/src/proguard/obfuscate/MapCleaner.java
index fdefec5..d6ca5f6 100644
--- a/src/proguard/obfuscate/MapCleaner.java
+++ b/src/proguard/obfuscate/MapCleaner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MappingKeeper.java b/src/proguard/obfuscate/MappingKeeper.java
index c9d6aa6..d02d7bc 100644
--- a/src/proguard/obfuscate/MappingKeeper.java
+++ b/src/proguard/obfuscate/MappingKeeper.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MappingPrinter.java b/src/proguard/obfuscate/MappingPrinter.java
index aa8b13e..c004b73 100644
--- a/src/proguard/obfuscate/MappingPrinter.java
+++ b/src/proguard/obfuscate/MappingPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MappingProcessor.java b/src/proguard/obfuscate/MappingProcessor.java
index 01c1809..7c9103a 100644
--- a/src/proguard/obfuscate/MappingProcessor.java
+++ b/src/proguard/obfuscate/MappingProcessor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MappingReader.java b/src/proguard/obfuscate/MappingReader.java
index 24fd26c..0798a4d 100644
--- a/src/proguard/obfuscate/MappingReader.java
+++ b/src/proguard/obfuscate/MappingReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MemberNameCleaner.java b/src/proguard/obfuscate/MemberNameCleaner.java
index c41c59d..0d5a519 100644
--- a/src/proguard/obfuscate/MemberNameCleaner.java
+++ b/src/proguard/obfuscate/MemberNameCleaner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MemberNameCollector.java b/src/proguard/obfuscate/MemberNameCollector.java
index c248820..92ec589 100644
--- a/src/proguard/obfuscate/MemberNameCollector.java
+++ b/src/proguard/obfuscate/MemberNameCollector.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MemberNameConflictFixer.java b/src/proguard/obfuscate/MemberNameConflictFixer.java
index b9093a6..22de855 100644
--- a/src/proguard/obfuscate/MemberNameConflictFixer.java
+++ b/src/proguard/obfuscate/MemberNameConflictFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MemberNameFilter.java b/src/proguard/obfuscate/MemberNameFilter.java
new file mode 100644
index 0000000..1447a25
--- /dev/null
+++ b/src/proguard/obfuscate/MemberNameFilter.java
@@ -0,0 +1,120 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.obfuscate;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.MemberVisitor;
+
+/**
+ * This <code>MemberVisitor</code> delegates its visits to another given
+ * <code>MemberVisitor</code>, but only when the visited member has a new name.
+ * Constructors are judged based on the class name.
+ *
+ * @see ClassObfuscator
+ * @see MemberObfuscator
+ *
+ * @author Eric Lafortune
+ */
+public class MemberNameFilter implements MemberVisitor
+{
+ private final MemberVisitor memberVisitor;
+
+
+ /**
+ * Creates a new MemberSpecialNameFilter.
+ * @param memberVisitor the <code>MemberVisitor</code> to which
+ * visits will be delegated.
+ */
+ public MemberNameFilter(MemberVisitor memberVisitor)
+ {
+ this.memberVisitor = memberVisitor;
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ if (hasName(programField))
+ {
+ memberVisitor.visitProgramField(programClass, programField);
+ }
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if (hasName(programClass, programMethod))
+ {
+ memberVisitor.visitProgramMethod(programClass, programMethod);
+ }
+ }
+
+
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
+ {
+ if (hasName(libraryField))
+ {
+ memberVisitor.visitLibraryField(libraryClass, libraryField);
+ }
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ if (hasName(libraryClass, libraryMethod))
+ {
+ memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
+ }
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Returns whether the given class has a new name.
+ */
+ private boolean hasName(Clazz clazz)
+ {
+ return ClassObfuscator.newClassName(clazz) != null;
+ }
+
+
+ /**
+ * Returns whether the given method has a new name.
+ */
+ private boolean hasName(Clazz clazz, Method method)
+ {
+ return
+ hasName(method) ||
+ (hasName(clazz) &&
+ method.getName(clazz).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT));
+ }
+
+
+ /**
+ * Returns whether the given class member has a new name.
+ */
+ private boolean hasName(Member member)
+ {
+ return MemberObfuscator.newMemberName(member) != null;
+ }
+} \ No newline at end of file
diff --git a/src/proguard/obfuscate/MemberObfuscator.java b/src/proguard/obfuscate/MemberObfuscator.java
index 332b849..7b30596 100644
--- a/src/proguard/obfuscate/MemberObfuscator.java
+++ b/src/proguard/obfuscate/MemberObfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MemberSpecialNameFilter.java b/src/proguard/obfuscate/MemberSpecialNameFilter.java
index f83374b..6da56da 100644
--- a/src/proguard/obfuscate/MemberSpecialNameFilter.java
+++ b/src/proguard/obfuscate/MemberSpecialNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -54,7 +54,7 @@ public class MemberSpecialNameFilter implements MemberVisitor
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
- if (isSpecialName(programField))
+ if (hasSpecialName(programField))
{
memberVisitor.visitProgramField(programClass, programField);
}
@@ -63,7 +63,7 @@ public class MemberSpecialNameFilter implements MemberVisitor
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- if (isSpecialName(programMethod))
+ if (hasSpecialName(programMethod))
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
@@ -72,7 +72,7 @@ public class MemberSpecialNameFilter implements MemberVisitor
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
- if (isSpecialName(libraryField))
+ if (hasSpecialName(libraryField))
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
@@ -81,7 +81,7 @@ public class MemberSpecialNameFilter implements MemberVisitor
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
- if (isSpecialName(libraryMethod))
+ if (hasSpecialName(libraryMethod))
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
@@ -94,7 +94,7 @@ public class MemberSpecialNameFilter implements MemberVisitor
* Returns whether the given class member has a special new name.
* @param member the class member.
*/
- private static boolean isSpecialName(Member member)
+ private static boolean hasSpecialName(Member member)
{
return SpecialNameFactory.isSpecialName(MemberObfuscator.newMemberName(member));
}
diff --git a/src/proguard/obfuscate/MultiMappingProcessor.java b/src/proguard/obfuscate/MultiMappingProcessor.java
index 4074ff8..8b67bb6 100644
--- a/src/proguard/obfuscate/MultiMappingProcessor.java
+++ b/src/proguard/obfuscate/MultiMappingProcessor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NameAndTypeShrinker.java b/src/proguard/obfuscate/NameAndTypeShrinker.java
deleted file mode 100644
index 1284c82..0000000
--- a/src/proguard/obfuscate/NameAndTypeShrinker.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * ProGuard -- shrinking, optimization, obfuscation, and preverification
- * of Java bytecode.
- *
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-package proguard.obfuscate;
-
-import proguard.classfile.*;
-import proguard.classfile.constant.Constant;
-import proguard.classfile.editor.ConstantPoolRemapper;
-import proguard.classfile.visitor.ClassVisitor;
-
-
-/**
- * This ClassVisitor removes NameAndType constant pool entries
- * that are not marked as being used.
- *
- * @see NameAndTypeUsageMarker
- *
- * @author Eric Lafortune
- */
-public class NameAndTypeShrinker implements ClassVisitor
-{
- private int[] constantIndexMap;
- private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
-
-
- // Implementations for ClassVisitor.
-
- public void visitProgramClass(ProgramClass programClass)
- {
- // Shift the used constant pool entries together, filling out the
- // index map.
- programClass.u2constantPoolCount =
- shrinkConstantPool(programClass.constantPool,
- programClass.u2constantPoolCount);
-
-
- // Remap all constant pool references.
- constantPoolRemapper.setConstantIndexMap(constantIndexMap);
- constantPoolRemapper.visitProgramClass(programClass);
- }
-
-
- public void visitLibraryClass(LibraryClass libraryClass)
- {
- }
-
-
- // Small utility methods.
-
- /**
- * Removes all NameAndType entries that are not marked as being used
- * from the given constant pool.
- * @return the new number of entries.
- */
- private int shrinkConstantPool(Constant[] constantPool, int length)
- {
- // Create a new index map, if necessary.
- if (constantIndexMap == null ||
- constantIndexMap.length < length)
- {
- constantIndexMap = new int[length];
- }
-
- int counter = 1;
- boolean isUsed = false;
-
- // Shift the used constant pool entries together.
- for (int index = 1; index < length; index++)
- {
- constantIndexMap[index] = counter;
-
- Constant constant = constantPool[index];
-
- // Don't update the flag if this is the second half of a long entry.
- if (constant != null)
- {
- isUsed = constant.getTag() != ClassConstants.CONSTANT_NameAndType ||
- NameAndTypeUsageMarker.isUsed(constant);
- }
-
- if (isUsed)
- {
- constantPool[counter++] = constant;
- }
- }
-
- // Clear the remaining constant pool elements.
- for (int index = counter; index < length; index++)
- {
- constantPool[index] = null;
- }
-
- return counter;
- }
-}
diff --git a/src/proguard/obfuscate/NameFactory.java b/src/proguard/obfuscate/NameFactory.java
index c64d1ad..9585381 100644
--- a/src/proguard/obfuscate/NameFactory.java
+++ b/src/proguard/obfuscate/NameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NameFactoryResetter.java b/src/proguard/obfuscate/NameFactoryResetter.java
index b6ba6ad..f3e889d 100644
--- a/src/proguard/obfuscate/NameFactoryResetter.java
+++ b/src/proguard/obfuscate/NameFactoryResetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NameMarker.java b/src/proguard/obfuscate/NameMarker.java
index 2ce0ee9..130260c 100644
--- a/src/proguard/obfuscate/NameMarker.java
+++ b/src/proguard/obfuscate/NameMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NumericNameFactory.java b/src/proguard/obfuscate/NumericNameFactory.java
index cc21c4b..5a6e3b4 100644
--- a/src/proguard/obfuscate/NumericNameFactory.java
+++ b/src/proguard/obfuscate/NumericNameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/Obfuscator.java b/src/proguard/obfuscate/Obfuscator.java
index dce563a..5f58a83 100644
--- a/src/proguard/obfuscate/Obfuscator.java
+++ b/src/proguard/obfuscate/Obfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -99,19 +99,30 @@ public class Obfuscator
libraryClassPool.classesAccept(new AllMemberVisitor(nameMarker));
// Mark attributes that have to be kept.
- AttributeUsageMarker requiredAttributeUsageMarker =
- new AttributeUsageMarker();
+ AttributeVisitor attributeUsageMarker =
+ new NonEmptyAttributeFilter(
+ new AttributeUsageMarker());
AttributeVisitor optionalAttributeUsageMarker =
configuration.keepAttributes == null ? null :
new AttributeNameFilter(new ListParser(new NameParser()).parse(configuration.keepAttributes),
- requiredAttributeUsageMarker);
+ attributeUsageMarker);
programClassPool.classesAccept(
new AllAttributeVisitor(true,
- new RequiredAttributeFilter(requiredAttributeUsageMarker,
+ new RequiredAttributeFilter(attributeUsageMarker,
optionalAttributeUsageMarker)));
+ // Keep parameter names and types if specified.
+ if (configuration.keepParameterNames)
+ {
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new MemberNameFilter(
+ new AllAttributeVisitor(true,
+ new ParameterNameMarker(attributeUsageMarker)))));
+ }
+
// Remove the attributes that can be discarded. Note that the attributes
// may only be discarded after the seeds have been marked, since the
// configuration may rely on annotations.
@@ -398,23 +409,28 @@ public class Obfuscator
programClassPool.classesAccept(
new AllConstantVisitor(
new AccessFixer()));
+
+ // Fix the access flags of the inner classes information.
+ programClassPool.classesAccept(
+ new AllAttributeVisitor(
+ new AllInnerClassesInfoVisitor(
+ new InnerClassesAccessFixer())));
}
+ // Fix the bridge method flags.
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new BridgeMethodFixer()));
+
// Rename the source file attributes, if requested.
if (configuration.newSourceFileAttribute != null)
{
programClassPool.classesAccept(new SourceFileRenamer(configuration.newSourceFileAttribute));
}
- // Mark NameAndType constant pool entries that have to be kept
- // and remove the other ones.
- programClassPool.classesAccept(new NameAndTypeUsageMarker());
- programClassPool.classesAccept(new NameAndTypeShrinker());
-
- // Mark Utf8 constant pool entries that have to be kept
- // and remove the other ones.
- programClassPool.classesAccept(new Utf8UsageMarker());
- programClassPool.classesAccept(new Utf8Shrinker());
+ // Remove unused constants.
+ programClassPool.classesAccept(
+ new ConstantPoolShrinker());
}
diff --git a/src/proguard/obfuscate/ParameterNameMarker.java b/src/proguard/obfuscate/ParameterNameMarker.java
new file mode 100644
index 0000000..2c3a3db
--- /dev/null
+++ b/src/proguard/obfuscate/ParameterNameMarker.java
@@ -0,0 +1,128 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.obfuscate;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.util.*;
+
+/**
+ * This AttributeVisitor trims and marks all local variable (type) table
+ * attributes that it visits. It keeps parameter names and types and removes
+ * the ordinary local variable names and types.
+ *
+ * @author Eric Lafortune
+ */
+public class ParameterNameMarker
+extends SimplifiedVisitor
+implements AttributeVisitor
+{
+ private final AttributeVisitor attributeUsageMarker;
+
+
+ /**
+ * Constructs a new ParameterNameMarker.
+ * @param attributeUsageMarker the marker that will be used to mark
+ * attributes containing local variable info.
+ */
+ public ParameterNameMarker(AttributeVisitor attributeUsageMarker)
+ {
+ this.attributeUsageMarker = attributeUsageMarker;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ if (!AttributeUsageMarker.isUsed(localVariableTableAttribute) &&
+ hasParameters(clazz, method))
+ {
+ // Shift the entries that start at offset 0 to the front.
+ int newIndex = 0;
+
+ for (int index = 0; index < localVariableTableAttribute.u2localVariableTableLength; index++)
+ {
+ LocalVariableInfo localVariableInfo =
+ localVariableTableAttribute.localVariableTable[index];
+
+ if (localVariableInfo.u2startPC == 0)
+ {
+ localVariableTableAttribute.localVariableTable[newIndex++] =
+ localVariableInfo;
+ }
+ }
+
+ // Trim the table.
+ localVariableTableAttribute.u2localVariableTableLength = newIndex;
+
+ // Mark the table if there are any entries.
+ if (newIndex > 0)
+ {
+ attributeUsageMarker.visitLocalVariableTableAttribute(clazz, method, codeAttribute, localVariableTableAttribute);
+ }
+ }
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ if (!AttributeUsageMarker.isUsed(localVariableTypeTableAttribute) &&
+ hasParameters(clazz, method))
+ {
+ // Shift the entries that start at offset 0 to the front.
+ int newIndex = 0;
+
+ for (int index = 0; index < localVariableTypeTableAttribute.u2localVariableTypeTableLength; index++)
+ {
+ LocalVariableTypeInfo localVariableTypeInfo =
+ localVariableTypeTableAttribute.localVariableTypeTable[index];
+
+ if (localVariableTypeInfo.u2startPC == 0)
+ {
+ localVariableTypeTableAttribute.localVariableTypeTable[newIndex++] =
+ localVariableTypeInfo;
+ }
+ }
+
+ // Trim the table.
+ localVariableTypeTableAttribute.u2localVariableTypeTableLength = newIndex;
+
+ // Mark the table if there are any entries.
+ if (newIndex > 0)
+ {
+ attributeUsageMarker.visitLocalVariableTypeTableAttribute(clazz, method, codeAttribute, localVariableTypeTableAttribute);
+ }
+ }
+ }
+
+
+ // Small utility methods.
+
+ private boolean hasParameters(Clazz clazz, Method method)
+ {
+ return method.getDescriptor(clazz).charAt(1) != ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE;
+ }
+} \ No newline at end of file
diff --git a/src/proguard/obfuscate/SimpleNameFactory.java b/src/proguard/obfuscate/SimpleNameFactory.java
index bce22de..d9b770b 100644
--- a/src/proguard/obfuscate/SimpleNameFactory.java
+++ b/src/proguard/obfuscate/SimpleNameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/SourceFileRenamer.java b/src/proguard/obfuscate/SourceFileRenamer.java
index cbf1b63..8805b08 100644
--- a/src/proguard/obfuscate/SourceFileRenamer.java
+++ b/src/proguard/obfuscate/SourceFileRenamer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/SpecialNameFactory.java b/src/proguard/obfuscate/SpecialNameFactory.java
index a5431ca..07c1674 100644
--- a/src/proguard/obfuscate/SpecialNameFactory.java
+++ b/src/proguard/obfuscate/SpecialNameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/Utf8Shrinker.java b/src/proguard/obfuscate/Utf8Shrinker.java
deleted file mode 100644
index 87ada80..0000000
--- a/src/proguard/obfuscate/Utf8Shrinker.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * ProGuard -- shrinking, optimization, obfuscation, and preverification
- * of Java bytecode.
- *
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-package proguard.obfuscate;
-
-import proguard.classfile.*;
-import proguard.classfile.constant.Constant;
-import proguard.classfile.editor.ConstantPoolRemapper;
-import proguard.classfile.visitor.ClassVisitor;
-
-
-/**
- * This ClassVisitor removes UTF-8 constant pool entries that are not marked
- * as being used.
- *
- * @see Utf8UsageMarker
- *
- * @author Eric Lafortune
- */
-public class Utf8Shrinker implements ClassVisitor
-{
- private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
- private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
-
-
- // Implementations for ClassVisitor.
-
- public void visitProgramClass(ProgramClass programClass)
- {
- // Shift the used constant pool entries together, filling out the
- // index map.
- programClass.u2constantPoolCount =
- shrinkConstantPool(programClass.constantPool,
- programClass.u2constantPoolCount);
-
- // Remap all constant pool references.
- constantPoolRemapper.setConstantIndexMap(constantIndexMap);
- constantPoolRemapper.visitProgramClass(programClass);
- }
-
-
- public void visitLibraryClass(LibraryClass libraryClass)
- {
- }
-
-
- // Small utility methods.
-
- /**
- * Removes all UTF-8 entries that are not marked as being used
- * from the given constant pool.
- * @return the new number of entries.
- */
- private int shrinkConstantPool(Constant[] constantPool, int length)
- {
- // Create a new index map, if necessary.
- if (constantIndexMap.length < length)
- {
- constantIndexMap = new int[length];
- }
-
- int counter = 1;
- boolean isUsed = false;
-
- // Shift the used constant pool entries together.
- for (int index = 1; index < length; index++)
- {
- constantIndexMap[index] = counter;
-
- Constant constant = constantPool[index];
-
- // Don't update the flag if this is the second half of a long entry.
- if (constant != null)
- {
- isUsed = constant.getTag() != ClassConstants.CONSTANT_Utf8 ||
- Utf8UsageMarker.isUsed(constant);
- }
-
- if (isUsed)
- {
- constantPool[counter++] = constant;
- }
- }
-
- // Clear the remaining constant pool elements.
- for (int index = counter; index < length; index++)
- {
- constantPool[index] = null;
- }
-
- return counter;
- }
-}
diff --git a/src/proguard/optimize/BootstrapMethodArgumentShrinker.java b/src/proguard/optimize/BootstrapMethodArgumentShrinker.java
new file mode 100644
index 0000000..70d031d
--- /dev/null
+++ b/src/proguard/optimize/BootstrapMethodArgumentShrinker.java
@@ -0,0 +1,103 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.editor.ConstantPoolEditor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.MemberVisitor;
+import proguard.optimize.info.*;
+import proguard.optimize.peephole.VariableShrinker;
+
+/**
+ * This BootstrapMethodInfoVisitor removes unused constant arguments from
+ * bootstrap method entries that it visits.
+ *
+ * @see ParameterUsageMarker
+ * @see VariableUsageMarker
+ * @see VariableShrinker
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodArgumentShrinker
+extends SimplifiedVisitor
+implements BootstrapMethodInfoVisitor,
+ ConstantVisitor,
+ MemberVisitor
+{
+ private long usedParameters;
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ // Check which method parameters are used.
+ usedParameters = -1L;
+ clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this);
+
+ // Remove the unused arguments.
+ int methodArgumentCount = bootstrapMethodInfo.u2methodArgumentCount;
+ int[] methodArguments = bootstrapMethodInfo.u2methodArguments;
+
+ int newArgumentIndex = 0;
+
+ for (int argumentIndex = 0; argumentIndex < methodArgumentCount; argumentIndex++)
+ {
+ if (argumentIndex >= 64 ||
+ (usedParameters & (1L << argumentIndex)) != 0L)
+ {
+ methodArguments[newArgumentIndex++] = methodArguments[argumentIndex];
+ }
+ }
+
+ // Update the number of arguments.
+ bootstrapMethodInfo.u2methodArgumentCount = newArgumentIndex;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Check the referenced bootstrap method.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ }
+
+
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ // Check the referenced class member itself.
+ refConstant.referencedMemberAccept(this);
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ usedParameters = ParameterUsageMarker.getUsedParameters(programMethod);
+ }
+}
diff --git a/src/proguard/optimize/ChangedCodePrinter.java b/src/proguard/optimize/ChangedCodePrinter.java
index 67a79ab..e0d00b8 100644
--- a/src/proguard/optimize/ChangedCodePrinter.java
+++ b/src/proguard/optimize/ChangedCodePrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -54,6 +54,12 @@ implements AttributeVisitor
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ attributeVisitor.visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute);
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
attributeVisitor.visitSourceFileAttribute(clazz, sourceFileAttribute);
diff --git a/src/proguard/optimize/ConstantMemberFilter.java b/src/proguard/optimize/ConstantMemberFilter.java
index 56437c3..d3a8207 100644
--- a/src/proguard/optimize/ConstantMemberFilter.java
+++ b/src/proguard/optimize/ConstantMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/ConstantParameterFilter.java b/src/proguard/optimize/ConstantParameterFilter.java
index 24a7040..6920990 100644
--- a/src/proguard/optimize/ConstantParameterFilter.java
+++ b/src/proguard/optimize/ConstantParameterFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/DuplicateInitializerFixer.java b/src/proguard/optimize/DuplicateInitializerFixer.java
index 746d182..07b7d82 100644
--- a/src/proguard/optimize/DuplicateInitializerFixer.java
+++ b/src/proguard/optimize/DuplicateInitializerFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -86,7 +86,7 @@ implements MemberVisitor,
if (!programMethod.equals(similarMethod))
{
// Should this initializer be preserved?
- if (!KeepMarker.isKept(programMethod))
+ if (KeepMarker.isKept(programMethod))
{
// Fix the other initializer.
programMethod = (ProgramMethod)similarMethod;
@@ -95,12 +95,23 @@ implements MemberVisitor,
int index = descriptor.indexOf(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE);
// Try to find a new, unique descriptor.
- for (int typeIndex = 0; typeIndex < TYPES.length; typeIndex++)
+ int typeCounter = 0;
+ while (true)
{
- String newDescriptor =
- descriptor.substring(0, index) +
- TYPES[typeIndex] +
- descriptor.substring(index);
+ // Construct the new descriptor by inserting a new type
+ // as an additional last argument.
+ StringBuffer newDescriptorBuffer =
+ new StringBuffer(descriptor.substring(0, index));
+
+ for (int arrayDimension = 0; arrayDimension < typeCounter / TYPES.length; arrayDimension++)
+ {
+ newDescriptorBuffer.append(ClassConstants.INTERNAL_TYPE_ARRAY);
+ }
+
+ newDescriptorBuffer.append(TYPES[typeCounter % TYPES.length]);
+ newDescriptorBuffer.append(descriptor.substring(index));
+
+ String newDescriptor = newDescriptorBuffer.toString();
// Is the new initializer descriptor unique?
if (programClass.findMethod(name, newDescriptor) == null)
@@ -108,7 +119,7 @@ implements MemberVisitor,
if (DEBUG)
{
System.out.println("DuplicateInitializerFixer:");
- System.out.println(" ["+programClass.getName()+"]: "+name+descriptor+" -> "+newDescriptor);
+ System.out.println(" ["+programClass.getName()+"."+name+descriptor+"] ("+ClassUtil.externalClassAccessFlags(programMethod.getAccessFlags())+") -> ["+newDescriptor+"]");
}
// Update the descriptor.
@@ -130,12 +141,9 @@ implements MemberVisitor,
// We're done with this constructor.
return;
}
- }
- throw new IllegalStateException("Can't find unique constructor descriptor for ["+
- programClass.getName()+"."+
- programMethod.getName(programClass)+
- programMethod.getDescriptor(programClass)+"]");
+ typeCounter++;
+ }
}
}
}
diff --git a/src/proguard/optimize/DuplicateInitializerInvocationFixer.java b/src/proguard/optimize/DuplicateInitializerInvocationFixer.java
index ca24481..e900232 100644
--- a/src/proguard/optimize/DuplicateInitializerInvocationFixer.java
+++ b/src/proguard/optimize/DuplicateInitializerInvocationFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -28,7 +28,7 @@ import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.editor.CodeAttributeEditor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
/**
@@ -48,12 +48,12 @@ implements AttributeVisitor,
private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor();
- private String descriptor;
- private boolean hasBeenFixed;
+ private String descriptor;
+ private int descriptorLengthDelta;
/**
- * Creates a new EvaluationSimplifier.
+ * Creates a new DuplicateInitializerInvocationFixer.
*/
public DuplicateInitializerInvocationFixer()
{
@@ -62,7 +62,7 @@ implements AttributeVisitor,
/**
- * Creates a new EvaluationSimplifier.
+ * Creates a new DuplicateInitializerInvocationFixer.
* @param extraAddedInstructionVisitor an optional extra visitor for all
* added instructions.
*/
@@ -102,21 +102,22 @@ implements AttributeVisitor,
{
if (constantInstruction.opcode == InstructionConstants.OP_INVOKESPECIAL)
{
- hasBeenFixed = false;
+ descriptorLengthDelta = 0;
clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
- if (hasBeenFixed)
+ if (descriptorLengthDelta > 0)
{
Instruction extraInstruction =
- new SimpleInstruction(InstructionConstants.OP_ICONST_0);
+ new SimpleInstruction(descriptorLengthDelta == 1 ?
+ InstructionConstants.OP_ICONST_0 :
+ InstructionConstants.OP_ACONST_NULL);
codeAttributeEditor.insertBeforeInstruction(offset,
extraInstruction);
if (DEBUG)
{
- System.out.println("DuplicateInitializerInvocationFixer:");
- System.out.println(" Inserting "+extraInstruction.toString()+" before "+constantInstruction.toString(offset));
+ System.out.println(" ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"] Inserting "+extraInstruction.toString()+" before "+constantInstruction.toString(offset));
}
if (extraAddedInstructionVisitor != null)
@@ -145,6 +146,16 @@ implements AttributeVisitor,
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- hasBeenFixed = !descriptor.equals(programMethod.getDescriptor(programClass));
+ descriptorLengthDelta =
+ programMethod.getDescriptor(programClass).length() - descriptor.length();
+
+ if (DEBUG)
+ {
+ if (descriptorLengthDelta > 0)
+ {
+ System.out.println("DuplicateInitializerInvocationFixer:");
+ System.out.println(" ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] ("+ClassUtil.externalClassAccessFlags(programMethod.getAccessFlags())+") referenced by:");
+ }
+ }
}
-} \ No newline at end of file
+}
diff --git a/src/proguard/optimize/KeepMarker.java b/src/proguard/optimize/KeepMarker.java
index 4297996..f8087be 100644
--- a/src/proguard/optimize/KeepMarker.java
+++ b/src/proguard/optimize/KeepMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/KeptClassFilter.java b/src/proguard/optimize/KeptClassFilter.java
new file mode 100644
index 0000000..4b9d090
--- /dev/null
+++ b/src/proguard/optimize/KeptClassFilter.java
@@ -0,0 +1,69 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This ClassVisitor delegates all its method calls to another ClassVisitor,
+ * but only for Clazz objects that are marked as kept.
+ *
+ * @see KeepMarker
+ *
+ * @author Eric Lafortune
+ */
+public class KeptClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ /**
+ * Creates a new KeptClassFilter.
+ * @param classVisitor the class visitor to which the visiting will be
+ * delegated.
+ */
+ public KeptClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (KeepMarker.isKept(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (KeepMarker.isKept(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/proguard/optimize/KeptMemberFilter.java b/src/proguard/optimize/KeptMemberFilter.java
new file mode 100644
index 0000000..5b25425
--- /dev/null
+++ b/src/proguard/optimize/KeptMemberFilter.java
@@ -0,0 +1,88 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.MemberVisitor;
+
+/**
+ * This MemberVisitor delegates all its method calls to another MemberVisitor,
+ * but only for Member objects that are marked as kept.
+ *
+ * @see KeepMarker
+ *
+ * @author Eric Lafortune
+ */
+public class KeptMemberFilter
+implements MemberVisitor
+{
+ private final MemberVisitor memberVisitor;
+
+
+ /**
+ * Creates a new KeptMemberFilter.
+ * @param memberVisitor the member visitor to which the visiting will be
+ * delegated.
+ */
+ public KeptMemberFilter(MemberVisitor memberVisitor)
+ {
+ this.memberVisitor = memberVisitor;
+ }
+
+
+ // Implementations for MemberVisitor.
+
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ if (KeepMarker.isKept(programField))
+ {
+ memberVisitor.visitProgramField(programClass, programField);
+ }
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if (KeepMarker.isKept(programMethod))
+ {
+ memberVisitor.visitProgramMethod(programClass, programMethod);
+ }
+ }
+
+
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
+ {
+ if (KeepMarker.isKept(libraryField))
+ {
+ memberVisitor.visitLibraryField(libraryClass, libraryField);
+ }
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ if (KeepMarker.isKept(libraryMethod))
+ {
+ memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/proguard/optimize/MemberDescriptorSpecializer.java b/src/proguard/optimize/MemberDescriptorSpecializer.java
index 0d0b841..7f051f5 100644
--- a/src/proguard/optimize/MemberDescriptorSpecializer.java
+++ b/src/proguard/optimize/MemberDescriptorSpecializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -39,7 +39,7 @@ public class MemberDescriptorSpecializer
extends SimplifiedVisitor
implements MemberVisitor
{
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private final MemberVisitor extraParameterMemberVisitor;
diff --git a/src/proguard/optimize/MethodDescriptorShrinker.java b/src/proguard/optimize/MethodDescriptorShrinker.java
index 48374e7..f4667ee 100644
--- a/src/proguard/optimize/MethodDescriptorShrinker.java
+++ b/src/proguard/optimize/MethodDescriptorShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -23,7 +23,7 @@ package proguard.optimize;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.editor.ConstantPoolEditor;
import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
@@ -95,11 +95,9 @@ implements MemberVisitor,
if (DEBUG)
{
System.out.println("MethodDescriptorShrinker:");
- System.out.println(" Class file = "+programClass.getName());
- System.out.println(" Method name = "+name);
- System.out.println(" -> "+newName);
- System.out.println(" Method descriptor = "+descriptor);
- System.out.println(" -> "+newDescriptor);
+ System.out.println(" ["+programClass.getName()+"."+
+ name+descriptor+"] -> ["+
+ newName+newDescriptor+"]");
}
ConstantPoolEditor constantPoolEditor =
diff --git a/src/proguard/optimize/MethodStaticizer.java b/src/proguard/optimize/MethodStaticizer.java
index 8dd11e1..9bd7b2a 100644
--- a/src/proguard/optimize/MethodStaticizer.java
+++ b/src/proguard/optimize/MethodStaticizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/OptimizationInfoMemberFilter.java b/src/proguard/optimize/OptimizationInfoMemberFilter.java
index 8760aee..a6d3cc7 100644
--- a/src/proguard/optimize/OptimizationInfoMemberFilter.java
+++ b/src/proguard/optimize/OptimizationInfoMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/Optimizer.java b/src/proguard/optimize/Optimizer.java
index a3e8a6e..c5db18b 100644
--- a/src/proguard/optimize/Optimizer.java
+++ b/src/proguard/optimize/Optimizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -23,7 +23,8 @@ package proguard.optimize;
import proguard.*;
import proguard.classfile.*;
import proguard.classfile.attribute.visitor.*;
-import proguard.classfile.constant.visitor.AllConstantVisitor;
+import proguard.classfile.constant.Constant;
+import proguard.classfile.constant.visitor.*;
import proguard.classfile.editor.*;
import proguard.classfile.instruction.visitor.*;
import proguard.classfile.util.MethodLinker;
@@ -66,6 +67,7 @@ public class Optimizer
private static final String CODE_SIMPLIFICATION_CAST = "code/simplification/cast";
private static final String CODE_SIMPLIFICATION_FIELD = "code/simplification/field";
private static final String CODE_SIMPLIFICATION_BRANCH = "code/simplification/branch";
+ private static final String CODE_SIMPLIFICATION_STRING = "code/simplification/string";
private static final String CODE_SIMPLIFICATION_ADVANCED = "code/simplification/advanced";
private static final String CODE_REMOVAL_ADVANCED = "code/removal/advanced";
private static final String CODE_REMOVAL_SIMPLE = "code/removal/simple";
@@ -80,6 +82,7 @@ public class Optimizer
CLASS_MERGING_VERTICAL,
CLASS_MERGING_HORIZONTAL,
FIELD_REMOVAL_WRITEONLY,
+ FIELD_MARKING_PRIVATE,
FIELD_PROPAGATION_VALUE,
METHOD_MARKING_PRIVATE,
METHOD_MARKING_STATIC,
@@ -96,6 +99,7 @@ public class Optimizer
CODE_SIMPLIFICATION_CAST,
CODE_SIMPLIFICATION_FIELD,
CODE_SIMPLIFICATION_BRANCH,
+ CODE_SIMPLIFICATION_STRING,
CODE_SIMPLIFICATION_ADVANCED,
CODE_REMOVAL_ADVANCED,
CODE_REMOVAL_SIMPLE,
@@ -157,6 +161,7 @@ public class Optimizer
boolean codeSimplificationCast = filter.matches(CODE_SIMPLIFICATION_CAST);
boolean codeSimplificationField = filter.matches(CODE_SIMPLIFICATION_FIELD);
boolean codeSimplificationBranch = filter.matches(CODE_SIMPLIFICATION_BRANCH);
+ boolean codeSimplificationString = filter.matches(CODE_SIMPLIFICATION_STRING);
boolean codeSimplificationAdvanced = filter.matches(CODE_SIMPLIFICATION_ADVANCED);
boolean codeRemovalAdvanced = filter.matches(CODE_REMOVAL_ADVANCED);
boolean codeRemovalSimple = filter.matches(CODE_REMOVAL_SIMPLE);
@@ -186,13 +191,15 @@ public class Optimizer
InstructionCounter codeSimplificationCastCounter = new InstructionCounter();
InstructionCounter codeSimplificationFieldCounter = new InstructionCounter();
InstructionCounter codeSimplificationBranchCounter = new InstructionCounter();
+ InstructionCounter codeSimplificationStringCounter = new InstructionCounter();
InstructionCounter codeSimplificationAdvancedCounter = new InstructionCounter();
InstructionCounter deletedCounter = new InstructionCounter();
InstructionCounter addedCounter = new InstructionCounter();
MemberCounter codeRemovalVariableCounter = new MemberCounter();
ExceptionCounter codeRemovalExceptionCounter = new ExceptionCounter();
MemberCounter codeAllocationVariableCounter = new MemberCounter();
- MemberCounter initializerFixCounter = new MemberCounter();
+ MemberCounter initializerFixCounter1 = new MemberCounter();
+ MemberCounter initializerFixCounter2 = new MemberCounter();
// Some optimizations are required by other optimizations.
codeSimplificationAdvanced =
@@ -250,10 +257,27 @@ public class Optimizer
new AllInstructionVisitor(
new DotClassClassVisitor(keepMarker)))));
- // We also keep all classes that are involved in Class.forName constructs.
+ // We also keep all classes that are accessed dynamically.
programClassPool.classesAccept(
new AllConstantVisitor(
- new ClassForNameClassVisitor(keepMarker)));
+ new ConstantTagFilter(ClassConstants.CONSTANT_String,
+ new ReferencedClassVisitor(keepMarker))));
+
+ // We also keep all class members that are accessed dynamically.
+ programClassPool.classesAccept(
+ new AllConstantVisitor(
+ new ConstantTagFilter(ClassConstants.CONSTANT_String,
+ new ReferencedMemberVisitor(keepMarker))));
+
+ // We also keep all bootstrap method signatures.
+ programClassPool.classesAccept(
+ new ClassVersionFilter(ClassConstants.INTERNAL_CLASS_VERSION_1_7,
+ new AllAttributeVisitor(
+ new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods,
+ new AllBootstrapMethodInfoVisitor(
+ new BootstrapMethodHandleTraveler(
+ new MethodrefTraveler(
+ new ReferencedMemberVisitor(keepMarker))))))));
// Attach some optimization info to all classes and class members, so
// it can be filled out later.
@@ -320,6 +344,9 @@ public class Optimizer
new ParameterUsageMarker(!methodMarkingStatic,
!methodRemovalParameter))));
+ // Mark all classes that have static initializers.
+ programClassPool.classesAccept(new StaticInitializerContainingClassMarker());
+
// Mark all methods that have side effects.
programClassPool.accept(new SideEffectMethodMarker());
@@ -347,18 +374,29 @@ public class Optimizer
new AllAttributeVisitor(
new PartialEvaluator(valueFactory, storingInvocationUnit, false))));
- // Count the constant fields and methods.
- programClassPool.classesAccept(
- new MultiClassVisitor(
- new ClassVisitor[]
- {
+ if (fieldPropagationValue)
+ {
+ // Count the constant fields.
+ programClassPool.classesAccept(
new AllFieldVisitor(
- new ConstantMemberFilter(fieldPropagationValueCounter)),
+ new ConstantMemberFilter(fieldPropagationValueCounter)));
+ }
+
+ if (methodPropagationParameter)
+ {
+ // Count the constant method parameters.
+ programClassPool.classesAccept(
new AllMethodVisitor(
- new ConstantParameterFilter(methodPropagationParameterCounter)),
+ new ConstantParameterFilter(methodPropagationParameterCounter)));
+ }
+
+ if (methodPropagationReturnvalue)
+ {
+ // Count the constant method return values.
+ programClassPool.classesAccept(
new AllMethodVisitor(
- new ConstantMemberFilter(methodPropagationReturnvalueCounter)),
- }));
+ new ConstantMemberFilter(methodPropagationReturnvalueCounter)));
+ }
}
InvocationUnit loadingInvocationUnit =
@@ -418,6 +456,12 @@ public class Optimizer
// This operation also updates the stack sizes.
programClassPool.classesAccept(
new MemberReferenceFixer());
+
+ // Remove unused bootstrap method arguments.
+ programClassPool.classesAccept(
+ new AllAttributeVisitor(
+ new AllBootstrapMethodInfoVisitor(
+ new BootstrapMethodArgumentShrinker())));
}
if (methodRemovalParameter ||
@@ -441,17 +485,39 @@ public class Optimizer
new StackSizeUpdater())));
}
-// // Specializing the class member descriptors seems to increase the
-// // class file size, on average.
-// // Specialize all class member descriptors.
-// programClassPool.classesAccept(new AllMemberVisitor(
-// new OptimizationInfoMemberFilter(
-// new MemberDescriptorSpecializer())));
-//
-// // Fix all references to classes, for MemberDescriptorSpecializer.
-// programClassPool.classesAccept(new AllMemberVisitor(
-// new OptimizationInfoMemberFilter(
-// new ClassReferenceFixer(true))));
+ if (methodRemovalParameter &&
+ methodRemovalParameterCounter.getCount() > 0)
+ {
+ // Tweak the descriptors of duplicate initializers, due to removed
+ // method parameters.
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new DuplicateInitializerFixer(initializerFixCounter1)));
+
+ if (initializerFixCounter1.getCount() > 0)
+ {
+ // Fix all invocations of tweaked initializers.
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new AllAttributeVisitor(
+ new DuplicateInitializerInvocationFixer(addedCounter))));
+
+ // Fix all references to tweaked initializers.
+ programClassPool.classesAccept(new MemberReferenceFixer());
+ }
+ }
+
+ //// Specializing the class member descriptors seems to increase the
+ //// class file size, on average.
+ //// Specialize all class member descriptors.
+ //programClassPool.classesAccept(new AllMemberVisitor(
+ // new OptimizationInfoMemberFilter(
+ // new MemberDescriptorSpecializer())));
+ //
+ //// Fix all references to classes, for MemberDescriptorSpecializer.
+ //programClassPool.classesAccept(new AllMemberVisitor(
+ // new OptimizationInfoMemberFilter(
+ // new ClassReferenceFixer(true))));
// Mark all classes with package visible members.
// Mark all exception catches of methods.
@@ -461,13 +527,13 @@ public class Optimizer
new MultiClassVisitor(
new ClassVisitor[]
{
+ new PackageVisibleMemberContainingClassMarker(),
new AllConstantVisitor(
new PackageVisibleMemberInvokingClassMarker()),
new AllMethodVisitor(
new MultiMemberVisitor(
new MemberVisitor[]
{
- new PackageVisibleMemberContainingClassMarker(),
new AllAttributeVisitor(
new MultiAttributeVisitor(
new AttributeVisitor[]
@@ -511,8 +577,8 @@ public class Optimizer
classMergingHorizontalCounter));
}
- if (classMergingVertical ||
- classMergingHorizontal)
+ if (classMergingVerticalCounter .getCount() > 0 ||
+ classMergingHorizontalCounter.getCount() > 0)
{
// Clean up inner class attributes to avoid loops.
programClassPool.classesAccept(new RetargetedInnerClassAttributeRemover());
@@ -530,18 +596,20 @@ public class Optimizer
new AllConstantVisitor(
new AccessFixer()));
}
- }
- if (methodRemovalParameter ||
- classMergingVertical ||
- classMergingHorizontal)
- {
- // Tweak the descriptors of duplicate initializers.
+ // Fix the access flags of the inner classes information.
+ programClassPool.classesAccept(
+ new AllAttributeVisitor(
+ new AllInnerClassesInfoVisitor(
+ new InnerClassesAccessFixer())));
+
+ // Tweak the descriptors of duplicate initializers, due to merged
+ // parameter classes.
programClassPool.classesAccept(
new AllMethodVisitor(
- new DuplicateInitializerFixer(initializerFixCounter)));
+ new DuplicateInitializerFixer(initializerFixCounter2)));
- if (initializerFixCounter.getCount() > 0)
+ if (initializerFixCounter2.getCount() > 0)
{
// Fix all invocations of tweaked initializers.
programClassPool.classesAccept(
@@ -595,14 +663,14 @@ public class Optimizer
new NonPrivateMemberMarker());
}
- if (fieldMarkingPrivate ||
- methodMarkingPrivate)
+ if (fieldMarkingPrivate)
{
// Make all non-private fields private, whereever possible.
programClassPool.classesAccept(
+ new ClassAccessFilter(0, ClassConstants.INTERNAL_ACC_INTERFACE,
new AllFieldVisitor(
new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
- new MemberPrivatizer(fieldMarkingPrivateCounter))));
+ new MemberPrivatizer(fieldMarkingPrivateCounter)))));
}
if (methodMarkingPrivate)
@@ -615,9 +683,9 @@ public class Optimizer
new MemberPrivatizer(methodMarkingPrivateCounter)))));
}
- if ((methodInliningUnique ||
- methodInliningShort ||
- methodInliningTailrecursion) &&
+ if ((methodInliningUniqueCounter .getCount() > 0 ||
+ methodInliningShortCounter .getCount() > 0 ||
+ methodInliningTailrecursionCounter.getCount() > 0) &&
configuration.allowAccessModification)
{
// Fix the access flags of referenced classes and class members,
@@ -627,10 +695,10 @@ public class Optimizer
new AccessFixer()));
}
- if (methodRemovalParameter ||
- classMergingVertical ||
- classMergingHorizontal ||
- methodMarkingPrivate)
+ if (methodRemovalParameterCounter .getCount() > 0 ||
+ classMergingVerticalCounter .getCount() > 0 ||
+ classMergingHorizontalCounter .getCount() > 0 ||
+ methodMarkingPrivateCounter .getCount() > 0 )
{
// Fix invocations of interface methods, of methods that have become
// non-abstract or private, and of methods that have moved to a
@@ -707,6 +775,15 @@ public class Optimizer
new GotoReturnReplacer(codeAttributeEditor, codeSimplificationBranchCounter));
}
+ if (codeSimplificationString)
+ {
+ // Peephole optimizations involving branches.
+ peepholeOptimizations.add(
+ new InstructionSequencesReplacer(InstructionSequenceConstants.CONSTANTS,
+ InstructionSequenceConstants.STRING,
+ branchTargetFinder, codeAttributeEditor, codeSimplificationStringCounter));
+ }
+
if (!peepholeOptimizations.isEmpty())
{
// Convert the list into an array.
@@ -749,14 +826,6 @@ public class Optimizer
new AllAttributeVisitor(
new VariableShrinker(codeRemovalVariableCounter))));
}
- else
- {
- // Clean up all unused local variables.
- programClassPool.classesAccept(
- new AllMethodVisitor(
- new AllAttributeVisitor(
- new VariableCleaner())));
- }
if (codeAllocationVariable)
{
@@ -767,6 +836,11 @@ public class Optimizer
new VariableOptimizer(false, codeAllocationVariableCounter))));
}
+
+ // Remove unused constants.
+ programClassPool.classesAccept(
+ new ConstantPoolShrinker());
+
int classMarkingFinalCount = classMarkingFinalCounter .getCount();
int classMergingVerticalCount = classMergingVerticalCounter .getCount();
int classMergingHorizontalCount = classMergingHorizontalCounter .getCount();
@@ -776,7 +850,7 @@ public class Optimizer
int methodMarkingPrivateCount = methodMarkingPrivateCounter .getCount();
int methodMarkingStaticCount = methodMarkingStaticCounter .getCount();
int methodMarkingFinalCount = methodMarkingFinalCounter .getCount();
- int methodRemovalParameterCount = methodRemovalParameterCounter .getCount() - methodMarkingStaticCounter.getCount() - initializerFixCounter.getCount();
+ int methodRemovalParameterCount = methodRemovalParameterCounter .getCount() - methodMarkingStaticCounter.getCount() - initializerFixCounter1.getCount() - initializerFixCounter2.getCount();
int methodPropagationParameterCount = methodPropagationParameterCounter .getCount();
int methodPropagationReturnvalueCount = methodPropagationReturnvalueCounter.getCount();
int methodInliningShortCount = methodInliningShortCounter .getCount();
@@ -788,12 +862,23 @@ public class Optimizer
int codeSimplificationCastCount = codeSimplificationCastCounter .getCount();
int codeSimplificationFieldCount = codeSimplificationFieldCounter .getCount();
int codeSimplificationBranchCount = codeSimplificationBranchCounter .getCount();
+ int codeSimplificationStringCount = codeSimplificationStringCounter .getCount();
int codeSimplificationAdvancedCount = codeSimplificationAdvancedCounter .getCount();
int codeRemovalCount = deletedCounter .getCount() - addedCounter.getCount();
int codeRemovalVariableCount = codeRemovalVariableCounter .getCount();
int codeRemovalExceptionCount = codeRemovalExceptionCounter .getCount();
int codeAllocationVariableCount = codeAllocationVariableCounter .getCount();
+ // Forget about constant fields, parameters, and return values, if they
+ // didn't lead to any useful optimizations. We want to avoid fruitless
+ // additional optimization passes.
+ if (codeSimplificationAdvancedCount == 0)
+ {
+ fieldPropagationValueCount = 0;
+ methodPropagationParameterCount = 0;
+ methodPropagationReturnvalueCount = 0;
+ }
+
if (configuration.verbose)
{
System.out.println(" Number of finalized classes: " + classMarkingFinalCount + disabled(classMarkingFinal));
@@ -817,6 +902,7 @@ public class Optimizer
System.out.println(" Number of cast peephole optimizations: " + codeSimplificationCastCount + disabled(codeSimplificationCast));
System.out.println(" Number of field peephole optimizations: " + codeSimplificationFieldCount + disabled(codeSimplificationField));
System.out.println(" Number of branch peephole optimizations: " + codeSimplificationBranchCount + disabled(codeSimplificationBranch));
+ System.out.println(" Number of string peephole optimizations: " + codeSimplificationStringCount + disabled(codeSimplificationString));
System.out.println(" Number of simplified instructions: " + codeSimplificationAdvancedCount + disabled(codeSimplificationAdvanced));
System.out.println(" Number of removed instructions: " + codeRemovalCount + disabled(codeRemovalAdvanced));
System.out.println(" Number of removed local variables: " + codeRemovalVariableCount + disabled(codeRemovalVariable));
@@ -845,6 +931,7 @@ public class Optimizer
codeSimplificationCastCount > 0 ||
codeSimplificationFieldCount > 0 ||
codeSimplificationBranchCount > 0 ||
+ codeSimplificationStringCount > 0 ||
codeSimplificationAdvancedCount > 0 ||
codeRemovalCount > 0 ||
codeRemovalVariableCount > 0 ||
diff --git a/src/proguard/optimize/ParameterShrinker.java b/src/proguard/optimize/ParameterShrinker.java
index a2bc6d3..2021861 100644
--- a/src/proguard/optimize/ParameterShrinker.java
+++ b/src/proguard/optimize/ParameterShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -23,7 +23,7 @@ package proguard.optimize;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
-import proguard.classfile.editor.*;
+import proguard.classfile.editor.VariableRemapper;
import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
import proguard.optimize.info.ParameterUsageMarker;
diff --git a/src/proguard/optimize/TailRecursionSimplifier.java b/src/proguard/optimize/TailRecursionSimplifier.java
index 0946b6a..f01dcd9 100644
--- a/src/proguard/optimize/TailRecursionSimplifier.java
+++ b/src/proguard/optimize/TailRecursionSimplifier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -54,9 +54,9 @@ implements AttributeVisitor,
private final CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer();
+ private final MyRecursionChecker recursionChecker = new MyRecursionChecker();
private Method targetMethod;
- private boolean recursive;
private boolean inlinedAny;
@@ -105,38 +105,31 @@ implements AttributeVisitor,
// clazz.getName().equals("abc/Def") &&
// method.getName(clazz).equals("abc");
- targetMethod = method;
- inlinedAny = false;
+ targetMethod = method;
+ inlinedAny = false;
codeAttributeComposer.reset();
- // Append the body of the code.
- copyCode(clazz, method, codeAttribute);
+ // The code may expand, due to expanding constant and variable
+ // instructions.
+ codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);
+
+ // Copy the instructions.
+ codeAttribute.instructionsAccept(clazz, method, this);
// Update the code attribute if any code has been inlined.
if (inlinedAny)
{
- codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute);
- }
- }
- }
+ // Copy the exceptions.
+ codeAttribute.exceptionsAccept(clazz, method, this);
+ // Append a label just after the code.
+ codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
- /**
- * Appends the code of the given code attribute.
- */
- private void copyCode(Clazz clazz, Method method, CodeAttribute codeAttribute)
- {
- // The code may expand, due to expanding constant and variable
- // instructions.
- codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);
-
- // Copy the instructions.
- codeAttribute.instructionsAccept(clazz, method, this);
+ codeAttributeComposer.endCodeFragment();
- // Append a label just after the code.
- codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
-
- codeAttributeComposer.endCodeFragment();
+ codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute);
+ }
+ }
}
@@ -159,9 +152,9 @@ implements AttributeVisitor,
case InstructionConstants.OP_INVOKESTATIC:
{
// Is it a recursive call?
- clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, recursionChecker);
- if (recursive)
+ if (recursionChecker.isRecursive())
{
// Is the next instruction a return?
int nextOffset =
@@ -180,13 +173,13 @@ implements AttributeVisitor,
case InstructionConstants.OP_RETURN:
{
// Isn't the recursive call inside a try/catch block?
- codeAttribute.exceptionsAccept(clazz, method, offset, this);
+ codeAttribute.exceptionsAccept(clazz, method, offset, recursionChecker);
- if (recursive)
+ if (recursionChecker.isRecursive())
{
if (DEBUG)
{
- System.out.println("TailRecursionSimplifier.visitConstantInstruction: ["+
+ System.out.println("TailRecursionSimplifier: ["+
clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"], inlining "+constantInstruction.toString(offset));
}
@@ -227,19 +220,52 @@ implements AttributeVisitor,
}
- // Implementations for ConstantVisitor.
+ // Implementations for ExceptionInfoVisitor.
- public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
+ public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
- recursive = targetMethod.equals(methodrefConstant.referencedMember);
+ codeAttributeComposer.appendException(new ExceptionInfo(exceptionInfo.u2startPC,
+ exceptionInfo.u2endPC,
+ exceptionInfo.u2handlerPC,
+ exceptionInfo.u2catchType));
}
- // Implementations for ExceptionInfoVisitor.
-
- public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
+ /**
+ * This ConstantVisitor and ExceptionInfoVisitor returns whether a method
+ * invocation can be treated as tail-recursive.
+ */
+ private class MyRecursionChecker
+ extends SimplifiedVisitor
+ implements ConstantVisitor,
+ ExceptionInfoVisitor
{
- recursive = false;
+ private boolean recursive;
+
+
+ /**
+ * Returns whether the method invocation can be treated as
+ * tail-recursive.
+ */
+ public boolean isRecursive()
+ {
+ return recursive;
+ }
+
+ // Implementations for ConstantVisitor.
+
+ public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
+ {
+ recursive = targetMethod.equals(methodrefConstant.referencedMember);
+ }
+
+
+ // Implementations for ExceptionInfoVisitor.
+
+ public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
+ {
+ recursive = false;
+ }
}
@@ -257,7 +283,6 @@ implements AttributeVisitor,
(method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0;
// Count the number of parameters, taking into account their categories.
- int parameterCount = ClassUtil.internalMethodParameterCount(descriptor);
int parameterSize = ClassUtil.internalMethodParameterSize(descriptor);
int parameterOffset = isStatic ? 0 : 1;
diff --git a/src/proguard/optimize/WriteOnlyFieldFilter.java b/src/proguard/optimize/WriteOnlyFieldFilter.java
index 578beb2..4a0e095 100644
--- a/src/proguard/optimize/WriteOnlyFieldFilter.java
+++ b/src/proguard/optimize/WriteOnlyFieldFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/EvaluationShrinker.java b/src/proguard/optimize/evaluation/EvaluationShrinker.java
index 1463feb..bc5f658 100644
--- a/src/proguard/optimize/evaluation/EvaluationShrinker.java
+++ b/src/proguard/optimize/evaluation/EvaluationShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -34,6 +34,8 @@ import proguard.evaluation.*;
import proguard.evaluation.value.*;
import proguard.optimize.info.*;
+import java.util.Arrays;
+
/**
* This AttributeVisitor simplifies the code attributes that it visits, based
* on partial evaluation.
@@ -55,13 +57,14 @@ implements AttributeVisitor
private final InstructionVisitor extraDeletedInstructionVisitor;
private final InstructionVisitor extraAddedInstructionVisitor;
- private final PartialEvaluator partialEvaluator;
- private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator();
- private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true);
- private final MyUnusedParameterSimplifier unusedParameterSimplifier = new MyUnusedParameterSimplifier();
- private final MyProducerMarker producerMarker = new MyProducerMarker();
- private final MyStackConsistencyFixer stackConsistencyFixer = new MyStackConsistencyFixer();
- private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);
+ private final PartialEvaluator partialEvaluator;
+ private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator();
+ private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true);
+ private final MyUnusedParameterSimplifier unusedParameterSimplifier = new MyUnusedParameterSimplifier();
+ private final MyProducerMarker producerMarker = new MyProducerMarker();
+ private final MyVariableInitializationMarker variableInitializationMarker = new MyVariableInitializationMarker();
+ private final MyStackConsistencyFixer stackConsistencyFixer = new MyStackConsistencyFixer();
+ private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);
private boolean[][] variablesNecessaryAfter = new boolean[ClassConstants.TYPICAL_CODE_LENGTH][ClassConstants.TYPICAL_VARIABLES_SIZE];
private boolean[][] stacksNecessaryAfter = new boolean[ClassConstants.TYPICAL_CODE_LENGTH][ClassConstants.TYPICAL_STACK_SIZE];
@@ -276,18 +279,10 @@ implements AttributeVisitor
if (partialEvaluator.isTraced(offset) &&
!isInstructionNecessary(offset))
{
- // Is the corresponding variable necessary anywhere in the code,
- // accoriding to a simple partial evaluation?
- int variableIndex = partialEvaluator.initializedVariable(offset);
- if (variableIndex >= 0 &&
- isVariableInitializationNecessary(clazz,
- method,
- codeAttribute,
- offset,
- variableIndex))
- {
- markInstruction(offset);
- }
+ Instruction instruction = InstructionFactory.create(codeAttribute.code,
+ offset);
+
+ instruction.accept(clazz, method, codeAttribute, offset, variableInitializationMarker);
}
}
if (DEBUG) System.out.println();
@@ -467,7 +462,9 @@ implements AttributeVisitor
*/
private class MyUnusedParameterSimplifier
extends SimplifiedVisitor
- implements InstructionVisitor, ConstantVisitor, MemberVisitor
+ implements InstructionVisitor,
+ ConstantVisitor,
+ MemberVisitor
{
private int invocationOffset;
private ConstantInstruction invocationInstruction;
@@ -657,6 +654,40 @@ implements AttributeVisitor
/**
+ * This InstructionVisitor marks variable initializations that are
+ * necessary to appease the JVM.
+ */
+ private class MyVariableInitializationMarker
+ extends SimplifiedVisitor
+ implements InstructionVisitor
+ {
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
+ {
+ if (!variableInstruction.isLoad())
+ {
+ int variableIndex = variableInstruction.variableIndex;
+
+ if (isVariableInitialization(offset,
+ variableIndex) &&
+ isVariableInitializationNecessary(clazz,
+ method,
+ codeAttribute,
+ offset,
+ variableIndex))
+ {
+ markInstruction(offset);
+ }
+ }
+ }
+ }
+
+
+ /**
* This InstructionVisitor fixes instructions locally, popping any unused
* produced stack entries after marked instructions, and popping produced
* stack entries and pushing missing stack entries instead of unmarked
@@ -687,12 +718,23 @@ implements AttributeVisitor
int requiredPushCount = 0;
for (int stackIndex = 0; stackIndex < popCount; stackIndex++)
{
- // Is the stack entry required by other consumers?
- if (!isStackSimplifiedBefore(offset, top - stackIndex) &&
- !isAnyStackEntryNecessaryAfter(tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(), top - stackIndex))
+ InstructionOffsetValue producerOffsets =
+ tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue();
+
+ if (!isStackSimplifiedBefore(offset, top - stackIndex))
{
- // Remember to push it.
- requiredPushCount++;
+ // Is the stack entry pushed by any producer,
+ // because it is required by other consumers?
+ if (isAnyStackEntryNecessaryAfter(producerOffsets, top - stackIndex))
+ {
+ // Make sure it is pushed after all producers.
+ markStackEntriesAfter(producerOffsets, top - stackIndex);
+ }
+ else
+ {
+ // Remember to push it.
+ requiredPushCount++;
+ }
}
}
@@ -757,9 +799,16 @@ implements AttributeVisitor
int expectedPopCount = 0;
for (int stackIndex = 0; stackIndex < popCount; stackIndex++)
{
- // Is the stack entry required by other consumers?
- if (isAnyStackEntryNecessaryAfter(tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(), top - stackIndex))
+ InstructionOffsetValue producerOffsets =
+ tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue();
+
+ // Is the stack entry pushed by any producer,
+ // because it is required by other consumers?
+ if (isAnyStackEntryNecessaryAfter(producerOffsets, top - stackIndex))
{
+ // Make sure it is pushed after all producers.
+ markStackEntriesAfter(producerOffsets, top - stackIndex);
+
// Remember to pop it.
expectedPopCount++;
}
@@ -1052,6 +1101,7 @@ implements AttributeVisitor
byte oldOpcode = instruction.opcode;
byte newOpcode = 0;
+ byte addOpcode = 0;
// Simplify the popping instruction if possible.
switch (oldOpcode)
@@ -1232,9 +1282,20 @@ implements AttributeVisitor
stackEntryPresent1)
{
// Will both elements be present?
- if (stackEntryPresent0 &&
- stackEntryPresent1)
+ if (!stackEntryPresent1)
{
+ // Pop the original top element (later bottom element).
+ newOpcode = InstructionConstants.OP_POP;
+ }
+ else if (!stackEntryPresent0)
+ {
+ // Swap both elements and pop the top one.
+ newOpcode = InstructionConstants.OP_SWAP;
+ addOpcode = InstructionConstants.OP_POP;
+ }
+ else
+ {
+ // Just swap both elements.
newOpcode = InstructionConstants.OP_SWAP;
}
}
@@ -1242,6 +1303,7 @@ implements AttributeVisitor
}
}
+ // Is there a replacement opcode?
if (newOpcode == 0)
{
// Delete the instruction.
@@ -1270,6 +1332,21 @@ implements AttributeVisitor
if (DEBUG) System.out.println(" Replacing instruction "+instruction.toString(dupOffset)+" by "+replacementInstruction.toString());
}
+
+ // Is there an additional opcode?
+ if (addOpcode != 0)
+ {
+ // Add the instruction.
+ Instruction additionalInstruction = new SimpleInstruction(addOpcode);
+ codeAttributeEditor.insertAfterInstruction(dupOffset, additionalInstruction);
+
+ if (extraAddedInstructionVisitor != null)
+ {
+ extraAddedInstructionVisitor.visitSimpleInstruction(null, null, null, dupOffset, null);
+ }
+
+ if (DEBUG) System.out.println(" Adding instruction "+additionalInstruction.toString(dupOffset));
+ }
}
@@ -1596,10 +1673,7 @@ implements AttributeVisitor
{
for (int offset = 0; offset < codeLength; offset++)
{
- for (int index = 0; index < maxLocals; index++)
- {
- variablesNecessaryAfter[offset][index] = false;
- }
+ Arrays.fill(variablesNecessaryAfter[offset], 0, maxLocals, false);
}
}
@@ -1612,10 +1686,7 @@ implements AttributeVisitor
{
for (int offset = 0; offset < codeLength; offset++)
{
- for (int index = 0; index < maxStack; index++)
- {
- stacksNecessaryAfter[offset][index] = false;
- }
+ Arrays.fill(stacksNecessaryAfter[offset], 0, maxStack, false);
}
}
@@ -1628,10 +1699,7 @@ implements AttributeVisitor
{
for (int offset = 0; offset < codeLength; offset++)
{
- for (int index = 0; index < maxStack; index++)
- {
- stacksSimplifiedBefore[offset][index] = false;
- }
+ Arrays.fill(stacksSimplifiedBefore[offset], 0, maxStack, false);
}
}
@@ -1641,10 +1709,7 @@ implements AttributeVisitor
}
else
{
- for (int index = 0; index < codeLength; index++)
- {
- instructionsNecessary[index] = false;
- }
+ Arrays.fill(instructionsNecessary, 0, codeLength, false);
}
}
@@ -1670,6 +1735,34 @@ implements AttributeVisitor
/**
+ * Returns whether the specified variable is initialized at the specified
+ * offset.
+ */
+ private boolean isVariableInitialization(int instructionOffset,
+ int variableIndex)
+ {
+ // Wasn't the variable set yet?
+ Value valueBefore = partialEvaluator.getVariablesBefore(instructionOffset).getValue(variableIndex);
+ if (valueBefore == null)
+ {
+ return true;
+ }
+
+ // Is the computational type different now?
+ Value valueAfter = partialEvaluator.getVariablesAfter(instructionOffset).getValue(variableIndex);
+ if (valueAfter.computationalType() != valueBefore.computationalType())
+ {
+ return true;
+ }
+
+ // Was the producer an argument (which may be removed)?
+ Value producersBefore = partialEvaluator.getVariablesBefore(instructionOffset).getProducerValue(variableIndex);
+ return producersBefore.instructionOffsetValue().instructionOffsetCount() == 1 &&
+ producersBefore.instructionOffsetValue().instructionOffset(0) == PartialEvaluator.AT_METHOD_ENTRY;
+ }
+
+
+ /**
* Returns whether the specified variable must be initialized at the
* specified offset, according to the verifier of the JVM.
*/
@@ -1686,8 +1779,8 @@ implements AttributeVisitor
{
if (DEBUG) System.out.println("Simple partial evaluation for initialization of variable v"+variableIndex+" at ["+initializationOffset+"]");
- // Lazily compute perform simple partial evaluation, the way the
- // JVM preverifier would do it.
+ // Lazily perform simple partial evaluation, the way the JVM
+ // verifier would do it.
simplePartialEvaluator.visitCodeAttribute(clazz, method, codeAttribute);
if (DEBUG) System.out.println("End of simple partial evaluation for initialization of variable v"+variableIndex+" at ["+initializationOffset+"]");
@@ -1695,7 +1788,7 @@ implements AttributeVisitor
// Check if the variable is necessary elsewhere.
for (int offset = 0; offset < codeLength; offset++)
{
- if (isInstructionNecessary(offset))
+ if (partialEvaluator.isTraced(offset))
{
Value producer = partialEvaluator.getVariablesBefore(offset).getProducerValue(variableIndex);
if (producer != null)
@@ -1708,16 +1801,22 @@ implements AttributeVisitor
InstructionOffsetValue simpleProducerOffsets =
simpleProducer.instructionOffsetValue();
- // Does the sophisticated partial evaluation have fewer
- // producers than the simple one?
- // And does the simple partial evaluation point to an
- // initialization of the variable?
- if (producerOffsets.instructionOffsetCount() <
- simpleProducerOffsets.instructionOffsetCount() &&
- isVariableNecessaryAfterAny(producerOffsets, variableIndex) &&
- simpleProducerOffsets.contains(initializationOffset))
+ if (DEBUG)
{
- // Then the initialization is necessary.
+ System.out.println(" ["+offset+"] producers ["+producerOffsets+"], simple producers ["+simpleProducerOffsets+"]");
+ }
+
+ // Is the variable being used without all of its
+ // immediate simple producers being marked?
+ if (isVariableNecessaryAfterAny(producerOffsets, variableIndex) &&
+ !isVariableNecessaryAfterAll(simpleProducerOffsets, variableIndex))
+ {
+ if (DEBUG)
+ {
+ System.out.println(" => initialization of variable v"+variableIndex+" at ["+initializationOffset+"] necessary");
+ }
+
+ // Then the initialization may be necessary.
return true;
}
}
@@ -1726,6 +1825,11 @@ implements AttributeVisitor
}
}
+ if (DEBUG)
+ {
+ System.out.println(" => initialization of variable v"+variableIndex+" at ["+initializationOffset+"] not necessary");
+ }
+
return false;
}
@@ -1749,7 +1853,7 @@ implements AttributeVisitor
/**
* Returns whether the specified variable is ever necessary after any
- * instruction in the specified block.
+ * instructions in the specified block.
*/
private boolean isVariableNecessaryAfterAny(int startOffset,
int endOffset,
@@ -1769,7 +1873,7 @@ implements AttributeVisitor
/**
* Returns whether the specified variable is ever necessary after any
- * instruction in the specified set of instructions offsets.
+ * instructions in the specified set of instructions offsets.
*/
private boolean isVariableNecessaryAfterAny(InstructionOffsetValue instructionOffsetValue,
int variableIndex)
@@ -1789,6 +1893,28 @@ implements AttributeVisitor
}
+ /**
+ * Returns whether the specified variable is ever necessary after all
+ * instructions in the specified set of instructions offsets.
+ */
+ private boolean isVariableNecessaryAfterAll(InstructionOffsetValue instructionOffsetValue,
+ int variableIndex)
+ {
+ int count = instructionOffsetValue.instructionOffsetCount();
+
+ for (int index = 0; index < count; index++)
+ {
+ if (!isVariableNecessaryAfter(instructionOffsetValue.instructionOffset(index),
+ variableIndex))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
private boolean isVariableNecessaryAfter(int instructionOffset,
int variableIndex)
{
@@ -1797,6 +1923,36 @@ implements AttributeVisitor
}
+ /**
+ * Marks the stack entries after the given offsets.
+ * @param instructionOffsets the offsets of the stack entries to be marked.
+ * @param stackIndex the index of the stack entries to be marked
+ * (counting from the bottom).
+ */
+ private void markStackEntriesAfter(InstructionOffsetValue instructionOffsets,
+ int stackIndex)
+ {
+ if (instructionOffsets != null)
+ {
+ int offsetCount = instructionOffsets.instructionOffsetCount();
+ for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
+ {
+ // Make sure the stack entry and the instruction are marked
+ // at the producing offset.
+ int offset = instructionOffsets.instructionOffset(offsetIndex);
+
+ markStackEntryAfter(offset, stackIndex);
+ }
+ }
+ }
+
+
+ /**
+ * Marks the stack entry after the given offset.
+ * @param instructionOffset the offset of the stack entry to be marked.
+ * @param stackIndex the index of the stack entry to be marked
+ * (counting from the bottom).
+ */
private void markStackEntryAfter(int instructionOffset,
int stackIndex)
{
@@ -1814,6 +1970,13 @@ implements AttributeVisitor
}
+ /**
+ * Returns whether any of the stack entries after the given offsets are
+ * necessary.
+ * @param instructionOffsets the offsets of the stack entries to be checked.
+ * @param stackIndex the index of the stack entries to be checked
+ * (counting from the bottom).
+ */
private boolean isAnyStackEntryNecessaryAfter(InstructionOffsetValue instructionOffsets,
int stackIndex)
{
@@ -1831,6 +1994,13 @@ implements AttributeVisitor
}
+ /**
+ * Returns whether any of the stack entries after the given offset are
+ * necessary.
+ * @param instructionOffset the offset of the stack entry to be checked.
+ * @param stackIndex the index of the stack entry to be checked
+ * (counting from the bottom).
+ */
private boolean isStackEntryNecessaryAfter(int instructionOffset,
int stackIndex)
{
diff --git a/src/proguard/optimize/evaluation/EvaluationSimplifier.java b/src/proguard/optimize/evaluation/EvaluationSimplifier.java
index 0c3a9c7..b207108 100644
--- a/src/proguard/optimize/evaluation/EvaluationSimplifier.java
+++ b/src/proguard/optimize/evaluation/EvaluationSimplifier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -43,6 +43,9 @@ extends SimplifiedVisitor
implements AttributeVisitor,
InstructionVisitor
{
+ private static int POS_ZERO_FLOAT_BITS = Float.floatToIntBits(0.0f);
+ private static long POS_ZERO_DOUBLE_BITS = Double.doubleToLongBits(0.0);
+
//*
private static final boolean DEBUG = false;
/*/
@@ -559,10 +562,11 @@ implements AttributeVisitor,
Value pushedValue = partialEvaluator.getStackAfter(offset).getTop(0);
if (pushedValue.isParticular())
{
+ // Make sure to distinguish between +0.0 and -0.0.
float value = pushedValue.floatValue().value();
- if (value == 0f ||
- value == 1f ||
- value == 2f)
+ if (value == 0.0f && Float.floatToIntBits(value) == POS_ZERO_FLOAT_BITS ||
+ value == 1.0f ||
+ value == 2.0f)
{
replaceConstantPushInstruction(clazz,
offset,
@@ -627,8 +631,9 @@ implements AttributeVisitor,
Value pushedValue = partialEvaluator.getStackAfter(offset).getTop(0);
if (pushedValue.isParticular())
{
+ // Make sure to distinguish between +0.0 and -0.0.
double value = pushedValue.doubleValue().value();
- if (value == 0.0 ||
+ if (value == 0.0 && Double.doubleToLongBits(value) == POS_ZERO_DOUBLE_BITS ||
value == 1.0)
{
replaceConstantPushInstruction(clazz,
diff --git a/src/proguard/optimize/evaluation/LivenessAnalyzer.java b/src/proguard/optimize/evaluation/LivenessAnalyzer.java
index 9915027..747f993 100644
--- a/src/proguard/optimize/evaluation/LivenessAnalyzer.java
+++ b/src/proguard/optimize/evaluation/LivenessAnalyzer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -79,6 +79,16 @@ implements AttributeVisitor,
/**
+ * Returns whether the instruction at the given offset has ever been
+ * executed during the partial evaluation.
+ */
+ public boolean isTraced(int instructionOffset)
+ {
+ return partialEvaluator.isTraced(instructionOffset);
+ }
+
+
+ /**
* Returns whether the specified variable is alive before the instruction
* at the given offset.
*/
diff --git a/src/proguard/optimize/evaluation/LoadingInvocationUnit.java b/src/proguard/optimize/evaluation/LoadingInvocationUnit.java
index 8379c57..578ece5 100644
--- a/src/proguard/optimize/evaluation/LoadingInvocationUnit.java
+++ b/src/proguard/optimize/evaluation/LoadingInvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -35,9 +35,9 @@ import proguard.evaluation.value.*;
public class LoadingInvocationUnit
extends BasicInvocationUnit
{
- private boolean loadFieldValues;
- private boolean loadMethodParameterValues;
- private boolean loadMethodReturnValues;
+ private final boolean loadFieldValues;
+ private final boolean loadMethodParameterValues;
+ private final boolean loadMethodReturnValues;
/**
@@ -84,8 +84,6 @@ extends BasicInvocationUnit
value.isParticular())
{
return value;
-// // Make sure the value is refreshed.
-// return refresh(value);
}
}
}
@@ -110,8 +108,6 @@ extends BasicInvocationUnit
value.isParticular())
{
return value;
-// // Make sure the value is refreshed.
-// return refresh(value);
}
}
}
@@ -134,8 +130,6 @@ extends BasicInvocationUnit
value.isParticular())
{
return value;
-// // Make sure the value is refreshed.
-// return refresh(value);
}
}
@@ -163,8 +157,6 @@ extends BasicInvocationUnit
value.isParticular())
{
return value;
-// // Make sure the value is refreshed.
-// return refresh(value);
}
}
}
@@ -173,8 +165,8 @@ extends BasicInvocationUnit
refConstant,
type);
}
-//
-//
+
+
// // Small utility methods.
//
// private Value refresh(Value value)
diff --git a/src/proguard/optimize/evaluation/PartialEvaluator.java b/src/proguard/optimize/evaluation/PartialEvaluator.java
index 5790a36..b2776d1 100644
--- a/src/proguard/optimize/evaluation/PartialEvaluator.java
+++ b/src/proguard/optimize/evaluation/PartialEvaluator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -31,6 +31,8 @@ import proguard.evaluation.*;
import proguard.evaluation.value.*;
import proguard.optimize.peephole.BranchTargetFinder;
+import java.util.Arrays;
+
/**
* This AttributeVisitor performs partial evaluation on the code attributes
* that it visits.
@@ -68,7 +70,6 @@ implements AttributeVisitor,
private TracedStack[] stacksAfter = new TracedStack[ClassConstants.TYPICAL_CODE_LENGTH];
private boolean[] generalizedContexts = new boolean[ClassConstants.TYPICAL_CODE_LENGTH];
private int[] evaluationCounts = new int[ClassConstants.TYPICAL_CODE_LENGTH];
- private int[] initializedVariables = new int[ClassConstants.TYPICAL_CODE_LENGTH];
private boolean evaluateExceptions;
private final BasicBranchUnit branchUnit;
@@ -189,6 +190,47 @@ implements AttributeVisitor,
if (DEBUG)
{
method.accept(clazz, new ClassPrinter());
+
+ System.out.println("Evaluation results:");
+
+ int offset = 0;
+ do
+ {
+ if (isBranchOrExceptionTarget(offset))
+ {
+ System.out.println("Branch target from ["+branchOriginValues[offset]+"]:");
+ if (isTraced(offset))
+ {
+ System.out.println(" Vars: "+variablesBefore[offset]);
+ System.out.println(" Stack: "+stacksBefore[offset]);
+ }
+ }
+
+ Instruction instruction = InstructionFactory.create(codeAttribute.code,
+ offset);
+ System.out.println(instruction.toString(offset));
+
+ if (isTraced(offset))
+ {
+ int initializationOffset = branchTargetFinder.initializationOffset(offset);
+ if (initializationOffset != NONE)
+ {
+ System.out.println(" is to be initialized at ["+initializationOffset+"]");
+ }
+
+ InstructionOffsetValue branchTargets = branchTargets(offset);
+ if (branchTargets != null)
+ {
+ System.out.println(" has overall been branching to "+branchTargets);
+ }
+
+ System.out.println(" Vars: "+variablesAfter[offset]);
+ System.out.println(" Stack: "+stacksAfter[offset]);
+ }
+
+ offset += instruction.length(offset);
+ }
+ while (offset < codeAttribute.u4codeLength);
}
throw ex;
@@ -212,7 +254,8 @@ implements AttributeVisitor,
TracedStack stack = new TracedStack(codeAttribute.u2maxStack);
// Initialize the reusable arrays and variables.
- initializeVariables(clazz, method, codeAttribute, variables, stack);
+ initializeArrays(codeAttribute);
+ initializeParameters(clazz, method, codeAttribute, variables);
// Find all instruction offsets,...
codeAttribute.accept(clazz, method, branchTargetFinder);
@@ -249,12 +292,6 @@ implements AttributeVisitor,
if (isTraced(offset))
{
- int variableIndex = initializedVariable(offset);
- if (variableIndex >= 0)
- {
- System.out.println(" is initializing variable v"+variableIndex);
- }
-
int initializationOffset = branchTargetFinder.initializationOffset(offset);
if (initializationOffset != NONE)
{
@@ -479,16 +516,6 @@ implements AttributeVisitor,
}
- /**
- * Returns the variable that is initialized at the given instruction offset,
- * or <code>NONE</code> if no variable was initialized.
- */
- public int initializedVariable(int instructionOffset)
- {
- return initializedVariables[instructionOffset];
- }
-
-
// Utility methods to evaluate instruction blocks.
/**
@@ -702,9 +729,6 @@ implements AttributeVisitor,
// Reset the trace value.
InstructionOffsetValue traceValue = InstructionOffsetValue.EMPTY_VALUE;
- // Reset the initialization flag.
- variables.resetInitialization();
-
// Note that the instruction is only volatile.
Instruction instruction = InstructionFactory.create(code, instructionOffset);
@@ -743,9 +767,6 @@ implements AttributeVisitor,
throw ex;
}
- // Collect the offsets of the instructions whose results were used.
- initializedVariables[instructionOffset] = variables.getInitializationIndex();
-
// Collect the branch targets from the branch unit.
InstructionOffsetValue branchTargets = branchUnit.getTraceBranchTargets();
int branchTargetCount = branchTargets.instructionOffsetCount();
@@ -896,11 +917,7 @@ implements AttributeVisitor,
subroutinePartialEvaluator = new PartialEvaluator(this);
- subroutinePartialEvaluator.initializeVariables(clazz,
- method,
- codeAttribute,
- variables,
- stack);
+ subroutinePartialEvaluator.initializeArrays(codeAttribute);
}
// Evaluate the subroutine.
@@ -952,13 +969,12 @@ implements AttributeVisitor,
if (evaluationCounts[offset] == 0)
{
- variablesBefore[offset] = other.variablesBefore[offset];
- stacksBefore[offset] = other.stacksBefore[offset];
- variablesAfter[offset] = other.variablesAfter[offset];
- stacksAfter[offset] = other.stacksAfter[offset];
- generalizedContexts[offset] = other.generalizedContexts[offset];
- evaluationCounts[offset] = other.evaluationCounts[offset];
- initializedVariables[offset] = other.initializedVariables[offset];
+ variablesBefore[offset] = other.variablesBefore[offset];
+ stacksBefore[offset] = other.stacksBefore[offset];
+ variablesAfter[offset] = other.variablesAfter[offset];
+ stacksAfter[offset] = other.stacksAfter[offset];
+ generalizedContexts[offset] = other.generalizedContexts[offset];
+ evaluationCounts[offset] = other.evaluationCounts[offset];
}
else
{
@@ -968,7 +984,6 @@ implements AttributeVisitor,
stacksAfter[offset] .generalize(other.stacksAfter[offset]);
//generalizedContexts[offset]
evaluationCounts[offset] += other.evaluationCounts[offset];
- //initializedVariables[offset]
}
}
}
@@ -1094,11 +1109,7 @@ implements AttributeVisitor,
/**
* Initializes the data structures for the variables, stack, etc.
*/
- private void initializeVariables(Clazz clazz,
- Method method,
- CodeAttribute codeAttribute,
- TracedVariables variables,
- TracedStack stack)
+ private void initializeArrays(CodeAttribute codeAttribute)
{
int codeLength = codeAttribute.u4codeLength;
@@ -1106,33 +1117,25 @@ implements AttributeVisitor,
if (variablesAfter.length < codeLength)
{
// Create new arrays.
- branchOriginValues = new InstructionOffsetValue[codeLength];
- branchTargetValues = new InstructionOffsetValue[codeLength];
- variablesBefore = new TracedVariables[codeLength];
- stacksBefore = new TracedStack[codeLength];
- variablesAfter = new TracedVariables[codeLength];
- stacksAfter = new TracedStack[codeLength];
- generalizedContexts = new boolean[codeLength];
- evaluationCounts = new int[codeLength];
- initializedVariables = new int[codeLength];
-
- // Reset the arrays.
- for (int index = 0; index < codeLength; index++)
- {
- initializedVariables[index] = NONE;
- }
+ branchOriginValues = new InstructionOffsetValue[codeLength];
+ branchTargetValues = new InstructionOffsetValue[codeLength];
+ variablesBefore = new TracedVariables[codeLength];
+ stacksBefore = new TracedStack[codeLength];
+ variablesAfter = new TracedVariables[codeLength];
+ stacksAfter = new TracedStack[codeLength];
+ generalizedContexts = new boolean[codeLength];
+ evaluationCounts = new int[codeLength];
}
else
{
// Reset the arrays.
+ Arrays.fill(branchOriginValues, null);
+ Arrays.fill(branchTargetValues, null);
+ Arrays.fill(generalizedContexts, false);
+ Arrays.fill(evaluationCounts, 0);
+
for (int index = 0; index < codeLength; index++)
{
- branchOriginValues[index] = null;
- branchTargetValues[index] = null;
- generalizedContexts[index] = false;
- evaluationCounts[index] = 0;
- initializedVariables[index] = NONE;
-
if (variablesBefore[index] != null)
{
variablesBefore[index].reset(codeAttribute.u2maxLocals);
@@ -1154,7 +1157,17 @@ implements AttributeVisitor,
}
}
}
+ }
+
+ /**
+ * Initializes the data structures for the variables, stack, etc.
+ */
+ private void initializeParameters(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ TracedVariables variables)
+ {
// Create the method parameters.
TracedVariables parameters = new TracedVariables(codeAttribute.u2maxLocals);
diff --git a/src/proguard/optimize/evaluation/StoringInvocationUnit.java b/src/proguard/optimize/evaluation/StoringInvocationUnit.java
index bcbb69f..010dab0 100644
--- a/src/proguard/optimize/evaluation/StoringInvocationUnit.java
+++ b/src/proguard/optimize/evaluation/StoringInvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/TracedBranchUnit.java b/src/proguard/optimize/evaluation/TracedBranchUnit.java
index fa5bb79..b7dd469 100644
--- a/src/proguard/optimize/evaluation/TracedBranchUnit.java
+++ b/src/proguard/optimize/evaluation/TracedBranchUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/VariableOptimizer.java b/src/proguard/optimize/evaluation/VariableOptimizer.java
index b3ae81c..a824481 100644
--- a/src/proguard/optimize/evaluation/VariableOptimizer.java
+++ b/src/proguard/optimize/evaluation/VariableOptimizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,10 +21,10 @@
package proguard.optimize.evaluation;
import proguard.classfile.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.editor.*;
import proguard.classfile.visitor.MemberVisitor;
import proguard.classfile.attribute.*;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
-import proguard.classfile.editor.VariableRemapper;
import proguard.classfile.util.*;
/**
@@ -35,7 +35,9 @@ import proguard.classfile.util.*;
*/
public class VariableOptimizer
extends SimplifiedVisitor
-implements AttributeVisitor
+implements AttributeVisitor,
+ LocalVariableInfoVisitor,
+ LocalVariableTypeInfoVisitor
{
//*
private static final boolean DEBUG = false;
@@ -51,6 +53,7 @@ implements AttributeVisitor
private final LivenessAnalyzer livenessAnalyzer = new LivenessAnalyzer();
private final VariableRemapper variableRemapper = new VariableRemapper();
+ private VariableCleaner variableCleaner = new VariableCleaner();
private int[] variableMap = new int[ClassConstants.TYPICAL_VARIABLES_SIZE];
@@ -101,6 +104,11 @@ implements AttributeVisitor
// Analyze the liveness of the variables in the code.
livenessAnalyzer.visitCodeAttribute(clazz, method, codeAttribute);
+ // Trim the variables in the local variable tables, because even
+ // clipping the tables individually may leave some inconsistencies
+ // between them.
+ codeAttribute.attributesAccept(clazz, method, this);
+
int startIndex =
(method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 ||
reuseThis ? 0 : 1;
@@ -142,23 +150,19 @@ implements AttributeVisitor
}
}
- // Remap the variables.
+ // Have we been able to remap any variables?
if (remapping)
{
if (DEBUG)
{
- System.out.println("Remapping variables:");
- System.out.println(" Class "+ ClassUtil.externalClassName(clazz.getName()));
- System.out.println(" Method "+ClassUtil.externalFullMethodDescription(clazz.getName(),
- 0,
- method.getName(clazz),
- method.getDescriptor(clazz)));
- for (int index = 0; index < variableSize; index++)
+ System.out.println("VariableOptimizer: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
+ for (int index= 0; index < variableSize; index++)
{
- System.out.println(" ["+index+"] -> ["+variableMap[index]+"]");
+ System.out.println(" v"+index+" -> "+variableMap[index]);
}
}
+ // Remap the variables.
variableRemapper.setVariableMap(variableMap);
variableRemapper.visitCodeAttribute(clazz, method, codeAttribute);
@@ -168,6 +172,59 @@ implements AttributeVisitor
method.accept(clazz, extraVariableMemberVisitor);
}
}
+ else
+ {
+ // Just clean up any empty variables.
+ variableCleaner.visitCodeAttribute(clazz, method, codeAttribute);
+ }
+ }
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ // Trim the variables in the local variable table.
+ localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ // Trim the variables in the local variable type table.
+ localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ // Implementations for LocalVariableInfoVisitor.
+
+ public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
+ {
+ // Trim the local variable to the instructions at which it is alive.
+ int variable = localVariableInfo.u2index;
+ int startPC = localVariableInfo.u2startPC;
+ int endPC = startPC + localVariableInfo.u2length;
+
+ startPC = firstLiveness(startPC, endPC, variable);
+ endPC = lastLiveness(startPC, endPC, variable);
+
+ localVariableInfo.u2startPC = startPC;
+ localVariableInfo.u2length = endPC - startPC;
+ }
+
+
+ // Implementations for LocalVariableTypeInfoVisitor.
+
+ public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
+ {
+ // Trim the local variable type to the instructions at which it is alive.
+ int variable = localVariableTypeInfo.u2index;
+ int startPC = localVariableTypeInfo.u2startPC;
+ int endPC = startPC + localVariableTypeInfo.u2length;
+
+ startPC = firstLiveness(startPC, endPC, variable);
+ endPC = lastLiveness(startPC, endPC, variable);
+
+ localVariableTypeInfo.u2startPC = startPC;
+ localVariableTypeInfo.u2length = endPC - startPC;
}
@@ -241,4 +298,48 @@ implements AttributeVisitor
}
}
}
+
+
+ /**
+ * Returns the first instruction offset between the given offsets at which
+ * the given variable goes alive.
+ */
+ private int firstLiveness(int startOffset, int endOffset, int variableIndex)
+ {
+ for (int offset = startOffset; offset < endOffset; offset++)
+ {
+ if (livenessAnalyzer.isTraced(offset) &&
+ livenessAnalyzer.isAliveBefore(offset, variableIndex))
+ {
+ return offset;
+ }
+ }
+
+ return endOffset;
+ }
+
+
+ /**
+ * Returns the last instruction offset between the given offsets before
+ * which the given variable is still alive.
+ */
+ private int lastLiveness(int startOffset, int endOffset, int variableIndex)
+ {
+ int previousOffset = endOffset;
+
+ for (int offset = endOffset-1; offset >= startOffset; offset--)
+ {
+ if (livenessAnalyzer.isTraced(offset))
+ {
+ if (livenessAnalyzer.isAliveBefore(offset, variableIndex))
+ {
+ return previousOffset;
+ }
+
+ previousOffset = offset;
+ }
+ }
+
+ return endOffset;
+ }
}
diff --git a/src/proguard/optimize/info/AccessMethodMarker.java b/src/proguard/optimize/info/AccessMethodMarker.java
index 6965cec..8d758ce 100644
--- a/src/proguard/optimize/info/AccessMethodMarker.java
+++ b/src/proguard/optimize/info/AccessMethodMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,8 @@
package proguard.optimize.info;
import proguard.classfile.*;
-import proguard.classfile.attribute.CodeAttribute;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
@@ -71,6 +72,20 @@ implements InstructionVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Check the bootstrap method.
+ invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Check the method reference.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
// Check the referenced class.
diff --git a/src/proguard/optimize/info/BackwardBranchMarker.java b/src/proguard/optimize/info/BackwardBranchMarker.java
index 9e09b0f..d53a5b2 100644
--- a/src/proguard/optimize/info/BackwardBranchMarker.java
+++ b/src/proguard/optimize/info/BackwardBranchMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/CatchExceptionMarker.java b/src/proguard/optimize/info/CatchExceptionMarker.java
index 3f2a06f..5d74047 100644
--- a/src/proguard/optimize/info/CatchExceptionMarker.java
+++ b/src/proguard/optimize/info/CatchExceptionMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/CaughtClassFilter.java b/src/proguard/optimize/info/CaughtClassFilter.java
index 5e17763..4f7caff 100644
--- a/src/proguard/optimize/info/CaughtClassFilter.java
+++ b/src/proguard/optimize/info/CaughtClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/CaughtClassMarker.java b/src/proguard/optimize/info/CaughtClassMarker.java
index 0cc350e..5a60aaf 100644
--- a/src/proguard/optimize/info/CaughtClassMarker.java
+++ b/src/proguard/optimize/info/CaughtClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -25,8 +25,9 @@ import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.ClassVisitor;
/**
- * This InstructionVisitor marks all classes that are used in an 'instanceof'
- * test by any of the instructions that it visits.
+ * This ClassVisitor marks all program classes that it visits as caught.
+ * This means that these classes are exception classes that occur in exception
+ * handlers.
*
* @author Eric Lafortune
*/
diff --git a/src/proguard/optimize/info/ClassOptimizationInfo.java b/src/proguard/optimize/info/ClassOptimizationInfo.java
index 99b6e7b..e440eef 100644
--- a/src/proguard/optimize/info/ClassOptimizationInfo.java
+++ b/src/proguard/optimize/info/ClassOptimizationInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -34,6 +34,7 @@ public class ClassOptimizationInfo
private boolean isInstanceofed = false;
private boolean isDotClassed = false;
private boolean isCaught = false;
+ private boolean containsStaticInitializer = false;
private boolean containsPackageVisibleMembers = false;
private boolean invokesPackageVisibleMembers = false;
private Clazz targetClass;
@@ -87,6 +88,18 @@ public class ClassOptimizationInfo
}
+ public void setContainsStaticInitializer()
+ {
+ containsStaticInitializer = true;
+ }
+
+
+ public boolean containsStaticInitializer()
+ {
+ return containsStaticInitializer;
+ }
+
+
public void setContainsPackageVisibleMembers()
{
containsPackageVisibleMembers = true;
@@ -129,6 +142,7 @@ public class ClassOptimizationInfo
this.isInstanceofed |= other.isInstanceofed;
this.isDotClassed |= other.isDotClassed;
this.isCaught |= other.isCaught;
+ this.containsStaticInitializer |= other.containsStaticInitializer;
this.containsPackageVisibleMembers |= other.containsPackageVisibleMembers;
this.invokesPackageVisibleMembers |= other.invokesPackageVisibleMembers;
}
diff --git a/src/proguard/optimize/info/ClassOptimizationInfoSetter.java b/src/proguard/optimize/info/ClassOptimizationInfoSetter.java
index 9cb167c..bc58f2d 100644
--- a/src/proguard/optimize/info/ClassOptimizationInfoSetter.java
+++ b/src/proguard/optimize/info/ClassOptimizationInfoSetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/DotClassFilter.java b/src/proguard/optimize/info/DotClassFilter.java
index 8cbe7f0..c55925c 100644
--- a/src/proguard/optimize/info/DotClassFilter.java
+++ b/src/proguard/optimize/info/DotClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/DotClassMarker.java b/src/proguard/optimize/info/DotClassMarker.java
index b5f12a7..2819441 100644
--- a/src/proguard/optimize/info/DotClassMarker.java
+++ b/src/proguard/optimize/info/DotClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/ExceptionInstructionChecker.java b/src/proguard/optimize/info/ExceptionInstructionChecker.java
index 2792d90..40287f3 100644
--- a/src/proguard/optimize/info/ExceptionInstructionChecker.java
+++ b/src/proguard/optimize/info/ExceptionInstructionChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -67,34 +67,39 @@ implements InstructionVisitor
byte opcode = simpleInstruction.opcode;
// Check for instructions that may throw exceptions.
- if (opcode == InstructionConstants.OP_IDIV ||
- opcode == InstructionConstants.OP_LDIV ||
- opcode == InstructionConstants.OP_IREM ||
- opcode == InstructionConstants.OP_LREM ||
- opcode == InstructionConstants.OP_IALOAD ||
- opcode == InstructionConstants.OP_LALOAD ||
- opcode == InstructionConstants.OP_FALOAD ||
- opcode == InstructionConstants.OP_DALOAD ||
- opcode == InstructionConstants.OP_AALOAD ||
- opcode == InstructionConstants.OP_BALOAD ||
- opcode == InstructionConstants.OP_CALOAD ||
- opcode == InstructionConstants.OP_SALOAD ||
- opcode == InstructionConstants.OP_IASTORE ||
- opcode == InstructionConstants.OP_LASTORE ||
- opcode == InstructionConstants.OP_FASTORE ||
- opcode == InstructionConstants.OP_DASTORE ||
- opcode == InstructionConstants.OP_AASTORE ||
- opcode == InstructionConstants.OP_BASTORE ||
- opcode == InstructionConstants.OP_CASTORE ||
- opcode == InstructionConstants.OP_SASTORE ||
- opcode == InstructionConstants.OP_NEWARRAY ||
- opcode == InstructionConstants.OP_ARRAYLENGTH ||
- opcode == InstructionConstants.OP_ATHROW ||
- opcode == InstructionConstants.OP_MONITORENTER ||
- opcode == InstructionConstants.OP_MONITOREXIT)
+ // Note that monitorexit can not sensibly throw exceptions, except the
+ // broken and deprecated asynchronous ThreadDeath. Removing the
+ // artificial infinite looping exception blocks that recent compilers
+ // add does not strictly follow the JVM specs, but it does have the
+ // additional benefit of avoiding a bug in the JVM in JDK 1.1.
+ switch (opcode)
{
- // These instructions may throw exceptions.
- mayThrowExceptions = true;
+ case InstructionConstants.OP_IDIV:
+ case InstructionConstants.OP_LDIV:
+ case InstructionConstants.OP_IREM:
+ case InstructionConstants.OP_LREM:
+ case InstructionConstants.OP_IALOAD:
+ case InstructionConstants.OP_LALOAD:
+ case InstructionConstants.OP_FALOAD:
+ case InstructionConstants.OP_DALOAD:
+ case InstructionConstants.OP_AALOAD:
+ case InstructionConstants.OP_BALOAD:
+ case InstructionConstants.OP_CALOAD:
+ case InstructionConstants.OP_SALOAD:
+ case InstructionConstants.OP_IASTORE:
+ case InstructionConstants.OP_LASTORE:
+ case InstructionConstants.OP_FASTORE:
+ case InstructionConstants.OP_DASTORE:
+ case InstructionConstants.OP_AASTORE:
+ case InstructionConstants.OP_BASTORE:
+ case InstructionConstants.OP_CASTORE:
+ case InstructionConstants.OP_SASTORE:
+ case InstructionConstants.OP_NEWARRAY:
+ case InstructionConstants.OP_ARRAYLENGTH:
+ case InstructionConstants.OP_ATHROW:
+ case InstructionConstants.OP_MONITORENTER:
+ // These instructions may throw exceptions.
+ mayThrowExceptions = true;
}
}
@@ -105,31 +110,32 @@ implements InstructionVisitor
byte opcode = constantInstruction.opcode;
// Check for instructions that may throw exceptions.
- if (opcode == InstructionConstants.OP_GETSTATIC ||
- opcode == InstructionConstants.OP_PUTSTATIC ||
- opcode == InstructionConstants.OP_GETFIELD ||
- opcode == InstructionConstants.OP_PUTFIELD ||
- opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
- opcode == InstructionConstants.OP_INVOKESPECIAL ||
- opcode == InstructionConstants.OP_INVOKESTATIC ||
- opcode == InstructionConstants.OP_INVOKEINTERFACE ||
- opcode == InstructionConstants.OP_NEW ||
- opcode == InstructionConstants.OP_ANEWARRAY ||
- opcode == InstructionConstants.OP_CHECKCAST ||
- opcode == InstructionConstants.OP_MULTIANEWARRAY)
+ switch (opcode)
{
- // These instructions may throw exceptions.
- mayThrowExceptions = true;
+ case InstructionConstants.OP_GETSTATIC:
+ case InstructionConstants.OP_PUTSTATIC:
+ case InstructionConstants.OP_GETFIELD:
+ case InstructionConstants.OP_PUTFIELD:
+ case InstructionConstants.OP_INVOKEVIRTUAL:
+ case InstructionConstants.OP_INVOKESPECIAL:
+ case InstructionConstants.OP_INVOKESTATIC:
+ case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
+ case InstructionConstants.OP_NEW:
+ case InstructionConstants.OP_ANEWARRAY:
+ case InstructionConstants.OP_CHECKCAST:
+ case InstructionConstants.OP_INSTANCEOF:
+ case InstructionConstants.OP_MULTIANEWARRAY:
+ // These instructions may throw exceptions.
+ mayThrowExceptions = true;
}
-// else
-// if (opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
-// opcode == InstructionConstants.OP_INVOKESPECIAL ||
-// opcode == InstructionConstants.OP_INVOKESTATIC ||
-// opcode == InstructionConstants.OP_INVOKEINTERFACE)
-// {
+
+// case InstructionConstants.OP_INVOKEVIRTUAL:
+// case InstructionConstants.OP_INVOKESPECIAL:
+// case InstructionConstants.OP_INVOKESTATIC:
+// case InstructionConstants.OP_INVOKEINTERFACE:
// // Check if the invoking the method may throw an exception.
// clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
-// }
}
diff --git a/src/proguard/optimize/info/FieldOptimizationInfo.java b/src/proguard/optimize/info/FieldOptimizationInfo.java
index 7a2d068..6797a14 100644
--- a/src/proguard/optimize/info/FieldOptimizationInfo.java
+++ b/src/proguard/optimize/info/FieldOptimizationInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,8 +21,11 @@
package proguard.optimize.info;
import proguard.classfile.*;
-import proguard.classfile.util.MethodLinker;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.util.*;
import proguard.evaluation.value.*;
+import proguard.evaluation.ConstantValueFactory;
/**
* This class stores some optimization information that can be attached to
@@ -31,8 +34,11 @@ import proguard.evaluation.value.*;
* @author Eric Lafortune
*/
public class FieldOptimizationInfo
+extends SimplifiedVisitor
+implements AttributeVisitor
{
- private static final SpecificValueFactory VALUE_FACTORY = new SpecificValueFactory();
+ private static final SpecificValueFactory VALUE_FACTORY = new SpecificValueFactory();
+ private static final ConstantValueFactory CONSTANT_VALUE_FACTORY = new ConstantValueFactory(VALUE_FACTORY);
private boolean isWritten;
private boolean isRead;
@@ -43,9 +49,33 @@ public class FieldOptimizationInfo
public FieldOptimizationInfo(Clazz clazz, Field field)
{
+ int accessFlags = field.getAccessFlags();
+
isWritten =
- isRead = (field.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0;
- value = initialValue(field.getDescriptor(clazz));
+ isRead = (accessFlags & ClassConstants.INTERNAL_ACC_VOLATILE) != 0;
+
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)
+ {
+ // See if we can initialize the static field with a constant value.
+ field.accept(clazz, new AllAttributeVisitor(this));
+ }
+
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0 &&
+ value == null)
+ {
+ // Otherwise initialize the non-final field with the default value.
+ value = initialValue(field.getDescriptor(clazz));
+ }
+ }
+
+
+ public FieldOptimizationInfo(FieldOptimizationInfo FieldOptimizationInfo)
+ {
+ this.isWritten = FieldOptimizationInfo.isWritten;
+ this.isRead = FieldOptimizationInfo.isRead;
+ this.canBeMadePrivate = FieldOptimizationInfo.canBeMadePrivate;
+ this.referencedClass = FieldOptimizationInfo.referencedClass;
+ this.value = FieldOptimizationInfo.value;
}
@@ -113,6 +143,18 @@ public class FieldOptimizationInfo
}
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
+ {
+ // Retrieve the initial static field value.
+ value = CONSTANT_VALUE_FACTORY.constantValue(clazz, constantValueAttribute.u2constantValueIndex);
+ }
+
+
// Small utility methods.
private Value initialValue(String type)
@@ -147,13 +189,13 @@ public class FieldOptimizationInfo
public static void setFieldOptimizationInfo(Clazz clazz, Field field)
{
- MethodLinker.lastMember(field).setVisitorInfo(new FieldOptimizationInfo(clazz, field));
+ field.setVisitorInfo(new FieldOptimizationInfo(clazz, field));
}
public static FieldOptimizationInfo getFieldOptimizationInfo(Field field)
{
- Object visitorInfo = MethodLinker.lastMember(field).getVisitorInfo();
+ Object visitorInfo = field.getVisitorInfo();
return visitorInfo instanceof FieldOptimizationInfo ?
(FieldOptimizationInfo)visitorInfo :
diff --git a/src/proguard/optimize/info/InstanceofClassFilter.java b/src/proguard/optimize/info/InstanceofClassFilter.java
index 35e1d77..955fe9e 100644
--- a/src/proguard/optimize/info/InstanceofClassFilter.java
+++ b/src/proguard/optimize/info/InstanceofClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/InstanceofClassMarker.java b/src/proguard/optimize/info/InstanceofClassMarker.java
index c60e1f8..6d2f8aa 100644
--- a/src/proguard/optimize/info/InstanceofClassMarker.java
+++ b/src/proguard/optimize/info/InstanceofClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/InstantiationClassFilter.java b/src/proguard/optimize/info/InstantiationClassFilter.java
index a24e617..e67e0b5 100644
--- a/src/proguard/optimize/info/InstantiationClassFilter.java
+++ b/src/proguard/optimize/info/InstantiationClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/InstantiationClassMarker.java b/src/proguard/optimize/info/InstantiationClassMarker.java
index 124c23b..dc623c2 100644
--- a/src/proguard/optimize/info/InstantiationClassMarker.java
+++ b/src/proguard/optimize/info/InstantiationClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/MemberOptimizationInfoSetter.java b/src/proguard/optimize/info/MemberOptimizationInfoSetter.java
index a170a8e..d222d81 100644
--- a/src/proguard/optimize/info/MemberOptimizationInfoSetter.java
+++ b/src/proguard/optimize/info/MemberOptimizationInfoSetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -38,22 +38,22 @@ implements MemberVisitor
{
// Implementations for MemberVisitor.
- public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
- if (!KeepMarker.isKept(programMethod))
+ if (!KeepMarker.isKept(programField))
{
- MethodOptimizationInfo.setMethodOptimizationInfo(programClass,
- programMethod);
+ FieldOptimizationInfo.setFieldOptimizationInfo(programClass,
+ programField);
}
}
- public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- if (!KeepMarker.isKept(programField))
+ if (!KeepMarker.isKept(programMethod))
{
- FieldOptimizationInfo.setFieldOptimizationInfo(programClass,
- programField);
+ MethodOptimizationInfo.setMethodOptimizationInfo(programClass,
+ programMethod);
}
}
}
diff --git a/src/proguard/optimize/info/MethodInvocationMarker.java b/src/proguard/optimize/info/MethodInvocationMarker.java
index 2528c94..9d573b7 100644
--- a/src/proguard/optimize/info/MethodInvocationMarker.java
+++ b/src/proguard/optimize/info/MethodInvocationMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/MethodOptimizationInfo.java b/src/proguard/optimize/info/MethodOptimizationInfo.java
index d3b1bde..dd76f97 100644
--- a/src/proguard/optimize/info/MethodOptimizationInfo.java
+++ b/src/proguard/optimize/info/MethodOptimizationInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -204,7 +204,7 @@ public class MethodOptimizationInfo
public void setParameterUsed(int parameterIndex)
{
- usedParameters |= 1 << parameterIndex;
+ usedParameters |= 1L << parameterIndex;
}
@@ -216,7 +216,7 @@ public class MethodOptimizationInfo
public boolean isParameterUsed(int parameterIndex)
{
- return parameterIndex >= 64 || (usedParameters & (1 << parameterIndex)) != 0;
+ return parameterIndex >= 64 || (usedParameters & (1L << parameterIndex)) != 0;
}
diff --git a/src/proguard/optimize/info/NoSideEffectMethodMarker.java b/src/proguard/optimize/info/NoSideEffectMethodMarker.java
index 5c78408..2e0516b 100644
--- a/src/proguard/optimize/info/NoSideEffectMethodMarker.java
+++ b/src/proguard/optimize/info/NoSideEffectMethodMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/NonPrivateMemberMarker.java b/src/proguard/optimize/info/NonPrivateMemberMarker.java
index d451643..23e33a9 100644
--- a/src/proguard/optimize/info/NonPrivateMemberMarker.java
+++ b/src/proguard/optimize/info/NonPrivateMemberMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -77,15 +77,9 @@ implements ClassVisitor,
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
- Clazz referencedClass = stringConstant.referencedClass;
-
- // Is it refering to another class or class member?
- if (referencedClass != null &&
- !referencedClass.equals(clazz))
- {
- // The referenced class member, if any, can never be made private.
- stringConstant.referencedMemberAccept(this);
- }
+ // The referenced class member, if any, can never be made private,
+ // even if it's in the same class.
+ stringConstant.referencedMemberAccept(this);
}
@@ -93,7 +87,7 @@ implements ClassVisitor,
{
Clazz referencedClass = refConstant.referencedClass;
- // Is it refering to a class member in another class?
+ // Is it referring to a class member in another class?
// The class member might be in another class, or
// it may be referenced through another class.
if (referencedClass != null &&
diff --git a/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java b/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java
index d40bc6b..85ff4b9 100644
--- a/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java
+++ b/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -22,18 +22,36 @@ package proguard.optimize.info;
import proguard.classfile.*;
import proguard.classfile.util.SimplifiedVisitor;
-import proguard.classfile.visitor.MemberVisitor;
+import proguard.classfile.visitor.*;
/**
- * This MemberVisitor marks all classes that contain visited package visible
- * members.
+ * This ClassVisitor marks all classes that contain package visible members.
*
* @author Eric Lafortune
*/
public class PackageVisibleMemberContainingClassMarker
extends SimplifiedVisitor
-implements MemberVisitor
+implements ClassVisitor,
+ MemberVisitor
{
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ // Check the class itself.
+ if ((clazz.getAccessFlags() & ClassConstants.INTERNAL_ACC_PUBLIC) == 0)
+ {
+ setPackageVisibleMembers(clazz);
+ }
+ else
+ {
+ // Check the members.
+ clazz.fieldsAccept(this);
+ clazz.methodsAccept(this);
+ }
+ }
+
+
// Implementations for MemberVisitor.
public void visitAnyMember(Clazz clazz, Member member)
diff --git a/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java b/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java
index 9ec8ec6..42cc14f 100644
--- a/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java
+++ b/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -24,39 +24,87 @@ import proguard.classfile.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.constant.*;
import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
/**
- * This ConstantVisitor marks all classes that invoke package visible members
- * in other classes.
+ * This ConstantVisitor marks all classes that refer to package visible classes
+ * or class members.
*
* @author Eric Lafortune
*/
public class PackageVisibleMemberInvokingClassMarker
extends SimplifiedVisitor
-implements ConstantVisitor
+implements ConstantVisitor,
+ ClassVisitor,
+ MemberVisitor
{
+ private Clazz referencingClass;
+
+
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant) {}
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ // Check the referenced class and class member, if any.
+ if (stringConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ stringConstant.referencedClassAccept(this);
+ stringConstant.referencedMemberAccept(this);
+ }
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
- Clazz referencedClass = refConstant.referencedClass;
- if (referencedClass != null &&
- (referencedClass.getAccessFlags() &
+ // Check the referenced class and class member.
+ if (refConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ refConstant.referencedClassAccept(this);
+ refConstant.referencedMemberAccept(this);
+ }
+ }
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ // Check the referenced class.
+ if (classConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ classConstant.referencedClassAccept(this);
+ }
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ if ((clazz.getAccessFlags() &
ClassConstants.INTERNAL_ACC_PUBLIC) == 0)
{
- setInvokesPackageVisibleMembers(clazz);
+ setInvokesPackageVisibleMembers(referencingClass);
}
+ }
- Member referencedMember = refConstant.referencedMember;
- if (referencedMember != null &&
- (referencedMember.getAccessFlags() &
+
+ // Implementations for MemberVisitor.
+
+ public void visitAnyMember(Clazz clazz, Member member)
+ {
+ if ((member.getAccessFlags() &
(ClassConstants.INTERNAL_ACC_PUBLIC |
ClassConstants.INTERNAL_ACC_PRIVATE)) == 0)
{
- setInvokesPackageVisibleMembers(clazz);
+ setInvokesPackageVisibleMembers(referencingClass);
}
}
diff --git a/src/proguard/optimize/info/ParameterUsageMarker.java b/src/proguard/optimize/info/ParameterUsageMarker.java
index 15ce88a..abae946 100644
--- a/src/proguard/optimize/info/ParameterUsageMarker.java
+++ b/src/proguard/optimize/info/ParameterUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,14 +21,14 @@
package proguard.optimize.info;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
-import proguard.classfile.attribute.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
+import proguard.evaluation.value.Value;
import proguard.optimize.evaluation.PartialEvaluator;
-import proguard.evaluation.value.*;
/**
* This MemberVisitor counts the parameters and marks the used parameters
diff --git a/src/proguard/optimize/info/ReadWriteFieldMarker.java b/src/proguard/optimize/info/ReadWriteFieldMarker.java
index 57d8561..236cb17 100644
--- a/src/proguard/optimize/info/ReadWriteFieldMarker.java
+++ b/src/proguard/optimize/info/ReadWriteFieldMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/SideEffectInstructionChecker.java b/src/proguard/optimize/info/SideEffectInstructionChecker.java
index 8be9dc1..1444e5a 100644
--- a/src/proguard/optimize/info/SideEffectInstructionChecker.java
+++ b/src/proguard/optimize/info/SideEffectInstructionChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -29,11 +29,14 @@ import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.*;
+import java.util.*;
+
/**
* This class can tell whether an instruction has any side effects. Return
* instructions can be included or not.
*
* @see ReadWriteFieldMarker
+ * @see StaticInitializerContainingClassMarker
* @see NoSideEffectMethodMarker
* @see SideEffectMethodMarker
* @author Eric Lafortune
@@ -47,6 +50,7 @@ implements InstructionVisitor,
private final boolean includeReturnInstructions;
// A return value for the visitor methods.
+ private Clazz referencingClass;
private boolean hasSideEffects;
@@ -60,7 +64,7 @@ implements InstructionVisitor,
{
hasSideEffects = false;
- instruction.accept(clazz, method, codeAttribute, offset, this);
+ instruction.accept(clazz, method, codeAttribute, offset, this);
return hasSideEffects;
}
@@ -118,14 +122,16 @@ implements InstructionVisitor,
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
byte opcode = constantInstruction.opcode;
-
// Check for instructions that might cause side effects.
- if (opcode == InstructionConstants.OP_PUTSTATIC ||
- opcode == InstructionConstants.OP_PUTFIELD ||
- opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
- opcode == InstructionConstants.OP_INVOKESPECIAL ||
- opcode == InstructionConstants.OP_INVOKESTATIC ||
- opcode == InstructionConstants.OP_INVOKEINTERFACE)
+ if (opcode == InstructionConstants.OP_GETSTATIC ||
+ opcode == InstructionConstants.OP_PUTSTATIC ||
+ opcode == InstructionConstants.OP_GETFIELD ||
+ opcode == InstructionConstants.OP_PUTFIELD ||
+ opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
+ opcode == InstructionConstants.OP_INVOKESPECIAL ||
+ opcode == InstructionConstants.OP_INVOKESTATIC ||
+ opcode == InstructionConstants.OP_INVOKEINTERFACE ||
+ opcode == InstructionConstants.OP_INVOKEDYNAMIC)
{
// Check if the field is write-only or volatile, or if the invoked
// method is causing any side effects.
@@ -150,48 +156,36 @@ implements InstructionVisitor,
// Implementations for ConstantVisitor.
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // We'll have to assume invoking an unknown method has side effects.
+ hasSideEffects = true;
+ }
+
+
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
+ // Pass the referencing class.
+ referencingClass = clazz;
+
// We'll have to assume accessing an unknown field has side effects.
hasSideEffects = true;
- // Check the referenced field.
+ // Check the referenced field, if known.
fieldrefConstant.referencedMemberAccept(this);
}
public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
{
- Member referencedMember = refConstant.referencedMember;
+ // Pass the referencing class.
+ referencingClass = clazz;
- // Do we have a reference to the method?
- if (referencedMember == null)
- {
- // We'll have to assume invoking the unknown method has side effects.
- hasSideEffects = true;
- }
- else
- {
- // First check the referenced method itself.
- refConstant.referencedMemberAccept(this);
-
- // If the result isn't conclusive, check down the hierarchy.
- if (!hasSideEffects)
- {
- Clazz referencedClass = refConstant.referencedClass;
- Method referencedMethod = (Method)referencedMember;
-
- // Check all other implementations of the method down the class
- // hierarchy.
- if ((referencedMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_PRIVATE) == 0)
- {
- clazz.hierarchyAccept(false, false, false, true,
- new NamedMethodVisitor(referencedMethod.getName(referencedClass),
- referencedMethod.getDescriptor(referencedClass),
- this));
- }
- }
- }
+ // We'll have to assume invoking an unknown method has side effects.
+ hasSideEffects = true;
+
+ // Check the referenced method, if known.
+ refConstant.referencedMemberAccept(this);
}
@@ -199,14 +193,24 @@ implements InstructionVisitor,
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
- hasSideEffects = ReadWriteFieldMarker.isRead(programField);
+ hasSideEffects =
+ (ReadWriteFieldMarker.isRead(programField) &&
+ ReadWriteFieldMarker.isWritten(programField)) ||
+ ((programField.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0) ||
+ (!programClass.equals(referencingClass) &&
+ !initializedSuperClasses(referencingClass).containsAll(initializedSuperClasses(programClass)));
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- hasSideEffects = hasSideEffects ||
- SideEffectMethodMarker.hasSideEffects(programMethod);
+ // Note that side effects already include synchronization of some
+ // implementation of the method.
+ hasSideEffects =
+ !NoSideEffectMethodMarker.hasNoSideEffects(programMethod) &&
+ (SideEffectMethodMarker.hasSideEffects(programMethod) ||
+ (!programClass.equals(referencingClass) &&
+ !initializedSuperClasses(referencingClass).containsAll(initializedSuperClasses(programClass))));
}
@@ -218,7 +222,24 @@ implements InstructionVisitor,
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
- hasSideEffects = hasSideEffects ||
- !NoSideEffectMethodMarker.hasNoSideEffects(libraryMethod);
+ hasSideEffects =
+ !NoSideEffectMethodMarker.hasNoSideEffects(libraryMethod);
+ }
+
+
+ /**
+ * Returns the set of superclasses and interfaces that are initialized.
+ */
+ private Set initializedSuperClasses(Clazz clazz)
+ {
+ Set set = new HashSet();
+
+ // Visit all superclasses and interfaces, collecting the ones that have
+ // static initializers.
+ clazz.hierarchyAccept(true, true, true, false,
+ new StaticInitializerContainingClassFilter(
+ new ClassCollector(set)));
+
+ return set;
}
}
diff --git a/src/proguard/optimize/info/SideEffectMethodMarker.java b/src/proguard/optimize/info/SideEffectMethodMarker.java
index 25fda72..d73179e 100644
--- a/src/proguard/optimize/info/SideEffectMethodMarker.java
+++ b/src/proguard/optimize/info/SideEffectMethodMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java b/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java
new file mode 100644
index 0000000..197668d
--- /dev/null
+++ b/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java
@@ -0,0 +1,62 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This ClassVisitor delegates all its method calls to another ClassVisitor,
+ * but only for Clazz objects that are instantiated.
+ *
+ * @author Eric Lafortune
+ */
+public class StaticInitializerContainingClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ public StaticInitializerContainingClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (StaticInitializerContainingClassMarker.containsStaticInitializer(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (StaticInitializerContainingClassMarker.containsStaticInitializer(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java b/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java
new file mode 100644
index 0000000..a121250
--- /dev/null
+++ b/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java
@@ -0,0 +1,65 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+
+/**
+ * This ClassVisitor marks all classes that contain static initializers.
+ *
+ * @author Eric Lafortune
+ */
+public class StaticInitializerContainingClassMarker
+extends SimplifiedVisitor
+implements ClassVisitor
+{
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ if (clazz.findMethod(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_CLINIT) != null)
+ {
+ setStaticInitializer(clazz);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void setStaticInitializer(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setContainsStaticInitializer();
+ }
+ }
+
+
+ public static boolean containsStaticInitializer(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.containsStaticInitializer();
+ }
+} \ No newline at end of file
diff --git a/src/proguard/optimize/info/SuperInvocationMarker.java b/src/proguard/optimize/info/SuperInvocationMarker.java
index 6f3d3bd..07e33bb 100644
--- a/src/proguard/optimize/info/SuperInvocationMarker.java
+++ b/src/proguard/optimize/info/SuperInvocationMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/info/VariableUsageMarker.java b/src/proguard/optimize/info/VariableUsageMarker.java
index 660c4ba..a1c6a9a 100644
--- a/src/proguard/optimize/info/VariableUsageMarker.java
+++ b/src/proguard/optimize/info/VariableUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -27,6 +27,8 @@ import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor marks the local variables that are used in the code
* attributes that it visits.
@@ -62,14 +64,13 @@ implements AttributeVisitor,
// Try to reuse the previous array.
if (variableUsed.length < maxLocals)
{
+ // Create a new array.
variableUsed = new boolean[maxLocals];
}
else
{
- for (int index = 0; index < maxLocals; index++)
- {
- variableUsed[index] = false;
- }
+ // Reset the array.
+ Arrays.fill(variableUsed, 0, maxLocals, false);
}
codeAttribute.instructionsAccept(clazz, method, this);
diff --git a/src/proguard/optimize/peephole/BranchTargetFinder.java b/src/proguard/optimize/peephole/BranchTargetFinder.java
index 8f650bb..7e5a11f 100644
--- a/src/proguard/optimize/peephole/BranchTargetFinder.java
+++ b/src/proguard/optimize/peephole/BranchTargetFinder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -29,6 +29,8 @@ import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor finds all instruction offsets, branch targets, and
* exception targets in the CodeAttribute objects that it visits.
@@ -312,25 +314,19 @@ implements AttributeVisitor,
initializationOffsets = new int[codeLength];
// Reset the arrays.
- for (int index = 0; index < codeLength; index++)
- {
- subroutineStarts[index] = NONE;
- subroutineEnds[index] = NONE;
- creationOffsets[index] = NONE;
- initializationOffsets[index] = NONE;
- }
+ Arrays.fill(subroutineStarts, 0, codeLength, NONE);
+ Arrays.fill(subroutineEnds, 0, codeLength, NONE);
+ Arrays.fill(creationOffsets, 0, codeLength, NONE);
+ Arrays.fill(initializationOffsets, 0, codeLength, NONE);
}
else
{
// Reset the arrays.
- for (int index = 0; index < codeLength; index++)
- {
- instructionMarks[index] = 0;
- subroutineStarts[index] = NONE;
- subroutineEnds[index] = NONE;
- creationOffsets[index] = NONE;
- initializationOffsets[index] = NONE;
- }
+ Arrays.fill(instructionMarks, 0, codeLength, (short)0);
+ Arrays.fill(subroutineStarts, 0, codeLength, NONE);
+ Arrays.fill(subroutineEnds, 0, codeLength, NONE);
+ Arrays.fill(creationOffsets, 0, codeLength, NONE);
+ Arrays.fill(initializationOffsets, 0, codeLength, NONE);
instructionMarks[codeLength] = 0;
}
diff --git a/src/proguard/optimize/peephole/ClassFinalizer.java b/src/proguard/optimize/peephole/ClassFinalizer.java
index b5e54f8..063f254 100644
--- a/src/proguard/optimize/peephole/ClassFinalizer.java
+++ b/src/proguard/optimize/peephole/ClassFinalizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/ClassMerger.java b/src/proguard/optimize/peephole/ClassMerger.java
index 1e1a950..4971cab 100644
--- a/src/proguard/optimize/peephole/ClassMerger.java
+++ b/src/proguard/optimize/peephole/ClassMerger.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,6 +21,7 @@
package proguard.optimize.peephole;
import proguard.classfile.*;
+import proguard.classfile.constant.ClassConstant;
import proguard.classfile.constant.visitor.*;
import proguard.classfile.editor.*;
import proguard.classfile.util.*;
@@ -59,6 +60,8 @@ implements ClassVisitor,
private final boolean mergeInterfacesAggressively;
private final ClassVisitor extraClassVisitor;
+ private final MemberVisitor fieldOptimizationInfoCopier = new FieldOptimizationInfoCopier();
+
/**
* Creates a new ClassMerger that will merge classes into the given target
@@ -151,7 +154,7 @@ implements ClassVisitor,
// infinite recursion.
(programClass.getAccessFlags() & ClassConstants.INTERNAL_ACC_ANNOTATTION) == 0 &&
- // Only merge classes if we can change the access permissioms, or
+ // Only merge classes if we can change the access permissions, or
// if they are in the same package, or
// if they are public and don't contain or invoke package visible
// class members.
@@ -235,11 +238,12 @@ implements ClassVisitor,
targetClass.u2accessFlags =
((targetAccessFlags &
sourceAccessFlags) &
- (ClassConstants.INTERNAL_ACC_INTERFACE |
+ (ClassConstants.INTERNAL_ACC_INTERFACE |
ClassConstants.INTERNAL_ACC_ABSTRACT)) |
((targetAccessFlags |
sourceAccessFlags) &
- (ClassConstants.INTERNAL_ACC_PUBLIC |
+ (ClassConstants.INTERNAL_ACC_PUBLIC |
+ ClassConstants.INTERNAL_ACC_SUPER |
ClassConstants.INTERNAL_ACC_ANNOTATTION |
ClassConstants.INTERNAL_ACC_ENUM));
@@ -260,7 +264,7 @@ implements ClassVisitor,
// Copy over the class members.
MemberAdder memberAdder =
- new MemberAdder(targetClass);
+ new MemberAdder(targetClass, fieldOptimizationInfoCopier);
programClass.fieldsAccept(memberAdder);
programClass.methodsAccept(memberAdder);
@@ -336,10 +340,8 @@ implements ClassVisitor,
// Visit all superclasses and interfaces, collecting the ones that have
// static initializers.
clazz.hierarchyAccept(true, true, true, false,
- new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
- ClassConstants.INTERNAL_METHOD_TYPE_INIT,
- new MemberToClassVisitor(
- new ClassCollector(set))));
+ new StaticInitializerContainingClassFilter(
+ new ClassCollector(set)));
return set;
}
@@ -368,12 +370,19 @@ implements ClassVisitor,
*/
private Set caughtSuperClasses(Clazz clazz)
{
+ // Don't bother if this isn't an exception at all.
+ if (!clazz.extends_(ClassConstants.INTERNAL_NAME_JAVA_LANG_THROWABLE))
+ {
+ return Collections.EMPTY_SET;
+ }
+
+ // Visit all superclasses, collecting the ones that are caught
+ // (plus java.lang.Object, in the current implementation).
Set set = new HashSet();
- // Visit all superclasses, collecting the ones that are caught.
clazz.hierarchyAccept(true, true, false, false,
new CaughtClassFilter(
- new ClassCollector(set)));
+ new ClassCollector(set)));
return set;
}
@@ -538,4 +547,30 @@ implements ClassVisitor,
targetClass = clazz;
}
}
+
+
+ /**
+ * This MemberVisitor copies field optimization info from copied fields.
+ */
+ private static class FieldOptimizationInfoCopier
+ extends SimplifiedVisitor
+ implements MemberVisitor
+ {
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ // Copy the optimization info from the field that was just copied.
+ ProgramField copiedField = (ProgramField)programField.getVisitorInfo();
+ Object info = copiedField.getVisitorInfo();
+
+ programField.setVisitorInfo(info instanceof FieldOptimizationInfo ?
+ new FieldOptimizationInfo((FieldOptimizationInfo)info) :
+ info);
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ // Linked methods share their optimization info.
+ }
+ }
} \ No newline at end of file
diff --git a/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java b/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
index 4833275..0dd93b1 100644
--- a/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
+++ b/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/GotoGotoReplacer.java b/src/proguard/optimize/peephole/GotoGotoReplacer.java
index 7d7e66c..d05d7b6 100644
--- a/src/proguard/optimize/peephole/GotoGotoReplacer.java
+++ b/src/proguard/optimize/peephole/GotoGotoReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -84,8 +84,9 @@ implements InstructionVisitor
int branchOffset = branchInstruction.branchOffset;
int targetOffset = offset + branchOffset;
- if (branchOffset != branchInstruction.length(offset) &&
- !codeAttributeEditor.isModified(offset) &&
+ if (branchOffset != 0 &&
+ branchOffset != branchInstruction.length(offset) &&
+ !codeAttributeEditor.isModified(offset) &&
!codeAttributeEditor.isModified(targetOffset))
{
Instruction targetInstruction =
diff --git a/src/proguard/optimize/peephole/GotoReturnReplacer.java b/src/proguard/optimize/peephole/GotoReturnReplacer.java
index 5c3eb77..cafda92 100644
--- a/src/proguard/optimize/peephole/GotoReturnReplacer.java
+++ b/src/proguard/optimize/peephole/GotoReturnReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/HorizontalClassMerger.java b/src/proguard/optimize/peephole/HorizontalClassMerger.java
index a37b9a5..d12c2c0 100644
--- a/src/proguard/optimize/peephole/HorizontalClassMerger.java
+++ b/src/proguard/optimize/peephole/HorizontalClassMerger.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/InstructionSequenceConstants.java b/src/proguard/optimize/peephole/InstructionSequenceConstants.java
index b33204b..eb24061 100644
--- a/src/proguard/optimize/peephole/InstructionSequenceConstants.java
+++ b/src/proguard/optimize/peephole/InstructionSequenceConstants.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -20,81 +20,179 @@
*/
package proguard.optimize.peephole;
+import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.instruction.*;
-import proguard.classfile.util.InstructionSequenceMatcher;
+import proguard.classfile.visitor.ClassPrinter;
/**
* This class contains a set of instruction sequences and their suggested
* replacements.
*
* @see InstructionSequencesReplacer
+ * @see InstructionSequenceReplacer
* @author Eric Lafortune
*/
public class InstructionSequenceConstants
{
- public static final int X = InstructionSequenceMatcher.X;
- public static final int Y = InstructionSequenceMatcher.Y;
- public static final int Z = InstructionSequenceMatcher.Z;
+ private static final int X = InstructionSequenceReplacer.X;
+ private static final int Y = InstructionSequenceReplacer.Y;
+ private static final int Z = InstructionSequenceReplacer.Z;
- public static final int A = InstructionSequenceMatcher.A;
- public static final int B = InstructionSequenceMatcher.B;
- public static final int C = InstructionSequenceMatcher.C;
- public static final int D = InstructionSequenceMatcher.D;
+ private static final int A = InstructionSequenceReplacer.A;
+ private static final int B = InstructionSequenceReplacer.B;
+ private static final int C = InstructionSequenceReplacer.C;
+ private static final int D = InstructionSequenceReplacer.D;
+ private static final int STRING_A_LENGTH = InstructionSequenceReplacer.STRING_A_LENGTH;
+ private static final int BOOLEAN_A_STRING = InstructionSequenceReplacer.BOOLEAN_A_STRING;
+ private static final int CHAR_A_STRING = InstructionSequenceReplacer.CHAR_A_STRING;
+ private static final int INT_A_STRING = InstructionSequenceReplacer.INT_A_STRING;
+ private static final int LONG_A_STRING = InstructionSequenceReplacer.LONG_A_STRING;
+ private static final int FLOAT_A_STRING = InstructionSequenceReplacer.FLOAT_A_STRING;
+ private static final int DOUBLE_A_STRING = InstructionSequenceReplacer.DOUBLE_A_STRING;
+ private static final int STRING_A_STRING = InstructionSequenceReplacer.STRING_A_STRING;
+ private static final int BOOLEAN_B_STRING = InstructionSequenceReplacer.BOOLEAN_B_STRING;
+ private static final int CHAR_B_STRING = InstructionSequenceReplacer.CHAR_B_STRING;
+ private static final int INT_B_STRING = InstructionSequenceReplacer.INT_B_STRING;
+ private static final int LONG_B_STRING = InstructionSequenceReplacer.LONG_B_STRING;
+ private static final int FLOAT_B_STRING = InstructionSequenceReplacer.FLOAT_B_STRING;
+ private static final int DOUBLE_B_STRING = InstructionSequenceReplacer.DOUBLE_B_STRING;
+ private static final int STRING_B_STRING = InstructionSequenceReplacer.STRING_B_STRING;
- private static final int I_32768 = 0;
- private static final int I_65536 = 1;
- private static final int I_16777216 = 2;
+ private static final int I_32768 = 0;
+ private static final int I_65536 = 1;
+ private static final int I_16777216 = 2;
// private static final int I_0x000000ff
- private static final int I_0x0000ff00 = 3;
- private static final int I_0x00ff0000 = 4;
- private static final int I_0xff000000 = 5;
- private static final int I_0x0000ffff = 6;
- private static final int I_0xffff0000 = 7;
+ private static final int I_0x0000ff00 = 3;
+ private static final int I_0x00ff0000 = 4;
+ private static final int I_0xff000000 = 5;
+ private static final int I_0x0000ffff = 6;
+ private static final int I_0xffff0000 = 7;
- private static final int L_M1 = 8;
- private static final int L_2 = 9;
- private static final int L_4 = 10;
- private static final int L_8 = 11;
- private static final int L_16 = 12;
- private static final int L_32 = 13;
- private static final int L_64 = 14;
- private static final int L_128 = 15;
- private static final int L_256 = 16;
- private static final int L_512 = 17;
- private static final int L_1024 = 18;
- private static final int L_2048 = 19;
- private static final int L_4096 = 20;
- private static final int L_8192 = 21;
- private static final int L_16384 = 22;
- private static final int L_32768 = 23;
- private static final int L_65536 = 24;
- private static final int L_16777216 = 25;
- private static final int L_4294967296 = 26;
+ private static final int L_M1 = 8;
+ private static final int L_2 = 9;
+ private static final int L_4 = 10;
+ private static final int L_8 = 11;
+ private static final int L_16 = 12;
+ private static final int L_32 = 13;
+ private static final int L_64 = 14;
+ private static final int L_128 = 15;
+ private static final int L_256 = 16;
+ private static final int L_512 = 17;
+ private static final int L_1024 = 18;
+ private static final int L_2048 = 19;
+ private static final int L_4096 = 20;
+ private static final int L_8192 = 21;
+ private static final int L_16384 = 22;
+ private static final int L_32768 = 23;
+ private static final int L_65536 = 24;
+ private static final int L_16777216 = 25;
+ private static final int L_4294967296 = 26;
- private static final int L_0x00000000ffffffff = 27;
- private static final int L_0xffffffff00000000 = 28;
+ private static final int L_0x00000000ffffffff = 27;
+ private static final int L_0xffffffff00000000 = 28;
- private static final int F_M1 = 29;
+ private static final int F_M1 = 29;
- private static final int D_M1 = 30;
+ private static final int D_M1 = 30;
- private static final int FIELD_I = 31;
- private static final int FIELD_L = 32;
- private static final int FIELD_F = 33;
- private static final int FIELD_D = 34;
+ private static final int STRING_EMPTY = 31;
- private static final int NAME_AND_TYPE_I = 35;
- private static final int NAME_AND_TYPE_L = 36;
- private static final int NAME_AND_TYPE_F = 37;
- private static final int NAME_AND_TYPE_D = 38;
+ private static final int FIELD_I = 32;
+ private static final int FIELD_L = 33;
+ private static final int FIELD_F = 34;
+ private static final int FIELD_D = 35;
- private static final int TYPE_I = 39;
- private static final int TYPE_L = 40;
- private static final int TYPE_F = 41;
- private static final int TYPE_D = 42;
+ private static final int METHOD_STRING_EQUALS = 36;
+ private static final int METHOD_STRING_LENGTH = 37;
+ private static final int METHOD_STRINGBUFFER_INIT = 38;
+ private static final int METHOD_STRINGBUFFER_INIT_STRING = 39;
+ private static final int METHOD_STRINGBUFFER_APPEND_BOOLEAN = 40;
+ private static final int METHOD_STRINGBUFFER_APPEND_CHAR = 41;
+ private static final int METHOD_STRINGBUFFER_APPEND_INTEGER = 42;
+ private static final int METHOD_STRINGBUFFER_APPEND_LONG = 43;
+ private static final int METHOD_STRINGBUFFER_APPEND_FLOAT = 44;
+ private static final int METHOD_STRINGBUFFER_APPEND_DOUBLE = 45;
+ private static final int METHOD_STRINGBUFFER_APPEND_STRING = 46;
+ private static final int METHOD_STRINGBUFFER_LENGTH = 47;
+ private static final int METHOD_STRINGBUFFER_TOSTRING = 48;
+ private static final int METHOD_STRINGBUILDER_INIT = 49;
+ private static final int METHOD_STRINGBUILDER_INIT_STRING = 50;
+ private static final int METHOD_STRINGBUILDER_APPEND_BOOLEAN = 51;
+ private static final int METHOD_STRINGBUILDER_APPEND_CHAR = 52;
+ private static final int METHOD_STRINGBUILDER_APPEND_INTEGER = 53;
+ private static final int METHOD_STRINGBUILDER_APPEND_LONG = 54;
+ private static final int METHOD_STRINGBUILDER_APPEND_FLOAT = 55;
+ private static final int METHOD_STRINGBUILDER_APPEND_DOUBLE = 56;
+ private static final int METHOD_STRINGBUILDER_APPEND_STRING = 57;
+ private static final int METHOD_STRINGBUILDER_LENGTH = 58;
+ private static final int METHOD_STRINGBUILDER_TOSTRING = 59;
+
+ private static final int CLASS_STRING = 60;
+ private static final int CLASS_STRINGBUFFER = 61;
+ private static final int CLASS_STRINGBUILDER = 62;
+
+ private static final int NAME_AND_TYPE_I = 63;
+ private static final int NAME_AND_TYPE_L = 64;
+ private static final int NAME_AND_TYPE_F = 65;
+ private static final int NAME_AND_TYPE_D = 66;
+
+ private static final int NAME_AND_TYPE_EQUALS = 67;
+ private static final int NAME_AND_TYPE_LENGTH = 68;
+ private static final int NAME_AND_TYPE_INIT = 69;
+ private static final int NAME_AND_TYPE_INIT_STRING = 70;
+ private static final int NAME_AND_TYPE_APPEND_Z_STRINGBUFFER = 71;
+ private static final int NAME_AND_TYPE_APPEND_C_STRINGBUFFER = 72;
+ private static final int NAME_AND_TYPE_APPEND_I_STRINGBUFFER = 73;
+ private static final int NAME_AND_TYPE_APPEND_J_STRINGBUFFER = 74;
+ private static final int NAME_AND_TYPE_APPEND_F_STRINGBUFFER = 75;
+ private static final int NAME_AND_TYPE_APPEND_D_STRINGBUFFER = 76;
+ private static final int NAME_AND_TYPE_APPEND_STRING_STRINGBUFFER = 77;
+ private static final int NAME_AND_TYPE_APPEND_Z_STRINGBUILDER = 78;
+ private static final int NAME_AND_TYPE_APPEND_C_STRINGBUILDER = 79;
+ private static final int NAME_AND_TYPE_APPEND_I_STRINGBUILDER = 80;
+ private static final int NAME_AND_TYPE_APPEND_J_STRINGBUILDER = 81;
+ private static final int NAME_AND_TYPE_APPEND_F_STRINGBUILDER = 82;
+ private static final int NAME_AND_TYPE_APPEND_D_STRINGBUILDER = 83;
+ private static final int NAME_AND_TYPE_APPEND_STRING_STRINGBUILDER = 84;
+ private static final int NAME_AND_TYPE_TOSTRING = 85;
+
+ private static final int UTF8_EMPTY = 86;
+ private static final int UTF8_I = 87;
+ private static final int UTF8_L = 88;
+ private static final int UTF8_F = 89;
+ private static final int UTF8_D = 90;
+ private static final int UTF8_STRING = 91;
+ private static final int UTF8_STRINGBUFFER = 92;
+ private static final int UTF8_STRINGBUILDER = 93;
+ private static final int UTF8_EQUALS = 94;
+ private static final int UTF8_OBJECT_Z = 95;
+ private static final int UTF8_LENGTH = 96;
+ private static final int UTF8__I = 97;
+ private static final int UTF8_INIT = 98;
+ private static final int UTF8__VOID = 99;
+ private static final int UTF8_STRING_VOID = 100;
+ private static final int UTF8_TOSTRING = 101;
+ private static final int UTF8__STRING = 102;
+ private static final int UTF8_APPEND = 103;
+ private static final int UTF8_Z_STRINGBUFFER = 104;
+ private static final int UTF8_C_STRINGBUFFER = 105;
+ private static final int UTF8_I_STRINGBUFFER = 106;
+ private static final int UTF8_J_STRINGBUFFER = 107;
+ private static final int UTF8_F_STRINGBUFFER = 108;
+ private static final int UTF8_D_STRINGBUFFER = 109;
+ private static final int UTF8_STRING_STRINGBUFFER = 110;
+ private static final int UTF8_Z_STRINGBUILDER = 111;
+ private static final int UTF8_C_STRINGBUILDER = 112;
+ private static final int UTF8_I_STRINGBUILDER = 113;
+ private static final int UTF8_J_STRINGBUILDER = 114;
+ private static final int UTF8_F_STRINGBUILDER = 115;
+ private static final int UTF8_D_STRINGBUILDER = 116;
+ private static final int UTF8_STRING_STRINGBUILDER = 117;
+
+ private static final int SENTINEL = 118;
public static final Constant[] CONSTANTS = new Constant[]
@@ -136,23 +234,100 @@ public class InstructionSequenceConstants
new DoubleConstant(-1d),
+ new StringConstant(UTF8_EMPTY, null, null),
+
new FieldrefConstant(X, NAME_AND_TYPE_I, null, null),
new FieldrefConstant(X, NAME_AND_TYPE_L, null, null),
new FieldrefConstant(X, NAME_AND_TYPE_F, null, null),
new FieldrefConstant(X, NAME_AND_TYPE_D, null, null),
- new NameAndTypeConstant(Y, TYPE_I),
- new NameAndTypeConstant(Y, TYPE_L),
- new NameAndTypeConstant(Y, TYPE_F),
- new NameAndTypeConstant(Y, TYPE_D),
+ new MethodrefConstant(CLASS_STRING, NAME_AND_TYPE_EQUALS, null, null),
+ new MethodrefConstant(CLASS_STRING, NAME_AND_TYPE_LENGTH, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_INIT, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_INIT_STRING, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_Z_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_C_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_I_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_J_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_F_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_D_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_STRING_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_LENGTH, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_TOSTRING, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_INIT, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_INIT_STRING, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_Z_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_C_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_I_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_J_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_F_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_D_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_STRING_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_LENGTH, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_TOSTRING, null, null),
+
+ new ClassConstant(UTF8_STRING, null),
+ new ClassConstant(UTF8_STRINGBUFFER, null),
+ new ClassConstant(UTF8_STRINGBUILDER, null),
+
+ new NameAndTypeConstant(Y, UTF8_I),
+ new NameAndTypeConstant(Y, UTF8_L),
+ new NameAndTypeConstant(Y, UTF8_F),
+ new NameAndTypeConstant(Y, UTF8_D),
+ new NameAndTypeConstant(UTF8_EQUALS, UTF8_OBJECT_Z),
+ new NameAndTypeConstant(UTF8_LENGTH, UTF8__I),
+ new NameAndTypeConstant(UTF8_INIT, UTF8__VOID),
+ new NameAndTypeConstant(UTF8_INIT, UTF8_STRING_VOID),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_Z_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_C_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_I_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_J_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_F_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_D_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_STRING_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_Z_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_C_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_I_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_J_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_F_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_D_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_STRING_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_TOSTRING, UTF8__STRING),
+ new Utf8Constant(""),
new Utf8Constant("I"),
new Utf8Constant("J"),
new Utf8Constant("F"),
new Utf8Constant("D"),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_EQUALS),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_EQUALS),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_LENGTH),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LENGTH),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_INIT),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INIT),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_VOID),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_TOSTRING),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_TOSTRING),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_APPEND),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CHAR_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INT_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LONG_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_FLOAT_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CHAR_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INT_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LONG_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_FLOAT_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_STRING_BUILDER),
};
-
public static final Instruction[][][] VARIABLE = new Instruction[][][]
{
{ // nop = nothing
@@ -237,7 +412,7 @@ public class InstructionSequenceConstants
{ // a = a = nothing
{
new VariableInstruction(InstructionConstants.OP_ALOAD, X),
- new SimpleInstruction(InstructionConstants.OP_POP),
+ new VariableInstruction(InstructionConstants.OP_ASTORE, X),
},{
// Nothing.
},
@@ -382,12 +557,12 @@ public class InstructionSequenceConstants
},
{ // c * i = i * c
{
- new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, A),
new VariableInstruction(InstructionConstants.OP_ILOAD, X),
new SimpleInstruction(InstructionConstants.OP_IMUL),
},{
new VariableInstruction(InstructionConstants.OP_ILOAD, X),
- new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, A),
new SimpleInstruction(InstructionConstants.OP_IMUL),
},
},
@@ -548,7 +723,7 @@ public class InstructionSequenceConstants
{ // i = i + c = i += c
{
new VariableInstruction(InstructionConstants.OP_ILOAD, X),
- new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, A),
new SimpleInstruction(InstructionConstants.OP_IADD),
new VariableInstruction(InstructionConstants.OP_ISTORE, X),
},{
@@ -651,22 +826,23 @@ public class InstructionSequenceConstants
// Nothing.
},
},
- { // ... + 0f = ...
- {
- new SimpleInstruction(InstructionConstants.OP_FCONST_0),
- new SimpleInstruction(InstructionConstants.OP_FADD),
- },{
- // Nothing.
- },
- },
- { // ... + 0d = ...
- {
- new SimpleInstruction(InstructionConstants.OP_DCONST_0),
- new SimpleInstruction(InstructionConstants.OP_DADD),
- },{
- // Nothing.
- },
- },
+ // Not valid for -0.0.
+// { // ... + 0f = ...
+// {
+// new SimpleInstruction(InstructionConstants.OP_FCONST_0),
+// new SimpleInstruction(InstructionConstants.OP_FADD),
+// },{
+// // Nothing.
+// },
+// },
+// { // ... + 0d = ...
+// {
+// new SimpleInstruction(InstructionConstants.OP_DCONST_0),
+// new SimpleInstruction(InstructionConstants.OP_DADD),
+// },{
+// // Nothing.
+// },
+// },
{ // ... - 0 = ...
{
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
@@ -1072,7 +1248,8 @@ public class InstructionSequenceConstants
new SimpleInstruction(InstructionConstants.OP_FNEG),
},
},
-// { // ... * 0f = 0f (or NaN)
+ // Not valid for -0.0 and for NaN.
+// { // ... * 0f = 0f
// {
// new SimpleInstruction(InstructionConstants.OP_FCONST_0),
// new SimpleInstruction(InstructionConstants.OP_FMUL),
@@ -1097,7 +1274,8 @@ public class InstructionSequenceConstants
new SimpleInstruction(InstructionConstants.OP_DNEG),
},
},
-// { // ... * 0d = 0d (or NaN)
+ // Not valid for -0.0 and for NaN.
+// { // ... * 0d = 0d
// {
// new SimpleInstruction(InstructionConstants.OP_DCONST_0),
// new SimpleInstruction(InstructionConstants.OP_DMUL),
@@ -1504,6 +1682,7 @@ public class InstructionSequenceConstants
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
},
},
+ // Not valid for negative values.
// { // ... % 2 = ... & 0x1
// {
// new SimpleInstruction(InstructionConstants.OP_ICONST_2),
@@ -3348,4 +3527,898 @@ public class InstructionSequenceConstants
// },
// }
};
-} \ No newline at end of file
+
+ public static final Instruction[][][] STRING = new Instruction[][][]
+ {
+ { // "...".equals("...") = true
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRING_EQUALS),
+ },{
+ new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+ },
+ },
+ { // "...".length() = ...
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRING_LENGTH),
+ },{
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH),
+ },
+ },
+
+ { // new StringBuffer("...").toString() = "..." (ignoring identity)
+ {
+ new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUFFER),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_TOSTRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ },
+ },
+ { // new StringBuffer("...").length() = length
+ {
+ new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUFFER),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_LENGTH),
+ },{
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH),
+ },
+ },
+ { // StringBuffer#append("") = nothing
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_EMPTY),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },{
+ // Nothing.
+ },
+ },
+ { // new StringBuffer().append(Z) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, BOOLEAN_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(C) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Cc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(I) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Ic) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(J) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Jc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(F) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Fc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(D) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Dc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append("...") = new StringBuffer("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Z) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(C) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Cc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(I) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Ic) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(J) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Jc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(F) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Fc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(D) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Dc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append("...") = new StringBuffer("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Z) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(C) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Cc) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(I) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Ic) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(J) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Jc) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(F) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Fc) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(D) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Dc) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append("...") = StringBuffer#append("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+
+ { // new StringBuilder("...").toString() = "..." (ignoring identity)
+ {
+ new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUILDER),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_TOSTRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ },
+ },
+ { // new StringBuilder("...").length() = length
+ {
+ new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUILDER),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_LENGTH),
+ },{
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH),
+ },
+ },
+ { // StringBuilder#append("") = nothing
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_EMPTY),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },{
+ // Nothing.
+ },
+ },
+ { // new StringBuilder().append(Z) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, BOOLEAN_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(C) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Cc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(I) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Ic) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(J) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Jc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(F) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Fc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(D) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Dc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append("...") = new StringBuilder("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Z) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(C) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Cc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(I) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Ic) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(J) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Jc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(F) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Fc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(D) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Dc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append("...") = new StringBuilder("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Z) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(C) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Cc) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(I) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Ic) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(J) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Jc) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(F) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Fc) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(D) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Dc) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append("...") = StringBuilder#append("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ };
+
+ /*
+ static
+ {
+ ProgramClass clazz = new ProgramClass();
+ clazz.constantPool = CONSTANTS;
+
+ ClassPrinter printer = new ClassPrinter();
+
+ for (int index = 0; index < CONSTANTS.length; index++)
+ {
+ System.out.print("["+index+"] ");
+ try
+ {
+ CONSTANTS[index].accept(clazz, printer);
+ }
+ catch (Exception e)
+ {
+ System.out.println("("+e.getClass().getName()+")");
+ }
+ }
+
+ if (CONSTANTS.length != SENTINEL)
+ {
+ throw new IllegalStateException("Constants length ["+CONSTANTS.length+"] different from number of constant names ["+SENTINEL+"]");
+ }
+
+ Instruction[] instructions = STRING[2][0];
+
+ for (int index = 0; index < instructions.length; index++)
+ {
+ Instruction instruction = instructions[index];
+ try
+ {
+ instruction.accept(clazz, null, null, index, new ClassPrinter());
+ }
+ catch (Exception e)
+ {
+ //System.out.println(" "+instruction.toString(offset));
+ }
+ }
+ }
+ //*/
+}
diff --git a/src/proguard/optimize/peephole/InstructionSequenceReplacer.java b/src/proguard/optimize/peephole/InstructionSequenceReplacer.java
index bce06e2..be65b53 100644
--- a/src/proguard/optimize/peephole/InstructionSequenceReplacer.java
+++ b/src/proguard/optimize/peephole/InstructionSequenceReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -22,9 +22,9 @@ package proguard.optimize.peephole;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
-import proguard.classfile.constant.Constant;
+import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
-import proguard.classfile.editor.CodeAttributeEditor;
+import proguard.classfile.editor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;
@@ -42,10 +42,48 @@ extends SimplifiedVisitor
implements InstructionVisitor,
ConstantVisitor
{
+ /*
+ public static boolean DEBUG = true;
+ /*/
private static final boolean DEBUG = false;
+ //*/
+
+ public static final int X = InstructionSequenceMatcher.X;
+ public static final int Y = InstructionSequenceMatcher.Y;
+ public static final int Z = InstructionSequenceMatcher.Z;
+
+ public static final int A = InstructionSequenceMatcher.A;
+ public static final int B = InstructionSequenceMatcher.B;
+ public static final int C = InstructionSequenceMatcher.C;
+ public static final int D = InstructionSequenceMatcher.D;
+
+ private static final int BOOLEAN_STRING = 0x1;
+ private static final int CHAR_STRING = 0x2;
+ private static final int INT_STRING = 0x3;
+ private static final int LONG_STRING = 0x4;
+ private static final int FLOAT_STRING = 0x5;
+ private static final int DOUBLE_STRING = 0x6;
+ private static final int STRING_STRING = 0x7;
+
+ public static final int STRING_A_LENGTH = 0x20000000;
+ public static final int BOOLEAN_A_STRING = 0x20000001;
+ public static final int CHAR_A_STRING = 0x20000002;
+ public static final int INT_A_STRING = 0x20000003;
+ public static final int LONG_A_STRING = 0x20000004;
+ public static final int FLOAT_A_STRING = 0x20000005;
+ public static final int DOUBLE_A_STRING = 0x20000006;
+ public static final int STRING_A_STRING = 0x20000007;
+ public static final int BOOLEAN_B_STRING = 0x20000010;
+ public static final int CHAR_B_STRING = 0x20000020;
+ public static final int INT_B_STRING = 0x20000030;
+ public static final int LONG_B_STRING = 0x20000040;
+ public static final int FLOAT_B_STRING = 0x20000050;
+ public static final int DOUBLE_B_STRING = 0x20000060;
+ public static final int STRING_B_STRING = 0x20000070;
private final InstructionSequenceMatcher instructionSequenceMatcher;
+ private final Constant[] patternConstants;
private final Instruction[] replacementInstructions;
private final BranchTargetFinder branchTargetFinder;
private final CodeAttributeEditor codeAttributeEditor;
@@ -101,6 +139,7 @@ implements InstructionVisitor,
InstructionVisitor extraInstructionVisitor)
{
this.instructionSequenceMatcher = new InstructionSequenceMatcher(patternConstants, patternInstructions);
+ this.patternConstants = patternConstants;
this.replacementInstructions = replacementInstructions;
this.branchTargetFinder = branchTargetFinder;
this.codeAttributeEditor = codeAttributeEditor;
@@ -140,7 +179,7 @@ implements InstructionVisitor,
for (int index = 0; index < replacementInstructions.length; index++)
{
int matchedOffset = instructionSequenceMatcher.matchedInstructionOffset(index);
- System.out.println(" "+replacementInstructionFactory.create(index).shrink().toString(matchedOffset));
+ System.out.println(" "+replacementInstructionFactory.create(clazz, index).shrink().toString(matchedOffset));
}
}
@@ -148,7 +187,7 @@ implements InstructionVisitor,
for (int index = 0; index < replacementInstructions.length; index++)
{
codeAttributeEditor.replaceInstruction(instructionSequenceMatcher.matchedInstructionOffset(index),
- replacementInstructionFactory.create(index).shrink());
+ replacementInstructionFactory.create(clazz, index).shrink());
}
// Delete any remaining instructions in the from sequence.
@@ -204,10 +243,10 @@ implements InstructionVisitor,
* Creates the replacement instruction for the given index in the
* instruction sequence.
*/
- public Instruction create(int index)
+ public Instruction create(Clazz clazz, int index)
{
// Create the instruction.
- replacementInstructions[index].accept(null,
+ replacementInstructions[index].accept(clazz,
null,
null,
instructionSequenceMatcher.matchedInstructionOffset(index),
@@ -224,7 +263,7 @@ implements InstructionVisitor,
{
replacementInstruction =
new SimpleInstruction(simpleInstruction.opcode,
- instructionSequenceMatcher.matchedArgument(simpleInstruction.constant));
+ matchedArgument(clazz, simpleInstruction.constant));
}
@@ -241,7 +280,8 @@ implements InstructionVisitor,
{
replacementInstruction =
new ConstantInstruction(constantInstruction.opcode,
- instructionSequenceMatcher.matchedConstantIndex(constantInstruction.constantIndex),
+ matchedConstantIndex((ProgramClass)clazz,
+ constantInstruction.constantIndex),
instructionSequenceMatcher.matchedArgument(constantInstruction.constant));
}
@@ -250,7 +290,8 @@ implements InstructionVisitor,
{
replacementInstruction =
new BranchInstruction(branchInstruction.opcode,
- instructionSequenceMatcher.matchedBranchOffset(offset, branchInstruction.branchOffset));
+ instructionSequenceMatcher.matchedBranchOffset(offset,
+ branchInstruction.branchOffset));
}
@@ -261,7 +302,8 @@ implements InstructionVisitor,
instructionSequenceMatcher.matchedBranchOffset(offset, tableSwitchInstruction.defaultOffset),
instructionSequenceMatcher.matchedArgument(tableSwitchInstruction.lowCase),
instructionSequenceMatcher.matchedArgument(tableSwitchInstruction.highCase),
- instructionSequenceMatcher.matchedJumpOffsets(offset, tableSwitchInstruction.jumpOffsets));
+ instructionSequenceMatcher.matchedJumpOffsets(offset,
+ tableSwitchInstruction.jumpOffsets));
}
@@ -274,5 +316,105 @@ implements InstructionVisitor,
instructionSequenceMatcher.matchedArguments(lookUpSwitchInstruction.cases),
instructionSequenceMatcher.matchedJumpOffsets(offset, lookUpSwitchInstruction.jumpOffsets));
}
+
+
+ /**
+ * Returns the matched argument for the given pattern argument.
+ */
+ private int matchedArgument(Clazz clazz, int argument)
+ {
+ // Special case: do we have to compute the string length?
+ if (argument == STRING_A_LENGTH)
+ {
+ // Return the string length.
+ return clazz.getStringString(instructionSequenceMatcher.matchedArgument(A)).length();
+ }
+
+ // Otherwise, just return the matched argument.
+ return instructionSequenceMatcher.matchedArgument(argument);
+ }
+
+
+ /**
+ * Returns the matched or newly created constant index for the given
+ * pattern constant index.
+ */
+ private int matchedConstantIndex(ProgramClass programClass, int constantIndex)
+ {
+ // Special case: do we have to create a concatenated string?
+ if (constantIndex >= BOOLEAN_A_STRING &&
+ constantIndex <= (STRING_A_STRING | STRING_B_STRING))
+ {
+ // Create a new string constant and return its index.
+ return new ConstantPoolEditor(programClass).addStringConstant(
+ argumentAsString(programClass, constantIndex & 0xf, A) +
+ argumentAsString(programClass, (constantIndex >>> 4) & 0xf, B),
+ null,
+ null);
+ }
+
+ int matchedConstantIndex =
+ instructionSequenceMatcher.matchedConstantIndex(constantIndex);
+
+ // Do we have a matched constant index?
+ if (matchedConstantIndex > 0)
+ {
+ // Return its index.
+ return matchedConstantIndex;
+ }
+
+ // Otherwise, we still have to create a new constant.
+ // This currently only works for constants without any wildcards.
+ ProgramClass dummyClass = new ProgramClass();
+ dummyClass.constantPool = patternConstants;
+
+ return new ConstantAdder(programClass).addConstant(dummyClass, constantIndex);
+ }
+
+
+ private String argumentAsString(ProgramClass programClass,
+ int valueType,
+ int argument)
+ {
+ switch (valueType)
+ {
+ case BOOLEAN_STRING:
+ return Boolean.toString((instructionSequenceMatcher.wasConstant(argument) ?
+ ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument)) != 0);
+
+ case CHAR_STRING:
+ return Character.toString((char)(instructionSequenceMatcher.wasConstant(argument) ?
+ ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument)));
+
+ case INT_STRING:
+ return Integer.toString(instructionSequenceMatcher.wasConstant(argument) ?
+ ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument));
+
+ case LONG_STRING:
+ return Long.toString(instructionSequenceMatcher.wasConstant(argument) ?
+ ((LongConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument));
+
+ case FLOAT_STRING:
+ return Float.toString(instructionSequenceMatcher.wasConstant(argument) ?
+ ((FloatConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument));
+
+ case DOUBLE_STRING:
+ return Double.toString(instructionSequenceMatcher.wasConstant(argument) ?
+ ((DoubleConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument));
+
+ case STRING_STRING:
+ return
+ programClass.getStringString(instructionSequenceMatcher.matchedConstantIndex(argument));
+
+ default:
+ return "";
+ }
+ }
}
}
diff --git a/src/proguard/optimize/peephole/InstructionSequencesReplacer.java b/src/proguard/optimize/peephole/InstructionSequencesReplacer.java
index f12b51a..72fc334 100644
--- a/src/proguard/optimize/peephole/InstructionSequencesReplacer.java
+++ b/src/proguard/optimize/peephole/InstructionSequencesReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/MemberPrivatizer.java b/src/proguard/optimize/peephole/MemberPrivatizer.java
index 55b2f31..254e968 100644
--- a/src/proguard/optimize/peephole/MemberPrivatizer.java
+++ b/src/proguard/optimize/peephole/MemberPrivatizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/MethodFinalizer.java b/src/proguard/optimize/peephole/MethodFinalizer.java
index af1811b..140a114 100644
--- a/src/proguard/optimize/peephole/MethodFinalizer.java
+++ b/src/proguard/optimize/peephole/MethodFinalizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/MethodInliner.java b/src/proguard/optimize/peephole/MethodInliner.java
index 55f9ccb..8857202 100644
--- a/src/proguard/optimize/peephole/MethodInliner.java
+++ b/src/proguard/optimize/peephole/MethodInliner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -29,10 +29,10 @@ import proguard.classfile.editor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;
-import proguard.classfile.visitor.MemberVisitor;
+import proguard.classfile.visitor.*;
import proguard.optimize.info.*;
-import java.util.Stack;
+import java.util.*;
/**
* This AttributeVisitor inlines short methods or methods that are only invoked
@@ -48,7 +48,7 @@ implements AttributeVisitor,
MemberVisitor
{
private static final int MAXIMUM_INLINED_CODE_LENGTH = Integer.parseInt(System.getProperty("maximum.inlined.code.length", "8"));
- private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "8000"));
+ private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "7000"));
private static final int MAXIMUM_RESULTING_CODE_LENGTH_JME = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "2000"));
private static final int MAXIMUM_CODE_EXPANSION = 2;
private static final int MAXIMUM_EXTRA_CODE_LENGTH = 128;
@@ -138,6 +138,42 @@ implements AttributeVisitor,
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
+ // TODO: Remove this when the method inliner has stabilized.
+ // Catch any unexpected exceptions from the actual visiting method.
+ try
+ {
+ // Process the code.
+ visitCodeAttribute0(clazz, method, codeAttribute);
+ }
+ catch (RuntimeException ex)
+ {
+ System.err.println("Unexpected error while inlining method:");
+ System.err.println(" Target class = ["+targetClass.getName()+"]");
+ System.err.println(" Target method = ["+targetMethod.getName(targetClass)+targetMethod.getDescriptor(targetClass)+"]");
+ if (inlining)
+ {
+ System.err.println(" Inlined class = ["+clazz.getName()+"]");
+ System.err.println(" Inlined method = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");
+ }
+ System.err.println(" Exception = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");
+ System.err.println("Not inlining this method");
+
+ if (DEBUG)
+ {
+ targetMethod.accept(targetClass, new ClassPrinter());
+ if (inlining)
+ {
+ method.accept(clazz, new ClassPrinter());
+ }
+
+ throw ex;
+ }
+ }
+ }
+
+
+ public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
if (!inlining)
{
// codeAttributeComposer.DEBUG = DEBUG =
@@ -305,12 +341,12 @@ implements AttributeVisitor,
// Copy the instructions.
codeAttribute.instructionsAccept(clazz, method, this);
- // Copy the exceptions.
- codeAttribute.exceptionsAccept(clazz, method, exceptionInfoAdder);
-
// Append a label just after the code.
codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
+ // Copy the exceptions.
+ codeAttribute.exceptionsAccept(clazz, method, exceptionInfoAdder);
+
codeAttributeComposer.endCodeFragment();
}
@@ -457,42 +493,42 @@ implements AttributeVisitor,
if (// Only inline the method if it is private, static, or final.
(accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_STATIC |
- ClassConstants.INTERNAL_ACC_FINAL)) != 0 &&
+ ClassConstants.INTERNAL_ACC_FINAL)) != 0 &&
// Only inline the method if it is not synchronized, etc.
(accessFlags & (ClassConstants.INTERNAL_ACC_SYNCHRONIZED |
ClassConstants.INTERNAL_ACC_NATIVE |
ClassConstants.INTERNAL_ACC_INTERFACE |
- ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
+ ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
// Don't inline an <init> method, except in an <init> method in the
// same class.
// (!programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ||
// (programClass.equals(targetClass) &&
// targetMethod.getName(targetClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))) &&
- !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) &&
+ !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) &&
// Don't inline a method into itself.
(!programMethod.equals(targetMethod) ||
- !programClass.equals(targetClass)) &&
+ !programClass.equals(targetClass)) &&
// Only inline the method if it isn't recursing.
- !inliningMethods.contains(programMethod) &&
+ !inliningMethods.contains(programMethod) &&
// Only inline the method if its target class has at least the
// same version number as the source class, in order to avoid
// introducing incompatible constructs.
- targetClass.u4version >= programClass.u4version &&
+ targetClass.u4version >= programClass.u4version &&
// Only inline the method if it doesn't invoke a super method, or if
// it is in the same class.
(!SuperInvocationMarker.invokesSuperMethods(programMethod) ||
- programClass.equals(targetClass)) &&
+ programClass.equals(targetClass)) &&
// Only inline the method if it doesn't branch backward while there
// are uninitialized objects.
(!BackwardBranchMarker.branchesBackward(programMethod) ||
- uninitializedObjectCount == 0) &&
+ uninitializedObjectCount == 0) &&
// Only inline if the code access of the inlined method allows it.
(allowAccessModification ||
@@ -501,47 +537,24 @@ implements AttributeVisitor,
(!AccessMethodMarker.accessesPackageCode(programMethod) ||
ClassUtil.internalPackageName(programClass.getName()).equals(
- ClassUtil.internalPackageName(targetClass.getName()))))) &&
+ ClassUtil.internalPackageName(targetClass.getName()))))) &&
// (!AccessMethodMarker.accessesProtectedCode(programMethod) ||
// targetClass.extends_(programClass) ||
// targetClass.implements_(programClass)) ||
(!AccessMethodMarker.accessesProtectedCode(programMethod) ||
- programClass.equals(targetClass)) &&
+ programClass.equals(targetClass)) &&
// Only inline the method if it doesn't catch exceptions, or if it
// is invoked with an empty stack.
(!CatchExceptionMarker.catchesExceptions(programMethod) ||
- emptyInvokingStack) &&
+ emptyInvokingStack) &&
- // Only inline the method if it comes from the same class or from
- // a class with a static initializer.
+ // Only inline the method if it comes from the a class with at most
+ // a subset of the initialized superclasses.
(programClass.equals(targetClass) ||
- programClass.findMethod(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
- ClassConstants.INTERNAL_METHOD_TYPE_CLINIT) == null))
- {
-// System.out.print("MethodInliner: inlining ");
-// programMethod.accept(programClass, new SimpleClassPrinter(true));
-// System.out.print(" in ");
-// targetMethod.accept(targetClass, new SimpleClassPrinter(true));
-//
-// System.out.println(" Private: "+
-// (!AccessMethodMarker.accessesPrivateCode(programMethod) ||
-// programClass.equals(targetClass)));
-//
-// System.out.println(" Package: "+
-// (!AccessMethodMarker.accessesPackageCode(programMethod) ||
-// ClassUtil.internalPackageName(programClass.getName()).equals(
-// ClassUtil.internalPackageName(targetClass.getName()))));
-//
-// System.out.println(" Protected: "+
-// ((!AccessMethodMarker.accessesProtectedCode(programMethod) ||
-// targetClass.extends_(programClass) ||
-// targetClass.implements_(programClass)) ||
-// ClassUtil.internalPackageName(programClass.getName()).equals(
-// ClassUtil.internalPackageName(targetClass.getName()))));
-
- boolean oldInlining = inlining;
+ initializedSuperClasses(targetClass).containsAll(initializedSuperClasses(programClass))))
+ { boolean oldInlining = inlining;
inlining = true;
inliningMethods.push(programMethod);
@@ -564,4 +577,21 @@ implements AttributeVisitor,
uninitializedObjectCount--;
}
}
+
+
+ /**
+ * Returns the set of superclasses and interfaces that are initialized.
+ */
+ private Set initializedSuperClasses(Clazz clazz)
+ {
+ Set set = new HashSet();
+
+ // Visit all superclasses and interfaces, collecting the ones that have
+ // static initializers.
+ clazz.hierarchyAccept(true, true, true, false,
+ new StaticInitializerContainingClassFilter(
+ new ClassCollector(set)));
+
+ return set;
+ }
}
diff --git a/src/proguard/optimize/peephole/NopRemover.java b/src/proguard/optimize/peephole/NopRemover.java
index 69adb30..4c99f3a 100644
--- a/src/proguard/optimize/peephole/NopRemover.java
+++ b/src/proguard/optimize/peephole/NopRemover.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/PeepholeOptimizer.java b/src/proguard/optimize/peephole/PeepholeOptimizer.java
index 98f8e8d..d865638 100644
--- a/src/proguard/optimize/peephole/PeepholeOptimizer.java
+++ b/src/proguard/optimize/peephole/PeepholeOptimizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/ReachableCodeMarker.java b/src/proguard/optimize/peephole/ReachableCodeMarker.java
index d9dbf2d..cac1965 100644
--- a/src/proguard/optimize/peephole/ReachableCodeMarker.java
+++ b/src/proguard/optimize/peephole/ReachableCodeMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -27,6 +27,8 @@ import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor finds all instruction offsets, branch targets, and
* exception targets in the CodeAttribute objects that it visits.
@@ -91,10 +93,7 @@ implements AttributeVisitor,
else
{
// Reset the array.
- for (int index = 0; index < codeLength; index++)
- {
- isReachable[index] = false;
- }
+ Arrays.fill(isReachable, 0, codeLength, false);
}
// Mark the code, starting at the entry point.
diff --git a/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java b/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java
index 6707a12..254f748 100644
--- a/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java
+++ b/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -28,6 +28,8 @@ import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.ClassVisitor;
+import java.util.Arrays;
+
/**
* This ClassVisitor removes InnerClasses and EnclosingMethod attributes in
* classes that are retargeted or that refer to classes that are retargeted.
@@ -70,10 +72,7 @@ implements ClassVisitor,
}
// Clean up any remaining array elements.
- for (int index = newAtributesCount; index < attributesCount; index++)
- {
- attributes[index] = null;
- }
+ Arrays.fill(attributes, newAtributesCount, attributesCount, null);
// Update the number of attribuets.
programClass.u2attributesCount = newAtributesCount;
@@ -90,8 +89,39 @@ implements ClassVisitor,
// Check whether the class itself is retargeted.
checkTarget(clazz);
- // Check whether the referenced classes are retargeted.
- innerClassesAttribute.innerClassEntriesAccept(clazz, this);
+ if (!retargeted)
+ {
+ // Check whether the referenced classes are retargeted.
+ innerClassesAttribute.innerClassEntriesAccept(clazz, this);
+ int classesCount = innerClassesAttribute.u2classesCount;
+ InnerClassesInfo[] classes = innerClassesAttribute.classes;
+
+ int newClassesCount = 0;
+
+ // Copy over all non-retargeted attributes.
+ for (int index = 0; index < classesCount; index++)
+ {
+ InnerClassesInfo classInfo = classes[index];
+
+ // Check if the outer class or inner class is a retargeted class.
+ retargeted = false;
+ classInfo.outerClassConstantAccept(clazz, this);
+ classInfo.innerClassConstantAccept(clazz, this);
+ if (!retargeted)
+ {
+ classes[newClassesCount++] = classInfo;
+ }
+ }
+
+ // Clean up any remaining array elements.
+ Arrays.fill(classes, newClassesCount, classesCount, null);
+
+ // Update the number of classes.
+ innerClassesAttribute.u2classesCount = newClassesCount;
+
+ // Remove the attribute altogether if it's empty.
+ retargeted = newClassesCount == 0;
+ }
}
diff --git a/src/proguard/optimize/peephole/TargetClassChanger.java b/src/proguard/optimize/peephole/TargetClassChanger.java
index 22fd83d..5fa4fac 100644
--- a/src/proguard/optimize/peephole/TargetClassChanger.java
+++ b/src/proguard/optimize/peephole/TargetClassChanger.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -51,13 +51,13 @@ implements ClassVisitor,
AnnotationVisitor,
ElementValueVisitor
{
+ private static final boolean DEBUG = false;
+
+
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
- Clazz superClass = null;
- Clazz[] interfaceClasses = null;
-
// Change the references of the constant pool.
programClass.constantPoolEntriesAccept(this);
@@ -80,34 +80,39 @@ implements ClassVisitor,
programClass.getName(),
programClass);
+ // This class will loose all its interfaces.
+ programClass.u2interfacesCount = 0;
+
// This class will loose all its subclasses.
programClass.subClasses = null;
}
-
- // Remove interface classes that are pointing to this class.
- int newInterfacesCount = 0;
- for (int index = 0; index < programClass.u2interfacesCount; index++)
+ else
{
- Clazz interfaceClass = programClass.getInterface(index);
- if (!programClass.equals(interfaceClass))
+ // Remove interface classes that are pointing to this class.
+ int newInterfacesCount = 0;
+ for (int index = 0; index < programClass.u2interfacesCount; index++)
{
- programClass.u2interfaces[newInterfacesCount++] =
- programClass.u2interfaces[index];
+ Clazz interfaceClass = programClass.getInterface(index);
+ if (!programClass.equals(interfaceClass))
+ {
+ programClass.u2interfaces[newInterfacesCount++] =
+ programClass.u2interfaces[index];
+ }
}
- }
- programClass.u2interfacesCount = newInterfacesCount;
+ programClass.u2interfacesCount = newInterfacesCount;
- // Update the subclasses of the superclass and interfaces of the
- // target class.
- ConstantVisitor subclassAdder =
- new ReferencedClassVisitor(
- new SubclassFilter(programClass,
- new SubclassAdder(programClass)));
+ // Update the subclasses of the superclass and interfaces of the
+ // target class.
+ ConstantVisitor subclassAdder =
+ new ReferencedClassVisitor(
+ new SubclassFilter(programClass,
+ new SubclassAdder(programClass)));
- programClass.superClassConstantAccept(subclassAdder);
- programClass.interfaceConstantsAccept(subclassAdder);
+ programClass.superClassConstantAccept(subclassAdder);
+ programClass.interfaceConstantsAccept(subclassAdder);
- // TODO: Maybe restore private method references.
+ // TODO: Maybe restore private method references.
+ }
}
@@ -188,6 +193,12 @@ implements ClassVisitor,
Clazz newReferencedClass = updateReferencedClass(referencedClass);
if (referencedClass != newReferencedClass)
{
+ if (DEBUG)
+ {
+ System.out.println("TargetClassChanger:");
+ System.out.println(" ["+clazz.getName()+"] changing reference from ["+refConstant.referencedClass+"."+refConstant.referencedMember.getName(refConstant.referencedClass)+refConstant.referencedMember.getDescriptor(refConstant.referencedClass)+"]");
+ }
+
// Change the referenced class.
refConstant.referencedClass = newReferencedClass;
@@ -197,6 +208,11 @@ implements ClassVisitor,
refConstant.getName(clazz),
refConstant.getType(clazz),
newReferencedClass);
+
+ if (DEBUG)
+ {
+ System.out.println(" ["+clazz.getName()+"] to ["+refConstant.referencedClass+"."+refConstant.referencedMember.getName(refConstant.referencedClass)+refConstant.referencedMember.getDescriptor(refConstant.referencedClass)+"]");
+ }
}
}
diff --git a/src/proguard/optimize/peephole/UnreachableCodeRemover.java b/src/proguard/optimize/peephole/UnreachableCodeRemover.java
index e8a99ab..fcb8914 100644
--- a/src/proguard/optimize/peephole/UnreachableCodeRemover.java
+++ b/src/proguard/optimize/peephole/UnreachableCodeRemover.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/UnreachableExceptionRemover.java b/src/proguard/optimize/peephole/UnreachableExceptionRemover.java
index 048f5e3..f3ecf0b 100644
--- a/src/proguard/optimize/peephole/UnreachableExceptionRemover.java
+++ b/src/proguard/optimize/peephole/UnreachableExceptionRemover.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/VariableShrinker.java b/src/proguard/optimize/peephole/VariableShrinker.java
index 45b694f..55f42ca 100644
--- a/src/proguard/optimize/peephole/VariableShrinker.java
+++ b/src/proguard/optimize/peephole/VariableShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/VerticalClassMerger.java b/src/proguard/optimize/peephole/VerticalClassMerger.java
index 29ed6ff..721f2a5 100644
--- a/src/proguard/optimize/peephole/VerticalClassMerger.java
+++ b/src/proguard/optimize/peephole/VerticalClassMerger.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/preverify/CodePreverifier.java b/src/proguard/preverify/CodePreverifier.java
index fa60b9a..670f26e 100644
--- a/src/proguard/preverify/CodePreverifier.java
+++ b/src/proguard/preverify/CodePreverifier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/preverify/CodeSubroutineInliner.java b/src/proguard/preverify/CodeSubroutineInliner.java
index 603eb75..9012b05 100644
--- a/src/proguard/preverify/CodeSubroutineInliner.java
+++ b/src/proguard/preverify/CodeSubroutineInliner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -67,6 +67,7 @@ implements AttributeVisitor,
// DEBUG =
// clazz.getName().equals("abc/Def") &&
// method.getName(clazz).equals("abc");
+// CodeAttributeComposer.DEBUG = DEBUG;
// TODO: Remove this when the subroutine inliner has stabilized.
// Catch any unexpected exceptions from the actual visiting method.
diff --git a/src/proguard/preverify/Preverifier.java b/src/proguard/preverify/Preverifier.java
index e071c5c..3cbd930 100644
--- a/src/proguard/preverify/Preverifier.java
+++ b/src/proguard/preverify/Preverifier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -59,13 +59,12 @@ public class Preverifier
new AllAttributeVisitor(
new CodePreverifier(configuration.microEdition)));
- // In Java Standard Edition, only class files from Java 6 or higher
- // should be preverified.
+ // Classes from Java 6 may optionally be preverified.
+ // Classes from Java 7 or higher must be preverified.
if (!configuration.microEdition)
{
preverifier =
new ClassVersionFilter(ClassConstants.INTERNAL_CLASS_VERSION_1_6,
- Integer.MAX_VALUE,
preverifier);
}
diff --git a/src/proguard/preverify/SubroutineInliner.java b/src/proguard/preverify/SubroutineInliner.java
index e28512f..38a824e 100644
--- a/src/proguard/preverify/SubroutineInliner.java
+++ b/src/proguard/preverify/SubroutineInliner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -65,7 +65,6 @@ public class SubroutineInliner
{
inliner =
new ClassVersionFilter(ClassConstants.INTERNAL_CLASS_VERSION_1_6,
- Integer.MAX_VALUE,
inliner);
}
diff --git a/src/proguard/retrace/ReTrace.java b/src/proguard/retrace/ReTrace.java
index 97ab27b..183d9a0 100644
--- a/src/proguard/retrace/ReTrace.java
+++ b/src/proguard/retrace/ReTrace.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -47,7 +47,7 @@ implements MappingProcessor
private static final String REGEX_CLASS_SLASH = "\\b(?:[A-Za-z0-9_$]+/)*[A-Za-z0-9_$]+\\b";
private static final String REGEX_LINE_NUMBER = "\\b[0-9]+\\b";
private static final String REGEX_TYPE = REGEX_CLASS + "(?:\\[\\])*";
- private static final String REGEX_MEMBER = "\\b[A-Za-z0-9_$]+\\b";
+ private static final String REGEX_MEMBER = "<?\\b[A-Za-z0-9_$]+\\b>?";
private static final String REGEX_ARGUMENTS = "(?:" + REGEX_TYPE + "(?:\\s*,\\s*" + REGEX_TYPE + ")*)?";
// The class settings.
diff --git a/src/proguard/shrink/AnnotationUsageMarker.java b/src/proguard/shrink/AnnotationUsageMarker.java
index 9aaae34..0b2fd91 100644
--- a/src/proguard/shrink/AnnotationUsageMarker.java
+++ b/src/proguard/shrink/AnnotationUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -52,7 +52,6 @@ implements AttributeVisitor,
// Fields acting as a return parameters for several methods.
private boolean attributeUsed;
private boolean annotationUsed;
- private boolean elementValueUsed;
private boolean classUsed;
private boolean methodUsed;
@@ -151,9 +150,6 @@ implements AttributeVisitor,
markConstant(clazz, constantElementValue.u2elementNameIndex);
markConstant(clazz, constantElementValue.u2constantValueIndex);
-
- // The return value.
- elementValueUsed = true;
}
}
@@ -164,7 +160,7 @@ implements AttributeVisitor,
{
// Check the referenced classes.
classUsed = true;
- enumConstantElementValue.referencedClassesAccept(usageMarker);
+ enumConstantElementValue.referencedClassesAccept(this);
if (classUsed)
{
@@ -174,9 +170,6 @@ implements AttributeVisitor,
markConstant(clazz, enumConstantElementValue.u2elementNameIndex);
markConstant(clazz, enumConstantElementValue.u2typeNameIndex);
markConstant(clazz, enumConstantElementValue.u2constantNameIndex);
-
- // The return value.
- elementValueUsed = true;
}
}
}
@@ -188,7 +181,7 @@ implements AttributeVisitor,
{
// Check the referenced classes.
classUsed = true;
- classElementValue.referencedClassesAccept(usageMarker);
+ classElementValue.referencedClassesAccept(this);
if (classUsed)
{
@@ -197,9 +190,6 @@ implements AttributeVisitor,
markConstant(clazz, classElementValue.u2elementNameIndex);
markConstant(clazz, classElementValue.u2classInfoIndex);
-
- // The return value.
- elementValueUsed = true;
}
}
}
@@ -221,9 +211,6 @@ implements AttributeVisitor,
usageMarker.markAsUsed(annotationElementValue);
markConstant(clazz, annotationElementValue.u2elementNameIndex);
-
- // The return value.
- elementValueUsed = true;
}
annotationUsed = oldAnnotationUsed;
@@ -235,26 +222,13 @@ implements AttributeVisitor,
{
if (isReferencedMethodUsed(arrayElementValue))
{
- boolean oldelementValueUsed = elementValueUsed;
-
// Check and mark the contained element values.
- elementValueUsed = false;
arrayElementValue.elementValuesAccept(clazz, annotation, this);
- if (elementValueUsed)
- {
- // Mark the element value as being used.
- usageMarker.markAsUsed(arrayElementValue);
-
- markConstant(clazz, arrayElementValue.u2elementNameIndex);
+ // Mark the element value as being used.
+ usageMarker.markAsUsed(arrayElementValue);
- // The return value.
- //elementValueUsed = true;
- }
- else
- {
- elementValueUsed = oldelementValueUsed;
- }
+ markConstant(clazz, arrayElementValue.u2elementNameIndex);
}
}
diff --git a/src/proguard/shrink/ClassShrinker.java b/src/proguard/shrink/ClassShrinker.java
index 0b5c5b7..f40e3ce 100644
--- a/src/proguard/shrink/ClassShrinker.java
+++ b/src/proguard/shrink/ClassShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -24,15 +24,17 @@ import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.annotation.visitor.*;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.editor.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
+import java.util.Arrays;
+
/**
- * This ClassVisitor removes constant pool entries and class members that
- * are not marked as being used.
+ * This ClassVisitor removes constant pool entries, class members, and other
+ * class elements that are not marked as being used.
*
* @see UsageMarker
*
@@ -48,8 +50,7 @@ implements ClassVisitor,
{
private final UsageMarker usageMarker;
- private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
-
+ private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
@@ -76,7 +77,7 @@ implements ClassVisitor,
programClass.u2interfacesCount);
// Shrinking the constant pool also sets up an index map.
- programClass.u2constantPoolCount =
+ int newConstantPoolCount =
shrinkConstantPool(programClass.constantPool,
programClass.u2constantPoolCount);
@@ -98,9 +99,15 @@ implements ClassVisitor,
programClass.methodsAccept(this);
programClass.attributesAccept(this);
- // Remap all constant pool references.
- constantPoolRemapper.setConstantIndexMap(constantIndexMap);
- constantPoolRemapper.visitProgramClass(programClass);
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
+
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
// Remove the unused interfaces from the class signature.
programClass.attributesAccept(new SignatureShrinker());
@@ -140,6 +147,15 @@ implements ClassVisitor,
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Shrink the array of BootstrapMethodInfo objects.
+ bootstrapMethodsAttribute.u2bootstrapMethodsCount =
+ shrinkArray(bootstrapMethodsAttribute.bootstrapMethods,
+ bootstrapMethodsAttribute.u2bootstrapMethodsCount);
+ }
+
+
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
// Shrink the array of InnerClassesInfo objects.
@@ -349,10 +365,7 @@ implements ClassVisitor,
}
// Clear the remaining constant pool elements.
- for (int index = counter; index < length; index++)
- {
- constantPool[index] = null;
- }
+ Arrays.fill(constantPool, counter, length, null);
return counter;
}
@@ -377,10 +390,7 @@ implements ClassVisitor,
}
// Clear the remaining array elements.
- for (int index = counter; index < length; index++)
- {
- array[index] = 0;
- }
+ Arrays.fill(array, counter, length, 0);
return counter;
}
@@ -437,10 +447,10 @@ implements ClassVisitor,
}
}
- // Clear the remaining array elements.
- for (int index = counter; index < length; index++)
+ // Clear any remaining array elements.
+ if (counter < length)
{
- array[index] = null;
+ Arrays.fill(array, counter, length, null);
}
return counter;
diff --git a/src/proguard/shrink/InnerUsageMarker.java b/src/proguard/shrink/InnerUsageMarker.java
index b8ca801..c95bc64 100644
--- a/src/proguard/shrink/InnerUsageMarker.java
+++ b/src/proguard/shrink/InnerUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/InterfaceUsageMarker.java b/src/proguard/shrink/InterfaceUsageMarker.java
index 7599898..065745d 100644
--- a/src/proguard/shrink/InterfaceUsageMarker.java
+++ b/src/proguard/shrink/InterfaceUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ShortestUsageMark.java b/src/proguard/shrink/ShortestUsageMark.java
index 757c713..a2ff762 100644
--- a/src/proguard/shrink/ShortestUsageMark.java
+++ b/src/proguard/shrink/ShortestUsageMark.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ShortestUsageMarker.java b/src/proguard/shrink/ShortestUsageMarker.java
index da8fad3..3f2cf94 100644
--- a/src/proguard/shrink/ShortestUsageMarker.java
+++ b/src/proguard/shrink/ShortestUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ShortestUsagePrinter.java b/src/proguard/shrink/ShortestUsagePrinter.java
index db42fe1..4f12e87 100644
--- a/src/proguard/shrink/ShortestUsagePrinter.java
+++ b/src/proguard/shrink/ShortestUsagePrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/Shrinker.java b/src/proguard/shrink/Shrinker.java
index edbc27f..66ca161 100644
--- a/src/proguard/shrink/Shrinker.java
+++ b/src/proguard/shrink/Shrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,7 @@
package proguard.shrink;
import proguard.*;
-import proguard.classfile.ClassPool;
+import proguard.classfile.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.visitor.*;
@@ -67,9 +67,20 @@ public class Shrinker
new UsageMarker() :
new ShortestUsageMarker();
+ // Automatically mark the parameterless constructors of seed classes,
+ // mainly for convenience and for backward compatibility.
+ ClassVisitor classUsageMarker =
+ new MultiClassVisitor(new ClassVisitor[]
+ {
+ usageMarker,
+ new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_INIT,
+ usageMarker)
+ });
+
ClassPoolVisitor classPoolvisitor =
ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
- usageMarker,
+ classUsageMarker,
usageMarker,
true,
false,
diff --git a/src/proguard/shrink/UsageMarker.java b/src/proguard/shrink/UsageMarker.java
index e913046..a1b2f53 100644
--- a/src/proguard/shrink/UsageMarker.java
+++ b/src/proguard/shrink/UsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -27,10 +27,10 @@ import proguard.classfile.attribute.preverification.*;
import proguard.classfile.attribute.preverification.visitor.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.constant.visitor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
@@ -65,18 +65,15 @@ implements ClassVisitor,
private static final Object USED = new Object();
- private final MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
- private final MyPossiblyUsedMemberUsageMarker possiblyUsedMemberUsageMarker = new MyPossiblyUsedMemberUsageMarker();
-// private ClassVisitor dynamicClassMarker =
-// new MultiClassVisitor(
-// new ClassVisitor[]
-// {
-// this,
-// new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
-// ClassConstants.INTERNAL_METHOD_TYPE_INIT,
-// this)
-// });
-
+ private final MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
+ private final MyPossiblyUsedMemberUsageMarker possiblyUsedMemberUsageMarker = new MyPossiblyUsedMemberUsageMarker();
+ private final MemberVisitor nonEmptyMethodUsageMarker = new AllAttributeVisitor(
+ new MyNonEmptyMethodUsageMarker());
+ private final ConstantVisitor parameterlessConstructorMarker = new ConstantTagFilter(new int[] { ClassConstants.CONSTANT_String, ClassConstants.CONSTANT_Class },
+ new ReferencedClassVisitor(
+ new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_INIT,
+ this)));
// Implementations for ClassVisitor.
@@ -107,15 +104,10 @@ implements ClassVisitor,
programClass.hierarchyAccept(false, false, true, false,
interfaceUsageMarker);
- // Explicitly mark the <clinit> method.
+ // Explicitly mark the <clinit> method, if it's not empty.
programClass.methodAccept(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
ClassConstants.INTERNAL_METHOD_TYPE_CLINIT,
- this);
-
- // Explicitly mark the parameterless <init> method.
- programClass.methodAccept(ClassConstants.INTERNAL_METHOD_NAME_INIT,
- ClassConstants.INTERNAL_METHOD_TYPE_INIT,
- this);
+ nonEmptyMethodUsageMarker);
// Process all class members that have already been marked as possibly used.
programClass.fieldsAccept(possiblyUsedMemberUsageMarker);
@@ -187,6 +179,10 @@ implements ClassVisitor,
}
+ /**
+ * This MemberVisitor marks ProgramField and ProgramMethod objects that
+ * have already been marked as possibly used.
+ */
private class MyPossiblyUsedMemberUsageMarker
extends SimplifiedVisitor
implements MemberVisitor
@@ -230,6 +226,28 @@ implements ClassVisitor,
}
+ /**
+ * This AttributeVisitor marks ProgramMethod objects of non-empty methods.
+ */
+ private class MyNonEmptyMethodUsageMarker
+ extends SimplifiedVisitor
+ implements AttributeVisitor
+ {
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ if (codeAttribute.u4codeLength > 1)
+ {
+ method.accept(clazz, UsageMarker.this);
+ }
+ }
+ }
+
+
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
@@ -337,7 +355,8 @@ implements ClassVisitor,
{
if ((method.getAccessFlags() &
(ClassConstants.INTERNAL_ACC_PRIVATE |
- ClassConstants.INTERNAL_ACC_STATIC)) == 0)
+ ClassConstants.INTERNAL_ACC_STATIC)) == 0 &&
+ !ClassUtil.isInitializer(method.getName(clazz)))
{
clazz.accept(new ConcreteClassDownTraveler(
new ClassHierarchyTraveler(true, true, false, true,
@@ -395,11 +414,7 @@ implements ClassVisitor,
markConstant(clazz, stringConstant.u2stringIndex);
- // Mark the referenced class and its parameterless constructor,
- // if the string is being used in a Class.forName construct.
- //stringConstant.referencedClassAccept(dynamicClassMarker);
-
- // Mark the referenced class or class member, if any.
+ // Mark the referenced class and class member, if any.
stringConstant.referencedClassAccept(this);
stringConstant.referencedMemberAccept(this);
}
@@ -415,6 +430,31 @@ implements ClassVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ if (shouldBeMarkedAsUsed(invokeDynamicConstant))
+ {
+ markAsUsed(invokeDynamicConstant);
+
+ markConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex);
+
+ // Mark the bootstrap methods attribute.
+ clazz.attributesAccept(new MyBootStrapMethodUsageMarker(invokeDynamicConstant.u2bootstrapMethodAttributeIndex));
+ }
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ if (shouldBeMarkedAsUsed(methodHandleConstant))
+ {
+ markAsUsed(methodHandleConstant);
+
+ markConstant(clazz, methodHandleConstant.u2referenceIndex);
+ }
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
if (shouldBeMarkedAsUsed(refConstant))
@@ -450,6 +490,17 @@ implements ClassVisitor,
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ if (shouldBeMarkedAsUsed(methodTypeConstant))
+ {
+ markAsUsed(methodTypeConstant);
+
+ markConstant(clazz, methodTypeConstant.u2descriptorIndex);
+ }
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
if (shouldBeMarkedAsUsed(nameAndTypeConstant))
@@ -462,6 +513,58 @@ implements ClassVisitor,
}
+ /**
+ * This AttributeVisitor marks the bootstrap methods attributes, their
+ * method entries, their method handles, and their arguments.
+ */
+ private class MyBootStrapMethodUsageMarker
+ extends SimplifiedVisitor
+ implements AttributeVisitor,
+ BootstrapMethodInfoVisitor
+ {
+ private int bootstrapMethodIndex;
+
+
+ private MyBootStrapMethodUsageMarker(int bootstrapMethodIndex)
+ {
+ this.bootstrapMethodIndex = bootstrapMethodIndex;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (shouldBeMarkedAsUsed(bootstrapMethodsAttribute))
+ {
+ markAsUsed(bootstrapMethodsAttribute);
+
+ markConstant(clazz, bootstrapMethodsAttribute.u2attributeNameIndex);
+
+ bootstrapMethodsAttribute.bootstrapMethodEntryAccept(clazz,
+ bootstrapMethodIndex,
+ this);
+ }
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ markAsUsed(bootstrapMethodInfo);
+
+ markConstant(clazz, bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Mark the constant pool entries referenced by the arguments.
+ bootstrapMethodInfo.methodArgumentsAccept(clazz, UsageMarker.this);
+ }
+ }
+
+
// Implementations for AttributeVisitor.
// Note that attributes are typically only referenced once, so we don't
// test if they have been marked already.
@@ -475,6 +578,13 @@ implements ClassVisitor,
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Don't mark the attribute and its name here. We may mark it in
+ // MyBootStrapMethodsAttributeUsageMarker.
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
markAsUsed(sourceFileAttribute);
@@ -837,6 +947,12 @@ implements ClassVisitor,
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
markConstant(clazz, constantInstruction.constantIndex);
+
+ // Also mark the parameterless constructor of the class, in case the
+ // string constant or class constant is being used in a Class.forName
+ // or a .class construct.
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex,
+ parameterlessConstructorMarker);
}
@@ -915,6 +1031,6 @@ implements ClassVisitor,
*/
private void markConstant(Clazz clazz, int index)
{
- clazz.constantPoolEntryAccept(index, this);
+ clazz.constantPoolEntryAccept(index, this);
}
}
diff --git a/src/proguard/shrink/UsagePrinter.java b/src/proguard/shrink/UsagePrinter.java
index 294b9e1..53f7bc2 100644
--- a/src/proguard/shrink/UsagePrinter.java
+++ b/src/proguard/shrink/UsagePrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/UsedClassFilter.java b/src/proguard/shrink/UsedClassFilter.java
index ec180bd..b5a77fb 100644
--- a/src/proguard/shrink/UsedClassFilter.java
+++ b/src/proguard/shrink/UsedClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/UsedMemberFilter.java b/src/proguard/shrink/UsedMemberFilter.java
index 755cfd1..0034ce7 100644
--- a/src/proguard/shrink/UsedMemberFilter.java
+++ b/src/proguard/shrink/UsedMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -39,7 +39,7 @@ implements MemberVisitor
/**
- * Creates a new UsedClassFilter.
+ * Creates a new UsedMemberFilter.
* @param usageMarker the usage marker that is used to mark the classes
* and class members.
* @param memberVisitor the member visitor to which the visiting will be
diff --git a/src/proguard/util/AndMatcher.java b/src/proguard/util/AndMatcher.java
index 94a37e5..ae70e5d 100644
--- a/src/proguard/util/AndMatcher.java
+++ b/src/proguard/util/AndMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/ClassNameParser.java b/src/proguard/util/ClassNameParser.java
index ee972f0..fd12475 100644
--- a/src/proguard/util/ClassNameParser.java
+++ b/src/proguard/util/ClassNameParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/ConstantMatcher.java b/src/proguard/util/ConstantMatcher.java
index 1764caa..90e5a0c 100644
--- a/src/proguard/util/ConstantMatcher.java
+++ b/src/proguard/util/ConstantMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/EmptyStringMatcher.java b/src/proguard/util/EmptyStringMatcher.java
index 543f446..5e56147 100644
--- a/src/proguard/util/EmptyStringMatcher.java
+++ b/src/proguard/util/EmptyStringMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/ExtensionMatcher.java b/src/proguard/util/ExtensionMatcher.java
index 5a9f658..9e3fd65 100644
--- a/src/proguard/util/ExtensionMatcher.java
+++ b/src/proguard/util/ExtensionMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/FileNameParser.java b/src/proguard/util/FileNameParser.java
index 913f22d..d5cbdf3 100644
--- a/src/proguard/util/FileNameParser.java
+++ b/src/proguard/util/FileNameParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/FixedStringMatcher.java b/src/proguard/util/FixedStringMatcher.java
index c1eb3f4..570b70e 100644
--- a/src/proguard/util/FixedStringMatcher.java
+++ b/src/proguard/util/FixedStringMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/ListMatcher.java b/src/proguard/util/ListMatcher.java
index b2559c8..30f1a9b 100644
--- a/src/proguard/util/ListMatcher.java
+++ b/src/proguard/util/ListMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/ListParser.java b/src/proguard/util/ListParser.java
index cec803b..b8f075d 100644
--- a/src/proguard/util/ListParser.java
+++ b/src/proguard/util/ListParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/ListUtil.java b/src/proguard/util/ListUtil.java
index 570dbe8..71556f3 100644
--- a/src/proguard/util/ListUtil.java
+++ b/src/proguard/util/ListUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -34,7 +34,7 @@ public class ListUtil
/**
* Creates a comma-separated String from the given List of String objects.
*/
- public static String commaSeparatedString(List list)
+ public static String commaSeparatedString(List list, boolean quoteStrings)
{
if (list == null)
{
@@ -50,7 +50,14 @@ public class ListUtil
buffer.append(',');
}
- buffer.append(quotedString((String)list.get(index)));
+ String string = (String)list.get(index);
+
+ if (quoteStrings)
+ {
+ string = quotedString(string);
+ }
+
+ buffer.append(string);
}
return buffer.toString();
@@ -165,7 +172,7 @@ public class ListUtil
System.out.println("["+list.get(index)+"]");
}
- String string = commaSeparatedString(list);
+ String string = commaSeparatedString(list, true);
System.out.println("Resulting string: ["+string+"]");
}
diff --git a/src/proguard/util/NameParser.java b/src/proguard/util/NameParser.java
index e311fbf..6bbf4f6 100644
--- a/src/proguard/util/NameParser.java
+++ b/src/proguard/util/NameParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/NotMatcher.java b/src/proguard/util/NotMatcher.java
index f2a9a51..53b87ae 100644
--- a/src/proguard/util/NotMatcher.java
+++ b/src/proguard/util/NotMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/OrMatcher.java b/src/proguard/util/OrMatcher.java
index 097c6c6..70b849b 100644
--- a/src/proguard/util/OrMatcher.java
+++ b/src/proguard/util/OrMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/SettableMatcher.java b/src/proguard/util/SettableMatcher.java
index 9557f62..48f01e1 100644
--- a/src/proguard/util/SettableMatcher.java
+++ b/src/proguard/util/SettableMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/StringMatcher.java b/src/proguard/util/StringMatcher.java
index bd66dcc..571ee7f 100644
--- a/src/proguard/util/StringMatcher.java
+++ b/src/proguard/util/StringMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/StringParser.java b/src/proguard/util/StringParser.java
index 29f4f16..541d30c 100644
--- a/src/proguard/util/StringParser.java
+++ b/src/proguard/util/StringParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/VariableStringMatcher.java b/src/proguard/util/VariableStringMatcher.java
index 1e41323..9b296d4 100644
--- a/src/proguard/util/VariableStringMatcher.java
+++ b/src/proguard/util/VariableStringMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/wtk/ProGuardObfuscator.java b/src/proguard/wtk/ProGuardObfuscator.java
index 4618437..da957ed 100644
--- a/src/proguard/wtk/ProGuardObfuscator.java
+++ b/src/proguard/wtk/ProGuardObfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free