summaryrefslogtreecommitdiffstats
path: root/src/proguard/classfile/editor
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/classfile/editor')
-rw-r--r--src/proguard/classfile/editor/AccessFixer.java234
-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.java42
-rw-r--r--src/proguard/classfile/editor/AttributeSorter.java2
-rw-r--r--src/proguard/classfile/editor/AttributesEditor.java71
-rw-r--r--src/proguard/classfile/editor/BootstrapMethodInfoAdder.java86
-rw-r--r--src/proguard/classfile/editor/BootstrapMethodRemapper.java88
-rw-r--r--src/proguard/classfile/editor/BootstrapMethodsAttributeAdder.java91
-rw-r--r--src/proguard/classfile/editor/BootstrapMethodsAttributeEditor.java60
-rw-r--r--src/proguard/classfile/editor/BridgeMethodFixer.java12
-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.java93
-rw-r--r--src/proguard/classfile/editor/CodeAttributeComposer.java73
-rw-r--r--src/proguard/classfile/editor/CodeAttributeEditor.java142
-rw-r--r--src/proguard/classfile/editor/CodeAttributeEditorResetter.java2
-rw-r--r--src/proguard/classfile/editor/ComparableConstant.java77
-rw-r--r--src/proguard/classfile/editor/ConstantAdder.java28
-rw-r--r--src/proguard/classfile/editor/ConstantPoolEditor.java2
-rw-r--r--src/proguard/classfile/editor/ConstantPoolRemapper.java36
-rw-r--r--src/proguard/classfile/editor/ConstantPoolShrinker.java34
-rw-r--r--src/proguard/classfile/editor/ConstantPoolSorter.java2
-rw-r--r--src/proguard/classfile/editor/ElementValueAdder.java2
-rw-r--r--src/proguard/classfile/editor/ElementValuesEditor.java4
-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.java6
-rw-r--r--src/proguard/classfile/editor/InstructionAdder.java6
-rw-r--r--src/proguard/classfile/editor/InstructionWriter.java2
-rw-r--r--src/proguard/classfile/editor/InterfaceAdder.java5
-rw-r--r--src/proguard/classfile/editor/InterfaceDeleter.java190
-rw-r--r--src/proguard/classfile/editor/InterfaceSorter.java48
-rw-r--r--src/proguard/classfile/editor/InterfacesEditor.java33
-rw-r--r--src/proguard/classfile/editor/LineNumberInfoAdder.java6
-rw-r--r--src/proguard/classfile/editor/LineNumberTableAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableInfoAdder.java16
-rw-r--r--src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java28
-rw-r--r--src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java16
-rw-r--r--src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java30
-rw-r--r--src/proguard/classfile/editor/MemberAdder.java18
-rw-r--r--src/proguard/classfile/editor/MemberReferenceFixer.java4
-rw-r--r--src/proguard/classfile/editor/MethodInvocationFixer.java12
-rw-r--r--src/proguard/classfile/editor/NameAndTypeShrinker.java17
-rw-r--r--src/proguard/classfile/editor/NamedAttributeDeleter.java36
-rw-r--r--src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java25
-rw-r--r--src/proguard/classfile/editor/ParameterInfoAdder.java62
-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.java38
-rw-r--r--src/proguard/classfile/editor/VariableCleaner.java2
-rw-r--r--src/proguard/classfile/editor/VariableEditor.java2
-rw-r--r--src/proguard/classfile/editor/VariableRemapper.java62
-rw-r--r--src/proguard/classfile/editor/VariableSizeUpdater.java2
57 files changed, 1435 insertions, 436 deletions
diff --git a/src/proguard/classfile/editor/AccessFixer.java b/src/proguard/classfile/editor/AccessFixer.java
index d770531..3c41159 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,160 +21,196 @@
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.*;
import proguard.classfile.visitor.*;
/**
- * This ConstantVisitor fixes the access modifiers of all classes and class
- * members that are referenced by the constants that it visits.
+ * This ClassVisitor fixes the access modifiers of all classes and class
+ * members that are referenced by the classes that it visits.
*
* @author Eric Lafortune
*/
public class AccessFixer
-extends SimplifiedVisitor
-implements ConstantVisitor,
- ClassVisitor,
- MemberVisitor
+extends ReferencedClassVisitor
+implements ClassVisitor
{
- private MyReferencedClassFinder referencedClassFinder = new MyReferencedClassFinder();
+ /**
+ * Creates a new AccessFixer.
+ */
+ public AccessFixer()
+ {
+ // Unfortunately, the inner class must be static to be passed to the
+ // super constructor. We therefore can't let it refer to this class;
+ // we'll let this class refer to the inner class instead.
+ super(new MyAccessFixer());
+ }
- private Clazz referencingClass;
- private Clazz referencedClass;
+ // Overridden methods for ClassVisitor.
- // Implementations for ConstantVisitor.
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Remember the referencing class.
+ ((MyAccessFixer)classVisitor).referencingClass = programClass;
- public void visitAnyConstant(Clazz clazz, Constant constant) {}
+ // Start visiting and fixing the referenced classes and class members.
+ super.visitProgramClass(programClass);
+ }
- public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ public void visitLibraryClass(LibraryClass libraryClass)
{
- referencingClass = clazz;
- referencedClass = stringConstant.referencedClass;
+ // Remember the referencing class.
+ ((MyAccessFixer)classVisitor).referencingClass = libraryClass;
- // Make sure the access flags of the referenced class or class member,
- // if any, are acceptable.
- stringConstant.referencedClassAccept(this);
- stringConstant.referencedMemberAccept(this);
+ // Start visiting and fixing the referenced classes and class members.
+ super.visitLibraryClass(libraryClass);
}
- public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ // Overridden methods for MemberVisitor.
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- // Check the bootstrap method.
- invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this);
+ // Fix the referenced classes and class members.
+ super.visitProgramMember(programClass, programMethod);
+
+ // Fix overridden or implemented methods higher up the hierarchy.
+ // We can ignore private and static methods and initializers.
+ if ((programMethod.getAccessFlags() & (ClassConstants.ACC_PRIVATE |
+ ClassConstants.ACC_STATIC)) == 0 &&
+ !ClassUtil.isInitializer(programMethod.getName(programClass)))
+ {
+ programClass.hierarchyAccept(false, true, false, false,
+ new NamedMethodVisitor(programMethod.getName(programClass),
+ programMethod.getDescriptor(programClass),
+ new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
+ ClassConstants.ACC_STATIC,
+ (MemberVisitor)classVisitor)));
+ }
}
- public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
- // Check the method reference.
- clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ // Fix the referenced classes and class members.
+ super.visitLibraryMember(libraryClass, libraryMethod);
+
+ // Fix overridden or implemented methods higher up the hierarchy.
+ // We can ignore private and static methods and initializers.
+ if ((libraryMethod.getAccessFlags() & (ClassConstants.ACC_PRIVATE |
+ ClassConstants.ACC_STATIC)) == 0 &&
+ !ClassUtil.isInitializer(libraryMethod.getName(libraryClass)))
+ {
+ libraryClass.hierarchyAccept(false, true, false, false,
+ new NamedMethodVisitor(libraryMethod.getName(libraryClass),
+ libraryMethod.getDescriptor(libraryClass),
+ new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
+ ClassConstants.ACC_STATIC,
+ (MemberVisitor)classVisitor)));
+ }
}
- public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
- {
- referencingClass = clazz;
+ // Overridden methods for ConstantVisitor.
- // Remember the specified class, since it might be different from
- // the referenced class that actually contains the class member.
- clazz.constantPoolEntryAccept(refConstant.u2classIndex, referencedClassFinder);
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ // Fix the access flags of the referenced class, if any.
+ super.visitStringConstant(clazz, stringConstant);
- // Make sure the access flags of the referenced class member are
- // acceptable.
- refConstant.referencedMemberAccept(this);
+ // Fix the access flags of the referenced class member, if any.
+ stringConstant.referencedMemberAccept((MemberVisitor)classVisitor);
}
- public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
- referencingClass = clazz;
+ // Fix the access flags of the referenced class.
+ super.visitAnyRefConstant(clazz, refConstant);
- // Make sure the access flags of the referenced class are acceptable.
- classConstant.referencedClassAccept(this);
+ // Fix the access flags of the referenced class member.
+ refConstant.referencedMemberAccept((MemberVisitor)classVisitor);
}
- // Implementations for ClassVisitor.
+ /**
+ * This ClassVisitor and MemberVisitor fixes the access flags of the
+ * classes and class members that it visits, relative to the referencing
+ * class.
+ */
+ private static class MyAccessFixer
+ extends SimplifiedVisitor
+ implements ClassVisitor,
+ MemberVisitor
+ {
+ private Clazz referencingClass;
- public void visitLibraryClass(LibraryClass libraryClass) {}
+ // Implementations for ClassVisitor.
- public void visitProgramClass(ProgramClass programClass)
- {
- int currentAccessFlags = programClass.getAccessFlags();
- int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+ public void visitLibraryClass(LibraryClass libraryClass) {}
- // Compute the required access level.
- Clazz referencingClass = this.referencingClass;
- int requiredAccessLevel =
- inSamePackage(programClass, referencingClass) ? AccessUtil.PACKAGE_VISIBLE :
- AccessUtil.PUBLIC;
- // Fix the class access flags if necessary.
- if (currentAccessLevel < requiredAccessLevel)
+ public void visitProgramClass(ProgramClass programClass)
{
- programClass.u2accessFlags =
- AccessUtil.replaceAccessFlags(currentAccessFlags,
- AccessUtil.accessFlags(requiredAccessLevel));
+ int currentAccessFlags = programClass.getAccessFlags();
+ int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+
+ // Compute the required access level.
+ int requiredAccessLevel =
+ inSamePackage(programClass, referencingClass) ?
+ AccessUtil.PACKAGE_VISIBLE :
+ AccessUtil.PUBLIC;
+
+ // Fix the class access flags if necessary.
+ if (currentAccessLevel < requiredAccessLevel)
+ {
+ programClass.u2accessFlags =
+ AccessUtil.replaceAccessFlags(currentAccessFlags,
+ AccessUtil.accessFlags(requiredAccessLevel));
+ }
}
- }
- // Implementations for MemberVisitor.
+ // Implementations for MemberVisitor.
- public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember) {}
+ public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember) {}
- public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
- {
- int currentAccessFlags = programMember.getAccessFlags();
- int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
-
- // Compute the required access level.
- int requiredAccessLevel =
- programClass.equals(referencingClass) ? AccessUtil.PRIVATE :
- inSamePackage(programClass, referencingClass) ? AccessUtil.PACKAGE_VISIBLE :
- referencedClass.extends_(referencingClass) &&
- referencingClass.extends_(programClass) ? AccessUtil.PROTECTED :
- AccessUtil.PUBLIC;
-
- // Fix the class member access flags if necessary.
- if (currentAccessLevel < requiredAccessLevel)
+ public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
- programMember.u2accessFlags =
- AccessUtil.replaceAccessFlags(currentAccessFlags,
- AccessUtil.accessFlags(requiredAccessLevel));
+ int currentAccessFlags = programMember.getAccessFlags();
+ int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+
+ // Compute the required access level.
+ int requiredAccessLevel =
+ programClass.equals(referencingClass) ? AccessUtil.PRIVATE :
+ inSamePackage(programClass, referencingClass) ? AccessUtil.PACKAGE_VISIBLE :
+ programClass.extends_(referencingClass) &&
+ referencingClass.extends_(programClass) ? AccessUtil.PROTECTED :
+ AccessUtil.PUBLIC;
+
+ // Fix the class member access flags if necessary.
+ if (currentAccessLevel < requiredAccessLevel)
+ {
+ programMember.u2accessFlags =
+ AccessUtil.replaceAccessFlags(currentAccessFlags,
+ AccessUtil.accessFlags(requiredAccessLevel));
+ }
}
- }
- /**
- * This ConstantVisitor returns the referenced class of the class constant
- * that it visits.
- */
- private class MyReferencedClassFinder
- extends SimplifiedVisitor
- implements ConstantVisitor
- {
- // Implementations for ConstantVisitor.
- public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ // Small utility methods.
+
+ /**
+ * Returns whether the two given classes are in the same package.
+ */
+ private boolean inSamePackage(ProgramClass class1, Clazz class2)
{
- referencedClass = classConstant.referencedClass;
+ return ClassUtil.internalPackageName(class1.getName()).equals(
+ ClassUtil.internalPackageName(class2.getName()));
}
}
-
-
- // Small utility methods.
-
- private boolean inSamePackage(ProgramClass class1, Clazz class2)
- {
- return ClassUtil.internalPackageName(class1.getName()).equals(
- ClassUtil.internalPackageName(class2.getName()));
- }
}
diff --git a/src/proguard/classfile/editor/AnnotationAdder.java b/src/proguard/classfile/editor/AnnotationAdder.java
index 0389ab1..3a3fad0 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 a175c33..53cee40 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 ad4ecc0..9abea45 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,9 @@ import proguard.classfile.attribute.preverification.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
/**
* This AttributeVisitor adds all attributes that it visits to the given
* target class, class member, or attribute.
@@ -41,6 +44,7 @@ implements AttributeVisitor
private static final int[] EMPTY_INTS = new int[0];
private static final Attribute[] EMPTY_ATTRIBUTES = new Attribute[0];
private static final ExceptionInfo[] EMPTY_EXCEPTIONS = new ExceptionInfo[0];
+ private static final Annotation[] EMPTY_ANNOTATIONS = new Annotation[0];
private final ProgramClass targetClass;
@@ -214,6 +218,24 @@ implements AttributeVisitor
}
+ public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute)
+ {
+ // Create a new local variable table attribute.
+ MethodParametersAttribute newMethodParametersAttribute =
+ new MethodParametersAttribute(constantAdder.addConstant(clazz, methodParametersAttribute.u2attributeNameIndex),
+ methodParametersAttribute.u1parametersCount,
+ new ParameterInfo[methodParametersAttribute.u1parametersCount]);
+
+ // Add the local variables.
+ methodParametersAttribute.parametersAccept(clazz,
+ method,
+ new ParameterInfoAdder(targetClass, newMethodParametersAttribute));
+
+ // Add it to the target.
+ attributesEditor.addAttribute(newMethodParametersAttribute);
+ }
+
+
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
// Create a new exceptions attribute.
@@ -399,11 +421,16 @@ implements AttributeVisitor
public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
{
// Create a new annotations attribute.
+ Annotation[][] parameterAnnotations =
+ new Annotation[runtimeVisibleParameterAnnotationsAttribute.u1parametersCount][];
+
+ Arrays.fill(parameterAnnotations, EMPTY_ANNOTATIONS);
+
RuntimeVisibleParameterAnnotationsAttribute newParameterAnnotationsAttribute =
new RuntimeVisibleParameterAnnotationsAttribute(constantAdder.addConstant(clazz, runtimeVisibleParameterAnnotationsAttribute.u2attributeNameIndex),
0,
- new int[runtimeVisibleParameterAnnotationsAttribute.u2parametersCount],
- new Annotation[runtimeVisibleParameterAnnotationsAttribute.u2parametersCount][]);
+ new int[runtimeVisibleParameterAnnotationsAttribute.u1parametersCount],
+ parameterAnnotations);
// Add the annotations.
runtimeVisibleParameterAnnotationsAttribute.annotationsAccept(clazz,
@@ -419,11 +446,16 @@ implements AttributeVisitor
public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
{
// Create a new annotations attribute.
+ Annotation[][] parameterAnnotations =
+ new Annotation[runtimeInvisibleParameterAnnotationsAttribute.u1parametersCount][];
+
+ Arrays.fill(parameterAnnotations, EMPTY_ANNOTATIONS);
+
RuntimeInvisibleParameterAnnotationsAttribute newParameterAnnotationsAttribute =
new RuntimeInvisibleParameterAnnotationsAttribute(constantAdder.addConstant(clazz, runtimeInvisibleParameterAnnotationsAttribute.u2attributeNameIndex),
0,
- new int[runtimeInvisibleParameterAnnotationsAttribute.u2parametersCount],
- new Annotation[runtimeInvisibleParameterAnnotationsAttribute.u2parametersCount][]);
+ new int[runtimeInvisibleParameterAnnotationsAttribute.u1parametersCount],
+ parameterAnnotations);
// Add the annotations.
runtimeInvisibleParameterAnnotationsAttribute.annotationsAccept(clazz,
diff --git a/src/proguard/classfile/editor/AttributeSorter.java b/src/proguard/classfile/editor/AttributeSorter.java
index 23fe027..8f1f414 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 f50b8f1..ce38a6b 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,27 @@ public class AttributesEditor
/**
+ * Finds the specified attribute in the target.
+ */
+ public Attribute findAttribute(String attributeName)
+ {
+ // What's the target?
+ return
+ targetAttribute != null ?
+ findAttribute(targetAttribute.u2attributesCount,
+ targetAttribute.attributes,
+ attributeName) :
+ targetMember != null ?
+ findAttribute(targetMember.u2attributesCount,
+ targetMember.attributes,
+ attributeName) :
+ findAttribute(targetClass.u2attributesCount,
+ targetClass.attributes,
+ attributeName);
+ }
+
+
+ /**
* Adds the given attribute to the target.
*/
public void addAttribute(Attribute attribute)
@@ -171,17 +192,17 @@ public class AttributesEditor
// Small utility methods.
/**
- * Tries put the given attribute in place of an existing attribute of the
- * same name, returning whether it was present.
+ * Tries to put the given attribute in place of an existing attribute of
+ * the same name, returning whether it was present.
*/
private boolean replaceAttribute(int attributesCount,
Attribute[] attributes,
Attribute attribute)
{
// Find the attribute with the same name.
- int index = findAttribute(attributesCount,
- attributes,
- attribute.getAttributeName(targetClass));
+ int index = findAttributeIndex(attributesCount,
+ attributes,
+ attribute.getAttributeName(targetClass));
if (index < 0)
{
return false;
@@ -228,9 +249,9 @@ public class AttributesEditor
String attributeName)
{
// Find the attribute.
- int index = findAttribute(attributesCount,
- attributes,
- attributeName);
+ int index = findAttributeIndex(attributesCount,
+ attributes,
+ attributeName);
if (index < 0)
{
return attributesCount;
@@ -252,13 +273,15 @@ public class AttributesEditor
* Finds the index of the attribute with the given name in the given
* array of attributes.
*/
- private int findAttribute(int attributesCount,
- Attribute[] attributes,
- String attributeName)
+ private int findAttributeIndex(int attributesCount,
+ Attribute[] attributes,
+ String attributeName)
{
for (int index = 0; index < attributesCount; index++)
{
- if (attributes[index].getAttributeName(targetClass).equals(attributeName))
+ Attribute attribute = attributes[index];
+
+ if (attribute.getAttributeName(targetClass).equals(attributeName))
{
return index;
}
@@ -266,4 +289,26 @@ public class AttributesEditor
return -1;
}
+
+
+ /**
+ * Finds the attribute with the given name in the given
+ * array of attributes.
+ */
+ private Attribute findAttribute(int attributesCount,
+ Attribute[] attributes,
+ String attributeName)
+ {
+ for (int index = 0; index < attributesCount; index++)
+ {
+ Attribute attribute = attributes[index];
+
+ if (attribute.getAttributeName(targetClass).equals(attributeName))
+ {
+ return attribute;
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/proguard/classfile/editor/BootstrapMethodInfoAdder.java b/src/proguard/classfile/editor/BootstrapMethodInfoAdder.java
new file mode 100644
index 0000000..260a561
--- /dev/null
+++ b/src/proguard/classfile/editor/BootstrapMethodInfoAdder.java
@@ -0,0 +1,86 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is 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.BootstrapMethodInfoVisitor;
+
+/**
+ * This BootstrapMethodInfoVisitor adds all bootstrap methods that it visits to
+ * the given target bootstrap methods attribute.
+ */
+public class BootstrapMethodInfoAdder
+implements BootstrapMethodInfoVisitor
+{
+ private final ConstantAdder constantAdder;
+ private final BootstrapMethodsAttributeEditor bootstrapMethodsAttributeEditor;
+
+ private int bootstrapMethodIndex;
+
+
+ /**
+ * Creates a new BootstrapMethodInfoAdder that will copy bootstrap methods
+ * into the given bootstrap methods attribute.
+ */
+ public BootstrapMethodInfoAdder(ProgramClass targetClass,
+ BootstrapMethodsAttribute targetBootstrapMethodsAttribute)
+ {
+ this.constantAdder = new ConstantAdder(targetClass);
+ this.bootstrapMethodsAttributeEditor = new BootstrapMethodsAttributeEditor(targetBootstrapMethodsAttribute);
+ }
+
+
+ /**
+ * Returns the index of the most recently added bootstrap method.
+ */
+ public int getBootstrapMethodIndex()
+ {
+ return bootstrapMethodIndex;
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ // Copy the method arguments.
+ int methodArgumentCount = bootstrapMethodInfo.u2methodArgumentCount;
+ int[] methodArguments = bootstrapMethodInfo.u2methodArguments;
+ int[] newMethodArguments = new int[methodArgumentCount];
+
+ for (int index = 0; index < methodArgumentCount; index++)
+ {
+ newMethodArguments[index] =
+ constantAdder.addConstant(clazz, methodArguments[index]);
+ }
+
+ // Create a new bootstrap method.
+ BootstrapMethodInfo newBootstrapMethodInfo =
+ new BootstrapMethodInfo(constantAdder.addConstant(clazz, bootstrapMethodInfo.u2methodHandleIndex),
+ methodArgumentCount,
+ newMethodArguments);
+
+ // Add it to the target.
+ bootstrapMethodIndex =
+ bootstrapMethodsAttributeEditor.addBootstrapMethodInfo(newBootstrapMethodInfo);
+ }
+} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/BootstrapMethodRemapper.java b/src/proguard/classfile/editor/BootstrapMethodRemapper.java
new file mode 100644
index 0000000..76d2766
--- /dev/null
+++ b/src/proguard/classfile/editor/BootstrapMethodRemapper.java
@@ -0,0 +1,88 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is 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.*;
+
+/**
+ * This ConstantVisitor remaps all possible indices of bootstrap methods
+ * of the constants that it visits, based on a given index map.
+ *
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodRemapper
+extends SimplifiedVisitor
+implements ConstantVisitor
+{
+ private int[] constantIndexMap;
+
+
+ /**
+ * Sets the given mapping of old constant pool entry indexes to their new
+ * indexes.
+ */
+ public void setConstantIndexMap(int[] constantIndexMap)
+ {
+ this.constantIndexMap = constantIndexMap;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ invokeDynamicConstant.u2bootstrapMethodAttributeIndex =
+ remapConstantIndex(invokeDynamicConstant.u2bootstrapMethodAttributeIndex);
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Returns the new bootstrap method index of the entry at the
+ * given index.
+ */
+ private int remapConstantIndex(int constantIndex)
+ {
+ int remappedConstantIndex = constantIndexMap[constantIndex];
+ if (remappedConstantIndex < 0)
+ {
+ throw new IllegalArgumentException("Can't remap constant index ["+constantIndex+"]");
+ }
+
+ return remappedConstantIndex;
+ }
+}
diff --git a/src/proguard/classfile/editor/BootstrapMethodsAttributeAdder.java b/src/proguard/classfile/editor/BootstrapMethodsAttributeAdder.java
new file mode 100644
index 0000000..1488b9b
--- /dev/null
+++ b/src/proguard/classfile/editor/BootstrapMethodsAttributeAdder.java
@@ -0,0 +1,91 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is 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.BootstrapMethodInfoVisitor;
+
+/**
+ * This BootstrapMethodInfoVisitor adds all bootstrap methods that it visits to
+ * the given target class, creating a bootstrap methods attribute if necessary.
+ */
+public class BootstrapMethodsAttributeAdder
+implements BootstrapMethodInfoVisitor
+{
+ private final ProgramClass targetClass;
+ private final ConstantPoolEditor constantPoolEditor;
+ private BootstrapMethodInfoAdder bootstrapMethodInfoAdder;
+
+
+ /**
+ * Creates a new BootstrapMethodsAttributeAdder that will copy bootstrap
+ * methods into the given target class/
+ */
+ public BootstrapMethodsAttributeAdder(ProgramClass targetClass)
+ {
+ this.targetClass = targetClass;
+ this.constantPoolEditor = new ConstantPoolEditor(targetClass);
+ }
+
+
+ /**
+ * Returns the index of the most recently added bootstrap method.
+ */
+ public int getBootstrapMethodIndex()
+ {
+ return bootstrapMethodInfoAdder.getBootstrapMethodIndex();
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ // Make sure we have a bootstrap methods attribute adder.
+ if (bootstrapMethodInfoAdder == null)
+ {
+ // Make sure we have a target bootstrap methods attribute.
+ AttributesEditor attributesEditor =
+ new AttributesEditor(targetClass, false);
+
+ BootstrapMethodsAttribute targetBootstrapMethodsAttribute =
+ (BootstrapMethodsAttribute)attributesEditor.findAttribute(ClassConstants.ATTR_BootstrapMethods);
+
+ if (targetBootstrapMethodsAttribute == null)
+ {
+ targetBootstrapMethodsAttribute =
+ new BootstrapMethodsAttribute(constantPoolEditor.addUtf8Constant(ClassConstants.ATTR_BootstrapMethods),
+ 0,
+ new BootstrapMethodInfo[0]);
+
+ attributesEditor.addAttribute(targetBootstrapMethodsAttribute);
+ }
+
+ // Create a bootstrap method adder for it.
+ bootstrapMethodInfoAdder = new BootstrapMethodInfoAdder(targetClass,
+ targetBootstrapMethodsAttribute);
+ }
+
+ // Delegate to the bootstrap method adder.
+ bootstrapMethodInfoAdder.visitBootstrapMethodInfo(clazz, bootstrapMethodInfo);
+ }
+} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/BootstrapMethodsAttributeEditor.java b/src/proguard/classfile/editor/BootstrapMethodsAttributeEditor.java
new file mode 100644
index 0000000..d00d47a
--- /dev/null
+++ b/src/proguard/classfile/editor/BootstrapMethodsAttributeEditor.java
@@ -0,0 +1,60 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is 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.attribute.*;
+import proguard.util.ArrayUtil;
+
+/**
+ * This class can add bootstrap methods to a given bootstrap methods attribute.
+ * Bootstrap methods to be added must have been filled out beforehand.
+ *
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodsAttributeEditor
+{
+ private BootstrapMethodsAttribute targetBootstrapMethodsAttribute;
+
+
+ /**
+ * Creates a new BootstrapMethodsAttributeEditor that will edit bootstrap
+ * methods in the given bootstrap methods attribute.
+ */
+ public BootstrapMethodsAttributeEditor(BootstrapMethodsAttribute targetBootstrapMethodsAttribute)
+ {
+ this.targetBootstrapMethodsAttribute = targetBootstrapMethodsAttribute;
+ }
+
+
+ /**
+ * Adds a given bootstrap method to the bootstrap methods attribute.
+ * @return the index of the bootstrap method.
+ */
+ public int addBootstrapMethodInfo(BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ targetBootstrapMethodsAttribute.bootstrapMethods =
+ (BootstrapMethodInfo[])ArrayUtil.add(targetBootstrapMethodsAttribute.bootstrapMethods,
+ targetBootstrapMethodsAttribute.u2bootstrapMethodsCount,
+ bootstrapMethodInfo);
+
+ return targetBootstrapMethodsAttribute.u2bootstrapMethodsCount++;
+ }
+} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/BridgeMethodFixer.java b/src/proguard/classfile/editor/BridgeMethodFixer.java
index 2f1120d..5699b8e 100644
--- a/src/proguard/classfile/editor/BridgeMethodFixer.java
+++ b/src/proguard/classfile/editor/BridgeMethodFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,12 +23,12 @@ 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.RefConstant;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.*;
-import proguard.classfile.visitor.*;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.MemberVisitor;
/**
* This MemberVisitor fixes all inappropriate bridge access flags of the
@@ -57,7 +57,7 @@ implements MemberVisitor,
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- if ((programMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_BRIDGE) != 0)
+ if ((programMethod.getAccessFlags() & ClassConstants.ACC_BRIDGE) != 0)
{
programMethod.attributesAccept(programClass, this);
}
@@ -101,7 +101,7 @@ implements MemberVisitor,
}
// Clear the bridge flag.
- ((ProgramMethod)method).u2accessFlags &= ~ClassConstants.INTERNAL_ACC_BRIDGE;
+ ((ProgramMethod)method).u2accessFlags &= ~ClassConstants.ACC_BRIDGE;
}
break;
}
diff --git a/src/proguard/classfile/editor/ClassEditor.java b/src/proguard/classfile/editor/ClassEditor.java
index 7703c9d..4d9055b 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 9875a29..c514471 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 ed0b5b1..7ebe12e 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 1f8b396..0570084 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -173,8 +173,11 @@ implements ClassVisitor,
String newDescriptor = newDescriptor(descriptor,
libraryMethod.referencedClasses);
- // Update the descriptor.
- libraryMethod.descriptor = newDescriptor;
+ if (!descriptor.equals(newDescriptor))
+ {
+ // Update the descriptor.
+ libraryMethod.descriptor = newDescriptor;
+ }
}
@@ -200,7 +203,12 @@ implements ClassVisitor,
// Update the String entry if required.
if (!newInternalClassName.equals(internalClassName))
{
- String newExternalClassName = ClassUtil.externalClassName(newInternalClassName);
+ // Only convert to an external class name if the original was
+ // an external class name too.
+ String newExternalClassName =
+ externalClassName.indexOf(JavaConstants.PACKAGE_SEPARATOR) >= 0 ?
+ ClassUtil.externalClassName(newInternalClassName) :
+ newInternalClassName;
// Refer to a new Utf8 entry.
stringConstant.u2stringIndex =
@@ -210,6 +218,24 @@ implements ClassVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Has the descriptor changed?
+ String descriptor = invokeDynamicConstant.getType(clazz);
+ String newDescriptor = newDescriptor(descriptor,
+ invokeDynamicConstant.referencedClasses);
+
+ if (!descriptor.equals(newDescriptor))
+ {
+ String name = invokeDynamicConstant.getName(clazz);
+
+ // Refer to a new NameAndType entry.
+ invokeDynamicConstant.u2nameAndTypeIndex =
+ new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(name, newDescriptor);
+ }
+ }
+
+
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Do we know the referenced class?
@@ -228,6 +254,23 @@ implements ClassVisitor,
}
}
+
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ // Has the descriptor changed?
+ String descriptor = methodTypeConstant.getType(clazz);
+ String newDescriptor = newDescriptor(descriptor,
+ methodTypeConstant.referencedClasses);
+
+ if (!descriptor.equals(newDescriptor))
+ {
+ // Update the descriptor.
+ methodTypeConstant.u2descriptorIndex =
+ new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newDescriptor);
+ }
+ }
+
+
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
@@ -263,13 +306,14 @@ implements ClassVisitor,
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
- // Compute the new signature.
- String signature = clazz.getString(signatureAttribute.u2signatureIndex);
+ // Has the signature changed?
+ String signature = signatureAttribute.getSignature(clazz);
String newSignature = newDescriptor(signature,
signatureAttribute.referencedClasses);
if (!signature.equals(newSignature))
{
+ // Update the signature.
signatureAttribute.u2signatureIndex =
new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newSignature);
}
@@ -308,7 +352,7 @@ implements ClassVisitor,
innerNameIndex != 0)
{
String newInnerName = clazz.getClassName(innerClassIndex);
- int index = newInnerName.lastIndexOf(ClassConstants.INTERNAL_INNER_CLASS_SEPARATOR);
+ int index = newInnerName.lastIndexOf(ClassConstants.INNER_CLASS_SEPARATOR);
if (index >= 0)
{
innerClassesInfo.u2innerNameIndex =
@@ -323,7 +367,7 @@ implements ClassVisitor,
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
// Has the descriptor changed?
- String descriptor = clazz.getString(localVariableInfo.u2descriptorIndex);
+ String descriptor = localVariableInfo.getDescriptor(clazz);
String newDescriptor = newDescriptor(descriptor,
localVariableInfo.referencedClass);
@@ -340,12 +384,13 @@ implements ClassVisitor,
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
// Has the signature changed?
- String signature = clazz.getString(localVariableTypeInfo.u2signatureIndex);
+ String signature = localVariableTypeInfo.getSignature(clazz);
String newSignature = newDescriptor(signature,
localVariableTypeInfo.referencedClasses);
if (!signature.equals(newSignature))
{
+ // Update the signature.
localVariableTypeInfo.u2signatureIndex =
new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newSignature);
}
@@ -355,14 +400,14 @@ implements ClassVisitor,
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
- // Compute the new type name.
- String typeName = clazz.getString(annotation.u2typeIndex);
+ // Has the type changed?
+ String typeName = annotation.getType(clazz);
String newTypeName = newDescriptor(typeName,
annotation.referencedClasses);
if (!typeName.equals(newTypeName))
{
- // Refer to a new Utf8 entry.
+ // Update the type.
annotation.u2typeIndex =
new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newTypeName);
}
@@ -381,14 +426,14 @@ implements ClassVisitor,
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
{
- // Compute the new type name.
- String typeName = clazz.getString(enumConstantElementValue.u2typeNameIndex);
+ // Has the type name chamged?
+ String typeName = enumConstantElementValue.getTypeName(clazz);
String newTypeName = newDescriptor(typeName,
enumConstantElementValue.referencedClasses);
if (!typeName.equals(newTypeName))
{
- // Refer to a new Utf8 entry.
+ // Update the type name.
enumConstantElementValue.u2typeNameIndex =
new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newTypeName);
}
@@ -397,14 +442,14 @@ implements ClassVisitor,
public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
{
- // Compute the new class name.
- String className = clazz.getString(classElementValue.u2classInfoIndex);
+ // Has the class info changed?
+ String className = classElementValue.getClassName(clazz);
String newClassName = newDescriptor(className,
classElementValue.referencedClasses);
if (!className.equals(newClassName))
{
- // Refer to a new Utf8 entry.
+ // Update the class info.
classElementValue.u2classInfoIndex =
new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newClassName);
}
@@ -492,7 +537,7 @@ implements ClassVisitor,
if (isInnerClassName)
{
newClassName =
- newClassName.substring(newClassName.lastIndexOf(ClassConstants.INTERNAL_INNER_CLASS_SEPARATOR)+1);
+ newClassName.substring(newClassName.lastIndexOf(ClassConstants.INNER_CLASS_SEPARATOR)+1);
}
newDescriptorBuffer.append(newClassName);
@@ -508,8 +553,8 @@ implements ClassVisitor,
*/
private String newUniqueMemberName(String name, String descriptor)
{
- return name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ?
- ClassConstants.INTERNAL_METHOD_NAME_INIT :
+ return name.equals(ClassConstants.METHOD_NAME_INIT) ?
+ ClassConstants.METHOD_NAME_INIT :
name + ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode()));
}
@@ -532,13 +577,13 @@ implements ClassVisitor,
String newClassName = referencedClass.getName();
// Is it an array type?
- if (className.charAt(0) == ClassConstants.INTERNAL_TYPE_ARRAY)
+ if (className.charAt(0) == ClassConstants.TYPE_ARRAY)
{
// Add the array prefixes and suffix "[L...;".
newClassName =
- className.substring(0, className.indexOf(ClassConstants.INTERNAL_TYPE_CLASS_START)+1) +
+ className.substring(0, className.indexOf(ClassConstants.TYPE_CLASS_START)+1) +
newClassName +
- ClassConstants.INTERNAL_TYPE_CLASS_END;
+ ClassConstants.TYPE_CLASS_END;
}
return newClassName;
diff --git a/src/proguard/classfile/editor/CodeAttributeComposer.java b/src/proguard/classfile/editor/CodeAttributeComposer.java
index c59b712..eaa8015 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,7 @@ implements AttributeVisitor,
private static final int INVALID = -1;
+ private final boolean allowExternalBranchTargets;
private final boolean allowExternalExceptionHandlers;
private final boolean shrinkInstructions;
@@ -85,17 +86,21 @@ implements AttributeVisitor,
/**
- * Creates a new CodeAttributeComposer that doesn't allow external exception
- * handlers and that automatically shrinks instructions.
+ * Creates a new CodeAttributeComposer that doesn't allow external branch
+ * targets or exception handlers and that automatically shrinks
+ * instructions.
*/
public CodeAttributeComposer()
{
- this(false, true);
+ this(false, false, true);
}
/**
* Creates a new CodeAttributeComposer.
+ * @param allowExternalBranchTargets specifies whether branch targets
+ * can lie outside the code fragment
+ * of the branch instructions.
* @param allowExternalExceptionHandlers specifies whether exception
* handlers can lie outside the code
* fragment in which exceptions are
@@ -104,9 +109,11 @@ implements AttributeVisitor,
* should automatically be shrunk
* before being written.
*/
- public CodeAttributeComposer(boolean allowExternalExceptionHandlers,
+ public CodeAttributeComposer(boolean allowExternalBranchTargets,
+ boolean allowExternalExceptionHandlers,
boolean shrinkInstructions)
{
+ this.allowExternalBranchTargets = allowExternalBranchTargets;
this.allowExternalExceptionHandlers = allowExternalExceptionHandlers;
this.shrinkInstructions = shrinkInstructions;
}
@@ -122,7 +129,9 @@ implements AttributeVisitor,
exceptionTableLength = 0;
level = -1;
- instructionWriter.reset(ClassConstants.TYPICAL_CODE_LENGTH);
+ // Make sure the instruction writer has at least the same buffer size
+ // as the local arrays.
+ instructionWriter.reset(code.length);
}
@@ -362,9 +371,6 @@ implements AttributeVisitor,
instructionOffset,
instructionWriter);
//instruction.write(code, codeLength);
-
- // Don't remap this instruction again.
- oldInstructionOffsets[instructionOffset] = -1;
}
// Continue remapping at the next instruction offset.
@@ -532,21 +538,48 @@ implements AttributeVisitor,
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
{
- // Adjust the branch offset.
- branchInstruction.branchOffset = newBranchOffset(offset,
- branchInstruction.branchOffset);
+ try
+ {
+ // Adjust the branch offset.
+ branchInstruction.branchOffset =
+ newBranchOffset(offset, branchInstruction.branchOffset);
+
+ // Don't remap this instruction again.
+ oldInstructionOffsets[offset] = -1;
+ }
+ catch (IllegalArgumentException e)
+ {
+ if (level == 0 || !allowExternalBranchTargets)
+ {
+ throw e;
+ }
+ }
}
public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction)
{
- // Adjust the default jump offset.
- switchInstruction.defaultOffset = newBranchOffset(offset,
- switchInstruction.defaultOffset);
+ try
+ {
+ // TODO: We're assuming we can adjust no offsets or all offsets at once.
+ // Adjust the default jump offset.
+ switchInstruction.defaultOffset =
+ newBranchOffset(offset, switchInstruction.defaultOffset);
+
+ // Adjust the jump offsets.
+ updateJumpOffsets(offset,
+ switchInstruction.jumpOffsets);
- // Adjust the jump offsets.
- updateJumpOffsets(offset,
- switchInstruction.jumpOffsets);
+ // Don't remap this instruction again.
+ oldInstructionOffsets[offset] = -1;
+ }
+ catch (IllegalArgumentException e)
+ {
+ if (level == 0 || !allowExternalBranchTargets)
+ {
+ throw e;
+ }
+ }
}
@@ -719,8 +752,10 @@ implements AttributeVisitor,
int oldInstructionOffset = oldInstructionOffsets[newInstructionOffset];
+ // For ordinary branch instructions, we can compute the offset
+ // relative to the instruction itself.
return newInstructionOffset(oldInstructionOffset + oldBranchOffset) -
- newInstructionOffset(oldInstructionOffset);
+ newInstructionOffset;
}
diff --git a/src/proguard/classfile/editor/CodeAttributeEditor.java b/src/proguard/classfile/editor/CodeAttributeEditor.java
index 337e0d4..41b7471 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,10 @@ package proguard.classfile.editor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.annotation.target.*;
+import proguard.classfile.attribute.annotation.target.visitor.*;
+import proguard.classfile.attribute.annotation.visitor.TypeAnnotationVisitor;
import proguard.classfile.attribute.preverification.*;
import proguard.classfile.attribute.preverification.visitor.*;
import proguard.classfile.attribute.visitor.*;
@@ -47,7 +51,10 @@ implements AttributeVisitor,
VerificationTypeVisitor,
LineNumberInfoVisitor,
LocalVariableInfoVisitor,
- LocalVariableTypeInfoVisitor
+ LocalVariableTypeInfoVisitor,
+ TypeAnnotationVisitor,
+ TargetInfoVisitor,
+ LocalVariableTargetElementVisitor
{
//*
private static final boolean DEBUG = false;
@@ -179,7 +186,6 @@ implements AttributeVisitor,
modified = true;
simple = false;
-
}
@@ -206,7 +212,6 @@ implements AttributeVisitor,
modified = true;
simple = false;
-
}
@@ -512,6 +517,12 @@ implements AttributeVisitor,
}
+ public void visitAnyTypeAnnotationsAttribute(Clazz clazz, TypeAnnotationsAttribute typeAnnotationsAttribute)
+ {
+ typeAnnotationsAttribute.typeAnnotationsAccept(clazz, this);
+ }
+
+
/**
* Checks if it is possible to modifies the given code without having to
* update any offsets.
@@ -840,9 +851,9 @@ implements AttributeVisitor,
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
{
- // Adjust the branch offset.
- branchInstruction.branchOffset = newBranchOffset(offset,
- branchInstruction.branchOffset);
+ // Update the branch offset, relative to the precise new offset.
+ branchInstruction.branchOffset =
+ newBranchOffset(offset, branchInstruction.branchOffset, newOffset);
// Write out the instruction.
instructionWriter.visitBranchInstruction(clazz,
@@ -857,13 +868,14 @@ implements AttributeVisitor,
public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)
{
- // Adjust the default jump offset.
- tableSwitchInstruction.defaultOffset = newBranchOffset(offset,
- tableSwitchInstruction.defaultOffset);
+ // Update the default jump offset, relative to the precise new offset.
+ tableSwitchInstruction.defaultOffset =
+ newBranchOffset(offset, tableSwitchInstruction.defaultOffset, newOffset);
- // Adjust the jump offsets.
+ // Update the jump offsets, relative to the precise new offset.
newJumpOffsets(offset,
- tableSwitchInstruction.jumpOffsets);
+ tableSwitchInstruction.jumpOffsets,
+ newOffset);
// Write out the instruction.
instructionWriter.visitTableSwitchInstruction(clazz,
@@ -878,13 +890,14 @@ implements AttributeVisitor,
public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
{
- // Adjust the default jump offset.
- lookUpSwitchInstruction.defaultOffset = newBranchOffset(offset,
- lookUpSwitchInstruction.defaultOffset);
+ // Update the default jump offset, relative to the precise new offset.
+ lookUpSwitchInstruction.defaultOffset =
+ newBranchOffset(offset, lookUpSwitchInstruction.defaultOffset, newOffset);
- // Adjust the jump offsets.
+ // Update the jump offsets, relative to the precise new offset.
newJumpOffsets(offset,
- lookUpSwitchInstruction.jumpOffsets);
+ lookUpSwitchInstruction.jumpOffsets,
+ newOffset);
// Write out the instruction.
instructionWriter.visitLookUpSwitchInstruction(clazz,
@@ -901,8 +914,8 @@ implements AttributeVisitor,
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
- // Update the code offsets. Note that the instruction offset map also has
- // an entry for the first offset after the code, for u2endPC.
+ // Update the code offsets. Note that the instruction offset map also
+ // has an entry for the first offset after the code, for u2endPC.
exceptionInfo.u2startPC = newInstructionOffset(exceptionInfo.u2startPC);
exceptionInfo.u2endPC = newInstructionOffset(exceptionInfo.u2endPC);
exceptionInfo.u2handlerPC = newInstructionOffset(exceptionInfo.u2handlerPC);
@@ -988,12 +1001,9 @@ implements AttributeVisitor,
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
// Update the code offset and length.
- int newStartPC = newInstructionOffset(localVariableInfo.u2startPC);
- int newEndPC = newInstructionOffset(localVariableInfo.u2startPC +
- localVariableInfo.u2length);
-
- localVariableInfo.u2length = newEndPC - newStartPC;
- localVariableInfo.u2startPC = newStartPC;
+ // Be careful to update the length first.
+ localVariableInfo.u2length = newBranchOffset(localVariableInfo.u2startPC, localVariableInfo.u2length);
+ localVariableInfo.u2startPC = newInstructionOffset(localVariableInfo.u2startPC);
}
@@ -1002,41 +1012,99 @@ implements AttributeVisitor,
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
// Update the code offset and length.
- int newStartPC = newInstructionOffset(localVariableTypeInfo.u2startPC);
- int newEndPC = newInstructionOffset(localVariableTypeInfo.u2startPC +
- localVariableTypeInfo.u2length);
+ // Be careful to update the length first.
+ localVariableTypeInfo.u2length = newBranchOffset(localVariableTypeInfo.u2startPC, localVariableTypeInfo.u2length);
+ localVariableTypeInfo.u2startPC = newInstructionOffset(localVariableTypeInfo.u2startPC);
+ }
+
+
+ // Implementations for TypeAnnotationVisitor.
+
+ public void visitTypeAnnotation(Clazz clazz, TypeAnnotation typeAnnotation)
+ {
+ // Update all local variable targets.
+ typeAnnotation.targetInfoAccept(clazz, this);
+ }
+
+
+ // Implementations for TargetInfoVisitor.
+
+ public void visitAnyTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, TargetInfo targetInfo) {}
+
- localVariableTypeInfo.u2length = newEndPC - newStartPC;
- localVariableTypeInfo.u2startPC = newStartPC;
+ public void visitLocalVariableTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo)
+ {
+ // Update the offsets of the variables.
+ localVariableTargetInfo.targetElementsAccept(clazz, method, codeAttribute, typeAnnotation, this);
+ }
+
+
+ public void visitOffsetTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, OffsetTargetInfo offsetTargetInfo)
+ {
+ // Update the offset.
+ offsetTargetInfo.u2offset = newInstructionOffset(offsetTargetInfo.u2offset);
+ }
+
+
+ // Implementations for LocalVariableTargetElementVisitor.
+
+ public void visitLocalVariableTargetElement(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo, LocalVariableTargetElement localVariableTargetElement)
+ {
+ // Update the variable start offset and length.
+ // Be careful to update the length first.
+ localVariableTargetElement.u2length = newBranchOffset(localVariableTargetElement.u2startPC, localVariableTargetElement.u2length);
+ localVariableTargetElement.u2startPC = newInstructionOffset(localVariableTargetElement.u2startPC);
}
// Small utility methods.
/**
- * Adjusts the given jump offsets for the instruction at the given offset.
+ * Updates the given jump offsets for the instruction at the given offset,
+ * relative to the given new offset.
*/
- private void newJumpOffsets(int oldInstructionOffset, int[] oldJumpOffsets)
+ private void newJumpOffsets(int oldInstructionOffset,
+ int[] oldJumpOffsets,
+ int newInstructionOffset)
{
for (int index = 0; index < oldJumpOffsets.length; index++)
{
- oldJumpOffsets[index] = newBranchOffset(oldInstructionOffset, oldJumpOffsets[index]);
+ oldJumpOffsets[index] = newBranchOffset(oldInstructionOffset,
+ oldJumpOffsets[index],
+ newInstructionOffset);
}
}
/**
* Computes the new branch offset for the instruction at the given offset
- * with the given branch offset.
+ * with the given branch offset, relative to the new instruction (block)
+ * offset.
+ */
+ private int newBranchOffset(int oldInstructionOffset,
+ int oldBranchOffset)
+ {
+ return newInstructionOffset(oldInstructionOffset + oldBranchOffset) -
+ newInstructionOffset(oldInstructionOffset);
+ }
+
+
+ /**
+ * Computes the new branch offset for the instruction at the given offset
+ * with the given branch offset, relative to the given new offset.
*/
- private int newBranchOffset(int oldInstructionOffset, int oldBranchOffset)
+ private int newBranchOffset(int oldInstructionOffset,
+ int oldBranchOffset,
+ int newInstructionOffset)
{
- return newInstructionOffset(oldInstructionOffset + oldBranchOffset) - newOffset;
+ return newInstructionOffset(oldInstructionOffset + oldBranchOffset) -
+ newInstructionOffset;
}
/**
- * Computes the new instruction offset for the instruction at the given offset.
+ * Computes the new instruction offset for the instruction at the given
+ * offset.
*/
private int newInstructionOffset(int oldInstructionOffset)
{
diff --git a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java
index 8f767c7..88e700b 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 476edd6..cd2a810 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -148,7 +148,7 @@ implements Comparable, ConstantVisitor
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
- {
+ {
result = Double.compare(doubleConstant.getValue(),
((DoubleConstant)otherConstant).getValue());
}
@@ -172,11 +172,10 @@ implements Comparable, ConstantVisitor
result = index < otherIndex ? -1 :
index > otherIndex ? 1 :
- (invokeDynamicConstant.getName(clazz) + ' ' +
- invokeDynamicConstant.getType(clazz))
- .compareTo
- (otherInvokeDynamicConstant.getName(clazz) + ' ' +
- otherInvokeDynamicConstant.getType(clazz));
+ compare(invokeDynamicConstant.getName(clazz),
+ invokeDynamicConstant.getType(clazz),
+ otherInvokeDynamicConstant.getName(clazz),
+ otherInvokeDynamicConstant.getType(clazz));
}
public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
@@ -184,27 +183,27 @@ implements Comparable, ConstantVisitor
MethodHandleConstant otherMethodHandleConstant = (MethodHandleConstant)otherConstant;
int kind = methodHandleConstant.getReferenceKind();
- int otherKind = methodHandleConstant.getReferenceKind();
+ int otherKind = otherMethodHandleConstant.getReferenceKind();
result = kind < otherKind ? -1 :
kind > otherKind ? 1 :
- (methodHandleConstant.getName(clazz) + ' ' +
- methodHandleConstant.getType(clazz))
- .compareTo
- (otherMethodHandleConstant.getName(clazz) + ' ' +
- otherMethodHandleConstant.getType(clazz));
+ compare(methodHandleConstant.getClassName(clazz),
+ methodHandleConstant.getName(clazz),
+ methodHandleConstant.getType(clazz),
+ otherMethodHandleConstant.getClassName(clazz),
+ otherMethodHandleConstant.getName(clazz),
+ otherMethodHandleConstant.getType(clazz));
}
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
RefConstant otherRefConstant = (RefConstant)otherConstant;
- result = (refConstant.getClassName(clazz) + ' ' +
- refConstant.getName(clazz) + ' ' +
- refConstant.getType(clazz))
- .compareTo
- (otherRefConstant.getClassName(clazz) + ' ' +
- otherRefConstant.getName(clazz) + ' ' +
- otherRefConstant.getType(clazz));
+ result = compare(refConstant.getClassName(clazz),
+ refConstant.getName(clazz),
+ refConstant.getType(clazz),
+ otherRefConstant.getClassName(clazz),
+ otherRefConstant.getName(clazz),
+ otherRefConstant.getType(clazz));
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
@@ -223,11 +222,10 @@ implements Comparable, ConstantVisitor
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
NameAndTypeConstant otherNameAndTypeConstant = (NameAndTypeConstant)otherConstant;
- result = (nameAndTypeConstant.getName(clazz) + ' ' +
- nameAndTypeConstant.getType(clazz))
- .compareTo
- (otherNameAndTypeConstant.getName(clazz) + ' ' +
- otherNameAndTypeConstant.getType(clazz));
+ result = compare(nameAndTypeConstant.getName(clazz),
+ nameAndTypeConstant.getType(clazz),
+ otherNameAndTypeConstant.getName(clazz),
+ otherNameAndTypeConstant.getType(clazz));
}
@@ -246,4 +244,33 @@ implements Comparable, ConstantVisitor
{
return this.getClass().hashCode();
}
+
+
+ // Small utility methods.
+
+ /**
+ * Compares the given two pairs of strings.
+ */
+ private int compare(String string1a, String string1b,
+ String string2a, String string2b)
+ {
+ int comparison;
+ return
+ (comparison = string1a.compareTo(string2a)) != 0 ? comparison :
+ string1b.compareTo(string2b);
+ }
+
+
+ /**
+ * Compares the given two triplets of strings.
+ */
+ private int compare(String string1a, String string1b, String string1c,
+ String string2a, String string2b, String string2c)
+ {
+ int comparison;
+ return
+ (comparison = string1a.compareTo(string2a)) != 0 ? comparison :
+ (comparison = string1b.compareTo(string2b)) != 0 ? comparison :
+ string1c.compareTo(string2c);
+ }
}
diff --git a/src/proguard/classfile/editor/ConstantAdder.java b/src/proguard/classfile/editor/ConstantAdder.java
index 9d20199..9f326ad 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,20 +21,24 @@
package proguard.classfile.editor;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
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
* of a given target class.
*
+ * Bootstrap methods attributes are automatically updated for invokedynamic
+ * constants.
+ *
* @author Eric Lafortune
*/
public class ConstantAdder
implements ConstantVisitor
{
- private final ConstantPoolEditor constantPoolEditor;
+ private final ConstantPoolEditor constantPoolEditor;
+ private final BootstrapMethodsAttributeAdder bootstrapMethodsAttributeAdder;
private int constantIndex;
@@ -45,7 +49,8 @@ implements ConstantVisitor
*/
public ConstantAdder(ProgramClass targetClass)
{
- constantPoolEditor = new ConstantPoolEditor(targetClass);
+ constantPoolEditor = new ConstantPoolEditor(targetClass);
+ bootstrapMethodsAttributeAdder = new BootstrapMethodsAttributeAdder(targetClass);
}
@@ -131,7 +136,14 @@ implements ConstantVisitor
public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
{
- // First add the name and type constant.
+ // Find the bootstrap methods attribute.
+ AttributesEditor attributesEditor =
+ new AttributesEditor((ProgramClass)clazz, false);
+
+ BootstrapMethodsAttribute bootstrapMethodsAttribute =
+ (BootstrapMethodsAttribute)attributesEditor.findAttribute(ClassConstants.ATTR_BootstrapMethods);
+
+ // Add the name and type constant.
clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this);
// Copy the referenced classes.
@@ -145,9 +157,13 @@ implements ConstantVisitor
referencedClasses.length);
}
+ bootstrapMethodsAttribute.bootstrapMethodEntryAccept(clazz,
+ invokeDynamicConstant.getBootstrapMethodAttributeIndex(),
+ bootstrapMethodsAttributeAdder);
+
// Then add the actual invoke dynamic constant.
constantIndex =
- constantPoolEditor.addInvokeDynamicConstant(invokeDynamicConstant.getBootstrapMethodAttributeIndex(),
+ constantPoolEditor.addInvokeDynamicConstant(bootstrapMethodsAttributeAdder.getBootstrapMethodIndex(),
constantIndex,
referencedClassesCopy);
}
diff --git a/src/proguard/classfile/editor/ConstantPoolEditor.java b/src/proguard/classfile/editor/ConstantPoolEditor.java
index 7adbc44..23f34fe 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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/ConstantPoolRemapper.java b/src/proguard/classfile/editor/ConstantPoolRemapper.java
index eaf7653..e033c30 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -53,6 +53,7 @@ implements ClassVisitor,
InstructionVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
+ ParameterInfoVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
@@ -333,6 +334,16 @@ implements ClassVisitor,
}
+ public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute)
+ {
+ methodParametersAttribute.u2attributeNameIndex =
+ remapConstantIndex(methodParametersAttribute.u2attributeNameIndex);
+
+ // Remap the constant pool references of the parameter information.
+ methodParametersAttribute.parametersAccept(clazz, method, this);
+ }
+
+
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
exceptionsAttribute.u2attributeNameIndex =
@@ -552,6 +563,15 @@ implements ClassVisitor,
}
+ // Implementations for ParameterInfoVisitor.
+
+ public void visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo)
+ {
+ parameterInfo.u2nameIndex =
+ remapConstantIndex(parameterInfo.u2nameIndex);
+ }
+
+
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
@@ -569,7 +589,7 @@ implements ClassVisitor,
{
localVariableTypeInfo.u2nameIndex =
remapConstantIndex(localVariableTypeInfo.u2nameIndex);
- localVariableTypeInfo.u2signatureIndex =
+ localVariableTypeInfo.u2signatureIndex =
remapConstantIndex(localVariableTypeInfo.u2signatureIndex);
}
@@ -637,8 +657,6 @@ implements ClassVisitor,
}
- // Small utility methods.
-
/**
* Remaps all constant pool indices in the given array.
*/
@@ -650,6 +668,8 @@ implements ClassVisitor,
}
}
+ // Small utility methods.
+
/**
* Returns the new constant pool index of the entry at the
@@ -657,6 +677,12 @@ implements ClassVisitor,
*/
private int remapConstantIndex(int constantIndex)
{
- return constantIndexMap[constantIndex];
+ int remappedConstantIndex = constantIndexMap[constantIndex];
+ if (remappedConstantIndex < 0)
+ {
+ throw new IllegalArgumentException("Can't remap constant index ["+constantIndex+"]");
+ }
+
+ return remappedConstantIndex;
}
}
diff --git a/src/proguard/classfile/editor/ConstantPoolShrinker.java b/src/proguard/classfile/editor/ConstantPoolShrinker.java
index ee309a0..0172321 100644
--- a/src/proguard/classfile/editor/ConstantPoolShrinker.java
+++ b/src/proguard/classfile/editor/ConstantPoolShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,6 +52,7 @@ implements ClassVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
+ ParameterInfoVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
@@ -251,6 +252,15 @@ implements ClassVisitor,
}
+ public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute)
+ {
+ markConstant(clazz, methodParametersAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the parameter information.
+ methodParametersAttribute.parametersAccept(clazz, method, this);
+ }
+
+
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
markConstant(clazz, exceptionsAttribute.u2attributeNameIndex);
@@ -405,6 +415,14 @@ implements ClassVisitor,
}
+ // Implementations for ParameterInfoVisitor.
+
+ public void visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo)
+ {
+ markConstant(clazz, parameterInfo.u2nameIndex);
+ }
+
+
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
@@ -554,11 +572,10 @@ implements ClassVisitor,
// 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.
+ // Is the constant being used? Don't update the flag if this is the
+ // second half of a long entry.
if (constant != null)
{
isUsed = isUsed(constant);
@@ -566,8 +583,17 @@ implements ClassVisitor,
if (isUsed)
{
+ // Remember the new index.
+ constantIndexMap[index] = counter;
+
+ // Shift the constant pool entry.
constantPool[counter++] = constant;
}
+ else
+ {
+ // Remember an invalid index.
+ constantIndexMap[index] = -1;
+ }
}
// Clear the remaining constant pool elements.
diff --git a/src/proguard/classfile/editor/ConstantPoolSorter.java b/src/proguard/classfile/editor/ConstantPoolSorter.java
index b578624..742bed2 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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/ElementValueAdder.java b/src/proguard/classfile/editor/ElementValueAdder.java
index 9c8b3f9..5a99b01 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 57671e6..c4add27 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,7 +20,7 @@
*/
package proguard.classfile.editor;
-import proguard.classfile.*;
+import proguard.classfile.ProgramClass;
import proguard.classfile.attribute.annotation.*;
/**
diff --git a/src/proguard/classfile/editor/ExceptionAdder.java b/src/proguard/classfile/editor/ExceptionAdder.java
index 152a065..2ba0bb6 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 c1c20fa..4798f84 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 98bb79e..8dd2e3c 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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
index 5a5e8a5..fdfdce5 100644
--- a/src/proguard/classfile/editor/InnerClassesAccessFixer.java
+++ b/src/proguard/classfile/editor/InnerClassesAccessFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,12 +21,12 @@
package proguard.classfile.editor;
import proguard.classfile.*;
-import proguard.classfile.attribute.visitor.InnerClassesInfoVisitor;
import proguard.classfile.attribute.InnerClassesInfo;
+import proguard.classfile.attribute.visitor.InnerClassesInfoVisitor;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.*;
-import proguard.classfile.visitor.*;
+import proguard.classfile.visitor.ClassVisitor;
/**
* This InnerClassesInfoVisitor fixes the inner class access flags of the
diff --git a/src/proguard/classfile/editor/InstructionAdder.java b/src/proguard/classfile/editor/InstructionAdder.java
index 422a348..4a20e59 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,9 +21,9 @@
package proguard.classfile.editor;
import proguard.classfile.*;
-import proguard.classfile.attribute.*;
-import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
/**
diff --git a/src/proguard/classfile/editor/InstructionWriter.java b/src/proguard/classfile/editor/InstructionWriter.java
index c4a9b09..cafdd87 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 1ad67dc..a7113b4 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,9 +21,6 @@
package proguard.classfile.editor;
import proguard.classfile.*;
-import proguard.classfile.attribute.*;
-import proguard.classfile.attribute.annotation.*;
-import proguard.classfile.attribute.preverification.*;
import proguard.classfile.constant.ClassConstant;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
diff --git a/src/proguard/classfile/editor/InterfaceDeleter.java b/src/proguard/classfile/editor/InterfaceDeleter.java
new file mode 100644
index 0000000..6fd22b6
--- /dev/null
+++ b/src/proguard/classfile/editor/InterfaceDeleter.java
@@ -0,0 +1,190 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is 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.Utf8Constant;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+import java.util.Arrays;
+
+/**
+ * This ClassVisitor removes specified interfaces from the classes and class
+ * signatures that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class InterfaceDeleter
+extends SimplifiedVisitor
+implements ClassVisitor,
+ AttributeVisitor
+{
+ private static final boolean DEBUG = false;
+
+
+ private final boolean[] delete;
+
+
+ /**
+ * Creates a new InterfaceDeleter to remove the specified interfaces.
+ * @param delete an array that corresponds to the interfaces of a class
+ * and that specifies the ones to be removed.
+ */
+ public InterfaceDeleter(boolean[] delete)
+ {
+ this.delete = delete;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ int[] interfaces = programClass.u2interfaces;
+ int interfacesCount = programClass.u2interfacesCount;
+
+ if (DEBUG)
+ {
+ System.out.println("InterfaceDeleter: "+programClass.getName()+" ("+interfacesCount+" interfaces)");
+ }
+
+ // Copy the interfaces that aren't deleted.
+ int newInterfacesCount = 0;
+ for (int index = 0; index < interfacesCount; index++)
+ {
+ if (DEBUG)
+ {
+ System.out.println("InterfaceDeleter: "+(delete[index]?"- ":"+ ")+programClass.getInterfaceName(index));
+ }
+
+ if (!delete[index])
+ {
+ interfaces[newInterfacesCount++] = interfaces[index];
+ }
+ }
+
+ // Update the signature.
+ if (newInterfacesCount < interfacesCount)
+ {
+ programClass.u2interfacesCount = newInterfacesCount;
+
+ programClass.attributesAccept(this);
+ }
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
+ {
+ Clazz[] referencedClasses = signatureAttribute.referencedClasses;
+ if (referencedClasses != null)
+ {
+ // Process the generic definitions, superclass, and implemented
+ // interfaces.
+ InternalTypeEnumeration internalTypeEnumeration =
+ new InternalTypeEnumeration(signatureAttribute.getSignature(clazz));
+
+ // Recompose the signature types in a string buffer.
+ StringBuffer newSignatureBuffer = new StringBuffer();
+
+ // Also update the array with referenced classes.
+ int referencedClassIndex = 0;
+ int newReferencedClassIndex = 0;
+
+ // Copy the variable type declarations and the super class type.
+ while (internalTypeEnumeration.hasMoreTypes())
+ {
+ String internalType = internalTypeEnumeration.nextType();
+
+ // Append the type.
+ newSignatureBuffer.append(internalType);
+
+ // Copy any referenced classes.
+ int classCount =
+ new DescriptorClassEnumeration(internalType).classCount();
+
+ for (int counter = 0; counter < classCount; counter++)
+ {
+ referencedClasses[newReferencedClassIndex++] =
+ referencedClasses[referencedClassIndex++];
+ }
+
+ if (DEBUG)
+ {
+ System.out.println("InterfaceDeleter: type = " + internalType + " (" + classCount + " referenced classes)");
+ }
+
+ if (ClassUtil.isInternalClassType(internalType))
+ {
+ break;
+ }
+ }
+
+ // Copy the interface types.
+ int index = 0;
+ while (internalTypeEnumeration.hasMoreTypes())
+ {
+ String internalType = internalTypeEnumeration.nextType();
+
+ int classCount =
+ new DescriptorClassEnumeration(internalType).classCount();
+
+ if (DEBUG)
+ {
+ System.out.println("InterfaceDeleter: type " + (delete[index] ? "- " : "+ ") + internalType + " (" + classCount + " referenced classes)");
+ }
+
+ if (!delete[index++])
+ {
+ // Append the type.
+ newSignatureBuffer.append(internalType);
+
+ // Copy any referenced classes.
+ for (int counter = 0; counter < classCount; counter++)
+ {
+ referencedClasses[newReferencedClassIndex++] =
+ referencedClasses[referencedClassIndex++];
+ }
+ }
+ else
+ {
+ referencedClassIndex += classCount;
+ }
+ }
+
+ // Update the signature.
+ ((Utf8Constant)((ProgramClass)clazz).constantPool[signatureAttribute.u2signatureIndex]).setString(newSignatureBuffer.toString());
+
+ // Clear the remaining referenced classes.
+ Arrays.fill(referencedClasses,
+ newReferencedClassIndex,
+ referencedClassIndex,
+ null);
+ }
+ }
+}
diff --git a/src/proguard/classfile/editor/InterfaceSorter.java b/src/proguard/classfile/editor/InterfaceSorter.java
index 0d1f28c..a67b0a2 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,12 +23,11 @@ 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.constant.Utf8Constant;
import proguard.classfile.util.*;
import proguard.classfile.visitor.ClassVisitor;
-import java.util.*;
+import java.util.Arrays;
/**
* This ClassVisitor sorts the interfaces of the program classes that it visits.
@@ -52,27 +51,30 @@ implements ClassVisitor,
// Sort the interfaces.
Arrays.sort(interfaces, 0, interfacesCount);
+ // Update the signature.
+ programClass.attributesAccept(this);
+
// Remove any duplicate entries.
- int newInterfacesCount = 0;
- int previousInterfaceIndex = 0;
- for (int index = 0; index < interfacesCount; index++)
+ boolean[] delete = null;
+ for (int index = 1; index < interfacesCount; index++)
{
- int interfaceIndex = interfaces[index];
-
- // Isn't this a duplicate of the previous interface?
- if (interfaceIndex != previousInterfaceIndex)
+ Clazz interfaceClass = programClass.getInterface(index);
+ if (interfaces[index] == interfaces[index - 1])
{
- interfaces[newInterfacesCount++] = interfaceIndex;
+ // Lazily create the array.
+ if (delete == null)
+ {
+ delete = new boolean[interfacesCount];
+ }
- // Remember the interface.
- previousInterfaceIndex = interfaceIndex;
+ delete[index] = true;
}
}
- programClass.u2interfacesCount = newInterfacesCount;
-
- // Update the signature, if any
- programClass.attributesAccept(this);
+ if (delete != null)
+ {
+ new InterfaceDeleter(delete).visitProgramClass(programClass);
+ }
}
}
@@ -86,7 +88,7 @@ implements ClassVisitor,
{
// Process the generic definitions, superclass, and implemented
// interfaces.
- String signature = clazz.getString(signatureAttribute.u2signatureIndex);
+ String signature = signatureAttribute.getSignature(clazz);
// Count the signature types.
InternalTypeEnumeration internalTypeEnumeration =
@@ -127,13 +129,7 @@ implements ClassVisitor,
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]);
- }
+ newSignatureBuffer.append(internalTypes[index]);
}
String newSignature = newSignatureBuffer.toString();
diff --git a/src/proguard/classfile/editor/InterfacesEditor.java b/src/proguard/classfile/editor/InterfacesEditor.java
index 8765e36..4de2b2b 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,10 +20,8 @@
*/
package proguard.classfile.editor;
-import proguard.classfile.*;
-import proguard.classfile.attribute.*;
-
-import java.util.Arrays;
+import proguard.classfile.ProgramClass;
+import proguard.util.ArrayUtil;
/**
* This class can add and delete interfaces to and from classes. References to
@@ -54,22 +52,11 @@ public class InterfacesEditor
// Is the interface not yet present?
if (findInterfaceIndex(interfaceConstantIndex) < 0)
{
- int interfacesCount = targetClass.u2interfacesCount++;
- int[] interfaces = targetClass.u2interfaces;
-
- // Is the array too small to contain the additional interface?
- if (interfaces.length <= interfacesCount)
- {
- // Create a new array and copy the interfaces into it.
- int[] newinterfaces = new int[interfacesCount + 1];
- System.arraycopy(interfaces, 0, newinterfaces, 0, interfacesCount);
- interfaces = newinterfaces;
-
- targetClass.u2interfaces = interfaces;
- }
-
// Append the interface.
- interfaces[interfacesCount] = interfaceConstantIndex;
+ targetClass.u2interfaces =
+ ArrayUtil.add(targetClass.u2interfaces,
+ targetClass.u2interfacesCount++,
+ interfaceConstantIndex);
}
}
@@ -112,9 +99,9 @@ public class InterfacesEditor
for (int index = 0; index < interfacesCount; index++)
{
if (interfaces[index] == interfaceConstantIndex)
- {
- return index;
- }
+ {
+ return index;
+ }
}
return -1;
diff --git a/src/proguard/classfile/editor/LineNumberInfoAdder.java b/src/proguard/classfile/editor/LineNumberInfoAdder.java
index e1bd14a..c53fc26 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,9 +20,9 @@
*/
package proguard.classfile.editor;
-import proguard.classfile.attribute.visitor.LineNumberInfoVisitor;
-import proguard.classfile.attribute.*;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.LineNumberInfoVisitor;
/**
* This LineNumberInfoVisitor adds all line numbers that it visits to the given
diff --git a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java
index f712d46..5c2cdf3 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 a270fcf..cfbb570 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,13 +20,13 @@
*/
package proguard.classfile.editor;
-import proguard.classfile.attribute.visitor.LocalVariableInfoVisitor;
-import proguard.classfile.attribute.*;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.LocalVariableInfoVisitor;
/**
- * This LocalVariableInfoVisitor adds all line numbers that it visits to the given
- * target line number attribute.
+ * This LocalVariableInfoVisitor adds all local variables that it visits to the
+ * given target local variable table attribute.
*/
public class LocalVariableInfoAdder
implements LocalVariableInfoVisitor
@@ -36,8 +36,8 @@ implements LocalVariableInfoVisitor
/**
- * Creates a new LocalVariableInfoAdder that will copy line numbers into the
- * given target line number table.
+ * Creates a new LocalVariableInfoAdder that will copy local variables
+ * into the given target local variable table.
*/
public LocalVariableInfoAdder(ProgramClass targetClass,
LocalVariableTableAttribute targetLocalVariableTableAttribute)
@@ -51,7 +51,7 @@ implements LocalVariableInfoVisitor
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
- // Create a new line number.
+ // Create a new local variable.
LocalVariableInfo newLocalVariableInfo =
new LocalVariableInfo(localVariableInfo.u2startPC,
localVariableInfo.u2length,
diff --git a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java
index b9e601f..d26f937 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.classfile.editor;
import proguard.classfile.attribute.*;
+import proguard.util.ArrayUtil;
/**
* This class can add local variables to a given local variable table attribute.
@@ -30,12 +31,12 @@ import proguard.classfile.attribute.*;
*/
public class LocalVariableTableAttributeEditor
{
- private LocalVariableTableAttribute targetLocalVariableTableAttribute;
+ private final LocalVariableTableAttribute targetLocalVariableTableAttribute;
/**
- * Creates a new LocalVariableTableAttributeEditor that will edit line numbers
- * in the given line number table attribute.
+ * Creates a new LocalVariableTableAttributeEditor that will edit local
+ * variables in the given local variable table attribute.
*/
public LocalVariableTableAttributeEditor(LocalVariableTableAttribute targetLocalVariableTableAttribute)
{
@@ -48,20 +49,9 @@ public class LocalVariableTableAttributeEditor
*/
public void addLocalVariableInfo(LocalVariableInfo localVariableInfo)
{
- int localVariableTableLength = targetLocalVariableTableAttribute.u2localVariableTableLength;
- LocalVariableInfo[] localVariableTable = targetLocalVariableTableAttribute.localVariableTable;
-
- // Make sure there is enough space for the new localVariableInfo.
- if (localVariableTable.length <= localVariableTableLength)
- {
- targetLocalVariableTableAttribute.localVariableTable = new LocalVariableInfo[localVariableTableLength+1];
- System.arraycopy(localVariableTable, 0,
- targetLocalVariableTableAttribute.localVariableTable, 0,
- localVariableTableLength);
- localVariableTable = targetLocalVariableTableAttribute.localVariableTable;
- }
-
- // Add the localVariableInfo.
- localVariableTable[targetLocalVariableTableAttribute.u2localVariableTableLength++] = localVariableInfo;
+ targetLocalVariableTableAttribute.localVariableTable =
+ (LocalVariableInfo[])ArrayUtil.add(targetLocalVariableTableAttribute.localVariableTable,
+ targetLocalVariableTableAttribute.u2localVariableTableLength++,
+ localVariableInfo);
}
} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java
index bed1366..94a5f2a 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,13 +20,13 @@
*/
package proguard.classfile.editor;
-import proguard.classfile.attribute.visitor.LocalVariableTypeInfoVisitor;
-import proguard.classfile.attribute.*;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.LocalVariableTypeInfoVisitor;
/**
- * This LocalVariableTypeInfoVisitor adds all line numbers that it visits to the given
- * target line number attribute.
+ * This LocalVariableTypeInfoVisitor adds all local variable types that it
+ * visits to the given target local variable type attribute.
*/
public class LocalVariableTypeInfoAdder
implements LocalVariableTypeInfoVisitor
@@ -36,8 +36,8 @@ implements LocalVariableTypeInfoVisitor
/**
- * Creates a new LocalVariableTypeInfoAdder that will copy line numbers into the
- * given target line number table.
+ * Creates a new LocalVariableTypeInfoAdder that will copy local variable
+ * types into the given target local variable type table.
*/
public LocalVariableTypeInfoAdder(ProgramClass targetClass,
LocalVariableTypeTableAttribute targetLocalVariableTypeTableAttribute)
@@ -51,7 +51,7 @@ implements LocalVariableTypeInfoVisitor
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
- // Create a new line number.
+ // Create a new local variable type.
LocalVariableTypeInfo newLocalVariableTypeInfo =
new LocalVariableTypeInfo(localVariableTypeInfo.u2startPC,
localVariableTypeInfo.u2length,
diff --git a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java
index 00f7ef3..724b7b0 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.classfile.editor;
import proguard.classfile.attribute.*;
+import proguard.util.ArrayUtil;
/**
* This class can add local variables to a given local variable type table
@@ -31,12 +32,12 @@ import proguard.classfile.attribute.*;
*/
public class LocalVariableTypeTableAttributeEditor
{
- private LocalVariableTypeTableAttribute targetLocalVariableTypeTableAttribute;
+ private final LocalVariableTypeTableAttribute targetLocalVariableTypeTableAttribute;
/**
- * Creates a new LocalVariableTypeTableAttributeEditor that will edit line numbers
- * in the given line number table attribute.
+ * Creates a new LocalVariableTypeTableAttributeEditor that will edit local
+ * variable types in the given local variable type table attribute.
*/
public LocalVariableTypeTableAttributeEditor(LocalVariableTypeTableAttribute targetLocalVariableTypeTableAttribute)
{
@@ -45,24 +46,13 @@ public class LocalVariableTypeTableAttributeEditor
/**
- * Adds a given line number to the line number table attribute.
+ * Adds a given local variable type to the local variable type table attribute.
*/
public void addLocalVariableTypeInfo(LocalVariableTypeInfo localVariableTypeInfo)
{
- int localVariableTypeTableLength = targetLocalVariableTypeTableAttribute.u2localVariableTypeTableLength;
- LocalVariableTypeInfo[] localVariableTypeTable = targetLocalVariableTypeTableAttribute.localVariableTypeTable;
-
- // Make sure there is enough space for the new localVariableTypeInfo.
- if (localVariableTypeTable.length <= localVariableTypeTableLength)
- {
- targetLocalVariableTypeTableAttribute.localVariableTypeTable = new LocalVariableTypeInfo[localVariableTypeTableLength+1];
- System.arraycopy(localVariableTypeTable, 0,
- targetLocalVariableTypeTableAttribute.localVariableTypeTable, 0,
- localVariableTypeTableLength);
- localVariableTypeTable = targetLocalVariableTypeTableAttribute.localVariableTypeTable;
- }
-
- // Add the localVariableTypeInfo.
- localVariableTypeTable[targetLocalVariableTypeTableAttribute.u2localVariableTypeTableLength++] = localVariableTypeInfo;
+ targetLocalVariableTypeTableAttribute.localVariableTypeTable =
+ (LocalVariableTypeInfo[])ArrayUtil.add(targetLocalVariableTypeTableAttribute.localVariableTypeTable,
+ targetLocalVariableTypeTableAttribute.u2localVariableTypeTableLength++,
+ localVariableTypeInfo);
}
} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/MemberAdder.java b/src/proguard/classfile/editor/MemberAdder.java
index 811acae..2a93016 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -110,8 +110,8 @@ implements MemberVisitor
// // Is the field private or static?
// int targetAccessFlags = targetField.getAccessFlags();
// if ((targetAccessFlags &
- // (ClassConstants.INTERNAL_ACC_PRIVATE |
- // ClassConstants.INTERNAL_ACC_STATIC)) != 0)
+ // (ClassConstants.ACC_PRIVATE |
+ // ClassConstants.ACC_STATIC)) != 0)
// {
// if (DEBUG)
// {
@@ -192,7 +192,7 @@ implements MemberVisitor
if (targetMethod != null)
{
// is this source method abstract?
- if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
+ if ((accessFlags & ClassConstants.ACC_ABSTRACT) != 0)
{
// Keep the target method.
if (DEBUG)
@@ -206,7 +206,7 @@ implements MemberVisitor
// Is the target method abstract?
int targetAccessFlags = targetMethod.getAccessFlags();
- if ((targetAccessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
+ if ((targetAccessFlags & ClassConstants.ACC_ABSTRACT) != 0)
{
// Keep the abstract method, but update its contents, in order
// to keep any references to it valid.
@@ -217,7 +217,7 @@ implements MemberVisitor
// Replace the access flags.
targetMethod.u2accessFlags =
- accessFlags & ~ClassConstants.INTERNAL_ACC_FINAL;
+ accessFlags & ~ClassConstants.ACC_FINAL;
// Add and replace the attributes.
programMethod.attributesAccept(programClass,
@@ -249,7 +249,7 @@ implements MemberVisitor
// Create a copy of the method.
ProgramMethod newProgramMethod =
- new ProgramMethod(accessFlags & ~ClassConstants.INTERNAL_ACC_FINAL,
+ new ProgramMethod(accessFlags & ~ClassConstants.ACC_FINAL,
constantAdder.addConstant(programClass, programMethod.u2nameIndex),
constantAdder.addConstant(programClass, programMethod.u2descriptorIndex),
0,
@@ -287,8 +287,8 @@ implements MemberVisitor
*/
private String newUniqueMemberName(String name, String descriptor)
{
- return name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ?
- ClassConstants.INTERNAL_METHOD_NAME_INIT :
+ return name.equals(ClassConstants.METHOD_NAME_INIT) ?
+ ClassConstants.METHOD_NAME_INIT :
name + ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode()));
}
}
diff --git a/src/proguard/classfile/editor/MemberReferenceFixer.java b/src/proguard/classfile/editor/MemberReferenceFixer.java
index b623047..3a32963 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -271,7 +271,7 @@ implements ClassVisitor,
Clazz referencedClass = classConstant.referencedClass;
if (referencedClass != null)
{
- isInterfaceMethod = (referencedClass.getAccessFlags() & ClassConstants.INTERNAL_ACC_INTERFACE) != 0;
+ isInterfaceMethod = (referencedClass.getAccessFlags() & ClassConstants.ACC_INTERFACE) != 0;
}
}
}
diff --git a/src/proguard/classfile/editor/MethodInvocationFixer.java b/src/proguard/classfile/editor/MethodInvocationFixer.java
index e457e63..81b33ea 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -92,7 +92,7 @@ implements AttributeVisitor,
byte opcode = constantInstruction.opcode;
// Is the method static?
- if ((referencedMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0)
+ if ((referencedMethod.getAccessFlags() & ClassConstants.ACC_STATIC) != 0)
{
// But is it not a static invocation?
if (opcode != InstructionConstants.OP_INVOKESTATIC)
@@ -112,8 +112,8 @@ implements AttributeVisitor,
}
// Is the method private, or an instance initializer?
- else if ((referencedMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_PRIVATE) != 0 ||
- referencedMethod.getName(referencedMethodClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))
+ else if ((referencedMethod.getAccessFlags() & ClassConstants.ACC_PRIVATE) != 0 ||
+ referencedMethod.getName(referencedMethodClass).equals(ClassConstants.METHOD_NAME_INIT))
{
// But is it not a special invocation?
if (opcode != InstructionConstants.OP_INVOKESPECIAL)
@@ -133,7 +133,7 @@ implements AttributeVisitor,
}
// Is the method an interface method?
- else if ((referencedClass.getAccessFlags() & ClassConstants.INTERNAL_ACC_INTERFACE) != 0)
+ else if ((referencedClass.getAccessFlags() & ClassConstants.ACC_INTERFACE) != 0)
{
int invokeinterfaceConstant =
(ClassUtil.internalMethodParameterSize(referencedMethod.getDescriptor(referencedMethodClass), false)) << 8;
@@ -234,7 +234,7 @@ implements AttributeVisitor,
System.out.println(" Instruction = "+constantInstruction.toString(offset));
System.out.println(" -> Class = "+referencedClass);
System.out.println(" Method = "+referencedMethod);
- if ((referencedClass.getAccessFlags() & ClassConstants.INTERNAL_ACC_INTERFACE) != 0)
+ if ((referencedClass.getAccessFlags() & ClassConstants.ACC_INTERFACE) != 0)
{
System.out.println(" Parameter size = "+(ClassUtil.internalMethodParameterSize(referencedMethod.getDescriptor(referencedMethodClass), false)));
}
diff --git a/src/proguard/classfile/editor/NameAndTypeShrinker.java b/src/proguard/classfile/editor/NameAndTypeShrinker.java
index 650f9ba..40181b2 100644
--- a/src/proguard/classfile/editor/NameAndTypeShrinker.java
+++ b/src/proguard/classfile/editor/NameAndTypeShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,6 @@ 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;
@@ -163,11 +162,10 @@ implements ClassVisitor,
// 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.
+ // Is the constant being used? Don't update the flag if this is the
+ // second half of a long entry.
if (constant != null)
{
isUsed = constant.getTag() != ClassConstants.CONSTANT_NameAndType ||
@@ -176,8 +174,17 @@ implements ClassVisitor,
if (isUsed)
{
+ // Remember the new index.
+ constantIndexMap[index] = counter;
+
+ // Shift the constant pool entry.
constantPool[counter++] = constant;
}
+ else
+ {
+ // Remember an invalid index.
+ constantIndexMap[index] = -1;
+ }
}
// Clear the remaining constant pool elements.
diff --git a/src/proguard/classfile/editor/NamedAttributeDeleter.java b/src/proguard/classfile/editor/NamedAttributeDeleter.java
index 6aa5cdf..c02ba84 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,17 +21,23 @@
package proguard.classfile.editor;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.*;
-import proguard.util.StringMatcher;
/**
* This ClassVisitor deletes attributes with a given name in the program
- * classes that it visits.
+ * classes, fields, methods, or code attributes that it visits.
*
* @author Eric Lafortune
*/
-public class NamedAttributeDeleter implements ClassVisitor
+public class NamedAttributeDeleter
+extends SimplifiedVisitor
+implements ClassVisitor,
+ MemberVisitor,
+ AttributeVisitor
{
private final String attributeName;
@@ -51,4 +57,26 @@ public class NamedAttributeDeleter implements ClassVisitor
{
new AttributesEditor(programClass, false).deleteAttribute(attributeName);
}
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember) {}
+
+
+ public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
+ {
+ new AttributesEditor(programClass, programMember, false).deleteAttribute(attributeName);
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ new AttributesEditor((ProgramClass)clazz, (ProgramMember)method, codeAttribute, false).deleteAttribute(attributeName);
+ }
} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java
index 232747f..b7d29f7 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.classfile.editor;
import proguard.classfile.attribute.annotation.*;
+import proguard.util.ArrayUtil;
/**
* This class can add annotations to a given parameter annotations attribute.
@@ -48,24 +49,8 @@ public class ParameterAnnotationsAttributeEditor
*/
public void addAnnotation(int parameterIndex, Annotation annotation)
{
- int annotationsCount = targetParameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex];
- Annotation[] annotations = targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex];
-
- // Make sure there is enough space for the new annotation.
- if (annotations == null ||
- annotations.length <= annotationsCount)
- {
- targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex] = new Annotation[annotationsCount+1];
- if (annotations != null)
- {
- System.arraycopy(annotations, 0,
- targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex], 0,
- annotationsCount);
- }
- annotations = targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex];
- }
-
- // Add the annotation.
- annotations[targetParameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex]++] = annotation;
+ ArrayUtil.add(targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex],
+ targetParameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex]++,
+ annotation);
}
} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/ParameterInfoAdder.java b/src/proguard/classfile/editor/ParameterInfoAdder.java
new file mode 100644
index 0000000..50d35b2
--- /dev/null
+++ b/src/proguard/classfile/editor/ParameterInfoAdder.java
@@ -0,0 +1,62 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is 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.ParameterInfoVisitor;
+
+/**
+ * This ParameterInfoVisitor adds all parameter information that it visits to
+ * the given target method parameters attribute.
+ */
+public class ParameterInfoAdder
+implements ParameterInfoVisitor
+{
+ private final ConstantAdder constantAdder;
+ private final MethodParametersAttribute targetMethodParametersAttribute;
+
+
+ /**
+ * Creates a new ParameterInfoAdder that will copy parameter information
+ * into the given target method parameters attribute.
+ */
+ public ParameterInfoAdder(ProgramClass targetClass,
+ MethodParametersAttribute targetMethodParametersAttribute)
+ {
+ this.constantAdder = new ConstantAdder(targetClass);
+ this.targetMethodParametersAttribute = targetMethodParametersAttribute;
+ }
+
+
+ // Implementations for ParameterInfoVisitor.
+
+ public void visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo)
+ {
+ // Create a new parameter.
+ ParameterInfo newParameterInfo =
+ new ParameterInfo(constantAdder.addConstant(clazz, parameterInfo.u2nameIndex),
+ parameterInfo.u2accessFlags);
+
+ // Add it to the target.
+ targetMethodParametersAttribute.parameters[parameterIndex] = newParameterInfo;
+ }
+} \ No newline at end of file
diff --git a/src/proguard/classfile/editor/StackSizeUpdater.java b/src/proguard/classfile/editor/StackSizeUpdater.java
index d90b3d0..d49e53c 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 717bb1c..d7f179a 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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 109152b..dc6de07 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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/Utf8Shrinker.java b/src/proguard/classfile/editor/Utf8Shrinker.java
index eda5826..35626d7 100644
--- a/src/proguard/classfile/editor/Utf8Shrinker.java
+++ b/src/proguard/classfile/editor/Utf8Shrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.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.*;
@@ -47,6 +46,7 @@ implements ClassVisitor,
ConstantVisitor,
AttributeVisitor,
InnerClassesInfoVisitor,
+ ParameterInfoVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
@@ -198,6 +198,15 @@ implements ClassVisitor,
}
+ public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute)
+ {
+ markCpUtf8Entry(clazz, methodParametersAttribute.u2attributeNameIndex);
+
+ // Mark the UTF-8 entries referenced by the parameter information.
+ methodParametersAttribute.parametersAccept(clazz, method, this);
+ }
+
+
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
markCpUtf8Entry(clazz, exceptionsAttribute.u2attributeNameIndex);
@@ -287,6 +296,17 @@ implements ClassVisitor,
}
+ // Implementations for ParameterInfoVisitor.
+
+ public void visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo)
+ {
+ if (parameterInfo.u2nameIndex != 0)
+ {
+ markCpUtf8Entry(clazz, parameterInfo.u2nameIndex);
+ }
+ }
+
+
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
@@ -430,11 +450,10 @@ implements ClassVisitor,
// 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.
+ // Is the constant being used? Don't update the flag if this is the
+ // second half of a long entry.
if (constant != null)
{
isUsed = constant.getTag() != ClassConstants.CONSTANT_Utf8 ||
@@ -443,8 +462,17 @@ implements ClassVisitor,
if (isUsed)
{
+ // Remember the new index.
+ constantIndexMap[index] = counter;
+
+ // Shift the constant pool entry.
constantPool[counter++] = constant;
}
+ else
+ {
+ // Remember an invalid index.
+ constantIndexMap[index] = -1;
+ }
}
// Clear the remaining constant pool elements.
diff --git a/src/proguard/classfile/editor/VariableCleaner.java b/src/proguard/classfile/editor/VariableCleaner.java
index 63b7d4a..be67e05 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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/VariableEditor.java b/src/proguard/classfile/editor/VariableEditor.java
index b5143b5..2fd5471 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute 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/VariableRemapper.java b/src/proguard/classfile/editor/VariableRemapper.java
index ca9d88a..1ca1cb5 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,10 @@ package proguard.classfile.editor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.annotation.target.*;
+import proguard.classfile.attribute.annotation.target.visitor.*;
+import proguard.classfile.attribute.annotation.visitor.TypeAnnotationVisitor;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
@@ -38,7 +42,10 @@ extends SimplifiedVisitor
implements AttributeVisitor,
InstructionVisitor,
LocalVariableInfoVisitor,
- LocalVariableTypeInfoVisitor
+ LocalVariableTypeInfoVisitor,
+ TypeAnnotationVisitor,
+ TargetInfoVisitor,
+ LocalVariableTargetElementVisitor
{
private static final boolean DEBUG = false;
@@ -63,6 +70,22 @@ implements AttributeVisitor,
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+ public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute)
+ {
+ // Reorder the array with parameter information.
+ ParameterInfo[] oldParameters = methodParametersAttribute.parameters;
+ ParameterInfo[] newParameters =
+ new ParameterInfo[methodParametersAttribute.u1parametersCount];
+
+ for (int index = 0; index < methodParametersAttribute.u1parametersCount; index++)
+ {
+ newParameters[remapVariable(index)] = oldParameters[index];
+ }
+
+ methodParametersAttribute.parameters = newParameters;
+ }
+
+
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
if (DEBUG)
@@ -103,6 +126,13 @@ implements AttributeVisitor,
}
+ public void visitAnyTypeAnnotationsAttribute(Clazz clazz, TypeAnnotationsAttribute typeAnnotationsAttribute)
+ {
+ // Remap the variable references of local variable type annotations.
+ typeAnnotationsAttribute.typeAnnotationsAccept(clazz, this);
+ }
+
+
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
@@ -121,6 +151,34 @@ implements AttributeVisitor,
}
+ // Implementations for TypeAnnotationVisitor.
+
+ public void visitTypeAnnotation(Clazz clazz, TypeAnnotation typeAnnotation)
+ {
+ typeAnnotation.targetInfoAccept(clazz, this);
+ }
+
+
+ // Implementations for TargetInfoVisitor.
+
+ public void visitAnyTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, TargetInfo targetInfo) {}
+
+
+ public void visitLocalVariableTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo)
+ {
+ localVariableTargetInfo.targetElementsAccept(clazz, method, codeAttribute, typeAnnotation, this);
+ }
+
+
+ // Implementations for LocalVariableTargetElementVisitor.
+
+ public void visitLocalVariableTargetElement(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo, LocalVariableTargetElement localVariableTargetElement)
+ {
+ localVariableTargetElement.u2index =
+ remapVariable(localVariableTargetElement.u2index);
+ }
+
+
// Implementations for InstructionVisitor.
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
diff --git a/src/proguard/classfile/editor/VariableSizeUpdater.java b/src/proguard/classfile/editor/VariableSizeUpdater.java
index 2feaa9d..f364f92 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-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free