aboutsummaryrefslogtreecommitdiffstats
path: root/src/proguard/shrink
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/shrink')
-rw-r--r--src/proguard/shrink/AnnotationUsageMarker.java76
-rw-r--r--src/proguard/shrink/ClassShrinker.java73
-rw-r--r--src/proguard/shrink/InnerUsageMarker.java2
-rw-r--r--src/proguard/shrink/InterfaceUsageMarker.java2
-rw-r--r--src/proguard/shrink/LocalVariableTypeUsageMarker.java178
-rw-r--r--src/proguard/shrink/ShortestUsageMark.java2
-rw-r--r--src/proguard/shrink/ShortestUsageMarker.java2
-rw-r--r--src/proguard/shrink/ShortestUsagePrinter.java56
-rw-r--r--src/proguard/shrink/Shrinker.java43
-rw-r--r--src/proguard/shrink/SignatureUsageMarker.java117
-rw-r--r--src/proguard/shrink/UsageMarker.java250
-rw-r--r--src/proguard/shrink/UsagePrinter.java46
-rw-r--r--src/proguard/shrink/UsedClassFilter.java2
-rw-r--r--src/proguard/shrink/UsedMemberFilter.java4
14 files changed, 653 insertions, 200 deletions
diff --git a/src/proguard/shrink/AnnotationUsageMarker.java b/src/proguard/shrink/AnnotationUsageMarker.java
index 9aaae34..b9051a0 100644
--- a/src/proguard/shrink/AnnotationUsageMarker.java
+++ b/src/proguard/shrink/AnnotationUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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,8 +52,7 @@ implements AttributeVisitor,
// Fields acting as a return parameters for several methods.
private boolean attributeUsed;
private boolean annotationUsed;
- private boolean elementValueUsed;
- private boolean classUsed;
+ private boolean allClassesUsed;
private boolean methodUsed;
@@ -151,9 +150,6 @@ implements AttributeVisitor,
markConstant(clazz, constantElementValue.u2elementNameIndex);
markConstant(clazz, constantElementValue.u2constantValueIndex);
-
- // The return value.
- elementValueUsed = true;
}
}
@@ -163,10 +159,10 @@ implements AttributeVisitor,
if (isReferencedMethodUsed(enumConstantElementValue))
{
// Check the referenced classes.
- classUsed = true;
- enumConstantElementValue.referencedClassesAccept(usageMarker);
+ allClassesUsed = true;
+ enumConstantElementValue.referencedClassesAccept(this);
- if (classUsed)
+ if (allClassesUsed)
{
// Mark the element value as being used.
usageMarker.markAsUsed(enumConstantElementValue);
@@ -174,9 +170,6 @@ implements AttributeVisitor,
markConstant(clazz, enumConstantElementValue.u2elementNameIndex);
markConstant(clazz, enumConstantElementValue.u2typeNameIndex);
markConstant(clazz, enumConstantElementValue.u2constantNameIndex);
-
- // The return value.
- elementValueUsed = true;
}
}
}
@@ -186,21 +179,16 @@ implements AttributeVisitor,
{
if (isReferencedMethodUsed(classElementValue))
{
- // Check the referenced classes.
- classUsed = true;
- classElementValue.referencedClassesAccept(usageMarker);
-
- if (classUsed)
- {
- // Mark the element value as being used.
- usageMarker.markAsUsed(classElementValue);
+ // Mark the element value as being used.
+ usageMarker.markAsUsed(classElementValue);
- markConstant(clazz, classElementValue.u2elementNameIndex);
- markConstant(clazz, classElementValue.u2classInfoIndex);
+ markConstant(clazz, classElementValue.u2elementNameIndex);
+ markConstant(clazz, classElementValue.u2classInfoIndex);
- // The return value.
- elementValueUsed = true;
- }
+ // Mark the referenced classes, since they can be retrieved from
+ // the annotation and then used.
+ // TODO: This could mark more annotation methods, affecting other annotations.
+ classElementValue.referencedClassesAccept(usageMarker);
}
}
@@ -221,9 +209,6 @@ implements AttributeVisitor,
usageMarker.markAsUsed(annotationElementValue);
markConstant(clazz, annotationElementValue.u2elementNameIndex);
-
- // The return value.
- elementValueUsed = true;
}
annotationUsed = oldAnnotationUsed;
@@ -235,26 +220,13 @@ implements AttributeVisitor,
{
if (isReferencedMethodUsed(arrayElementValue))
{
- boolean oldelementValueUsed = elementValueUsed;
-
// Check and mark the contained element values.
- elementValueUsed = false;
arrayElementValue.elementValuesAccept(clazz, annotation, this);
- if (elementValueUsed)
- {
- // Mark the element value as being used.
- usageMarker.markAsUsed(arrayElementValue);
-
- markConstant(clazz, arrayElementValue.u2elementNameIndex);
+ // Mark the element value as being used.
+ usageMarker.markAsUsed(arrayElementValue);
- // The return value.
- //elementValueUsed = true;
- }
- else
- {
- elementValueUsed = oldelementValueUsed;
- }
+ markConstant(clazz, arrayElementValue.u2elementNameIndex);
}
}
@@ -269,17 +241,15 @@ implements AttributeVisitor,
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
- classUsed = usageMarker.isUsed(classConstant);
-
// Is the class constant marked as being used?
- if (!classUsed)
+ if (!usageMarker.isUsed(classConstant))
{
// Check the referenced class.
- classUsed = true;
+ allClassesUsed = true;
classConstant.referencedClassAccept(this);
// Is the referenced class marked as being used?
- if (classUsed)
+ if (allClassesUsed)
{
// Mark the class constant and its Utf8 constant.
usageMarker.markAsUsed(classConstant);
@@ -294,13 +264,12 @@ implements AttributeVisitor,
public void visitProgramClass(ProgramClass programClass)
{
- classUsed = usageMarker.isUsed(programClass);
+ allClassesUsed &= usageMarker.isUsed(programClass);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
- classUsed = true;
}
@@ -314,7 +283,6 @@ implements AttributeVisitor,
public void visitLibraryMethod(LibraryClass LibraryClass, LibraryMethod libraryMethod)
{
- classUsed = true;
}
@@ -326,10 +294,10 @@ implements AttributeVisitor,
private boolean isReferencedClassUsed(Annotation annotation)
{
// Check if the referenced class is being used.
- classUsed = true;
+ allClassesUsed = true;
annotation.referencedClassAccept(this);
- return classUsed;
+ return allClassesUsed;
}
diff --git a/src/proguard/shrink/ClassShrinker.java b/src/proguard/shrink/ClassShrinker.java
index 0b5c5b7..f590c63 100644
--- a/src/proguard/shrink/ClassShrinker.java
+++ b/src/proguard/shrink/ClassShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -24,15 +24,17 @@ import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.annotation.visitor.*;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.editor.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
+import java.util.Arrays;
+
/**
- * This ClassVisitor removes constant pool entries and class members that
- * are not marked as being used.
+ * This ClassVisitor removes constant pool entries, class members, and other
+ * class elements that are not marked as being used.
*
* @see UsageMarker
*
@@ -48,8 +50,7 @@ implements ClassVisitor,
{
private final UsageMarker usageMarker;
- private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
-
+ private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
@@ -76,7 +77,7 @@ implements ClassVisitor,
programClass.u2interfacesCount);
// Shrinking the constant pool also sets up an index map.
- programClass.u2constantPoolCount =
+ int newConstantPoolCount =
shrinkConstantPool(programClass.constantPool,
programClass.u2constantPoolCount);
@@ -98,9 +99,15 @@ implements ClassVisitor,
programClass.methodsAccept(this);
programClass.attributesAccept(this);
- // Remap all constant pool references.
- constantPoolRemapper.setConstantIndexMap(constantIndexMap);
- constantPoolRemapper.visitProgramClass(programClass);
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
+
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
// Remove the unused interfaces from the class signature.
programClass.attributesAccept(new SignatureShrinker());
@@ -140,6 +147,15 @@ implements ClassVisitor,
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Shrink the array of BootstrapMethodInfo objects.
+ bootstrapMethodsAttribute.u2bootstrapMethodsCount =
+ shrinkArray(bootstrapMethodsAttribute.bootstrapMethods,
+ bootstrapMethodsAttribute.u2bootstrapMethodsCount);
+ }
+
+
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
// Shrink the array of InnerClassesInfo objects.
@@ -173,6 +189,27 @@ implements ClassVisitor,
codeAttribute.u2attributesCount =
shrinkArray(codeAttribute.attributes,
codeAttribute.u2attributesCount);
+
+ // Shrink the attributes themselves.
+ codeAttribute.attributesAccept(clazz, method, this);
+ }
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ // Shrink the local variable info array.
+ localVariableTableAttribute.u2localVariableTableLength =
+ shrinkArray(localVariableTableAttribute.localVariableTable,
+ localVariableTableAttribute.u2localVariableTableLength);
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ // Shrink the local variable type info array.
+ localVariableTypeTableAttribute.u2localVariableTypeTableLength =
+ shrinkArray(localVariableTypeTableAttribute.localVariableTypeTable,
+ localVariableTypeTableAttribute.u2localVariableTypeTableLength);
}
@@ -349,10 +386,7 @@ implements ClassVisitor,
}
// Clear the remaining constant pool elements.
- for (int index = counter; index < length; index++)
- {
- constantPool[index] = null;
- }
+ Arrays.fill(constantPool, counter, length, null);
return counter;
}
@@ -377,10 +411,7 @@ implements ClassVisitor,
}
// Clear the remaining array elements.
- for (int index = counter; index < length; index++)
- {
- array[index] = 0;
- }
+ Arrays.fill(array, counter, length, 0);
return counter;
}
@@ -437,10 +468,10 @@ implements ClassVisitor,
}
}
- // Clear the remaining array elements.
- for (int index = counter; index < length; index++)
+ // Clear any remaining array elements.
+ if (counter < length)
{
- array[index] = null;
+ Arrays.fill(array, counter, length, null);
}
return counter;
diff --git a/src/proguard/shrink/InnerUsageMarker.java b/src/proguard/shrink/InnerUsageMarker.java
index b8ca801..6d77e81 100644
--- a/src/proguard/shrink/InnerUsageMarker.java
+++ b/src/proguard/shrink/InnerUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/InterfaceUsageMarker.java b/src/proguard/shrink/InterfaceUsageMarker.java
index 7599898..240838e 100644
--- a/src/proguard/shrink/InterfaceUsageMarker.java
+++ b/src/proguard/shrink/InterfaceUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/LocalVariableTypeUsageMarker.java b/src/proguard/shrink/LocalVariableTypeUsageMarker.java
new file mode 100644
index 0000000..573d8f6
--- /dev/null
+++ b/src/proguard/shrink/LocalVariableTypeUsageMarker.java
@@ -0,0 +1,178 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is 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.shrink;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.Constant;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This AttributeVisitor recursively marks all information that points to used
+ * classes, in the LocalVariableTable and LocalVariableTypeTable attributes that
+ * it visits.
+ *
+ * @see UsageMarker
+ *
+ * @author Eric Lafortune
+ */
+public class LocalVariableTypeUsageMarker
+extends SimplifiedVisitor
+implements AttributeVisitor,
+ LocalVariableInfoVisitor,
+ LocalVariableTypeInfoVisitor,
+ ClassVisitor,
+ ConstantVisitor
+{
+ private final UsageMarker usageMarker;
+
+ // Fields acting as a return parameters for several methods.
+ private boolean tableUsed;
+ private boolean variableInfoUsed;
+
+
+ /**
+ * Creates a new LocalVariableTypeUsageMarker.
+ * @param usageMarker the usage marker that is used to mark the classes
+ * and class members.
+ */
+ public LocalVariableTypeUsageMarker(UsageMarker usageMarker)
+ {
+ this.usageMarker = usageMarker;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ // Check and mark the individual entries.
+ tableUsed = false;
+ localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+
+ // Mark the table if any of the entries is marked.
+ if (tableUsed)
+ {
+ usageMarker.markAsUsed(localVariableTableAttribute);
+
+ markConstant(clazz, localVariableTableAttribute.u2attributeNameIndex);
+ }
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ // Check and mark the individual entries.
+ tableUsed = false;
+ localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+
+ // Mark the table if any of the entries is marked.
+ if (tableUsed)
+ {
+ usageMarker.markAsUsed(localVariableTypeTableAttribute);
+
+ markConstant(clazz, localVariableTypeTableAttribute.u2attributeNameIndex);
+ }
+ }
+
+
+ // Implementations for LocalVariableInfoVisitor.
+
+ public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
+ {
+ // Only keep the local variable info if all of its classes are used.
+ variableInfoUsed = true;
+ localVariableInfo.referencedClassAccept(this);
+
+ if (variableInfoUsed)
+ {
+ // We got a positive used flag, so the local variable info is useful.
+ usageMarker.markAsUsed(localVariableInfo);
+
+ markConstant(clazz, localVariableInfo.u2nameIndex);
+ markConstant(clazz, localVariableInfo.u2descriptorIndex);
+
+ tableUsed = true;
+ }
+ }
+
+
+ // Implementations for LocalVariableTypeInfoVisitor.
+
+ public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
+ {
+ // Only keep the local variable info if all of its classes are used.
+ variableInfoUsed = true;
+ localVariableTypeInfo.referencedClassesAccept(this);
+
+ if (variableInfoUsed)
+ {
+ // We got a positive used flag, so the local variable info is useful.
+ usageMarker.markAsUsed(localVariableTypeInfo);
+
+ markConstant(clazz, localVariableTypeInfo.u2nameIndex);
+ markConstant(clazz, localVariableTypeInfo.u2signatureIndex);
+
+ tableUsed = true;
+ }
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Don't keep the local variable info if one of its classes is not used.
+ if (!usageMarker.isUsed(programClass))
+ {
+ variableInfoUsed = false;
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant)
+ {
+ usageMarker.markAsUsed(constant);
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Marks the given constant pool entry of the given class.
+ */
+ private void markConstant(Clazz clazz, int index)
+ {
+ clazz.constantPoolEntryAccept(index, this);
+ }
+}
diff --git a/src/proguard/shrink/ShortestUsageMark.java b/src/proguard/shrink/ShortestUsageMark.java
index 757c713..e2df7fa 100644
--- a/src/proguard/shrink/ShortestUsageMark.java
+++ b/src/proguard/shrink/ShortestUsageMark.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ShortestUsageMarker.java b/src/proguard/shrink/ShortestUsageMarker.java
index da8fad3..1ac6e7e 100644
--- a/src/proguard/shrink/ShortestUsageMarker.java
+++ b/src/proguard/shrink/ShortestUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ShortestUsagePrinter.java b/src/proguard/shrink/ShortestUsagePrinter.java
index db42fe1..8740b9f 100644
--- a/src/proguard/shrink/ShortestUsagePrinter.java
+++ b/src/proguard/shrink/ShortestUsagePrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,9 @@
package proguard.shrink;
import proguard.classfile.*;
-import proguard.classfile.util.ClassUtil;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
import java.io.PrintStream;
@@ -36,8 +38,10 @@ import java.io.PrintStream;
* @author Eric Lafortune
*/
public class ShortestUsagePrinter
+extends SimplifiedVisitor
implements ClassVisitor,
- MemberVisitor
+ MemberVisitor,
+ AttributeVisitor
{
private final ShortestUsageMarker shortestUsageMarker;
private final boolean verbose;
@@ -117,8 +121,7 @@ implements ClassVisitor,
ps.println(ClassUtil.externalClassName(programClass.getName()) +
(verbose ?
": " + ClassUtil.externalFullFieldDescription(0, name, type):
- "." + name) +
- lineNumberRange(programClass, programField));
+ "." + name));
// Print the reason for keeping this method.
printReason(programField);
@@ -131,11 +134,12 @@ implements ClassVisitor,
String name = programMethod.getName(programClass);
String type = programMethod.getDescriptor(programClass);
- ps.println(ClassUtil.externalClassName(programClass.getName()) +
- (verbose ?
- ": " + ClassUtil.externalFullMethodDescription(programClass.getName(), 0, name, type):
- "." + name) +
- lineNumberRange(programClass, programMethod));
+ ps.print(ClassUtil.externalClassName(programClass.getName()) +
+ (verbose ?
+ ": " + ClassUtil.externalFullMethodDescription(programClass.getName(), 0, name, type):
+ "." + name));
+ programMethod.attributesAccept(programClass, this);
+ ps.println();
// Print the reason for keeping this method.
printReason(programMethod);
@@ -174,6 +178,25 @@ implements ClassVisitor,
}
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ codeAttribute.attributesAccept(clazz, method, this);
+ }
+
+
+ public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
+ {
+ ps.print(" (" +
+ lineNumberTableAttribute.getLowestLineNumber() + ":" +
+ lineNumberTableAttribute.getHighestLineNumber() + ")");
+ }
+
+
// Small utility methods.
private void printReason(VisitorAccepter visitorAccepter)
@@ -194,17 +217,4 @@ implements ClassVisitor,
ps.println(" is not being kept.\n");
}
}
-
-
- /**
- * Returns the line number range of the given class member, followed by a
- * colon, or just an empty String if no range is available.
- */
- private static String lineNumberRange(ProgramClass programClass, ProgramMember programMember)
- {
- String range = programMember.getLineNumberRange(programClass);
- return range != null ?
- (" (" + range + ")") :
- "";
- }
}
diff --git a/src/proguard/shrink/Shrinker.java b/src/proguard/shrink/Shrinker.java
index edbc27f..0472c3d 100644
--- a/src/proguard/shrink/Shrinker.java
+++ b/src/proguard/shrink/Shrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,7 @@
package proguard.shrink;
import proguard.*;
-import proguard.classfile.ClassPool;
+import proguard.classfile.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.visitor.*;
@@ -67,9 +67,20 @@ public class Shrinker
new UsageMarker() :
new ShortestUsageMarker();
+ // Automatically mark the parameterless constructors of seed classes,
+ // mainly for convenience and for backward compatibility.
+ ClassVisitor classUsageMarker =
+ new MultiClassVisitor(new ClassVisitor[]
+ {
+ usageMarker,
+ new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_INIT,
+ usageMarker)
+ });
+
ClassPoolVisitor classPoolvisitor =
ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
- usageMarker,
+ classUsageMarker,
usageMarker,
true,
false,
@@ -89,6 +100,8 @@ public class Shrinker
{
new InnerUsageMarker(usageMarker),
new AnnotationUsageMarker(usageMarker),
+ new SignatureUsageMarker(usageMarker),
+ new LocalVariableTypeUsageMarker(usageMarker)
}))));
// Should we explain ourselves?
@@ -113,15 +126,21 @@ public class Shrinker
if (configuration.printUsage != null)
{
- PrintStream ps = isFile(configuration.printUsage) ?
- new PrintStream(new BufferedOutputStream(new FileOutputStream(configuration.printUsage))) :
- System.out;
+ PrintStream ps =
+ configuration.printUsage == Configuration.STD_OUT ? System.out :
+ new PrintStream(
+ new BufferedOutputStream(
+ new FileOutputStream(configuration.printUsage)));
// Print out items that will be removed.
programClassPool.classesAcceptAlphabetically(
new UsagePrinter(usageMarker, true, ps));
- if (ps != System.out)
+ if (ps == System.out)
+ {
+ ps.flush();
+ }
+ else
{
ps.close();
}
@@ -157,14 +176,4 @@ public class Shrinker
return newProgramClassPool;
}
-
-
- /**
- * Returns whether the given file is actually a file, or just a placeholder
- * for the standard output.
- */
- private boolean isFile(File file)
- {
- return file.getPath().length() > 0;
- }
}
diff --git a/src/proguard/shrink/SignatureUsageMarker.java b/src/proguard/shrink/SignatureUsageMarker.java
new file mode 100644
index 0000000..9c5cd4d
--- /dev/null
+++ b/src/proguard/shrink/SignatureUsageMarker.java
@@ -0,0 +1,117 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is 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.shrink;
+
+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.SimplifiedVisitor;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This AttributeVisitor recursively marks all Signature attributes that it
+ * visits and that point to used classes.
+ *
+ * @see UsageMarker
+ *
+ * @author Eric Lafortune
+ */
+public class SignatureUsageMarker
+extends SimplifiedVisitor
+implements AttributeVisitor,
+ ClassVisitor,
+ ConstantVisitor
+{
+ private final UsageMarker usageMarker;
+
+ // Fields acting as a return parameters for several methods.
+ private boolean attributeUsed;
+
+
+ /**
+ * Creates a new SignatureUsageMarker.
+ * @param usageMarker the usage marker that is used to mark the classes
+ * and class members.
+ */
+ public SignatureUsageMarker(UsageMarker usageMarker)
+ {
+ this.usageMarker = usageMarker;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
+ {
+ // Only keep the signature if all of its classes are used.
+ attributeUsed = true;
+ signatureAttribute.referencedClassesAccept(this);
+
+ if (attributeUsed)
+ {
+ // We got a positive used flag, so the signature is useful.
+ usageMarker.markAsUsed(signatureAttribute);
+
+ markConstant(clazz, signatureAttribute.u2attributeNameIndex);
+ markConstant(clazz, signatureAttribute.u2signatureIndex);
+ }
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Don't keep the signature if one of its classes is not used.
+ if (!usageMarker.isUsed(programClass))
+ {
+ attributeUsed = false;
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant)
+ {
+ usageMarker.markAsUsed(constant);
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Marks the given constant pool entry of the given class.
+ */
+ private void markConstant(Clazz clazz, int index)
+ {
+ clazz.constantPoolEntryAccept(index, this);
+ }
+}
diff --git a/src/proguard/shrink/UsageMarker.java b/src/proguard/shrink/UsageMarker.java
index e913046..51210b5 100644
--- a/src/proguard/shrink/UsageMarker.java
+++ b/src/proguard/shrink/UsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -27,10 +27,10 @@ import proguard.classfile.attribute.preverification.*;
import proguard.classfile.attribute.preverification.visitor.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.constant.visitor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
@@ -65,18 +65,15 @@ implements ClassVisitor,
private static final Object USED = new Object();
- private final MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
- private final MyPossiblyUsedMemberUsageMarker possiblyUsedMemberUsageMarker = new MyPossiblyUsedMemberUsageMarker();
-// private ClassVisitor dynamicClassMarker =
-// new MultiClassVisitor(
-// new ClassVisitor[]
-// {
-// this,
-// new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
-// ClassConstants.INTERNAL_METHOD_TYPE_INIT,
-// this)
-// });
-
+ private final MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
+ private final MyPossiblyUsedMemberUsageMarker possiblyUsedMemberUsageMarker = new MyPossiblyUsedMemberUsageMarker();
+ private final MemberVisitor nonEmptyMethodUsageMarker = new AllAttributeVisitor(
+ new MyNonEmptyMethodUsageMarker());
+ private final ConstantVisitor parameterlessConstructorMarker = new ConstantTagFilter(new int[] { ClassConstants.CONSTANT_String, ClassConstants.CONSTANT_Class },
+ new ReferencedClassVisitor(
+ new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_INIT,
+ this)));
// Implementations for ClassVisitor.
@@ -107,15 +104,10 @@ implements ClassVisitor,
programClass.hierarchyAccept(false, false, true, false,
interfaceUsageMarker);
- // Explicitly mark the <clinit> method.
+ // Explicitly mark the <clinit> method, if it's not empty.
programClass.methodAccept(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
ClassConstants.INTERNAL_METHOD_TYPE_CLINIT,
- this);
-
- // Explicitly mark the parameterless <init> method.
- programClass.methodAccept(ClassConstants.INTERNAL_METHOD_NAME_INIT,
- ClassConstants.INTERNAL_METHOD_TYPE_INIT,
- this);
+ nonEmptyMethodUsageMarker);
// Process all class members that have already been marked as possibly used.
programClass.fieldsAccept(possiblyUsedMemberUsageMarker);
@@ -187,6 +179,10 @@ implements ClassVisitor,
}
+ /**
+ * This MemberVisitor marks ProgramField and ProgramMethod objects that
+ * have already been marked as possibly used.
+ */
private class MyPossiblyUsedMemberUsageMarker
extends SimplifiedVisitor
implements MemberVisitor
@@ -230,6 +226,28 @@ implements ClassVisitor,
}
+ /**
+ * This AttributeVisitor marks ProgramMethod objects of non-empty methods.
+ */
+ private class MyNonEmptyMethodUsageMarker
+ extends SimplifiedVisitor
+ implements AttributeVisitor
+ {
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ if (codeAttribute.u4codeLength > 1)
+ {
+ method.accept(clazz, UsageMarker.this);
+ }
+ }
+ }
+
+
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
@@ -335,15 +353,26 @@ implements ClassVisitor,
*/
protected void markMethodHierarchy(Clazz clazz, Method method)
{
- if ((method.getAccessFlags() &
+ int accessFlags = method.getAccessFlags();
+ if ((accessFlags &
(ClassConstants.INTERNAL_ACC_PRIVATE |
- ClassConstants.INTERNAL_ACC_STATIC)) == 0)
+ ClassConstants.INTERNAL_ACC_STATIC)) == 0 &&
+ !ClassUtil.isInitializer(method.getName(clazz)))
{
+ // We can skip private and static methods in the hierarchy, and
+ // also abstract methods, unless they might widen a current
+ // non-public access.
+ int requiredUnsetAccessFlags =
+ ClassConstants.INTERNAL_ACC_PRIVATE |
+ ClassConstants.INTERNAL_ACC_STATIC |
+ ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) == 0 ? 0 :
+ ClassConstants.INTERNAL_ACC_ABSTRACT);
+
clazz.accept(new ConcreteClassDownTraveler(
new ClassHierarchyTraveler(true, true, false, true,
new NamedMethodVisitor(method.getName(clazz),
method.getDescriptor(clazz),
- new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE | ClassConstants.INTERNAL_ACC_STATIC | ClassConstants.INTERNAL_ACC_ABSTRACT,
+ new MemberAccessFilter(0, requiredUnsetAccessFlags,
this)))));
}
}
@@ -395,11 +424,7 @@ implements ClassVisitor,
markConstant(clazz, stringConstant.u2stringIndex);
- // Mark the referenced class and its parameterless constructor,
- // if the string is being used in a Class.forName construct.
- //stringConstant.referencedClassAccept(dynamicClassMarker);
-
- // Mark the referenced class or class member, if any.
+ // Mark the referenced class and class member, if any.
stringConstant.referencedClassAccept(this);
stringConstant.referencedMemberAccept(this);
}
@@ -415,6 +440,31 @@ implements ClassVisitor,
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ if (shouldBeMarkedAsUsed(invokeDynamicConstant))
+ {
+ markAsUsed(invokeDynamicConstant);
+
+ markConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex);
+
+ // Mark the bootstrap methods attribute.
+ clazz.attributesAccept(new MyBootStrapMethodUsageMarker(invokeDynamicConstant.u2bootstrapMethodAttributeIndex));
+ }
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ if (shouldBeMarkedAsUsed(methodHandleConstant))
+ {
+ markAsUsed(methodHandleConstant);
+
+ markConstant(clazz, methodHandleConstant.u2referenceIndex);
+ }
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
if (shouldBeMarkedAsUsed(refConstant))
@@ -450,6 +500,17 @@ implements ClassVisitor,
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ if (shouldBeMarkedAsUsed(methodTypeConstant))
+ {
+ markAsUsed(methodTypeConstant);
+
+ markConstant(clazz, methodTypeConstant.u2descriptorIndex);
+ }
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
if (shouldBeMarkedAsUsed(nameAndTypeConstant))
@@ -462,6 +523,58 @@ implements ClassVisitor,
}
+ /**
+ * This AttributeVisitor marks the bootstrap methods attributes, their
+ * method entries, their method handles, and their arguments.
+ */
+ private class MyBootStrapMethodUsageMarker
+ extends SimplifiedVisitor
+ implements AttributeVisitor,
+ BootstrapMethodInfoVisitor
+ {
+ private int bootstrapMethodIndex;
+
+
+ private MyBootStrapMethodUsageMarker(int bootstrapMethodIndex)
+ {
+ this.bootstrapMethodIndex = bootstrapMethodIndex;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (shouldBeMarkedAsUsed(bootstrapMethodsAttribute))
+ {
+ markAsUsed(bootstrapMethodsAttribute);
+
+ markConstant(clazz, bootstrapMethodsAttribute.u2attributeNameIndex);
+
+ bootstrapMethodsAttribute.bootstrapMethodEntryAccept(clazz,
+ bootstrapMethodIndex,
+ this);
+ }
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ markAsUsed(bootstrapMethodInfo);
+
+ markConstant(clazz, bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Mark the constant pool entries referenced by the arguments.
+ bootstrapMethodInfo.methodArgumentsAccept(clazz, UsageMarker.this);
+ }
+ }
+
+
// Implementations for AttributeVisitor.
// Note that attributes are typically only referenced once, so we don't
// test if they have been marked already.
@@ -475,6 +588,13 @@ implements ClassVisitor,
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Don't mark the attribute and its name here. We may mark it in
+ // MyBootStrapMethodsAttributeUsageMarker.
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
markAsUsed(sourceFileAttribute);
@@ -538,10 +658,12 @@ implements ClassVisitor,
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
- markAsUsed(signatureAttribute);
-
- markConstant(clazz, signatureAttribute.u2attributeNameIndex);
- markConstant(clazz, signatureAttribute.u2signatureIndex);
+ // Don't mark the attribute and its contents yet. We may mark them later,
+ // in SignatureUsageMarker.
+ //markAsUsed(signatureAttribute);
+ //
+ //markConstant(clazz, signatureAttribute.u2attributeNameIndex);
+ //markConstant(clazz, signatureAttribute.u2signatureIndex);
}
@@ -611,23 +733,27 @@ implements ClassVisitor,
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
- markAsUsed(localVariableTableAttribute);
-
- markConstant(clazz, localVariableTableAttribute.u2attributeNameIndex);
-
- // Mark the constant pool entries referenced by the local variables.
- localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ // Don't mark the attribute and its contents yet. We may mark them later,
+ // in LocalVariableTypeUsageMarker.
+ //markAsUsed(localVariableTableAttribute);
+ //
+ //markConstant(clazz, localVariableTableAttribute.u2attributeNameIndex);
+ //
+ //// Mark the constant pool entries referenced by the local variables.
+ //localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
- markAsUsed(localVariableTypeTableAttribute);
-
- markConstant(clazz, localVariableTypeTableAttribute.u2attributeNameIndex);
-
- // Mark the constant pool entries referenced by the local variable types.
- localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ // Don't mark the attribute and its contents yet. We may mark them later,
+ // in LocalVariableTypeUsageMarker.
+ //markAsUsed(localVariableTypeTableAttribute);
+ //
+ //markConstant(clazz, localVariableTypeTableAttribute.u2attributeNameIndex);
+ //
+ //// Mark the constant pool entries referenced by the local variable types.
+ //localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
@@ -635,12 +761,12 @@ implements ClassVisitor,
{
// Don't mark the attribute and its contents yet. We may mark them later,
// in AnnotationUsageMarker.
-// markAsUsed(annotationsAttribute);
-//
-// markConstant(clazz, annotationsAttribute.u2attributeNameIndex);
-//
-// // Mark the constant pool entries referenced by the annotations.
-// annotationsAttribute.annotationsAccept(clazz, this);
+ //markAsUsed(annotationsAttribute);
+ //
+ //markConstant(clazz, annotationsAttribute.u2attributeNameIndex);
+ //
+ //// Mark the constant pool entries referenced by the annotations.
+ //annotationsAttribute.annotationsAccept(clazz, this);
}
@@ -648,12 +774,12 @@ implements ClassVisitor,
{
// Don't mark the attribute and its contents yet. We may mark them later,
// in AnnotationUsageMarker.
-// markAsUsed(parameterAnnotationsAttribute);
-//
-// markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex);
-//
-// // Mark the constant pool entries referenced by the annotations.
-// parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
+ //markAsUsed(parameterAnnotationsAttribute);
+ //
+ //markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex);
+ //
+ //// Mark the constant pool entries referenced by the annotations.
+ //parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
}
@@ -837,6 +963,12 @@ implements ClassVisitor,
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
markConstant(clazz, constantInstruction.constantIndex);
+
+ // Also mark the parameterless constructor of the class, in case the
+ // string constant or class constant is being used in a Class.forName
+ // or a .class construct.
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex,
+ parameterlessConstructorMarker);
}
@@ -915,6 +1047,6 @@ implements ClassVisitor,
*/
private void markConstant(Clazz clazz, int index)
{
- clazz.constantPoolEntryAccept(index, this);
+ clazz.constantPoolEntryAccept(index, this);
}
}
diff --git a/src/proguard/shrink/UsagePrinter.java b/src/proguard/shrink/UsagePrinter.java
index 294b9e1..69df7fa 100644
--- a/src/proguard/shrink/UsagePrinter.java
+++ b/src/proguard/shrink/UsagePrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,6 +21,8 @@
package proguard.shrink;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
@@ -38,7 +40,8 @@ import java.io.PrintStream;
public class UsagePrinter
extends SimplifiedVisitor
implements ClassVisitor,
- MemberVisitor
+ MemberVisitor,
+ AttributeVisitor
{
private final UsageMarker usageMarker;
private final boolean printUnusedItems;
@@ -121,7 +124,6 @@ implements ClassVisitor,
printClassNameHeader();
ps.println(" " +
- lineNumberRange(programClass, programField) +
ClassUtil.externalFullFieldDescription(
programField.getAccessFlags(),
programField.getName(programClass),
@@ -136,9 +138,10 @@ implements ClassVisitor,
{
printClassNameHeader();
- ps.println(" " +
- lineNumberRange(programClass, programMethod) +
- ClassUtil.externalFullMethodDescription(
+ ps.print("====");
+ ps.print(" ");
+ programMethod.attributesAccept(programClass, this);
+ ps.println(ClassUtil.externalFullMethodDescription(
programClass.getName(),
programMethod.getAccessFlags(),
programMethod.getName(programClass),
@@ -147,6 +150,24 @@ implements ClassVisitor,
}
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ codeAttribute.attributesAccept(clazz, method, this);
+ }
+
+
+ public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
+ {
+ ps.print(lineNumberTableAttribute.getLowestLineNumber() + ":" +
+ lineNumberTableAttribute.getHighestLineNumber() + ":");
+ }
+
+
// Small utility methods.
/**
@@ -161,17 +182,4 @@ implements ClassVisitor,
className = null;
}
}
-
-
- /**
- * Returns the line number range of the given class member, followed by a
- * colon, or just an empty String if no range is available.
- */
- private static String lineNumberRange(ProgramClass programClass, ProgramMember programMember)
- {
- String range = programMember.getLineNumberRange(programClass);
- return range != null ?
- (range + ":") :
- "";
- }
}
diff --git a/src/proguard/shrink/UsedClassFilter.java b/src/proguard/shrink/UsedClassFilter.java
index ec180bd..7630b0b 100644
--- a/src/proguard/shrink/UsedClassFilter.java
+++ b/src/proguard/shrink/UsedClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/UsedMemberFilter.java b/src/proguard/shrink/UsedMemberFilter.java
index 755cfd1..f1a9c75 100644
--- a/src/proguard/shrink/UsedMemberFilter.java
+++ b/src/proguard/shrink/UsedMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -39,7 +39,7 @@ implements MemberVisitor
/**
- * Creates a new UsedClassFilter.
+ * Creates a new UsedMemberFilter.
* @param usageMarker the usage marker that is used to mark the classes
* and class members.
* @param memberVisitor the member visitor to which the visiting will be