diff options
Diffstat (limited to 'src/proguard/classfile')
263 files changed, 5012 insertions, 920 deletions
diff --git a/src/proguard/classfile/ClassConstants.java b/src/proguard/classfile/ClassConstants.java index 3b243e0..081305b 100644 --- a/src/proguard/classfile/ClassConstants.java +++ b/src/proguard/classfile/ClassConstants.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -43,6 +43,8 @@ public interface ClassConstants public static final int INTERNAL_CLASS_VERSION_1_5_MINOR = 0; public static final int INTERNAL_CLASS_VERSION_1_6_MAJOR = 50; public static final int INTERNAL_CLASS_VERSION_1_6_MINOR = 0; + public static final int INTERNAL_CLASS_VERSION_1_7_MAJOR = 51; + public static final int INTERNAL_CLASS_VERSION_1_7_MINOR = 0; public static final int INTERNAL_CLASS_VERSION_1_0 = (INTERNAL_CLASS_VERSION_1_0_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_0_MINOR; public static final int INTERNAL_CLASS_VERSION_1_2 = (INTERNAL_CLASS_VERSION_1_2_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_2_MINOR; @@ -50,6 +52,7 @@ public interface ClassConstants public static final int INTERNAL_CLASS_VERSION_1_4 = (INTERNAL_CLASS_VERSION_1_4_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_4_MINOR; public static final int INTERNAL_CLASS_VERSION_1_5 = (INTERNAL_CLASS_VERSION_1_5_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_5_MINOR; public static final int INTERNAL_CLASS_VERSION_1_6 = (INTERNAL_CLASS_VERSION_1_6_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_6_MINOR; + public static final int INTERNAL_CLASS_VERSION_1_7 = (INTERNAL_CLASS_VERSION_1_7_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_7_MINOR; public static final String EXTERNAL_CLASS_VERSION_1_0 = "1.0"; public static final String EXTERNAL_CLASS_VERSION_1_1 = "1.1"; @@ -58,8 +61,10 @@ public interface ClassConstants public static final String EXTERNAL_CLASS_VERSION_1_4 = "1.4"; public static final String EXTERNAL_CLASS_VERSION_1_5 = "1.5"; public static final String EXTERNAL_CLASS_VERSION_1_6 = "1.6"; + public static final String EXTERNAL_CLASS_VERSION_1_7 = "1.7"; public static final String EXTERNAL_CLASS_VERSION_1_5_ALIAS = "5"; public static final String EXTERNAL_CLASS_VERSION_1_6_ALIAS = "6"; + public static final String EXTERNAL_CLASS_VERSION_1_7_ALIAS = "7"; public static final int INTERNAL_ACC_PUBLIC = 0x0001; public static final int INTERNAL_ACC_PRIVATE = 0x0002; @@ -119,10 +124,13 @@ public interface ClassConstants public static final String EXTERNAL_ACC_SYNCHRONIZED = "synchronized"; public static final String EXTERNAL_ACC_VOLATILE = "volatile"; public static final String EXTERNAL_ACC_TRANSIENT = "transient"; + public static final String EXTERNAL_ACC_BRIDGE = "bridge"; + public static final String EXTERNAL_ACC_VARARGS = "varargs"; public static final String EXTERNAL_ACC_NATIVE = "native"; public static final String EXTERNAL_ACC_INTERFACE = "interface"; public static final String EXTERNAL_ACC_ABSTRACT = "abstract"; public static final String EXTERNAL_ACC_STRICT = "strictfp"; + public static final String EXTERNAL_ACC_SYNTHETIC = "synthetic"; public static final String EXTERNAL_ACC_ANNOTATION = "@"; public static final String EXTERNAL_ACC_ENUM = "enum"; @@ -137,7 +145,21 @@ public interface ClassConstants public static final int CONSTANT_Methodref = 10; public static final int CONSTANT_InterfaceMethodref = 11; public static final int CONSTANT_NameAndType = 12; + public static final int CONSTANT_MethodHandle = 15; + public static final int CONSTANT_MethodType = 16; + public static final int CONSTANT_InvokeDynamic = 18; + public static final int REF_getField = 1; + public static final int REF_getStatic = 2; + public static final int REF_putField = 3; + public static final int REF_putStatic = 4; + public static final int REF_invokeVirtual = 5; + public static final int REF_invokeStatic = 6; + public static final int REF_invokeSpecial = 7; + public static final int REF_newInvokeSpecial = 8; + public static final int REF_invokeInterface = 9; + + public static final String ATTR_BootstrapMethods = "BootstrapMethods"; public static final String ATTR_SourceFile = "SourceFile"; public static final String ATTR_SourceDir = "SourceDir"; public static final String ATTR_InnerClasses = "InnerClasses"; @@ -179,32 +201,48 @@ public interface ClassConstants public static final char INTERNAL_METHOD_ARGUMENTS_OPEN = '('; public static final char INTERNAL_METHOD_ARGUMENTS_CLOSE = ')'; - public static final String INTERNAL_PACKAGE_JAVA_LANG = "java/lang/"; - public static final String INTERNAL_NAME_JAVA_LANG_OBJECT = "java/lang/Object"; - public static final String INTERNAL_TYPE_JAVA_LANG_OBJECT = "Ljava/lang/Object;"; - public static final String INTERNAL_NAME_JAVA_LANG_CLONEABLE = "java/lang/Cloneable"; - public static final String INTERNAL_NAME_JAVA_LANG_THROWABLE = "java/lang/Throwable"; - public static final String INTERNAL_NAME_JAVA_LANG_CLASS = "java/lang/Class"; - public static final String INTERNAL_NAME_JAVA_LANG_STRING = "java/lang/String"; - public static final String INTERNAL_NAME_JAVA_IO_SERIALIZABLE = "java/io/Serializable"; + public static final String INTERNAL_PACKAGE_JAVA_LANG = "java/lang/"; + public static final String INTERNAL_NAME_JAVA_LANG_OBJECT = "java/lang/Object"; + public static final String INTERNAL_TYPE_JAVA_LANG_OBJECT = "Ljava/lang/Object;"; + public static final String INTERNAL_NAME_JAVA_LANG_CLONEABLE = "java/lang/Cloneable"; + public static final String INTERNAL_NAME_JAVA_LANG_THROWABLE = "java/lang/Throwable"; + public static final String INTERNAL_NAME_JAVA_LANG_CLASS = "java/lang/Class"; + public static final String INTERNAL_NAME_JAVA_LANG_STRING = "java/lang/String"; + public static final String INTERNAL_NAME_JAVA_LANG_STRING_BUFFER = "java/lang/StringBuffer"; + public static final String INTERNAL_NAME_JAVA_LANG_STRING_BUILDER = "java/lang/StringBuilder"; + public static final String INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE = "java/lang/invoke/MethodHandle"; + public static final String INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE = "java/lang/invoke/MethodType"; + public static final String INTERNAL_NAME_JAVA_IO_SERIALIZABLE = "java/io/Serializable"; + + public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_INTEGER_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicIntegerFieldUpdater"; + public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_LONG_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicLongFieldUpdater"; + public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_REFERENCE_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicReferenceFieldUpdater"; public static final String INTERNAL_METHOD_NAME_INIT = "<init>"; public static final String INTERNAL_METHOD_TYPE_INIT = "()V"; public static final String INTERNAL_METHOD_NAME_CLINIT = "<clinit>"; public static final String INTERNAL_METHOD_TYPE_CLINIT = "()V"; - public static final String INTERNAL_METHOD_NAME_CLASS_FOR_NAME = "forName"; - public static final String INTERNAL_METHOD_TYPE_CLASS_FOR_NAME = "(Ljava/lang/String;)Ljava/lang/Class;"; - public static final String INTERNAL_METHOD_NAME_CLASS_GET_COMPONENT_TYPE = "getComponentType"; - public static final String INTERNAL_METHOD_TYPE_CLASS_GET_COMPONENT_TYPE = "()Ljava/lang/Class;"; - public static final String INTERNAL_METHOD_NAME_CLASS_GET_FIELD = "getField"; - public static final String INTERNAL_METHOD_TYPE_CLASS_GET_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;"; - public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_FIELD = "getDeclaredField"; - public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;"; - public static final String INTERNAL_METHOD_NAME_CLASS_GET_METHOD = "getMethod"; - public static final String INTERNAL_METHOD_TYPE_CLASS_GET_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"; - public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_METHOD = "getDeclaredMethod"; - public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"; + public static final String INTERNAL_METHOD_NAME_CLASS_FOR_NAME = "forName"; + public static final String INTERNAL_METHOD_TYPE_CLASS_FOR_NAME = "(Ljava/lang/String;)Ljava/lang/Class;"; + public static final String INTERNAL_METHOD_NAME_CLASS_GET_COMPONENT_TYPE = "getComponentType"; + public static final String INTERNAL_METHOD_TYPE_CLASS_GET_COMPONENT_TYPE = "()Ljava/lang/Class;"; + public static final String INTERNAL_METHOD_NAME_CLASS_GET_FIELD = "getField"; + public static final String INTERNAL_METHOD_TYPE_CLASS_GET_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;"; + public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_FIELD = "getDeclaredField"; + public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;"; + public static final String INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_CONSTRUCTOR = "getConstructor"; + public static final String INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_CONSTRUCTOR = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;"; + public static final String INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_DECLARED_CONSTRUCTOR = "getDeclaredConstructor"; + public static final String INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_DECLARED_CONSTRUCTOR = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;"; + public static final String INTERNAL_METHOD_NAME_CLASS_GET_METHOD = "getMethod"; + public static final String INTERNAL_METHOD_TYPE_CLASS_GET_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"; + public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_METHOD = "getDeclaredMethod"; + public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"; + public static final String INTERNAL_METHOD_NAME_NEW_UPDATER = "newUpdater"; + public static final String INTERNAL_METHOD_TYPE_NEW_INTEGER_UPDATER = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicIntegerFieldUpdater;"; + public static final String INTERNAL_METHOD_TYPE_NEW_LONG_UPDATER = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;"; + public static final String INTERNAL_METHOD_TYPE_NEW_REFERENCE_UPDATER = "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;"; public static final String INTERNAL_METHOD_NAME_DOT_CLASS_JAVAC = "class$"; public static final String INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC = "(Ljava/lang/String;)Ljava/lang/Class;"; @@ -214,6 +252,29 @@ public interface ClassConstants public static final String INTERNAL_METHOD_NAME_NEW_INSTANCE = "newInstance"; public static final String INTERNAL_METHOD_TYPE_NEW_INSTANCE = "()Ljava/lang/Object;"; + public static final String INTERNAL_METHOD_NAME_EQUALS = "equals"; + public static final String INTERNAL_METHOD_TYPE_EQUALS = "(Ljava/lang/Object;)Z"; + public static final String INTERNAL_METHOD_NAME_LENGTH = "length"; + public static final String INTERNAL_METHOD_TYPE_LENGTH = "()I"; + public static final String INTERNAL_METHOD_NAME_APPEND = "append"; + public static final String INTERNAL_METHOD_TYPE_STRING_VOID = "(Ljava/lang/String;)V"; + public static final String INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUFFER = "(Z)Ljava/lang/StringBuffer;"; + public static final String INTERNAL_METHOD_TYPE_CHAR_STRING_BUFFER = "(C)Ljava/lang/StringBuffer;"; + public static final String INTERNAL_METHOD_TYPE_INT_STRING_BUFFER = "(I)Ljava/lang/StringBuffer;"; + public static final String INTERNAL_METHOD_TYPE_LONG_STRING_BUFFER = "(J)Ljava/lang/StringBuffer;"; + public static final String INTERNAL_METHOD_TYPE_FLOAT_STRING_BUFFER = "(F)Ljava/lang/StringBuffer;"; + public static final String INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUFFER = "(D)Ljava/lang/StringBuffer;"; + public static final String INTERNAL_METHOD_TYPE_STRING_STRING_BUFFER = "(Ljava/lang/String;)Ljava/lang/StringBuffer;"; + public static final String INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUILDER = "(Z)Ljava/lang/StringBuilder;"; + public static final String INTERNAL_METHOD_TYPE_CHAR_STRING_BUILDER = "(C)Ljava/lang/StringBuilder;"; + public static final String INTERNAL_METHOD_TYPE_INT_STRING_BUILDER = "(I)Ljava/lang/StringBuilder;"; + public static final String INTERNAL_METHOD_TYPE_LONG_STRING_BUILDER = "(J)Ljava/lang/StringBuilder;"; + public static final String INTERNAL_METHOD_TYPE_FLOAT_STRING_BUILDER = "(F)Ljava/lang/StringBuilder;"; + public static final String INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUILDER = "(D)Ljava/lang/StringBuilder;"; + public static final String INTERNAL_METHOD_TYPE_STRING_STRING_BUILDER = "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; + public static final String INTERNAL_METHOD_NAME_TOSTRING = "toString"; + public static final String INTERNAL_METHOD_TYPE_TOSTRING = "()Ljava/lang/String;"; + public static final char INTERNAL_TYPE_VOID = 'V'; public static final char INTERNAL_TYPE_BOOLEAN = 'Z'; public static final char INTERNAL_TYPE_BYTE = 'B'; diff --git a/src/proguard/classfile/ClassPool.java b/src/proguard/classfile/ClassPool.java index 57728a5..c5defe8 100644 --- a/src/proguard/classfile/ClassPool.java +++ b/src/proguard/classfile/ClassPool.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -26,14 +26,16 @@ import proguard.classfile.visitor.*; import java.util.*; /** - * This is a set of representations of classes. They can be enumerated or + * This is a set of representations of classes. They can be enumerated or * retrieved by name. They can also be accessed by means of class visitors. * * @author Eric Lafortune */ public class ClassPool { - private final Map classes = new HashMap(); + // We're using a sorted tree map instead of a hash map to store the classes, + // in order to make the processing more deterministic. + private final Map classes = new TreeMap(); /** @@ -66,11 +68,11 @@ public class ClassPool /** * Returns a Clazz from the class pool based on its name. Returns * <code>null</code> if the class with the given name is not in the class - * pool. Returns the base class if the class name is an array type. + * pool. */ public Clazz getClass(String className) { - return (Clazz)classes.get(ClassUtil.internalClassNameFromClassType(className)); + return (Clazz)classes.get(className); } @@ -122,8 +124,11 @@ public class ClassPool */ public void classesAcceptAlphabetically(ClassVisitor classVisitor) { - TreeMap sortedClasses = new TreeMap(classes); - Iterator iterator = sortedClasses.values().iterator(); + // We're already using a tree map. + //TreeMap sortedClasses = new TreeMap(classes); + //Iterator iterator = sortedClasses.values().iterator(); + + Iterator iterator = classes.values().iterator(); while (iterator.hasNext()) { Clazz clazz = (Clazz)iterator.next(); diff --git a/src/proguard/classfile/Clazz.java b/src/proguard/classfile/Clazz.java index da37d9a..3dfdcd0 100644 --- a/src/proguard/classfile/Clazz.java +++ b/src/proguard/classfile/Clazz.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -90,6 +90,16 @@ public interface Clazz extends VisitorAccepter */ public String getType(int constantIndex); + /** + * Returns the name of the RefConstant at the specified index. + */ + public String getRefName(int constantIndex); + + /** + * Returns the type of the RefConstant at the specified index. + */ + public String getRefType(int constantIndex); + // Methods pertaining to related classes. @@ -116,12 +126,26 @@ public interface Clazz extends VisitorAccepter public boolean extends_(Clazz clazz); /** + * Returns whether this class extends the specified class. + * A class is always considered to extend itself. + * Interfaces are considered to only extend the root Object class. + */ + public boolean extends_(String className); + + /** * Returns whether this class implements the given class. * A class is always considered to implement itself. * Interfaces are considered to implement all their superinterfaces. */ public boolean extendsOrImplements(Clazz clazz); + /** + * Returns whether this class implements the specified class. + * A class is always considered to implement itself. + * Interfaces are considered to implement all their superinterfaces. + */ + public boolean extendsOrImplements(String className); + // Methods for getting specific class members. @@ -229,4 +253,9 @@ public interface Clazz extends VisitorAccepter * Lets the given attribute info visitor visit all attributes of this class. */ public void attributesAccept(AttributeVisitor attributeVisitor); + + /** + * Lets the given attribute info visitor visit the specified attribute. + */ + public void attributeAccept(String name, AttributeVisitor attributeVisitor); } diff --git a/src/proguard/classfile/Field.java b/src/proguard/classfile/Field.java index ba1315a..c30321d 100644 --- a/src/proguard/classfile/Field.java +++ b/src/proguard/classfile/Field.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/LibraryClass.java b/src/proguard/classfile/LibraryClass.java index 0a27593..625d088 100644 --- a/src/proguard/classfile/LibraryClass.java +++ b/src/proguard/classfile/LibraryClass.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -137,6 +137,17 @@ public class LibraryClass implements Clazz } + public String getRefName(int constantIndex) + { + throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool"); + } + + public String getRefType(int constantIndex) + { + throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool"); + } + + public void addSubClass(Clazz clazz) { if (subClasses == null) @@ -179,6 +190,18 @@ public class LibraryClass implements Clazz } + public boolean extends_(String className) + { + if (getName().equals(className)) + { + return true; + } + + return superClass != null && + superClass.extends_(className); + } + + public boolean extendsOrImplements(Clazz clazz) { if (this.equals(clazz)) @@ -209,6 +232,36 @@ public class LibraryClass implements Clazz } + public boolean extendsOrImplements(String className) + { + if (getName().equals(className)) + { + return true; + } + + if (superClass != null && + superClass.extendsOrImplements(className)) + { + return true; + } + + if (interfaceClasses != null) + { + for (int index = 0; index < interfaceClasses.length; index++) + { + Clazz interfaceClass = interfaceClasses[index]; + if (interfaceClass != null && + interfaceClass.extendsOrImplements(className)) + { + return true; + } + } + } + + return false; + } + + public Field findField(String name, String descriptor) { for (int index = 0; index < fields.length; index++) @@ -467,6 +520,12 @@ public class LibraryClass implements Clazz } + public void attributeAccept(String name, AttributeVisitor attributeVisitor) + { + throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store attributes"); + } + + // Implementations for VisitorAccepter. public Object getVisitorInfo() diff --git a/src/proguard/classfile/LibraryField.java b/src/proguard/classfile/LibraryField.java index 2908c37..e9c8469 100644 --- a/src/proguard/classfile/LibraryField.java +++ b/src/proguard/classfile/LibraryField.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/LibraryMember.java b/src/proguard/classfile/LibraryMember.java index 41ccb60..ef5a4d7 100644 --- a/src/proguard/classfile/LibraryMember.java +++ b/src/proguard/classfile/LibraryMember.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/LibraryMethod.java b/src/proguard/classfile/LibraryMethod.java index a49a5f1..cd95ea6 100644 --- a/src/proguard/classfile/LibraryMethod.java +++ b/src/proguard/classfile/LibraryMethod.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/Member.java b/src/proguard/classfile/Member.java index 1400b9c..2e984c2 100644 --- a/src/proguard/classfile/Member.java +++ b/src/proguard/classfile/Member.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/Method.java b/src/proguard/classfile/Method.java index ebcae2b..ec8f2b5 100644 --- a/src/proguard/classfile/Method.java +++ b/src/proguard/classfile/Method.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/ProgramClass.java b/src/proguard/classfile/ProgramClass.java index 9d0fc0c..e3caddb 100644 --- a/src/proguard/classfile/ProgramClass.java +++ b/src/proguard/classfile/ProgramClass.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -117,8 +117,7 @@ public class ProgramClass implements Clazz } catch (ClassCastException ex) { - new ClassPrinter().visitProgramClass(this); - throw new ClassCastException("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]"); + throw ((IllegalStateException)new IllegalStateException("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex)); } } @@ -130,7 +129,7 @@ public class ProgramClass implements Clazz } catch (ClassCastException ex) { - throw new ClassCastException("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]"); + throw ((IllegalStateException)new IllegalStateException("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex)); } } @@ -142,7 +141,7 @@ public class ProgramClass implements Clazz } catch (ClassCastException ex) { - throw new ClassCastException("Expected ClassConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]"); + throw ((IllegalStateException)new IllegalStateException("Expected ClassConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex)); } } @@ -154,7 +153,7 @@ public class ProgramClass implements Clazz } catch (ClassCastException ex) { - throw new ClassCastException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]"); + throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex)); } } @@ -166,7 +165,32 @@ public class ProgramClass implements Clazz } catch (ClassCastException ex) { - throw new ClassCastException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]"); + throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex)); + } + } + + + public String getRefName(int constantIndex) + { + try + { + return ((RefConstant)constantPool[constantIndex]).getName(this); + } + catch (ClassCastException ex) + { + throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex)); + } + } + + public String getRefType(int constantIndex) + { + try + { + return ((RefConstant)constantPool[constantIndex]).getType(this); + } + catch (ClassCastException ex) + { + throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex)); } } @@ -216,6 +240,19 @@ public class ProgramClass implements Clazz } + public boolean extends_(String className) + { + if (getName().equals(className)) + { + return true; + } + + Clazz superClass = getSuperClass(); + return superClass != null && + superClass.extends_(className); + } + + public boolean extendsOrImplements(Clazz clazz) { if (this.equals(clazz)) @@ -244,6 +281,34 @@ public class ProgramClass implements Clazz } + public boolean extendsOrImplements(String className) + { + if (getName().equals(className)) + { + return true; + } + + Clazz superClass = getSuperClass(); + if (superClass != null && + superClass.extendsOrImplements(className)) + { + return true; + } + + for (int index = 0; index < u2interfacesCount; index++) + { + Clazz interfaceClass = getInterface(index); + if (interfaceClass != null && + interfaceClass.extendsOrImplements(className)) + { + return true; + } + } + + return false; + } + + public Field findField(String name, String descriptor) { for (int index = 0; index < u2fieldsCount; index++) @@ -472,6 +537,19 @@ public class ProgramClass implements Clazz } + public void attributeAccept(String name, AttributeVisitor attributeVisitor) + { + for (int index = 0; index < u2attributesCount; index++) + { + Attribute attribute = attributes[index]; + if (attribute.getAttributeName(this).equals(name)) + { + attribute.accept(this, attributeVisitor); + } + } + } + + // Implementations for VisitorAccepter. public Object getVisitorInfo() diff --git a/src/proguard/classfile/ProgramField.java b/src/proguard/classfile/ProgramField.java index 5991b00..761fe95 100644 --- a/src/proguard/classfile/ProgramField.java +++ b/src/proguard/classfile/ProgramField.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/ProgramMember.java b/src/proguard/classfile/ProgramMember.java index ea6f46d..86d12d9 100644 --- a/src/proguard/classfile/ProgramMember.java +++ b/src/proguard/classfile/ProgramMember.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/ProgramMethod.java b/src/proguard/classfile/ProgramMethod.java index 943c3d6..39e720f 100644 --- a/src/proguard/classfile/ProgramMethod.java +++ b/src/proguard/classfile/ProgramMethod.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/VisitorAccepter.java b/src/proguard/classfile/VisitorAccepter.java index e38f888..551d025 100644 --- a/src/proguard/classfile/VisitorAccepter.java +++ b/src/proguard/classfile/VisitorAccepter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/Attribute.java b/src/proguard/classfile/attribute/Attribute.java index 2e16e22..0eaafbb 100644 --- a/src/proguard/classfile/attribute/Attribute.java +++ b/src/proguard/classfile/attribute/Attribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/BootstrapMethodInfo.java b/src/proguard/classfile/attribute/BootstrapMethodInfo.java new file mode 100755 index 0000000..c593251 --- /dev/null +++ b/src/proguard/classfile/attribute/BootstrapMethodInfo.java @@ -0,0 +1,89 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.attribute; + +import proguard.classfile.*; +import proguard.classfile.constant.visitor.ConstantVisitor; + +/** + * Representation of a bootstrap method. + * + * @author Eric Lafortune + */ +public class BootstrapMethodInfo implements VisitorAccepter +{ + public int u2methodHandleIndex; + public int u2methodArgumentCount; + public int[] u2methodArguments; + + /** + * An extra field in which visitors can store information. + */ + public Object visitorInfo; + + + /** + * Creates an uninitialized BootstrapMethodInfo. + */ + public BootstrapMethodInfo() + { + } + + + /** + * Creates an initialized BootstrapMethodInfo. + */ + public BootstrapMethodInfo(int u2methodHandleIndex, + int u2methodArgumentCount, + int[] u2methodArguments) + { + this.u2methodHandleIndex = u2methodHandleIndex; + this.u2methodArgumentCount = u2methodArgumentCount; + this.u2methodArguments = u2methodArguments; + } + + + /** + * Applies the given constant pool visitor to the argument constants of the + * bootstrap method. + */ + public void methodArgumentsAccept(Clazz clazz, ConstantVisitor constantVisitor) + { + for (int index = 0; index < u2methodArgumentCount; index++) + { + clazz.constantPoolEntryAccept(u2methodArguments[index], + constantVisitor); + } + } + + + // Implementations for VisitorAccepter. + + public Object getVisitorInfo() + { + return visitorInfo; + } + + public void setVisitorInfo(Object visitorInfo) + { + this.visitorInfo = visitorInfo; + } +} diff --git a/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java b/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java new file mode 100755 index 0000000..b8ec9bd --- /dev/null +++ b/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java @@ -0,0 +1,95 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.attribute; + +import proguard.classfile.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.visitor.ConstantVisitor; + +/** + * This Attribute represents a bootstrap methods attribute. + * + * @author Eric Lafortune + */ +public class BootstrapMethodsAttribute extends Attribute +{ + public int u2bootstrapMethodsCount; + public BootstrapMethodInfo[] bootstrapMethods; + + + /** + * Creates an uninitialized BootstrapMethodsAttribute. + */ + public BootstrapMethodsAttribute() + { + } + + + /** + * Creates an initialized BootstrapMethodsAttribute. + */ + public BootstrapMethodsAttribute(int u2attributeNameIndex, + int u2bootstrapMethodsCount, + BootstrapMethodInfo[] bootstrapMethods) + { + super(u2attributeNameIndex); + + this.u2bootstrapMethodsCount = u2bootstrapMethodsCount; + this.bootstrapMethods = bootstrapMethods; + } + + + // Implementations for Attribute. + + public void accept(Clazz clazz, AttributeVisitor attributeVisitor) + { + attributeVisitor.visitBootstrapMethodsAttribute(clazz, this); + } + + + /** + * Applies the given constant pool visitor to all bootstrap method info + * entries. + */ + public void bootstrapMethodEntriesAccept(Clazz clazz, BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor) + { + for (int index = 0; index < u2bootstrapMethodsCount; index++) + { + // We don't need double dispatching here, since there is only one + // type of BootstrapMethodInfo. + bootstrapMethodInfoVisitor.visitBootstrapMethodInfo(clazz, bootstrapMethods[index]); + } + } + + + /** + * Applies the given constant pool visitor to the specified bootstrap method + * info entry. + */ + public void bootstrapMethodEntryAccept(Clazz clazz, + int bootstrapMethodIndex, + BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor) + { + // We don't need double dispatching here, since there is only one + // type of BootstrapMethodInfo. + bootstrapMethodInfoVisitor.visitBootstrapMethodInfo(clazz, bootstrapMethods[bootstrapMethodIndex]); + } +} diff --git a/src/proguard/classfile/attribute/CodeAttribute.java b/src/proguard/classfile/attribute/CodeAttribute.java index 92ff9ea..9d5a254 100644 --- a/src/proguard/classfile/attribute/CodeAttribute.java +++ b/src/proguard/classfile/attribute/CodeAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/ConstantValueAttribute.java b/src/proguard/classfile/attribute/ConstantValueAttribute.java index 3ae991e..737ade0 100644 --- a/src/proguard/classfile/attribute/ConstantValueAttribute.java +++ b/src/proguard/classfile/attribute/ConstantValueAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/DeprecatedAttribute.java b/src/proguard/classfile/attribute/DeprecatedAttribute.java index 4180950..d440242 100644 --- a/src/proguard/classfile/attribute/DeprecatedAttribute.java +++ b/src/proguard/classfile/attribute/DeprecatedAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/EnclosingMethodAttribute.java b/src/proguard/classfile/attribute/EnclosingMethodAttribute.java index 9275b3a..befd585 100644 --- a/src/proguard/classfile/attribute/EnclosingMethodAttribute.java +++ b/src/proguard/classfile/attribute/EnclosingMethodAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/ExceptionInfo.java b/src/proguard/classfile/attribute/ExceptionInfo.java index 082efab..5f605cf 100644 --- a/src/proguard/classfile/attribute/ExceptionInfo.java +++ b/src/proguard/classfile/attribute/ExceptionInfo.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/ExceptionsAttribute.java b/src/proguard/classfile/attribute/ExceptionsAttribute.java index d22c4a6..8dfd096 100644 --- a/src/proguard/classfile/attribute/ExceptionsAttribute.java +++ b/src/proguard/classfile/attribute/ExceptionsAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -69,12 +69,12 @@ public class ExceptionsAttribute extends Attribute * Applies the given constant pool visitor to all exception class pool info * entries. */ - public void exceptionEntriesAccept(ProgramClass programClass, ConstantVisitor constantVisitor) + public void exceptionEntriesAccept(Clazz clazz, ConstantVisitor constantVisitor) { for (int index = 0; index < u2exceptionIndexTableLength; index++) { - programClass.constantPoolEntryAccept(u2exceptionIndexTable[index], - constantVisitor); + clazz.constantPoolEntryAccept(u2exceptionIndexTable[index], + constantVisitor); } } } diff --git a/src/proguard/classfile/attribute/InnerClassesAttribute.java b/src/proguard/classfile/attribute/InnerClassesAttribute.java index 2f7e310..135c61c 100644 --- a/src/proguard/classfile/attribute/InnerClassesAttribute.java +++ b/src/proguard/classfile/attribute/InnerClassesAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/InnerClassesInfo.java b/src/proguard/classfile/attribute/InnerClassesInfo.java index 1bdd6c3..87f9768 100644 --- a/src/proguard/classfile/attribute/InnerClassesInfo.java +++ b/src/proguard/classfile/attribute/InnerClassesInfo.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -74,8 +74,7 @@ public class InnerClassesInfo implements VisitorAccepter { if (u2innerClassIndex != 0) { - clazz.constantPoolEntryAccept(u2innerClassIndex, - constantVisitor); + clazz.constantPoolEntryAccept(u2innerClassIndex, constantVisitor); } } @@ -88,8 +87,7 @@ public class InnerClassesInfo implements VisitorAccepter { if (u2outerClassIndex != 0) { - clazz.constantPoolEntryAccept(u2outerClassIndex, - constantVisitor); + clazz.constantPoolEntryAccept(u2outerClassIndex, constantVisitor); } } @@ -102,8 +100,7 @@ public class InnerClassesInfo implements VisitorAccepter { if (u2innerNameIndex != 0) { - clazz.constantPoolEntryAccept(u2innerNameIndex, - constantVisitor); + clazz.constantPoolEntryAccept(u2innerNameIndex, constantVisitor); } } diff --git a/src/proguard/classfile/attribute/LineNumberInfo.java b/src/proguard/classfile/attribute/LineNumberInfo.java index f58083a..6ad7ed2 100644 --- a/src/proguard/classfile/attribute/LineNumberInfo.java +++ b/src/proguard/classfile/attribute/LineNumberInfo.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/LineNumberTableAttribute.java b/src/proguard/classfile/attribute/LineNumberTableAttribute.java index 4d507d9..b9056d9 100644 --- a/src/proguard/classfile/attribute/LineNumberTableAttribute.java +++ b/src/proguard/classfile/attribute/LineNumberTableAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/LocalVariableInfo.java b/src/proguard/classfile/attribute/LocalVariableInfo.java index 4e54c22..589bb7a 100644 --- a/src/proguard/classfile/attribute/LocalVariableInfo.java +++ b/src/proguard/classfile/attribute/LocalVariableInfo.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -28,7 +28,7 @@ import proguard.classfile.visitor.ClassVisitor; * * @author Eric Lafortune */ -public class LocalVariableInfo +public class LocalVariableInfo implements Comparable { public int u2startPC; public int u2length; @@ -80,4 +80,20 @@ public class LocalVariableInfo referencedClass.accept(classVisitor); } } + + + // Implementations for Comparable. + + public int compareTo(Object object) + { + LocalVariableInfo other = (LocalVariableInfo)object; + + return + this.u2startPC < other.u2startPC ? -1 : this.u2startPC > other.u2startPC ? 1 : + this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 : + this.u2index < other.u2index ? -1 : this.u2index > other.u2index ? 1 : + this.u2descriptorIndex < other.u2descriptorIndex ? -1 : this.u2descriptorIndex > other.u2descriptorIndex ? 1 : + this.u2nameIndex < other.u2nameIndex ? -1 : this.u2nameIndex > other.u2nameIndex ? 1 : + 0; + } } diff --git a/src/proguard/classfile/attribute/LocalVariableTableAttribute.java b/src/proguard/classfile/attribute/LocalVariableTableAttribute.java index 9c3f115..02eae2a 100644 --- a/src/proguard/classfile/attribute/LocalVariableTableAttribute.java +++ b/src/proguard/classfile/attribute/LocalVariableTableAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/LocalVariableTypeInfo.java b/src/proguard/classfile/attribute/LocalVariableTypeInfo.java index 1b71f35..3a77e3d 100644 --- a/src/proguard/classfile/attribute/LocalVariableTypeInfo.java +++ b/src/proguard/classfile/attribute/LocalVariableTypeInfo.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -28,7 +28,7 @@ import proguard.classfile.visitor.ClassVisitor; * * @author Eric Lafortune */ -public class LocalVariableTypeInfo +public class LocalVariableTypeInfo implements Comparable { public int u2startPC; public int u2length; @@ -88,4 +88,20 @@ public class LocalVariableTypeInfo } } } + + + // Implementations for Comparable. + + public int compareTo(Object object) + { + LocalVariableTypeInfo other = (LocalVariableTypeInfo)object; + + return + this.u2startPC < other.u2startPC ? -1 : this.u2startPC > other.u2startPC ? 1 : + this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 : + this.u2index < other.u2index ? -1 : this.u2index > other.u2index ? 1 : + this.u2signatureIndex < other.u2signatureIndex ? -1 : this.u2signatureIndex > other.u2signatureIndex ? 1 : + this.u2nameIndex < other.u2nameIndex ? -1 : this.u2nameIndex > other.u2nameIndex ? 1 : + 0; + } } diff --git a/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java b/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java index fd856fe..3a2ab75 100644 --- a/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java +++ b/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/SignatureAttribute.java b/src/proguard/classfile/attribute/SignatureAttribute.java index c7585fe..2b59775 100644 --- a/src/proguard/classfile/attribute/SignatureAttribute.java +++ b/src/proguard/classfile/attribute/SignatureAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/SourceDirAttribute.java b/src/proguard/classfile/attribute/SourceDirAttribute.java index a26e8b1..f9e4005 100644 --- a/src/proguard/classfile/attribute/SourceDirAttribute.java +++ b/src/proguard/classfile/attribute/SourceDirAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/SourceFileAttribute.java b/src/proguard/classfile/attribute/SourceFileAttribute.java index 24269b7..b28e139 100644 --- a/src/proguard/classfile/attribute/SourceFileAttribute.java +++ b/src/proguard/classfile/attribute/SourceFileAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/SyntheticAttribute.java b/src/proguard/classfile/attribute/SyntheticAttribute.java index 6ccb1b5..cbb7e30 100644 --- a/src/proguard/classfile/attribute/SyntheticAttribute.java +++ b/src/proguard/classfile/attribute/SyntheticAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/UnknownAttribute.java b/src/proguard/classfile/attribute/UnknownAttribute.java index 2f138bd..11f6029 100644 --- a/src/proguard/classfile/attribute/UnknownAttribute.java +++ b/src/proguard/classfile/attribute/UnknownAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/Annotation.java b/src/proguard/classfile/attribute/annotation/Annotation.java index 41bb8e3..248c8f3 100644 --- a/src/proguard/classfile/attribute/annotation/Annotation.java +++ b/src/proguard/classfile/attribute/annotation/Annotation.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java b/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java index b378cd2..9ac7eae 100644 --- a/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java +++ b/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java b/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java index 29129d0..0cfefac 100644 --- a/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java +++ b/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java index 8117077..1786f15 100644 --- a/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java +++ b/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/ArrayElementValue.java b/src/proguard/classfile/attribute/annotation/ArrayElementValue.java index 25b8b9f..f2bf911 100644 --- a/src/proguard/classfile/attribute/annotation/ArrayElementValue.java +++ b/src/proguard/classfile/attribute/annotation/ArrayElementValue.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/ClassElementValue.java b/src/proguard/classfile/attribute/annotation/ClassElementValue.java index ba51641..b174695 100644 --- a/src/proguard/classfile/attribute/annotation/ClassElementValue.java +++ b/src/proguard/classfile/attribute/annotation/ClassElementValue.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/ConstantElementValue.java b/src/proguard/classfile/attribute/annotation/ConstantElementValue.java index 3ebe5e5..f8bfc7f 100644 --- a/src/proguard/classfile/attribute/annotation/ConstantElementValue.java +++ b/src/proguard/classfile/attribute/annotation/ConstantElementValue.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/ElementValue.java b/src/proguard/classfile/attribute/annotation/ElementValue.java index 39f8953..415aa6a 100644 --- a/src/proguard/classfile/attribute/annotation/ElementValue.java +++ b/src/proguard/classfile/attribute/annotation/ElementValue.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java b/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java index d46bb7f..c6fbb52 100644 --- a/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java +++ b/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java index 3c700c8..0aca20f 100644 --- a/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java +++ b/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java index 9c8180c..4494b4c 100644 --- a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java +++ b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java index 7e41656..5696a37 100644 --- a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java +++ b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java index 380c52e..e25d868 100644 --- a/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java +++ b/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java index 626fbda..722792e 100644 --- a/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java +++ b/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java index bce7170..4af6946 100644 --- a/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java +++ b/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java index 7a1d7c6..4582728 100644 --- a/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java +++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java index c206c16..c3e5eb0 100644 --- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java +++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java index d869fd2..6068dfb 100644 --- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java +++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java index 16b2a56..b079628 100644 --- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java +++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java index 112084a..0f89b06 100644 --- a/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java +++ b/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/DoubleType.java b/src/proguard/classfile/attribute/preverification/DoubleType.java index d574dcb..4cc614d 100644 --- a/src/proguard/classfile/attribute/preverification/DoubleType.java +++ b/src/proguard/classfile/attribute/preverification/DoubleType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/FloatType.java b/src/proguard/classfile/attribute/preverification/FloatType.java index 2f24720..2559d53 100644 --- a/src/proguard/classfile/attribute/preverification/FloatType.java +++ b/src/proguard/classfile/attribute/preverification/FloatType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/FullFrame.java b/src/proguard/classfile/attribute/preverification/FullFrame.java index adf5684..39cc7f6 100644 --- a/src/proguard/classfile/attribute/preverification/FullFrame.java +++ b/src/proguard/classfile/attribute/preverification/FullFrame.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/IntegerType.java b/src/proguard/classfile/attribute/preverification/IntegerType.java index 55e3abe..3dc6382 100644 --- a/src/proguard/classfile/attribute/preverification/IntegerType.java +++ b/src/proguard/classfile/attribute/preverification/IntegerType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/LessZeroFrame.java b/src/proguard/classfile/attribute/preverification/LessZeroFrame.java index fcc8e0a..e995346 100644 --- a/src/proguard/classfile/attribute/preverification/LessZeroFrame.java +++ b/src/proguard/classfile/attribute/preverification/LessZeroFrame.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/LongType.java b/src/proguard/classfile/attribute/preverification/LongType.java index 9b14dd6..a2f3eaa 100644 --- a/src/proguard/classfile/attribute/preverification/LongType.java +++ b/src/proguard/classfile/attribute/preverification/LongType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java b/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java index 881f188..1a375f1 100644 --- a/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java +++ b/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/NullType.java b/src/proguard/classfile/attribute/preverification/NullType.java index f35cefd..4832751 100644 --- a/src/proguard/classfile/attribute/preverification/NullType.java +++ b/src/proguard/classfile/attribute/preverification/NullType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/ObjectType.java b/src/proguard/classfile/attribute/preverification/ObjectType.java index fbdeec7..acc45e1 100644 --- a/src/proguard/classfile/attribute/preverification/ObjectType.java +++ b/src/proguard/classfile/attribute/preverification/ObjectType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/SameOneFrame.java b/src/proguard/classfile/attribute/preverification/SameOneFrame.java index db6747b..7d5db73 100644 --- a/src/proguard/classfile/attribute/preverification/SameOneFrame.java +++ b/src/proguard/classfile/attribute/preverification/SameOneFrame.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/SameZeroFrame.java b/src/proguard/classfile/attribute/preverification/SameZeroFrame.java index 64b17f5..ffde7f5 100644 --- a/src/proguard/classfile/attribute/preverification/SameZeroFrame.java +++ b/src/proguard/classfile/attribute/preverification/SameZeroFrame.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/StackMapAttribute.java b/src/proguard/classfile/attribute/preverification/StackMapAttribute.java index db53ff1..fe0e010 100644 --- a/src/proguard/classfile/attribute/preverification/StackMapAttribute.java +++ b/src/proguard/classfile/attribute/preverification/StackMapAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/StackMapFrame.java b/src/proguard/classfile/attribute/preverification/StackMapFrame.java index aa3e1f2..999863b 100644 --- a/src/proguard/classfile/attribute/preverification/StackMapFrame.java +++ b/src/proguard/classfile/attribute/preverification/StackMapFrame.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java b/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java index 0cddf70..7a2be14 100644 --- a/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java +++ b/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/TopType.java b/src/proguard/classfile/attribute/preverification/TopType.java index bde8dda..27321bc 100644 --- a/src/proguard/classfile/attribute/preverification/TopType.java +++ b/src/proguard/classfile/attribute/preverification/TopType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/UninitializedThisType.java b/src/proguard/classfile/attribute/preverification/UninitializedThisType.java index dc4654f..1a9bf83 100644 --- a/src/proguard/classfile/attribute/preverification/UninitializedThisType.java +++ b/src/proguard/classfile/attribute/preverification/UninitializedThisType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/UninitializedType.java b/src/proguard/classfile/attribute/preverification/UninitializedType.java index a495f1f..4b2963c 100644 --- a/src/proguard/classfile/attribute/preverification/UninitializedType.java +++ b/src/proguard/classfile/attribute/preverification/UninitializedType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/VerificationType.java b/src/proguard/classfile/attribute/preverification/VerificationType.java index f33d511..720f221 100644 --- a/src/proguard/classfile/attribute/preverification/VerificationType.java +++ b/src/proguard/classfile/attribute/preverification/VerificationType.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java b/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java index f8ef7e0..c99ee7d 100644 --- a/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java +++ b/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java b/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java index 7db246c..1b4ffad 100644 --- a/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java +++ b/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java b/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java index e9931f8..703e8c4 100644 --- a/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java +++ b/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java b/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java index 61b0f1a..8c4555d 100644 --- a/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java +++ b/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java new file mode 100644 index 0000000..fbc9189 --- /dev/null +++ b/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java @@ -0,0 +1,55 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.attribute.visitor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This AttributeVisitor lets a given BootstrapMethodInfoVisitor visit all + * bootstrap method objects of the BootstrapMethodsAttribute objects it visits. + * + * @author Eric Lafortune + */ +public class AllBootstrapMethodInfoVisitor +extends SimplifiedVisitor +implements AttributeVisitor +{ + private final BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor; + + + public AllBootstrapMethodInfoVisitor(BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor) + { + this.bootstrapMethodInfoVisitor = bootstrapMethodInfoVisitor; + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, bootstrapMethodInfoVisitor); + } +} diff --git a/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java index 839e104..e502123 100644 --- a/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java +++ b/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java new file mode 100644 index 0000000..3e1f0a7 --- /dev/null +++ b/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java @@ -0,0 +1,55 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.attribute.visitor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This AttributeVisitor lets a given InnerClassesInfoVisitor visit all + * InnerClassessInfo objects of the InnerClassesAttribute objects it visits. + * + * @author Eric Lafortune + */ +public class AllInnerClassesInfoVisitor +extends SimplifiedVisitor +implements AttributeVisitor +{ + private final InnerClassesInfoVisitor innerClassesInfoVisitor; + + + public AllInnerClassesInfoVisitor(InnerClassesInfoVisitor innerClassesInfoVisitor) + { + this.innerClassesInfoVisitor = innerClassesInfoVisitor; + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) + { + innerClassesAttribute.innerClassEntriesAccept(clazz, innerClassesInfoVisitor); + } +}
\ No newline at end of file diff --git a/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java b/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java index aa81ce0..9906483 100644 --- a/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java +++ b/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -24,7 +24,7 @@ import proguard.classfile.*; import proguard.classfile.attribute.*; import proguard.classfile.attribute.annotation.*; import proguard.classfile.attribute.preverification.*; -import proguard.util.StringMatcher; +import proguard.util.*; /** * This AttributeVisitor delegates its visits another AttributeVisitor, but @@ -41,7 +41,21 @@ implements AttributeVisitor /** - * Creates a new AttributeNameFilter. + * Creates a new AttributeNameFilter based on a given name. + * @param name the string matcher that will check the attribute + * names. + * @param attributeVisitor the <code>AttributeVisitor</code> to which + * visits will be delegated. + */ + public AttributeNameFilter(String name, + AttributeVisitor attributeVisitor) + { + this(new FixedStringMatcher(name), attributeVisitor); + } + + + /** + * Creates a new AttributeNameFilter based on a given string matcher. * @param stringMatcher the string matcher that will check the attribute * names. * @param attributeVisitor the <code>AttributeVisitor</code> to which @@ -66,6 +80,15 @@ implements AttributeVisitor } + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + if (accepted(clazz, bootstrapMethodsAttribute)) + { + bootstrapMethodsAttribute.accept(clazz, attributeVisitor); + } + } + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { if (accepted(clazz, sourceFileAttribute)) diff --git a/src/proguard/classfile/attribute/visitor/AttributeVisitor.java b/src/proguard/classfile/attribute/visitor/AttributeVisitor.java index e8f226b..bb7ee34 100644 --- a/src/proguard/classfile/attribute/visitor/AttributeVisitor.java +++ b/src/proguard/classfile/attribute/visitor/AttributeVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -35,11 +35,12 @@ public interface AttributeVisitor { // Attributes that are attached to classes. - public void visitUnknownAttribute( Clazz clazz, UnknownAttribute unknownAttribute); - public void visitSourceFileAttribute( Clazz clazz, SourceFileAttribute sourceFileAttribute); - public void visitSourceDirAttribute( Clazz clazz, SourceDirAttribute sourceDirAttribute); - public void visitInnerClassesAttribute( Clazz clazz, InnerClassesAttribute innerClassesAttribute); - public void visitEnclosingMethodAttribute( Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute); + public void visitUnknownAttribute( Clazz clazz, UnknownAttribute unknownAttribute); + public void visitBootstrapMethodsAttribute( Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute); + public void visitSourceFileAttribute( Clazz clazz, SourceFileAttribute sourceFileAttribute); + public void visitSourceDirAttribute( Clazz clazz, SourceDirAttribute sourceDirAttribute); + public void visitInnerClassesAttribute( Clazz clazz, InnerClassesAttribute innerClassesAttribute); + public void visitEnclosingMethodAttribute( Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute); // Attributes that are attached to classes, fields, and methods. diff --git a/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java b/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java new file mode 100755 index 0000000..4828d7f --- /dev/null +++ b/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java @@ -0,0 +1,40 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.attribute.visitor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; + +import java.beans.MethodDescriptor; + + +/** + * This interface specifies the methods for a visitor of + * <code>BootstrapMethodInfo</code> objects. Note that there is only a single + * implementation of <code>BootstrapMethodInfo</code>, such that this interface + * is not strictly necessary as a visitor. + * + * @author Eric Lafortune + */ +public interface BootstrapMethodInfoVisitor +{ + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo); +} diff --git a/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java b/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java index 7c85e53..a96d4bf 100644 --- a/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java +++ b/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java b/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java index 91267b0..8f033bf 100644 --- a/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java +++ b/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java index e59ed7b..32efa63 100644 --- a/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java +++ b/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java index 8647cb3..d00e184 100644 --- a/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java +++ b/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java index 9ad38e0..7018fea 100644 --- a/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java +++ b/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java b/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java index 870ba94..4156654 100644 --- a/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java +++ b/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -85,6 +85,15 @@ public class MultiAttributeVisitor implements AttributeVisitor } + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + for (int index = 0; index < attributeVisitors.length; index++) + { + attributeVisitors[index].visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute); + } + } + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { for (int index = 0; index < attributeVisitors.length; index++) diff --git a/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java b/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java new file mode 100644 index 0000000..1b0460f --- /dev/null +++ b/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java @@ -0,0 +1,293 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.attribute.visitor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.preverification.*; +import proguard.util.StringMatcher; + +/** + * This AttributeVisitor delegates its visits another AttributeVisitor, but + * only when the visited attribute is not empty. For instance, a local variable + * table without variables is empty. + * + * @author Eric Lafortune + */ +public class NonEmptyAttributeFilter +implements AttributeVisitor +{ + private final AttributeVisitor attributeVisitor; + + + /** + * Creates a new NonEmptyAttributeFilter. + * @param attributeVisitor the <code>AttributeVisitor</code> to which + * visits will be delegated. + */ + public NonEmptyAttributeFilter(AttributeVisitor attributeVisitor) + { + this.attributeVisitor = attributeVisitor; + } + + + // Implementations for AttributeVisitor. + + public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) + { + unknownAttribute.accept(clazz, attributeVisitor); + } + + + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + if (bootstrapMethodsAttribute.u2bootstrapMethodsCount > 0) + { + bootstrapMethodsAttribute.accept(clazz, attributeVisitor); + } + } + + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) + { + sourceFileAttribute.accept(clazz, attributeVisitor); + } + + + public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) + { + sourceDirAttribute.accept(clazz, attributeVisitor); + } + + + public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) + { + if (innerClassesAttribute.u2classesCount > 0) + { + innerClassesAttribute.accept(clazz, attributeVisitor); + } + } + + + public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) + { + enclosingMethodAttribute.accept(clazz, attributeVisitor); + } + + + public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) + { + deprecatedAttribute.accept(clazz, attributeVisitor); + } + + + public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute) + { + deprecatedAttribute.accept(clazz, field, attributeVisitor); + } + + + public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute) + { + deprecatedAttribute.accept(clazz, method, attributeVisitor); + } + + + public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) + { + syntheticAttribute.accept(clazz, attributeVisitor); + } + + + public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute) + { + syntheticAttribute.accept(clazz, field, attributeVisitor); + } + + + public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute) + { + syntheticAttribute.accept(clazz, method, attributeVisitor); + } + + + public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) + { + signatureAttribute.accept(clazz, attributeVisitor); + } + + + public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute) + { + signatureAttribute.accept(clazz, field, attributeVisitor); + } + + + public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute) + { + signatureAttribute.accept(clazz, method, attributeVisitor); + } + + + public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) + { + constantValueAttribute.accept(clazz, field, attributeVisitor); + } + + + public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) + { + if (exceptionsAttribute.u2exceptionIndexTableLength > 0) + { + exceptionsAttribute.accept(clazz, method, attributeVisitor); + } + } + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + codeAttribute.accept(clazz, method, attributeVisitor); + } + + + public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) + { + if (stackMapAttribute.u2stackMapFramesCount > 0) + { + stackMapAttribute.accept(clazz, method, codeAttribute, attributeVisitor); + } + } + + + public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) + { + if (stackMapTableAttribute.u2stackMapFramesCount > 0) + { + stackMapTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor); + } + } + + + public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) + { + if (lineNumberTableAttribute.u2lineNumberTableLength > 0) + { + lineNumberTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor); + } + } + + + public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) + { + if (localVariableTableAttribute.u2localVariableTableLength > 0) + { + localVariableTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor); + } + } + + + public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) + { + if (localVariableTypeTableAttribute.u2localVariableTypeTableLength > 0) + { + localVariableTypeTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor); + } + } + + + public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) + { + if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0) + { + runtimeVisibleAnnotationsAttribute.accept(clazz, attributeVisitor); + } + } + + + public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) + { + if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0) + { + runtimeVisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor); + } + } + + + public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) + { + if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0) + { + runtimeVisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor); + } + } + + + public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) + { + if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0) + { + runtimeInvisibleAnnotationsAttribute.accept(clazz, attributeVisitor); + } + } + + + public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) + { + if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0) + { + runtimeInvisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor); + } + } + + + public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) + { + if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0) + { + runtimeInvisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor); + } + } + + + public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute) + { + if (runtimeVisibleParameterAnnotationsAttribute.u2parametersCount > 0) + { + runtimeVisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor); + } + } + + + public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute) + { + if (runtimeInvisibleParameterAnnotationsAttribute.u2parametersCount > 0) + { + runtimeInvisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor); + } + } + + + public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) + { + annotationDefaultAttribute.accept(clazz, method, attributeVisitor); + } +} diff --git a/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java b/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java index 92099f9..e392ee7 100644 --- a/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java +++ b/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -80,6 +80,15 @@ implements AttributeVisitor } + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + if (requiredAttributeVisitor != null) + { + bootstrapMethodsAttribute.accept(clazz, requiredAttributeVisitor); + } + } + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { if (optionalAttributeVisitor != null) diff --git a/src/proguard/classfile/attribute/visitor/StackSizeComputer.java b/src/proguard/classfile/attribute/visitor/StackSizeComputer.java index 401f188..c4711d1 100644 --- a/src/proguard/classfile/attribute/visitor/StackSizeComputer.java +++ b/src/proguard/classfile/attribute/visitor/StackSizeComputer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -27,6 +27,8 @@ import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; +import java.util.Arrays; + /** * This AttributeVisitor computes the stack sizes at all instruction offsets * of the code attributes that it visits. @@ -140,10 +142,7 @@ implements AttributeVisitor, } else { - for (int index = 0; index < codeLength; index++) - { - evaluated[index] = false; - } + Arrays.fill(evaluated, 0, codeLength, false); } // The initial stack is always empty. diff --git a/src/proguard/classfile/constant/ClassConstant.java b/src/proguard/classfile/constant/ClassConstant.java index d217bf6..b9089d2 100644 --- a/src/proguard/classfile/constant/ClassConstant.java +++ b/src/proguard/classfile/constant/ClassConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/Constant.java b/src/proguard/classfile/constant/Constant.java index 30ce5df..ec25a67 100644 --- a/src/proguard/classfile/constant/Constant.java +++ b/src/proguard/classfile/constant/Constant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/DoubleConstant.java b/src/proguard/classfile/constant/DoubleConstant.java index 61779b5..08827c2 100644 --- a/src/proguard/classfile/constant/DoubleConstant.java +++ b/src/proguard/classfile/constant/DoubleConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/FieldrefConstant.java b/src/proguard/classfile/constant/FieldrefConstant.java index d4afce5..ddd6fb1 100644 --- a/src/proguard/classfile/constant/FieldrefConstant.java +++ b/src/proguard/classfile/constant/FieldrefConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/FloatConstant.java b/src/proguard/classfile/constant/FloatConstant.java index 578f567..e98aec2 100644 --- a/src/proguard/classfile/constant/FloatConstant.java +++ b/src/proguard/classfile/constant/FloatConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/IntegerConstant.java b/src/proguard/classfile/constant/IntegerConstant.java index 8a476c6..bd6afa0 100644 --- a/src/proguard/classfile/constant/IntegerConstant.java +++ b/src/proguard/classfile/constant/IntegerConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/InterfaceMethodrefConstant.java b/src/proguard/classfile/constant/InterfaceMethodrefConstant.java index ddee42f..80fe817 100644 --- a/src/proguard/classfile/constant/InterfaceMethodrefConstant.java +++ b/src/proguard/classfile/constant/InterfaceMethodrefConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/InvokeDynamicConstant.java b/src/proguard/classfile/constant/InvokeDynamicConstant.java new file mode 100755 index 0000000..bbff88d --- /dev/null +++ b/src/proguard/classfile/constant/InvokeDynamicConstant.java @@ -0,0 +1,148 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.constant; + +import proguard.classfile.*; +import proguard.classfile.constant.visitor.*; +import proguard.classfile.visitor.*; + +/** + * This Constant represents an invoke dynamic constant in the constant pool. + * + * @author Eric Lafortune + */ +public class InvokeDynamicConstant extends Constant +{ + public int u2bootstrapMethodAttributeIndex; + public int u2nameAndTypeIndex; + + /** + * An extra field pointing to the Clazz objects referenced in the + * descriptor string. This field is filled out by the <code>{@link + * proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}</code>. + * References to primitive types are ignored. + */ + public Clazz[] referencedClasses; + + + /** + * Creates an uninitialized InvokeDynamicConstant. + */ + public InvokeDynamicConstant() + { + } + + + /** + * Creates a new InvokeDynamicConstant with the given bootstrap method + * and name-and-type indices. + * @param u2bootstrapMethodAttributeIndex the index of the bootstrap method + * entry in the bootstrap methods + * attribute. + * @param u2nameAndTypeIndex the index of the name and type + * entry in the constant pool. + * @param referencedClasses the classes referenced by the + * type. + */ + public InvokeDynamicConstant(int u2bootstrapMethodAttributeIndex, + int u2nameAndTypeIndex, + Clazz[] referencedClasses) + { + this.u2bootstrapMethodAttributeIndex = u2bootstrapMethodAttributeIndex; + this.u2nameAndTypeIndex = u2nameAndTypeIndex; + this.referencedClasses = referencedClasses; + } + + + /** + * Returns the index of the bootstrap method in the bootstrap methods + * attribute of the class. + */ + public int getBootstrapMethodAttributeIndex() + { + return u2bootstrapMethodAttributeIndex; + } + + /** + * Returns the name-and-type index. + */ + public int getNameAndTypeIndex() + { + return u2nameAndTypeIndex; + } + + /** + * Returns the method name. + */ + public String getName(Clazz clazz) + { + return clazz.getName(u2nameAndTypeIndex); + } + + /** + * Returns the method type. + */ + public String getType(Clazz clazz) + { + return clazz.getType(u2nameAndTypeIndex); + } + + + /** + * Lets the Clazz objects referenced in the descriptor string + * accept the given visitor. + */ + public void referencedClassesAccept(ClassVisitor classVisitor) + { + if (referencedClasses != null) + { + for (int index = 0; index < referencedClasses.length; index++) + { + if (referencedClasses[index] != null) + { + referencedClasses[index].accept(classVisitor); + } + } + } + } + + + /** + * Lets the bootstrap method handle constant accept the given visitor. + */ + public void bootstrapMethodHandleAccept(Clazz clazz, ConstantVisitor constantVisitor) + { + new BootstrapMethodHandleTraveler(constantVisitor).visitInvokeDynamicConstant(clazz, this); + } + + + // Implementations for Constant. + + public int getTag() + { + return ClassConstants.CONSTANT_InvokeDynamic; + } + + public void accept(Clazz clazz, ConstantVisitor constantVisitor) + { + constantVisitor.visitInvokeDynamicConstant(clazz, this); + } +} diff --git a/src/proguard/classfile/constant/LongConstant.java b/src/proguard/classfile/constant/LongConstant.java index ea66e07..2d55e6a 100644 --- a/src/proguard/classfile/constant/LongConstant.java +++ b/src/proguard/classfile/constant/LongConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/MethodHandleConstant.java b/src/proguard/classfile/constant/MethodHandleConstant.java new file mode 100755 index 0000000..c2e068e --- /dev/null +++ b/src/proguard/classfile/constant/MethodHandleConstant.java @@ -0,0 +1,124 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.constant; + +import proguard.classfile.*; +import proguard.classfile.constant.visitor.ConstantVisitor; + +/** + * This Constant represents a method handle constant in the constant pool. + * + * @author Eric Lafortune + */ +public class MethodHandleConstant extends Constant +{ + public int u1referenceKind; + public int u2referenceIndex; + + + /** + * An extra field pointing to the java.lang.invoke.MethodHandle Clazz object. + * This field is typically filled out by the <code>{@link + * proguard.classfile.util.ClassReferenceInitializer + * ClassReferenceInitializer}</code>.. + */ + public Clazz javaLangInvokeMethodHandleClass; + + + /** + * Creates an uninitialized MethodHandleConstant. + */ + public MethodHandleConstant() + { + } + + + /** + * Creates a new MethodHandleConstant with the given type and method ref + * index. + * @param u1referenceKind the reference kind. + * @param u2referenceIndex the index of the field ref constant, interface + * method ref constant, or method ref constant in + * the constant pool. + */ + public MethodHandleConstant(int u1referenceKind, int u2referenceIndex) + { + this.u1referenceKind = u1referenceKind; + this.u2referenceIndex = u2referenceIndex; + } + + + /** + * Returns the kind of reference to which this constant is pointing. + * @return One of + * {@link ClassConstants#REF_getField }, + * {@link ClassConstants#REF_getStatic }, + * {@link ClassConstants#REF_putField }, + * {@link ClassConstants#REF_putStatic }, + * {@link ClassConstants#REF_invokeVirtual }, + * {@link ClassConstants#REF_invokeStatic }, + * {@link ClassConstants#REF_invokeSpecial }, + * {@link ClassConstants#REF_newInvokeSpecial}, or + * {@link ClassConstants#REF_invokeInterface }. + */ + public int getReferenceKind() + { + return u1referenceKind; + } + + /** + * Returns the field ref, interface method ref, or method ref index. + */ + public int getReferenceIndex() + { + return u2referenceIndex; + } + + + /** + * Returns the method/field name. + */ + public String getName(Clazz clazz) + { + return clazz.getRefName(u2referenceIndex); + } + + /** + * Returns the type. + */ + public String getType(Clazz clazz) + { + return clazz.getRefType(u2referenceIndex); + } + + + // Implementations for Constant. + + public int getTag() + { + return ClassConstants.CONSTANT_MethodHandle; + } + + public void accept(Clazz clazz, ConstantVisitor constantVisitor) + { + constantVisitor.visitMethodHandleConstant(clazz, this); + } +} diff --git a/src/proguard/classfile/constant/MethodTypeConstant.java b/src/proguard/classfile/constant/MethodTypeConstant.java new file mode 100644 index 0000000..29f79d7 --- /dev/null +++ b/src/proguard/classfile/constant/MethodTypeConstant.java @@ -0,0 +1,93 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.constant; + +import proguard.classfile.*; +import proguard.classfile.constant.visitor.ConstantVisitor; + +/** + * This Constant represents a method handle constant in the constant pool. + * + * @author Eric Lafortune + */ +public class MethodTypeConstant extends Constant +{ + public int u2descriptorIndex; + + + /** + * An extra field pointing to the java.lang.invoke.MethodType Clazz object. + * This field is typically filled out by the <code>{@link + * proguard.classfile.util.ClassReferenceInitializer + * ClassReferenceInitializer}</code>.. + */ + public Clazz javaLangInvokeMethodTypeClass; + + + /** + * Creates an uninitialized MethodTypeConstant. + */ + public MethodTypeConstant() + { + } + + + /** + * Creates a new MethodTypeConstant with the given descriptor index. + * @param u2descriptorIndex the index of the descriptor in the constant + * pool. + */ + public MethodTypeConstant(int u2descriptorIndex) + { + this.u2descriptorIndex = u2descriptorIndex; + } + + + /** + * Returns the descriptor index. + */ + public int getDescriptorIndex() + { + return u2descriptorIndex; + } + + + /** + * Returns the type. + */ + public String getType(Clazz clazz) + { + return clazz.getString(u2descriptorIndex); + } + + + // Implementations for Constant. + + public int getTag() + { + return ClassConstants.CONSTANT_MethodType; + } + + public void accept(Clazz clazz, ConstantVisitor constantVisitor) + { + constantVisitor.visitMethodTypeConstant(clazz, this); + } +} diff --git a/src/proguard/classfile/constant/MethodrefConstant.java b/src/proguard/classfile/constant/MethodrefConstant.java index 858eec9..a69c04e 100644 --- a/src/proguard/classfile/constant/MethodrefConstant.java +++ b/src/proguard/classfile/constant/MethodrefConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/NameAndTypeConstant.java b/src/proguard/classfile/constant/NameAndTypeConstant.java index e83d2f1..f8f814a 100644 --- a/src/proguard/classfile/constant/NameAndTypeConstant.java +++ b/src/proguard/classfile/constant/NameAndTypeConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/RefConstant.java b/src/proguard/classfile/constant/RefConstant.java index 4e4d019..c0531f6 100644 --- a/src/proguard/classfile/constant/RefConstant.java +++ b/src/proguard/classfile/constant/RefConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/StringConstant.java b/src/proguard/classfile/constant/StringConstant.java index 9a8d453..923c6dd 100644 --- a/src/proguard/classfile/constant/StringConstant.java +++ b/src/proguard/classfile/constant/StringConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/Utf8Constant.java b/src/proguard/classfile/constant/Utf8Constant.java index ae419c9..27ef218 100644 --- a/src/proguard/classfile/constant/Utf8Constant.java +++ b/src/proguard/classfile/constant/Utf8Constant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/visitor/AllConstantVisitor.java b/src/proguard/classfile/constant/visitor/AllConstantVisitor.java index d2d3c2c..2b89657 100644 --- a/src/proguard/classfile/constant/visitor/AllConstantVisitor.java +++ b/src/proguard/classfile/constant/visitor/AllConstantVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java b/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java new file mode 100644 index 0000000..6b02b73 --- /dev/null +++ b/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java @@ -0,0 +1,100 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.constant.visitor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; +import proguard.optimize.info.MethodOptimizationInfo; + +/** + * This ConstantVisitor and BootstrapMethodInfoVisitor travels from any invoke + * dynamic constants or bootstrap method info entries that it visits to their + * bootstrap method handle constants, and applies a given constant visitor. + * + * @author Eric Lafortune + */ +public class BootstrapMethodHandleTraveler +extends SimplifiedVisitor +implements ConstantVisitor, + AttributeVisitor, + BootstrapMethodInfoVisitor +{ + private ConstantVisitor bootstrapMethodHandleVisitor; + + // Field serving as a method argument. + int bootstrapMethodAttributeIndex; + + + /** + * Creates a new BootstrapMethodHandleVisitor that will delegate to the + * given constant visitor. + */ + public BootstrapMethodHandleTraveler(ConstantVisitor bootstrapMethodHandleVisitor) + { + this.bootstrapMethodHandleVisitor = bootstrapMethodHandleVisitor; + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + // Pass the method index. + bootstrapMethodAttributeIndex = + invokeDynamicConstant.u2bootstrapMethodAttributeIndex; + + // Delegate to the bootstrap method. + clazz.attributesAccept(this); + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + // Check bootstrap methods. + bootstrapMethodsAttribute.bootstrapMethodEntryAccept(clazz, + bootstrapMethodAttributeIndex, + this); + } + + + // Implementations for BootstrapMethodInfoVisitor. + + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) + { + // Check bootstrap method. + clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, + bootstrapMethodHandleVisitor); + } +} diff --git a/src/proguard/classfile/constant/visitor/ConstantTagFilter.java b/src/proguard/classfile/constant/visitor/ConstantTagFilter.java new file mode 100644 index 0000000..bfa7149 --- /dev/null +++ b/src/proguard/classfile/constant/visitor/ConstantTagFilter.java @@ -0,0 +1,86 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.constant.visitor; + +import proguard.classfile.Clazz; +import proguard.classfile.constant.*; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This <code>ConstantVisitor</code> delegates its visits to one or more + * specified types of constants. + * + * @author Eric Lafortune + */ +public class ConstantTagFilter +extends SimplifiedVisitor +implements ConstantVisitor +{ + private final int constantTagMask; + private final ConstantVisitor constantVisitor; + + + /** + * Creates a new ConstantTagFilter. + * @param constantTag the type of constants for which visits will be + * delegated. + * @param constantVisitor the <code>ConstantVisitor</code> to which visits + * will be delegated. + */ + public ConstantTagFilter(int constantTag, + ConstantVisitor constantVisitor) + { + this.constantTagMask = 1 << constantTag; + this.constantVisitor = constantVisitor; + } + + + /** + * Creates a new ConstantTagFilter. + * @param constantTags the types of constants for which visits will be + * delegated. + * @param constantVisitor the <code>ConstantVisitor</code> to which visits + * will be delegated. + */ + public ConstantTagFilter(int[] constantTags, + ConstantVisitor constantVisitor) + { + int constantTagMask = 0; + for (int index = 0; index < constantTags.length; index++) + { + constantTagMask |= 1 << constantTags[index]; + } + + this.constantTagMask = constantTagMask; + this.constantVisitor = constantVisitor; + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) + { + if (((1 << constant.getTag()) & constantTagMask) != 0) + { + constant.accept(clazz, constantVisitor); + } + } +}
\ No newline at end of file diff --git a/src/proguard/classfile/constant/visitor/ConstantVisitor.java b/src/proguard/classfile/constant/visitor/ConstantVisitor.java index 6cae352..2cec804 100644 --- a/src/proguard/classfile/constant/visitor/ConstantVisitor.java +++ b/src/proguard/classfile/constant/visitor/ConstantVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -38,9 +38,12 @@ public interface ConstantVisitor public void visitDoubleConstant( Clazz clazz, DoubleConstant doubleConstant); public void visitStringConstant( Clazz clazz, StringConstant stringConstant); public void visitUtf8Constant( Clazz clazz, Utf8Constant utf8Constant); + public void visitInvokeDynamicConstant( Clazz clazz, InvokeDynamicConstant invokeDynamicConstant); + public void visitMethodHandleConstant( Clazz clazz, MethodHandleConstant methodHandleConstant); public void visitFieldrefConstant( Clazz clazz, FieldrefConstant fieldrefConstant); public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant); public void visitMethodrefConstant( Clazz clazz, MethodrefConstant methodrefConstant); public void visitClassConstant( Clazz clazz, ClassConstant classConstant); + public void visitMethodTypeConstant( Clazz clazz, MethodTypeConstant methodTypeConstant); public void visitNameAndTypeConstant( Clazz clazz, NameAndTypeConstant nameAndTypeConstant); } diff --git a/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java b/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java index fbb3e52..0477631 100644 --- a/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java +++ b/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -44,16 +44,16 @@ implements ConstantVisitor /** - * Creates a new ClassNameFilter. + * Creates a new ExceptClassConstantFilter. * @param exceptClassName the name of the class that will not be visited. * @param constantVisitor the <code>ConstantVisitor</code> to which visits * will be delegated. */ - public ExceptClassConstantFilter(String exceptClassName, - ConstantVisitor constantVisitor) + public ExceptClassConstantFilter(String exceptClassName, + ConstantVisitor constantVisitor) { - this.exceptClassName = exceptClassName; - this.constantVisitor = constantVisitor; + this.exceptClassName = exceptClassName; + this.constantVisitor = constantVisitor; } diff --git a/src/proguard/classfile/visitor/ClassForNameClassVisitor.java b/src/proguard/classfile/constant/visitor/MethodrefTraveler.java index ee028f8..49c0917 100644 --- a/src/proguard/classfile/visitor/ClassForNameClassVisitor.java +++ b/src/proguard/classfile/constant/visitor/MethodrefTraveler.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -18,38 +18,32 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -package proguard.classfile.visitor; +package proguard.classfile.constant.visitor; import proguard.classfile.Clazz; +import proguard.classfile.attribute.*; import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.util.SimplifiedVisitor; - /** - * This ConstantVisitor lets a given <code>ClassVisitor</code> visit all - * constant classes involved in any <code>Class.forName</code> constructs that - * it visits. - * - * @see DotClassClassVisitor + * This ConstantVisitor travels from any method handle constants that it visits + * to their methodref constants, and applies a given constant visitor. * * @author Eric Lafortune */ -public class ClassForNameClassVisitor +public class MethodrefTraveler extends SimplifiedVisitor implements ConstantVisitor { - private final ClassVisitor classVisitor; + private ConstantVisitor methodrefConstantVisitor; /** - * Creates a new ClassHierarchyTraveler. - * @param classVisitor the <code>ClassVisitor</code> to which visits will - * be delegated. + * Creates a new v that will delegate to the given constant visitor. */ - public ClassForNameClassVisitor(ClassVisitor classVisitor) + public MethodrefTraveler(ConstantVisitor methodrefConstantVisitor) { - this.classVisitor = classVisitor; + this.methodrefConstantVisitor = methodrefConstantVisitor; } @@ -58,9 +52,9 @@ implements ConstantVisitor public void visitAnyConstant(Clazz clazz, Constant constant) {} - public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) { - // Visit the referenced class from the Class.forName construct, if any. - stringConstant.referencedClassAccept(classVisitor); + clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, + methodrefConstantVisitor); } } diff --git a/src/proguard/classfile/editor/AccessFixer.java b/src/proguard/classfile/editor/AccessFixer.java index 7d6274e..8ff08f3 100644 --- a/src/proguard/classfile/editor/AccessFixer.java +++ b/src/proguard/classfile/editor/AccessFixer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -21,6 +21,8 @@ package proguard.classfile.editor; import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.*; import proguard.classfile.constant.*; import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.util.*; @@ -61,12 +63,26 @@ implements ConstantVisitor, } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + // Check the bootstrap method. + invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + // Check the method reference. + clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); + } + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { referencingClass = clazz; // Remember the specified class, since it might be different from - // the referenced class that acutally contains the class member. + // the referenced class that actually contains the class member. clazz.constantPoolEntryAccept(refConstant.u2classIndex, referencedClassFinder); // Make sure the access flags of the referenced class member are @@ -91,8 +107,8 @@ implements ConstantVisitor, public void visitProgramClass(ProgramClass programClass) { - int currentAccessFlags = programClass.getAccessFlags(); - int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags); + int currentAccessFlags = programClass.getAccessFlags(); + int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags); // Compute the required access level. Clazz referencingClass = this.referencingClass; @@ -117,8 +133,8 @@ implements ConstantVisitor, public void visitProgramMember(ProgramClass programClass, ProgramMember programMember) { - int currentAccessFlags = programMember.getAccessFlags(); - int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags); + int currentAccessFlags = programMember.getAccessFlags(); + int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags); // Compute the required access level. int requiredAccessLevel = diff --git a/src/proguard/classfile/editor/AnnotationAdder.java b/src/proguard/classfile/editor/AnnotationAdder.java index 359164a..3c35608 100644 --- a/src/proguard/classfile/editor/AnnotationAdder.java +++ b/src/proguard/classfile/editor/AnnotationAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/AnnotationsAttributeEditor.java b/src/proguard/classfile/editor/AnnotationsAttributeEditor.java index bf8852c..5537f5e 100644 --- a/src/proguard/classfile/editor/AnnotationsAttributeEditor.java +++ b/src/proguard/classfile/editor/AnnotationsAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/AttributeAdder.java b/src/proguard/classfile/editor/AttributeAdder.java index 2b610b7..a7f8dc3 100644 --- a/src/proguard/classfile/editor/AttributeAdder.java +++ b/src/proguard/classfile/editor/AttributeAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -256,7 +256,7 @@ implements AttributeVisitor CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer(); - codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength); + codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength + 32); // Add the instructions. codeAttribute.instructionsAccept(clazz, diff --git a/src/proguard/classfile/editor/AttributeSorter.java b/src/proguard/classfile/editor/AttributeSorter.java index d8e3367..dcae85e 100644 --- a/src/proguard/classfile/editor/AttributeSorter.java +++ b/src/proguard/classfile/editor/AttributeSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/AttributesEditor.java b/src/proguard/classfile/editor/AttributesEditor.java index 10846cc..91c0080 100644 --- a/src/proguard/classfile/editor/AttributesEditor.java +++ b/src/proguard/classfile/editor/AttributesEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/BridgeMethodFixer.java b/src/proguard/classfile/editor/BridgeMethodFixer.java new file mode 100644 index 0000000..010c8a2 --- /dev/null +++ b/src/proguard/classfile/editor/BridgeMethodFixer.java @@ -0,0 +1,117 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.editor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; + +/** + * This MemberVisitor fixes all inappropriate bridge access flags of the + * program methods that it visits, checking whether the methods to which they + * bridge have the same name. Some compilers, like in Eclipse and in later + * versions of JDK 1.6, complain if they can't find the method with the same + * name. + * + * @author Eric Lafortune + */ +public class BridgeMethodFixer +extends SimplifiedVisitor +implements MemberVisitor, + AttributeVisitor, + InstructionVisitor, + ConstantVisitor +{ + private static final boolean DEBUG = false; + + + // Return values for the visitor methods. + private String bridgedMethodName; + + + // Implementations for MemberVisitor. + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + if ((programMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_BRIDGE) != 0) + { + programMethod.attributesAccept(programClass, this); + } + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + // Go over the instructions of the bridge method. + codeAttribute.instructionsAccept(clazz, method, this); + } + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + switch (constantInstruction.opcode) + { + case InstructionConstants.OP_INVOKEVIRTUAL: + case InstructionConstants.OP_INVOKESPECIAL: + case InstructionConstants.OP_INVOKESTATIC: + case InstructionConstants.OP_INVOKEINTERFACE: + // Get the name of the bridged method. + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + + // Check if the name is different. + if (!method.getName(clazz).equals(bridgedMethodName)) + { + if (DEBUG) + { + System.out.println("BridgeMethodFixer: ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"] does not bridge to ["+bridgedMethodName+"]"); + } + + // Clear the bridge flag. + ((ProgramMethod)method).u2accessFlags &= ~ClassConstants.INTERNAL_ACC_BRIDGE; + } + break; + } + } + + + // Implementations for ConstantVisitor. + + public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) + { + bridgedMethodName = refConstant.getName(clazz); + } +}
\ No newline at end of file diff --git a/src/proguard/classfile/editor/ClassEditor.java b/src/proguard/classfile/editor/ClassEditor.java index e503ea3..f51ae45 100644 --- a/src/proguard/classfile/editor/ClassEditor.java +++ b/src/proguard/classfile/editor/ClassEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ClassElementSorter.java b/src/proguard/classfile/editor/ClassElementSorter.java index 3256c88..c5eb366 100644 --- a/src/proguard/classfile/editor/ClassElementSorter.java +++ b/src/proguard/classfile/editor/ClassElementSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ClassMemberSorter.java b/src/proguard/classfile/editor/ClassMemberSorter.java index f31fcd0..61d69b2 100644 --- a/src/proguard/classfile/editor/ClassMemberSorter.java +++ b/src/proguard/classfile/editor/ClassMemberSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ClassReferenceFixer.java b/src/proguard/classfile/editor/ClassReferenceFixer.java index 9857903..808d339 100644 --- a/src/proguard/classfile/editor/ClassReferenceFixer.java +++ b/src/proguard/classfile/editor/ClassReferenceFixer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/CodeAttributeComposer.java b/src/proguard/classfile/editor/CodeAttributeComposer.java index e783203..a645f57 100644 --- a/src/proguard/classfile/editor/CodeAttributeComposer.java +++ b/src/proguard/classfile/editor/CodeAttributeComposer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -29,6 +29,8 @@ import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; +import java.util.Arrays; + /** * This AttributeVisitor accumulates instructions and exceptions, and then * copies them into code attributes that it visits. @@ -49,7 +51,7 @@ implements AttributeVisitor, //* private static final boolean DEBUG = false; /*/ - public static boolean DEBUG = true; + public static boolean DEBUG = false; //*/ @@ -313,7 +315,7 @@ implements AttributeVisitor, int handlerPC = -exceptionInfo.u2handlerPC; if (handlerPC > 0) { - if (remappableInstructionOffset(handlerPC)) + if (remappableExceptionHandler(handlerPC)) { exceptionInfo.u2handlerPC = remapInstructionOffset(handlerPC); } @@ -490,7 +492,7 @@ implements AttributeVisitor, int handlerPC = exceptionInfo.u2handlerPC; exceptionInfo.u2handlerPC = !allowExternalExceptionHandlers || - remappableInstructionOffset(handlerPC) ? + remappableExceptionHandler(handlerPC) ? remapInstructionOffset(handlerPC) : -handlerPC; } @@ -674,13 +676,21 @@ implements AttributeVisitor, /** - * Returns whether the given old instruction offset can be remapped at the + * Returns whether the given old exception handler can be remapped in the + * current code fragment. */ - private boolean remappableInstructionOffset(int oldInstructionOffset) + private boolean remappableExceptionHandler(int oldInstructionOffset) { - return - oldInstructionOffset <= codeFragmentLengths[level] && - instructionOffsetMap[level][oldInstructionOffset] > INVALID; + if (oldInstructionOffset > codeFragmentLengths[level]) + { + return false; + } + + int newInstructionOffset = + instructionOffsetMap[level][oldInstructionOffset]; + + return newInstructionOffset > INVALID && + newInstructionOffset < codeLength; } @@ -703,10 +713,7 @@ implements AttributeVisitor, } // Clear the unused array entries. - for (int index = newIndex; index < exceptionInfoCount; index++) - { - exceptionInfos[index] = null; - } + Arrays.fill(exceptionInfos, newIndex, exceptionInfoCount, null); return newIndex; } @@ -734,10 +741,7 @@ implements AttributeVisitor, } // Clear the unused array entries. - for (int index = newIndex; index < lineNumberInfoCount; index++) - { - lineNumberInfos[index] = null; - } + Arrays.fill(lineNumberInfos, newIndex, lineNumberInfoCount, null); return newIndex; } @@ -764,10 +768,7 @@ implements AttributeVisitor, } // Clear the unused array entries. - for (int index = newIndex; index < localVariableInfoCount; index++) - { - localVariableInfos[index] = null; - } + Arrays.fill(localVariableInfos, newIndex, localVariableInfoCount, null); return newIndex; } @@ -794,10 +795,7 @@ implements AttributeVisitor, } // Clear the unused array entries. - for (int index = newIndex; index < localVariableTypeInfoCount; index++) - { - localVariableTypeInfos[index] = null; - } + Arrays.fill(localVariableTypeInfos, newIndex, localVariableTypeInfoCount, null); return newIndex; } diff --git a/src/proguard/classfile/editor/CodeAttributeEditor.java b/src/proguard/classfile/editor/CodeAttributeEditor.java index 9658c98..82ed29e 100644 --- a/src/proguard/classfile/editor/CodeAttributeEditor.java +++ b/src/proguard/classfile/editor/CodeAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -28,7 +28,8 @@ import proguard.classfile.attribute.visitor.*; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.ClassPrinter; + +import java.util.Arrays; /** * This AttributeVisitor accumulates specified changes to code, and then applies @@ -105,13 +106,10 @@ implements AttributeVisitor, } else { - for (int index = 0; index < codeLength; index++) - { - preInsertions[index] = null; - replacements[index] = null; - postInsertions[index] = null; - deleted[index] = false; - } + Arrays.fill(preInsertions, 0, codeLength, null); + Arrays.fill(replacements, 0, codeLength, null); + Arrays.fill(postInsertions, 0, codeLength, null); + Arrays.fill(deleted, 0, codeLength, false); } modified = false; @@ -328,52 +326,51 @@ implements AttributeVisitor, { if (DEBUG) { - System.out.println("CodeAttributeEditor: ["+clazz.getName()+"."+method.getName(clazz)+"]"); + System.out.println("CodeAttributeEditor: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)); } - // Avoid doing any work if nothing is changing anyway. - if (!modified) + // Do we have to update the code? + if (modified) { - return; - } - - // Check if we can perform a faster simple replacement of instructions. - if (canPerformSimpleReplacements(codeAttribute)) - { - // Simply overwrite the instructions. - performSimpleReplacements(codeAttribute); + // Can we perform a faster simple replacement of instructions? + if (canPerformSimpleReplacements(codeAttribute)) + { + if (DEBUG) + { + System.out.println(" Simple editing"); + } - // Update the maximum stack size and local variable frame size. - updateFrameSizes(clazz, method, codeAttribute); - } - else - { - // Move and remap the instructions. - codeAttribute.u4codeLength = - updateInstructions(clazz, method, codeAttribute); + // Simply overwrite the instructions. + performSimpleReplacements(codeAttribute); + } + else + { + if (DEBUG) + { + System.out.println(" Full editing"); + } - // Remap the exception table. - codeAttribute.exceptionsAccept(clazz, method, this); + // Move and remap the instructions. + codeAttribute.u4codeLength = + updateInstructions(clazz, method, codeAttribute); - // Remove exceptions with empty code blocks. - codeAttribute.u2exceptionTableLength = - removeEmptyExceptions(codeAttribute.exceptionTable, - codeAttribute.u2exceptionTableLength); + // Remap the exception table. + codeAttribute.exceptionsAccept(clazz, method, this); - // Update the maximum stack size and local variable frame size. - updateFrameSizes(clazz, method, codeAttribute); + // Remove exceptions with empty code blocks. + codeAttribute.u2exceptionTableLength = + removeEmptyExceptions(codeAttribute.exceptionTable, + codeAttribute.u2exceptionTableLength); - // Remap the line number table and the local variable table. - codeAttribute.attributesAccept(clazz, method, this); + // Remap the line number table and the local variable tables. + codeAttribute.attributesAccept(clazz, method, this); + } // Make sure instructions are widened if necessary. instructionWriter.visitCodeAttribute(clazz, method, codeAttribute); } - } - - private void updateFrameSizes(Clazz clazz, Method method, CodeAttribute codeAttribute) - { + // Update the maximum stack size and local variable frame size. if (updateFrameSizes) { stackSizeUpdater.visitCodeAttribute(clazz, method, codeAttribute); @@ -415,12 +412,6 @@ implements AttributeVisitor, { // Remap all local variable table entries. localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - - // Remove local variables with empty code blocks. - localVariableTableAttribute.u2localVariableTableLength = - removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable, - localVariableTableAttribute.u2localVariableTableLength, - codeAttribute.u2maxLocals); } @@ -428,12 +419,6 @@ implements AttributeVisitor, { // Remap all local variable table entries. localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - - // Remove local variables with empty code blocks. - localVariableTypeTableAttribute.u2localVariableTypeTableLength = - removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, - localVariableTypeTableAttribute.u2localVariableTypeTableLength, - codeAttribute.u2maxLocals); } @@ -912,10 +897,12 @@ implements AttributeVisitor, public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) { // Remap the code offset and length. - // TODO: The local variable frame might not be strictly preserved. - localVariableInfo.u2length = remapBranchOffset(localVariableInfo.u2startPC, - localVariableInfo.u2length); - localVariableInfo.u2startPC = remapInstructionOffset(localVariableInfo.u2startPC); + int newStartPC = remapInstructionOffset(localVariableInfo.u2startPC); + int newEndPC = remapInstructionOffset(localVariableInfo.u2startPC + + localVariableInfo.u2length); + + localVariableInfo.u2length = newEndPC - newStartPC; + localVariableInfo.u2startPC = newStartPC; } @@ -924,10 +911,12 @@ implements AttributeVisitor, public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) { // Remap the code offset and length. - // TODO: The local variable frame might not be strictly preserved. - localVariableTypeInfo.u2length = remapBranchOffset(localVariableTypeInfo.u2startPC, - localVariableTypeInfo.u2length); - localVariableTypeInfo.u2startPC = remapInstructionOffset(localVariableTypeInfo.u2startPC); + int newStartPC = remapInstructionOffset(localVariableTypeInfo.u2startPC); + int newEndPC = remapInstructionOffset(localVariableTypeInfo.u2startPC + + localVariableTypeInfo.u2length); + + localVariableTypeInfo.u2length = newEndPC - newStartPC; + localVariableTypeInfo.u2startPC = newStartPC; } @@ -1017,54 +1006,6 @@ implements AttributeVisitor, } - /** - * Returns the given list of local variables, without the ones that have empty - * code blocks or that exceed the actual number of local variables. - */ - private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, - int localVariableInfoCount, - int maxLocals) - { - // Overwrite all empty local variable entries. - int newIndex = 0; - for (int index = 0; index < localVariableInfoCount; index++) - { - LocalVariableInfo localVariableInfo = localVariableInfos[index]; - if (localVariableInfo.u2length > 0 && - localVariableInfo.u2index < maxLocals) - { - localVariableInfos[newIndex++] = localVariableInfo; - } - } - - return newIndex; - } - - - /** - * Returns the given list of local variable types, without the ones that - * have empty code blocks or that exceed the actual number of local variables. - */ - private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, - int localVariableTypeInfoCount, - int maxLocals) - { - // Overwrite all empty local variable type entries. - int newIndex = 0; - for (int index = 0; index < localVariableTypeInfoCount; index++) - { - LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; - if (localVariableTypeInfo.u2length > 0 && - localVariableTypeInfo.u2index < maxLocals) - { - localVariableTypeInfos[newIndex++] = localVariableTypeInfo; - } - } - - return newIndex; - } - - private class CompositeInstruction extends Instruction { diff --git a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java index 9962ea5..eedc045 100644 --- a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java +++ b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ComparableConstant.java b/src/proguard/classfile/editor/ComparableConstant.java index bb81221..ba5f3b1 100644 --- a/src/proguard/classfile/editor/ComparableConstant.java +++ b/src/proguard/classfile/editor/ComparableConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -39,7 +39,7 @@ class ComparableConstant extends SimplifiedVisitor implements Comparable, ConstantVisitor { - private static final int[] PRIORITIES = new int[13]; + private static final int[] PRIORITIES = new int[19]; static { PRIORITIES[ClassConstants.CONSTANT_Integer] = 0; // Possibly byte index (ldc). @@ -47,12 +47,15 @@ implements Comparable, ConstantVisitor PRIORITIES[ClassConstants.CONSTANT_String] = 2; PRIORITIES[ClassConstants.CONSTANT_Class] = 3; PRIORITIES[ClassConstants.CONSTANT_Long] = 4; // Always wide index (ldc2_w). - PRIORITIES[ClassConstants.CONSTANT_Double] = 5; - PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index. - PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7; - PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8; - PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 9; - PRIORITIES[ClassConstants.CONSTANT_Utf8] = 10; + PRIORITIES[ClassConstants.CONSTANT_Double] = 5; // Always wide index (ldc2_w). + PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index (getfield,...). + PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7; // Always wide index (invokespecial,...). + PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8; // Always wide index (invokeinterface). + PRIORITIES[ClassConstants.CONSTANT_InvokeDynamic] = 9; // Always wide index (invokedynamic). + PRIORITIES[ClassConstants.CONSTANT_MethodHandle] = 10; + PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 11; + PRIORITIES[ClassConstants.CONSTANT_MethodType] = 12; + PRIORITIES[ClassConstants.CONSTANT_Utf8] = 13; } private final Clazz clazz; @@ -122,26 +125,32 @@ implements Comparable, ConstantVisitor public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) { - // In JDK 1.4, we can use Integer.compare(a,b). - result = new Integer(integerConstant.getValue()).compareTo(new Integer(((IntegerConstant)otherConstant).getValue())); + int value = integerConstant.getValue(); + int otherValue = ((IntegerConstant)otherConstant).getValue(); + result = value < otherValue ? -1 : + value == otherValue ? 0 : + 1; } public void visitLongConstant(Clazz clazz, LongConstant longConstant) { - // In JDK 1.4, we can use Long.compare(a,b). - result = new Long(longConstant.getValue()).compareTo(new Long(((LongConstant)otherConstant).getValue())); + long value = longConstant.getValue(); + long otherValue = ((LongConstant)otherConstant).getValue(); + result = value < otherValue ? -1 : + value == otherValue ? 0 : + 1; } public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) { - // In JDK 1.4, we can use Float.compare(a,b). - result = new Float(floatConstant.getValue()).compareTo(new Float(((FloatConstant)otherConstant).getValue())); + result = Float.compare(floatConstant.getValue(), + ((FloatConstant)otherConstant).getValue()); } public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) - { - // In JDK 1.4, we can use Double.compare(a,b). - result = new Double(doubleConstant.getValue()).compareTo(new Double(((DoubleConstant)otherConstant).getValue())); + { + result = Double.compare(doubleConstant.getValue(), + ((DoubleConstant)otherConstant).getValue()); } public void visitStringConstant(Clazz clazz, StringConstant stringConstant) @@ -154,6 +163,38 @@ implements Comparable, ConstantVisitor result = utf8Constant.getString().compareTo(((Utf8Constant)otherConstant).getString()); } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + InvokeDynamicConstant otherInvokeDynamicConstant = (InvokeDynamicConstant)otherConstant; + + int index = invokeDynamicConstant.getBootstrapMethodAttributeIndex(); + int otherIndex = otherInvokeDynamicConstant.getBootstrapMethodAttributeIndex(); + + result = index < otherIndex ? -1 : + index > otherIndex ? 1 : + (invokeDynamicConstant.getName(clazz) + ' ' + + invokeDynamicConstant.getType(clazz)) + .compareTo + (otherInvokeDynamicConstant.getName(clazz) + ' ' + + otherInvokeDynamicConstant.getType(clazz)); + } + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + MethodHandleConstant otherMethodHandleConstant = (MethodHandleConstant)otherConstant; + + int kind = methodHandleConstant.getReferenceKind(); + int otherKind = methodHandleConstant.getReferenceKind(); + + result = kind < otherKind ? -1 : + kind > otherKind ? 1 : + (methodHandleConstant.getName(clazz) + ' ' + + methodHandleConstant.getType(clazz)) + .compareTo + (otherMethodHandleConstant.getName(clazz) + ' ' + + otherMethodHandleConstant.getType(clazz)); + } + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { RefConstant otherRefConstant = (RefConstant)otherConstant; @@ -171,6 +212,14 @@ implements Comparable, ConstantVisitor result = classConstant.getName(clazz).compareTo(((ClassConstant)otherConstant).getName(clazz)); } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant MethodTypeConstant) + { + MethodTypeConstant otherMethodTypeConstant = (MethodTypeConstant)otherConstant; + result = MethodTypeConstant.getType(clazz) + .compareTo + (otherMethodTypeConstant.getType(clazz)); + } + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { NameAndTypeConstant otherNameAndTypeConstant = (NameAndTypeConstant)otherConstant; diff --git a/src/proguard/classfile/editor/ConstantAdder.java b/src/proguard/classfile/editor/ConstantAdder.java index 2b74f5f..14edbce 100644 --- a/src/proguard/classfile/editor/ConstantAdder.java +++ b/src/proguard/classfile/editor/ConstantAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -23,6 +23,7 @@ package proguard.classfile.editor; import proguard.classfile.*; import proguard.classfile.constant.*; import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.util.ListUtil; /** * This ConstantVisitor adds all constants that it visits to the constant pool @@ -128,6 +129,43 @@ implements ConstantVisitor } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + // First add the name and type constant. + clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this); + + // Copy the referenced classes. + Clazz[] referencedClasses = invokeDynamicConstant.referencedClasses; + Clazz[] referencedClassesCopy = null; + if (referencedClasses != null) + { + referencedClassesCopy = new Clazz[referencedClasses.length]; + System.arraycopy(referencedClasses, 0, + referencedClassesCopy, 0, + referencedClasses.length); + } + + // Then add the actual invoke dynamic constant. + constantIndex = + constantPoolEditor.addInvokeDynamicConstant(invokeDynamicConstant.getBootstrapMethodAttributeIndex(), + constantIndex, + referencedClassesCopy); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + // First add the field ref, interface method ref, or method ref + // constant. + clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); + + // Then add the actual method handle constant. + constantIndex = + constantPoolEditor.addMethodHandleConstant(methodHandleConstant.getReferenceKind(), + constantIndex); + } + + public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) { // First add the referenced class constant, with its own referenced class. @@ -185,6 +223,13 @@ implements ConstantVisitor } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + constantIndex = + constantPoolEditor.addMethodTypeConstant(methodTypeConstant.getType(clazz)); + } + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { constantIndex = diff --git a/src/proguard/classfile/editor/ConstantPoolEditor.java b/src/proguard/classfile/editor/ConstantPoolEditor.java index 8663dee..6ba4857 100644 --- a/src/proguard/classfile/editor/ConstantPoolEditor.java +++ b/src/proguard/classfile/editor/ConstantPoolEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -199,6 +199,93 @@ public class ConstantPoolEditor /** + * Finds or creates a InvokeDynamicConstant constant pool entry with the + * given bootstrap method constant pool entry index, method name, and + * descriptor. + * @return the constant pool index of the InvokeDynamicConstant. + */ + public int addInvokeDynamicConstant(int bootstrapMethodIndex, + String name, + String descriptor, + Clazz[] referencedClasses) + { + return addInvokeDynamicConstant(bootstrapMethodIndex, + addNameAndTypeConstant(name, descriptor), + referencedClasses); + } + + + /** + * Finds or creates a InvokeDynamicConstant constant pool entry with the given + * class constant pool entry index and name and type constant pool entry + * index. + * @return the constant pool index of the InvokeDynamicConstant. + */ + public int addInvokeDynamicConstant(int bootstrapMethodIndex, + int nameAndTypeIndex, + Clazz[] referencedClasses) + { + int constantPoolCount = targetClass.u2constantPoolCount; + Constant[] constantPool = targetClass.constantPool; + + // Check if the entry already exists. + for (int index = 1; index < constantPoolCount; index++) + { + Constant constant = constantPool[index]; + + if (constant != null && + constant.getTag() == ClassConstants.CONSTANT_InvokeDynamic) + { + InvokeDynamicConstant invokeDynamicConstant = (InvokeDynamicConstant)constant; + if (invokeDynamicConstant.u2bootstrapMethodAttributeIndex == bootstrapMethodIndex && + invokeDynamicConstant.u2nameAndTypeIndex == nameAndTypeIndex) + { + return index; + } + } + } + + return addConstant(new InvokeDynamicConstant(bootstrapMethodIndex, + nameAndTypeIndex, + referencedClasses)); + } + + + /** + * Finds or creates a MethodHandleConstant constant pool entry of the + * specified kind and with the given field ref, interface method ref, + * or method ref constant pool entry index. + * @return the constant pool index of the MethodHandleConstant. + */ + public int addMethodHandleConstant(int referenceKind, + int referenceIndex) + { + int constantPoolCount = targetClass.u2constantPoolCount; + Constant[] constantPool = targetClass.constantPool; + + // Check if the entry already exists. + for (int index = 1; index < constantPoolCount; index++) + { + Constant constant = constantPool[index]; + + if (constant != null && + constant.getTag() == ClassConstants.CONSTANT_MethodHandle) + { + MethodHandleConstant methodHandleConstant = (MethodHandleConstant)constant; + if (methodHandleConstant.u1referenceKind == referenceKind && + methodHandleConstant.u2referenceIndex == referenceIndex) + { + return index; + } + } + } + + return addConstant(new MethodHandleConstant(referenceKind, + referenceIndex)); + } + + + /** * Finds or creates a FieldrefConstant constant pool entry for the given * class and field. * @return the constant pool index of the FieldrefConstant. @@ -563,6 +650,36 @@ public class ConstantPoolEditor /** + * Finds or creates a MethodTypeConstant constant pool entry with the given + * type. + * @return the constant pool index of the MethodTypeConstant. + */ + public int addMethodTypeConstant(String type) + { + int constantPoolCount = targetClass.u2constantPoolCount; + Constant[] constantPool = targetClass.constantPool; + + // Check if the entry already exists. + for (int index = 1; index < constantPoolCount; index++) + { + Constant constant = constantPool[index]; + + if (constant != null && + constant.getTag() == ClassConstants.CONSTANT_MethodType) + { + MethodTypeConstant methodTypeConstant = (MethodTypeConstant)constant; + if (methodTypeConstant.getType(targetClass).equals(type)) + { + return index; + } + } + } + + return addConstant(new MethodTypeConstant(addUtf8Constant(type))); + } + + + /** * Finds or creates a NameAndTypeConstant constant pool entry with the given * name and type. * @return the constant pool index of the NameAndTypeConstant. diff --git a/src/proguard/classfile/editor/ConstantPoolRemapper.java b/src/proguard/classfile/editor/ConstantPoolRemapper.java index 7430d3d..7677218 100644 --- a/src/proguard/classfile/editor/ConstantPoolRemapper.java +++ b/src/proguard/classfile/editor/ConstantPoolRemapper.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -47,9 +47,10 @@ implements ClassVisitor, ConstantVisitor, MemberVisitor, AttributeVisitor, - InstructionVisitor, + BootstrapMethodInfoVisitor, InnerClassesInfoVisitor, ExceptionInfoVisitor, + InstructionVisitor, StackMapFrameVisitor, VerificationTypeVisitor, LocalVariableInfoVisitor, @@ -57,7 +58,7 @@ implements ClassVisitor, AnnotationVisitor, ElementValueVisitor { - private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); + private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false); private int[] constantIndexMap; @@ -100,40 +101,66 @@ implements ClassVisitor, // Implementations for ConstantVisitor. - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) { - classConstant.u2nameIndex = - remapConstantIndex(classConstant.u2nameIndex); + // Nothing to do. } - public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) + public void visitLongConstant(Clazz clazz, LongConstant longConstant) { // Nothing to do. } - public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) + public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) { - fieldrefConstant.u2classIndex = - remapConstantIndex(fieldrefConstant.u2classIndex); - fieldrefConstant.u2nameAndTypeIndex = - remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex); + // Nothing to do. } - public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) + public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) { // Nothing to do. } - public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + { + stringConstant.u2stringIndex = + remapConstantIndex(stringConstant.u2stringIndex); + } + + + public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) { // Nothing to do. } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + invokeDynamicConstant.u2nameAndTypeIndex = + remapConstantIndex(invokeDynamicConstant.u2nameAndTypeIndex); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + methodHandleConstant.u2referenceIndex = + remapConstantIndex(methodHandleConstant.u2referenceIndex); + } + + + public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) + { + fieldrefConstant.u2classIndex = + remapConstantIndex(fieldrefConstant.u2classIndex); + fieldrefConstant.u2nameAndTypeIndex = + remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex); + } + + public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) { interfaceMethodrefConstant.u2classIndex = @@ -143,12 +170,6 @@ implements ClassVisitor, } - public void visitLongConstant(Clazz clazz, LongConstant longConstant) - { - // Nothing to do. - } - - public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) { methodrefConstant.u2classIndex = @@ -158,25 +179,26 @@ implements ClassVisitor, } - public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { - nameAndTypeConstant.u2nameIndex = - remapConstantIndex(nameAndTypeConstant.u2nameIndex); - nameAndTypeConstant.u2descriptorIndex = - remapConstantIndex(nameAndTypeConstant.u2descriptorIndex); + classConstant.u2nameIndex = + remapConstantIndex(classConstant.u2nameIndex); } - public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) { - stringConstant.u2stringIndex = - remapConstantIndex(stringConstant.u2stringIndex); + methodTypeConstant.u2descriptorIndex = + remapConstantIndex(methodTypeConstant.u2descriptorIndex); } - public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { - // Nothing to do. + nameAndTypeConstant.u2nameIndex = + remapConstantIndex(nameAndTypeConstant.u2nameIndex); + nameAndTypeConstant.u2descriptorIndex = + remapConstantIndex(nameAndTypeConstant.u2descriptorIndex); } @@ -230,6 +252,16 @@ implements ClassVisitor, } + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + bootstrapMethodsAttribute.u2attributeNameIndex = + remapConstantIndex(bootstrapMethodsAttribute.u2attributeNameIndex); + + // Remap the constant pool references of the bootstrap method entries. + bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); + } + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { sourceFileAttribute.u2attributeNameIndex = @@ -410,6 +442,19 @@ implements ClassVisitor, } + // Implementations for BootstrapMethodInfoVisitor. + + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) + { + bootstrapMethodInfo.u2methodHandleIndex = + remapConstantIndex(bootstrapMethodInfo.u2methodHandleIndex); + + // Remap the constant pool references of the bootstrap methods.. + remapConstantIndexArray(bootstrapMethodInfo.u2methodArguments, + bootstrapMethodInfo.u2methodArgumentCount); + } + + // Implementations for InnerClassesInfoVisitor. public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) diff --git a/src/proguard/classfile/editor/ConstantPoolShrinker.java b/src/proguard/classfile/editor/ConstantPoolShrinker.java new file mode 100644 index 0000000..8c8e5d6 --- /dev/null +++ b/src/proguard/classfile/editor/ConstantPoolShrinker.java @@ -0,0 +1,578 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.editor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.preverification.*; +import proguard.classfile.attribute.preverification.visitor.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +import java.util.Arrays; + +/** + * This ClassVisitor removes all unused entries from the constant pool. + * + * @author Eric Lafortune + */ +public class ConstantPoolShrinker +extends SimplifiedVisitor +implements ClassVisitor, + MemberVisitor, + ConstantVisitor, + AttributeVisitor, + BootstrapMethodInfoVisitor, + InnerClassesInfoVisitor, + ExceptionInfoVisitor, + StackMapFrameVisitor, + VerificationTypeVisitor, + LocalVariableInfoVisitor, + LocalVariableTypeInfoVisitor, + AnnotationVisitor, + ElementValueVisitor, + InstructionVisitor +{ + // A visitor info flag to indicate the constant is being used. + private static final Object USED = new Object(); + + private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE]; + private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper(); + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + // Mark this class's name. + markConstant(programClass, programClass.u2thisClass); + + // Mark the superclass class constant. + programClass.superClassConstantAccept(this); + + // Mark the interface class constants. + programClass.interfaceConstantsAccept(this); + + // Mark the constants referenced by the class members. + programClass.fieldsAccept(this); + programClass.methodsAccept(this); + + // Mark the attributes. + programClass.attributesAccept(this); + + // Shift the used constant pool entries together, filling out the + // index map. + int newConstantPoolCount = + shrinkConstantPool(programClass.constantPool, + programClass.u2constantPoolCount); + + // Remap the references to the constant pool if it has shrunk. + if (newConstantPoolCount < programClass.u2constantPoolCount) + { + programClass.u2constantPoolCount = newConstantPoolCount; + + // Remap all constant pool references. + constantPoolRemapper.setConstantIndexMap(constantIndexMap); + constantPoolRemapper.visitProgramClass(programClass); + } + } + + + // Implementations for MemberVisitor. + + public void visitProgramMember(ProgramClass programClass, ProgramMember programMember) + { + // Mark the name and descriptor. + markConstant(programClass, programMember.u2nameIndex); + markConstant(programClass, programMember.u2descriptorIndex); + + // Mark the attributes. + programMember.attributesAccept(programClass, this); + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) + { + markAsUsed(constant); + } + + + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + { + markAsUsed(stringConstant); + + markConstant(clazz, stringConstant.u2stringIndex); + } + + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + markAsUsed(invokeDynamicConstant); + + markConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex); + + // Mark the bootstrap methods attribute. + clazz.attributesAccept(this); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + markAsUsed(methodHandleConstant); + + markConstant(clazz, methodHandleConstant.u2referenceIndex); + } + + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) + { + markAsUsed(refConstant); + + markConstant(clazz, refConstant.u2classIndex); + markConstant(clazz, refConstant.u2nameAndTypeIndex); + } + + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + markAsUsed(classConstant); + + markConstant(clazz, classConstant.u2nameIndex); + } + + + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + markAsUsed(methodTypeConstant); + + markConstant(clazz, methodTypeConstant.u2descriptorIndex); + } + + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) + { + markAsUsed(nameAndTypeConstant); + + markConstant(clazz, nameAndTypeConstant.u2nameIndex); + markConstant(clazz, nameAndTypeConstant.u2descriptorIndex); + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) + { + markConstant(clazz, attribute.u2attributeNameIndex); + } + + + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + markConstant(clazz, bootstrapMethodsAttribute.u2attributeNameIndex); + + // Mark the bootstrap method entries. + bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); + } + + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) + { + markConstant(clazz, sourceFileAttribute.u2attributeNameIndex); + markConstant(clazz, sourceFileAttribute.u2sourceFileIndex); + } + + + public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) + { + markConstant(clazz, sourceDirAttribute.u2attributeNameIndex); + markConstant(clazz, sourceDirAttribute.u2sourceDirIndex); + } + + + public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) + { + markConstant(clazz, innerClassesAttribute.u2attributeNameIndex); + + // Mark the outer class entries. + innerClassesAttribute.innerClassEntriesAccept(clazz, this); + } + + + public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) + { + markConstant(clazz, enclosingMethodAttribute.u2attributeNameIndex); + markConstant(clazz, enclosingMethodAttribute.u2classIndex); + + if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) + { + markConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); + } + } + + + public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) + { + markConstant(clazz, signatureAttribute.u2attributeNameIndex); + markConstant(clazz, signatureAttribute.u2signatureIndex); + } + + + public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) + { + markConstant(clazz, constantValueAttribute.u2attributeNameIndex); + markConstant(clazz, constantValueAttribute.u2constantValueIndex); + } + + + public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) + { + markConstant(clazz, exceptionsAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the exceptions. + exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this); + } + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + markConstant(clazz, codeAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the instructions, + // by the exceptions, and by the attributes. + codeAttribute.instructionsAccept(clazz, method, this); + codeAttribute.exceptionsAccept(clazz, method, this); + codeAttribute.attributesAccept(clazz, method, this); + } + + + public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) + { + markConstant(clazz, stackMapAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the stack map frames. + stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); + } + + + public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) + { + markConstant(clazz, stackMapTableAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the stack map frames. + stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); + } + + + public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) + { + markConstant(clazz, localVariableTableAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the local variables. + localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + } + + + public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) + { + markConstant(clazz, localVariableTypeTableAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the local variable types. + localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + } + + + public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) + { + markConstant(clazz, annotationsAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the annotations. + annotationsAttribute.annotationsAccept(clazz, this); + } + + + public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) + { + markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the annotations. + parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); + } + + + public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) + { + markConstant(clazz, annotationDefaultAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the element value. + annotationDefaultAttribute.defaultValueAccept(clazz, this); + } + + + // Implementations for BootstrapMethodInfoVisitor. + + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) + { + markConstant(clazz, bootstrapMethodInfo.u2methodHandleIndex); + + // Mark the constant pool entries referenced by the arguments. + bootstrapMethodInfo.methodArgumentsAccept(clazz, this); + } + + + // Implementations for InnerClassesInfoVisitor. + + public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) + { + innerClassesInfo.innerClassConstantAccept(clazz, this); + innerClassesInfo.outerClassConstantAccept(clazz, this); + innerClassesInfo.innerNameConstantAccept(clazz, this); + } + + + // Implementations for ExceptionInfoVisitor. + + public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) + { + if (exceptionInfo.u2catchType != 0) + { + markConstant(clazz, exceptionInfo.u2catchType); + } + } + + + // Implementations for StackMapFrameVisitor. + + public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {} + + + public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame) + { + // Mark the constant pool entries referenced by the verification types. + sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this); + } + + + public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame) + { + // Mark the constant pool entries referenced by the verification types. + moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this); + } + + + public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame) + { + // Mark the constant pool entries referenced by the verification types. + fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this); + fullFrame.stackAccept(clazz, method, codeAttribute, offset, this); + } + + + // Implementations for VerificationTypeVisitor. + + public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {} + + + public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType) + { + markConstant(clazz, objectType.u2classIndex); + } + + + // Implementations for LocalVariableInfoVisitor. + + public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) + { + markConstant(clazz, localVariableInfo.u2nameIndex); + markConstant(clazz, localVariableInfo.u2descriptorIndex); + } + + + // Implementations for LocalVariableTypeInfoVisitor. + + public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) + { + markConstant(clazz, localVariableTypeInfo.u2nameIndex); + markConstant(clazz, localVariableTypeInfo.u2signatureIndex); + } + + + // Implementations for AnnotationVisitor. + + public void visitAnnotation(Clazz clazz, Annotation annotation) + { + markConstant(clazz, annotation.u2typeIndex); + + // Mark the constant pool entries referenced by the element values. + annotation.elementValuesAccept(clazz, this); + } + + + // Implementations for ElementValueVisitor. + + public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) + { + if (constantElementValue.u2elementNameIndex != 0) + { + markConstant(clazz, constantElementValue.u2elementNameIndex); + } + + markConstant(clazz, constantElementValue.u2constantValueIndex); + } + + + public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) + { + if (enumConstantElementValue.u2elementNameIndex != 0) + { + markConstant(clazz, enumConstantElementValue.u2elementNameIndex); + } + + markConstant(clazz, enumConstantElementValue.u2typeNameIndex); + markConstant(clazz, enumConstantElementValue.u2constantNameIndex); + } + + + public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) + { + if (classElementValue.u2elementNameIndex != 0) + { + markConstant(clazz, classElementValue.u2elementNameIndex); + } + + markConstant(clazz, classElementValue.u2classInfoIndex); + } + + + public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) + { + if (annotationElementValue.u2elementNameIndex != 0) + { + markConstant(clazz, annotationElementValue.u2elementNameIndex); + } + + // Mark the constant pool entries referenced by the annotation. + annotationElementValue.annotationAccept(clazz, this); + } + + + public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) + { + if (arrayElementValue.u2elementNameIndex != 0) + { + markConstant(clazz, arrayElementValue.u2elementNameIndex); + } + + // Mark the constant pool entries referenced by the element values. + arrayElementValue.elementValuesAccept(clazz, annotation, this); + } + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + markConstant(clazz, constantInstruction.constantIndex); + } + + + // Small utility methods. + + /** + * Marks the given constant pool entry of the given class. This includes + * visiting any referenced objects. + */ + private void markConstant(Clazz clazz, int index) + { + clazz.constantPoolEntryAccept(index, this); + } + + + /** + * Marks the given visitor accepter as being used. + */ + private void markAsUsed(Constant constant) + { + constant.setVisitorInfo(USED); + } + + + /** + * Returns whether the given visitor accepter has been marked as being used. + */ + private boolean isUsed(VisitorAccepter visitorAccepter) + { + return visitorAccepter.getVisitorInfo() == USED; + } + + + /** + * Removes all constants that are not marked as being used from the given + * constant pool. + * @return the new number of entries. + */ + private int shrinkConstantPool(Constant[] constantPool, int length) + { + // Create a new index map, if necessary. + if (constantIndexMap.length < length) + { + constantIndexMap = new int[length]; + } + + int counter = 1; + boolean isUsed = false; + + // Shift the used constant pool entries together. + for (int index = 1; index < length; index++) + { + constantIndexMap[index] = counter; + + Constant constant = constantPool[index]; + + // Don't update the flag if this is the second half of a long entry. + if (constant != null) + { + isUsed = isUsed(constant); + } + + if (isUsed) + { + constantPool[counter++] = constant; + } + } + + // Clear the remaining constant pool elements. + Arrays.fill(constantPool, counter, length, null); + + return counter; + } +} diff --git a/src/proguard/classfile/editor/ConstantPoolSorter.java b/src/proguard/classfile/editor/ConstantPoolSorter.java index faae318..8e18865 100644 --- a/src/proguard/classfile/editor/ConstantPoolSorter.java +++ b/src/proguard/classfile/editor/ConstantPoolSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -112,10 +112,7 @@ implements ClassVisitor System.arraycopy(newConstantPool, 0, programClass.constantPool, 0, newLength); // Clear any remaining entries. - for (int index = newLength; index < constantPoolCount; index++) - { - programClass.constantPool[index] = null; - } + Arrays.fill(programClass.constantPool, newLength, constantPoolCount, null); programClass.u2constantPoolCount = newLength; diff --git a/src/proguard/classfile/editor/ElementValueAdder.java b/src/proguard/classfile/editor/ElementValueAdder.java index 8cbd11d..895fd68 100644 --- a/src/proguard/classfile/editor/ElementValueAdder.java +++ b/src/proguard/classfile/editor/ElementValueAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ElementValuesEditor.java b/src/proguard/classfile/editor/ElementValuesEditor.java index bfc4e9f..ce9352a 100644 --- a/src/proguard/classfile/editor/ElementValuesEditor.java +++ b/src/proguard/classfile/editor/ElementValuesEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ExceptionAdder.java b/src/proguard/classfile/editor/ExceptionAdder.java index 1ccb1a6..ee0fb52 100644 --- a/src/proguard/classfile/editor/ExceptionAdder.java +++ b/src/proguard/classfile/editor/ExceptionAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ExceptionInfoAdder.java b/src/proguard/classfile/editor/ExceptionInfoAdder.java index e0cc9c5..5fd98a8 100644 --- a/src/proguard/classfile/editor/ExceptionInfoAdder.java +++ b/src/proguard/classfile/editor/ExceptionInfoAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ExceptionsAttributeEditor.java b/src/proguard/classfile/editor/ExceptionsAttributeEditor.java index 4509a9a..d49658a 100644 --- a/src/proguard/classfile/editor/ExceptionsAttributeEditor.java +++ b/src/proguard/classfile/editor/ExceptionsAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/InnerClassesAccessFixer.java b/src/proguard/classfile/editor/InnerClassesAccessFixer.java new file mode 100644 index 0000000..1d991df --- /dev/null +++ b/src/proguard/classfile/editor/InnerClassesAccessFixer.java @@ -0,0 +1,83 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.editor; + +import proguard.classfile.*; +import proguard.classfile.attribute.visitor.InnerClassesInfoVisitor; +import proguard.classfile.attribute.InnerClassesInfo; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; + +/** + * This InnerClassesInfoVisitor fixes the inner class access flags of the + * inner classes information that it visits. + * + * @author Eric Lafortune + */ +public class InnerClassesAccessFixer +extends SimplifiedVisitor +implements InnerClassesInfoVisitor, + ConstantVisitor, + ClassVisitor +{ + private int innerClassAccessFlags; + + + // Implementations for InnerClassesInfoVisitor. + + public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) + { + // The current access flags are the default. + innerClassAccessFlags = innerClassesInfo.u2innerClassAccessFlags; + + // See if we can find new access flags. + innerClassesInfo.innerClassConstantAccept(clazz, this); + + // Update the access flags. + innerClassesInfo.u2innerClassAccessFlags = innerClassAccessFlags; + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + classConstant.referencedClassAccept(this); + } + + + // Implementations for ClassVisitor. + + public void visitLibraryClass(LibraryClass libraryClass) {} + + + public void visitProgramClass(ProgramClass programClass) + { + innerClassAccessFlags = + AccessUtil.replaceAccessFlags(innerClassAccessFlags, + programClass.u2accessFlags); + } +}
\ No newline at end of file diff --git a/src/proguard/classfile/editor/InstructionAdder.java b/src/proguard/classfile/editor/InstructionAdder.java index 60fde6d..34fb63b 100644 --- a/src/proguard/classfile/editor/InstructionAdder.java +++ b/src/proguard/classfile/editor/InstructionAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/InstructionWriter.java b/src/proguard/classfile/editor/InstructionWriter.java index d842358..b7da62f 100644 --- a/src/proguard/classfile/editor/InstructionWriter.java +++ b/src/proguard/classfile/editor/InstructionWriter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/InterfaceAdder.java b/src/proguard/classfile/editor/InterfaceAdder.java index e095af6..9c11d97 100644 --- a/src/proguard/classfile/editor/InterfaceAdder.java +++ b/src/proguard/classfile/editor/InterfaceAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/InterfaceSorter.java b/src/proguard/classfile/editor/InterfaceSorter.java index 6521369..176e13e 100644 --- a/src/proguard/classfile/editor/InterfaceSorter.java +++ b/src/proguard/classfile/editor/InterfaceSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -21,10 +21,14 @@ package proguard.classfile.editor; import proguard.classfile.*; -import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.util.*; import proguard.classfile.visitor.ClassVisitor; -import java.util.Arrays; +import java.util.*; /** * This ClassVisitor sorts the interfaces of the program classes that it visits. @@ -33,7 +37,8 @@ import java.util.Arrays; */ public class InterfaceSorter extends SimplifiedVisitor -implements ClassVisitor +implements ClassVisitor, + AttributeVisitor { // Implementations for ClassVisitor. @@ -42,26 +47,106 @@ implements ClassVisitor int[] interfaces = programClass.u2interfaces; int interfacesCount = programClass.u2interfacesCount; - // Sort the interfaces. - Arrays.sort(interfaces, 0, interfacesCount); + if (interfacesCount > 1) + { + // Sort the interfaces. + Arrays.sort(interfaces, 0, interfacesCount); + + // Remove any duplicate entries. + int newInterfacesCount = 0; + int previousInterfaceIndex = 0; + for (int index = 0; index < interfacesCount; index++) + { + int interfaceIndex = interfaces[index]; + + // Isn't this a duplicate of the previous interface? + if (interfaceIndex != previousInterfaceIndex) + { + interfaces[newInterfacesCount++] = interfaceIndex; + + // Remember the interface. + previousInterfaceIndex = interfaceIndex; + } + } + + programClass.u2interfacesCount = newInterfacesCount; + + // Update the signature, if any + programClass.attributesAccept(this); + } + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) + { + // Process the generic definitions, superclass, and implemented + // interfaces. + String signature = clazz.getString(signatureAttribute.u2signatureIndex); + + // Count the signature types. + InternalTypeEnumeration internalTypeEnumeration = + new InternalTypeEnumeration(signature); - // Remove any duplicate entries. - int newInterfacesCount = 0; - int previousInterfaceIndex = 0; - for (int index = 0; index < interfacesCount; index++) + int count = 0; + int interfacesCount = -1; + while (internalTypeEnumeration.hasMoreTypes()) { - int interfaceIndex = interfaces[index]; + String internalType = internalTypeEnumeration.nextType(); - // Isn't this a duplicate of the previous interface? - if (interfaceIndex != previousInterfaceIndex) + count++; + + if (ClassUtil.isInternalClassType(internalType)) { - interfaces[newInterfacesCount++] = interfaceIndex; + interfacesCount++; + } + } + + // Put the signature types in an array. + internalTypeEnumeration = + new InternalTypeEnumeration(signature); + + String[] internalTypes = new String[count]; + + for (int index = 0; index < count; index++) + { + String internalType = internalTypeEnumeration.nextType(); + + internalTypes[index] = internalType; + } - // Remember the interface. - previousInterfaceIndex = interfaceIndex; + // Sort the interface types in the array. + Arrays.sort(internalTypes, count - interfacesCount, count); + + // Recompose the signature types in a string. + StringBuffer newSignatureBuffer = new StringBuffer(); + + for (int index = 0; index < count; index++) + { + // Is this not an interface type, or an interface type that isn't + // a duplicate of the previous interface type? + if (index < count - interfacesCount || + !internalTypes[index].equals(internalTypes[index-1])) + { + newSignatureBuffer.append(internalTypes[index]); } } - programClass.u2interfacesCount = newInterfacesCount; + String newSignature = newSignatureBuffer.toString(); + + // Did the signature change? + if (!newSignature.equals(signature)) + { + // Update the signature. + ((Utf8Constant)((ProgramClass)clazz).constantPool[signatureAttribute.u2signatureIndex]).setString(newSignatureBuffer.toString()); + + // Clear the referenced classes. + // TODO: Properly update the referenced classes. + signatureAttribute.referencedClasses = null; + } } } diff --git a/src/proguard/classfile/editor/InterfacesEditor.java b/src/proguard/classfile/editor/InterfacesEditor.java index d3170e1..59cdd6a 100644 --- a/src/proguard/classfile/editor/InterfacesEditor.java +++ b/src/proguard/classfile/editor/InterfacesEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LineNumberInfoAdder.java b/src/proguard/classfile/editor/LineNumberInfoAdder.java index aa8c0c4..b0db7fb 100644 --- a/src/proguard/classfile/editor/LineNumberInfoAdder.java +++ b/src/proguard/classfile/editor/LineNumberInfoAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java index ab96b38..7497458 100644 --- a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java +++ b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LocalVariableInfoAdder.java b/src/proguard/classfile/editor/LocalVariableInfoAdder.java index f285e4f..0f47933 100644 --- a/src/proguard/classfile/editor/LocalVariableInfoAdder.java +++ b/src/proguard/classfile/editor/LocalVariableInfoAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java index 053b628..8bb051d 100644 --- a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java +++ b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java index ca50f3f..a1c1379 100644 --- a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java +++ b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java index fe5a64d..9b1ebd5 100644 --- a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java +++ b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/MemberAdder.java b/src/proguard/classfile/editor/MemberAdder.java index 5f939bb..7791e3b 100644 --- a/src/proguard/classfile/editor/MemberAdder.java +++ b/src/proguard/classfile/editor/MemberAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -26,8 +26,9 @@ import proguard.classfile.util.SimplifiedVisitor; import proguard.classfile.visitor.MemberVisitor; /** - * This ConstantVisitor adds all class members that it visits to the given - * target class. + * This MemberVisitor copies all class members that it visits to the given + * target class. Their visitor info is set to the class members from which they + * were copied. * * @author Eric Lafortune */ @@ -45,8 +46,9 @@ implements MemberVisitor private static final Attribute[] EMPTY_ATTRIBUTES = new Attribute[0]; - private final ProgramClass targetClass; -// private final boolean addFields; + private final ProgramClass targetClass; +// private final boolean addFields; + private final MemberVisitor extraMemberVisitor; private final ConstantAdder constantAdder; private final ClassEditor classEditor; @@ -59,13 +61,30 @@ implements MemberVisitor * @param targetClass the class to which all visited class members will be * added. */ + public MemberAdder(ProgramClass targetClass) + { + this(targetClass, null); + } + + + /** + * Creates a new MemberAdder that will copy methods into the given target + * class. + * @param targetClass the class to which all visited class members + * will be added. + * @param extraMemberVisitor an optional member visitor that visits each + * new member right after it has been added. This + * allows changing the visitor info, for instance. + */ // * @param addFields specifies whether fields should be added, or fused // * with the present fields. - public MemberAdder(ProgramClass targetClass)//), -// boolean addFields) + public MemberAdder(ProgramClass targetClass, +// boolean addFields, + MemberVisitor extraMemberVisitor) { - this.targetClass = targetClass; -// this.addFields = addFields; + this.targetClass = targetClass; +// this.addFields = addFields; + this.extraMemberVisitor = extraMemberVisitor; constantAdder = new ConstantAdder(targetClass); classEditor = new ClassEditor(targetClass); @@ -150,6 +169,12 @@ implements MemberVisitor // Add the completed field. classEditor.addField(newProgramField); + + // Visit the newly added field, if necessary. + if (extraMemberVisitor != null) + { + extraMemberVisitor.visitProgramField(targetClass, newProgramField); + } } @@ -240,6 +265,12 @@ implements MemberVisitor // Add the completed method. classEditor.addMethod(newProgramMethod); + + // Visit the newly added method, if necessary. + if (extraMemberVisitor != null) + { + extraMemberVisitor.visitProgramMethod(targetClass, newProgramMethod); + } } diff --git a/src/proguard/classfile/editor/MemberReferenceFixer.java b/src/proguard/classfile/editor/MemberReferenceFixer.java index 4bd8af5..6d665c1 100644 --- a/src/proguard/classfile/editor/MemberReferenceFixer.java +++ b/src/proguard/classfile/editor/MemberReferenceFixer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -298,22 +298,17 @@ implements ClassVisitor, { Clazz referencedClass = enclosingMethodAttribute.referencedClass; - // Does it have a new class? - if (!enclosingMethodAttribute.getClassName(clazz).equals(referencedClass.getName())) - { - // Update the class index. - enclosingMethodAttribute.u2classIndex = - new ConstantPoolEditor((ProgramClass)clazz).addClassConstant(referencedClass); - } - // Does it have a new name or type? - if (!enclosingMethodAttribute.getName(clazz).equals(referencedMember.getName(referencedClass)) || - !enclosingMethodAttribute.getType(clazz).equals(referencedMember.getDescriptor(referencedClass))) + String newName = referencedMember.getName(referencedClass); + String newType = referencedMember.getDescriptor(referencedClass); + + if (!enclosingMethodAttribute.getName(clazz).equals(newName) || + !enclosingMethodAttribute.getType(clazz).equals(newType)) { // Update the name and type index. enclosingMethodAttribute.u2nameAndTypeIndex = - new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(referencedMember.getName(referencedClass), - referencedMember.getDescriptor(referencedClass)); + new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(newName, + newType); } } } @@ -433,10 +428,9 @@ implements ClassVisitor, Member referencedMember) { System.out.println("MemberReferenceFixer:"); - System.out.println(" Class file = "+clazz.getName()); - System.out.println(" Ref class = "+referencedClass.getName()); - System.out.println(" Ref member name = "+stringConstant.getString(clazz)); - System.out.println(" -> "+referencedMember.getName(referencedClass)); + System.out.println(" ["+clazz.getName()+"]: String ["+ + stringConstant.getString(clazz)+"] -> ["+ + referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]"); } @@ -446,11 +440,8 @@ implements ClassVisitor, Member referencedMember) { System.out.println("MemberReferenceFixer:"); - System.out.println(" Class file = "+clazz.getName()); - System.out.println(" Ref class = "+referencedClass.getName()); - System.out.println(" Ref member name = "+refConstant.getName(clazz)); - System.out.println(" -> "+referencedMember.getName(referencedClass)); - System.out.println(" Ref descriptor = "+refConstant.getType(clazz)); - System.out.println(" -> "+referencedMember.getDescriptor(referencedClass)); + System.out.println(" ["+clazz.getName()+"]: ["+ + refConstant.getClassName(clazz)+"."+refConstant.getName(clazz)+" "+refConstant.getType(clazz)+"] -> ["+ + referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]"); } } diff --git a/src/proguard/classfile/editor/MethodInvocationFixer.java b/src/proguard/classfile/editor/MethodInvocationFixer.java index ef76012..f33ef1d 100644 --- a/src/proguard/classfile/editor/MethodInvocationFixer.java +++ b/src/proguard/classfile/editor/MethodInvocationFixer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -28,7 +28,6 @@ import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.*; -import proguard.classfile.visitor.*; /** * This AttributeVisitor fixes all inappropriate special/virtual/static/interface @@ -40,9 +39,7 @@ public class MethodInvocationFixer extends SimplifiedVisitor implements AttributeVisitor, InstructionVisitor, - ConstantVisitor, - ClassVisitor, - MemberVisitor + ConstantVisitor { private static final boolean DEBUG = false; @@ -88,7 +85,8 @@ implements AttributeVisitor, clazz.constantPoolEntryAccept(constantIndex, this); // Did we find the called class and method? - if (referencedMethod != null) + if (referencedClass != null && + referencedMethod != null) { // Do we need to update the opcode? byte opcode = constantInstruction.opcode; @@ -168,6 +166,7 @@ implements AttributeVisitor, // but not a super call)? if (opcode != InstructionConstants.OP_INVOKEVIRTUAL && (opcode != InstructionConstants.OP_INVOKESPECIAL || + clazz.equals(referencedClass) || !clazz.extends_(referencedClass))) { // Replace the invocation by an invokevirtual instruction. @@ -194,40 +193,30 @@ implements AttributeVisitor, public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) { - // Check if this is an interface method. Note that we're interested in - // the class of the method reference, not in the class in which the - // method was actually found. - //refConstant.referencedClassAccept(this); - clazz.constantPoolEntryAccept(refConstant.u2classIndex, this); - - // Get the referenced access flags and names. - refConstant.referencedMemberAccept(this); - } - + // Remember the referenced class. Note that we're interested in the + // class of the method reference, not in the class in which the + // method was actually found, unless it is an array type. + // + if (ClassUtil.isInternalArrayType(refConstant.getClassName(clazz))) + { + // For an array type, the class will be java.lang.Object. + referencedClass = refConstant.referencedClass; + } + else + { + clazz.constantPoolEntryAccept(refConstant.u2classIndex, this); + } - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) - { - // Check if this is an interface class. - classConstant.referencedClassAccept(this); + // Remember the referenced method. + referencedMethodClass = refConstant.referencedClass; + referencedMethod = refConstant.referencedMember; } - // Implementations for ClassVisitor. - - public void visitAnyClass(Clazz clazz) + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { // Remember the referenced class. - referencedClass = clazz; - } - - - // Implementations for MemberVisitor. - - public void visitAnyMember(Clazz clazz, Member member) - { - // Remember the referenced method. - referencedMethodClass = clazz; - referencedMethod = member; + referencedClass = classConstant.referencedClass; } diff --git a/src/proguard/classfile/editor/NameAndTypeShrinker.java b/src/proguard/classfile/editor/NameAndTypeShrinker.java new file mode 100644 index 0000000..f316884 --- /dev/null +++ b/src/proguard/classfile/editor/NameAndTypeShrinker.java @@ -0,0 +1,188 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.editor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.editor.ConstantPoolRemapper; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ClassVisitor; + +import java.util.Arrays; + + +/** + * This ClassVisitor removes NameAndType constant pool entries that are not + * used. + * + * @author Eric Lafortune + */ +public class NameAndTypeShrinker +extends SimplifiedVisitor +implements ClassVisitor, + ConstantVisitor, + AttributeVisitor +{ + // A visitor info flag to indicate the NameAndType constant pool entry is being used. + private static final Object USED = new Object(); + + private int[] constantIndexMap; + private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper(); + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + // Mark the NameAndType entries referenced by all other constant pool + // entries. + programClass.constantPoolEntriesAccept(this); + + // Mark the NameAndType entries referenced by all EnclosingMethod + // attributes. + programClass.attributesAccept(this); + + // Shift the used constant pool entries together, filling out the + // index map. + int newConstantPoolCount = + shrinkConstantPool(programClass.constantPool, + programClass.u2constantPoolCount); + + // Remap the references to the constant pool if it has shrunk. + if (newConstantPoolCount < programClass.u2constantPoolCount) + { + programClass.u2constantPoolCount = newConstantPoolCount; + + // Remap all constant pool references. + constantPoolRemapper.setConstantIndexMap(constantIndexMap); + constantPoolRemapper.visitProgramClass(programClass); + } + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + markNameAndTypeConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex); + } + + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) + { + markNameAndTypeConstant(clazz, refConstant.u2nameAndTypeIndex); + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) + { + if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) + { + markNameAndTypeConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); + } + } + + + // Small utility methods. + + /** + * Marks the given UTF-8 constant pool entry of the given class. + */ + private void markNameAndTypeConstant(Clazz clazz, int index) + { + markAsUsed((NameAndTypeConstant)((ProgramClass)clazz).getConstant(index)); + } + + + /** + * Marks the given VisitorAccepter as being used. + * In this context, the VisitorAccepter will be a NameAndTypeConstant object. + */ + private void markAsUsed(VisitorAccepter visitorAccepter) + { + visitorAccepter.setVisitorInfo(USED); + } + + + /** + * Returns whether the given VisitorAccepter has been marked as being used. + * In this context, the VisitorAccepter will be a NameAndTypeConstant object. + */ + private boolean isUsed(VisitorAccepter visitorAccepter) + { + return visitorAccepter.getVisitorInfo() == USED; + } + + + /** + * Removes all NameAndType entries that are not marked as being used + * from the given constant pool. + * @return the new number of entries. + */ + private int shrinkConstantPool(Constant[] constantPool, int length) + { + // Create a new index map, if necessary. + if (constantIndexMap == null || + constantIndexMap.length < length) + { + constantIndexMap = new int[length]; + } + + int counter = 1; + boolean isUsed = false; + + // Shift the used constant pool entries together. + for (int index = 1; index < length; index++) + { + constantIndexMap[index] = counter; + + Constant constant = constantPool[index]; + + // Don't update the flag if this is the second half of a long entry. + if (constant != null) + { + isUsed = constant.getTag() != ClassConstants.CONSTANT_NameAndType || + isUsed(constant); + } + + if (isUsed) + { + constantPool[counter++] = constant; + } + } + + // Clear the remaining constant pool elements. + Arrays.fill(constantPool, counter, length, null); + + return counter; + } +} diff --git a/src/proguard/classfile/editor/NamedAttributeDeleter.java b/src/proguard/classfile/editor/NamedAttributeDeleter.java index 0c4d339..5ae950d 100644 --- a/src/proguard/classfile/editor/NamedAttributeDeleter.java +++ b/src/proguard/classfile/editor/NamedAttributeDeleter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java index 4cad6b8..c97e2c8 100644 --- a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java +++ b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/StackSizeUpdater.java b/src/proguard/classfile/editor/StackSizeUpdater.java index 94e0519..cc743b1 100644 --- a/src/proguard/classfile/editor/StackSizeUpdater.java +++ b/src/proguard/classfile/editor/StackSizeUpdater.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/SubclassAdder.java b/src/proguard/classfile/editor/SubclassAdder.java index 6b9fd64..f944ef8 100644 --- a/src/proguard/classfile/editor/SubclassAdder.java +++ b/src/proguard/classfile/editor/SubclassAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/SubclassToAdder.java b/src/proguard/classfile/editor/SubclassToAdder.java index deb242f..f4cdd70 100644 --- a/src/proguard/classfile/editor/SubclassToAdder.java +++ b/src/proguard/classfile/editor/SubclassToAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/Utf8Shrinker.java b/src/proguard/classfile/editor/Utf8Shrinker.java new file mode 100644 index 0000000..b9dac44 --- /dev/null +++ b/src/proguard/classfile/editor/Utf8Shrinker.java @@ -0,0 +1,455 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.editor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.preverification.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.editor.ConstantPoolRemapper; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +import java.util.Arrays; + + +/** + * This ClassVisitor removes UTF-8 constant pool entries that are not used. + * + * @author Eric Lafortune + */ +public class Utf8Shrinker +extends SimplifiedVisitor +implements ClassVisitor, + MemberVisitor, + ConstantVisitor, + AttributeVisitor, + InnerClassesInfoVisitor, + LocalVariableInfoVisitor, + LocalVariableTypeInfoVisitor, + AnnotationVisitor, + ElementValueVisitor +{ + // A visitor info flag to indicate the UTF-8 constant pool entry is being used. + private static final Object USED = new Object(); + + private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE]; + private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper(); + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + // Mark the UTF-8 entries referenced by the other constant pool entries. + programClass.constantPoolEntriesAccept(this); + + // Mark the UTF-8 entries referenced by the fields and methods. + programClass.fieldsAccept(this); + programClass.methodsAccept(this); + + // Mark the UTF-8 entries referenced by the attributes. + programClass.attributesAccept(this); + + // Shift the used constant pool entries together, filling out the + // index map. + int newConstantPoolCount = + shrinkConstantPool(programClass.constantPool, + programClass.u2constantPoolCount); + + // Remap the references to the constant pool if it has shrunk. + if (newConstantPoolCount < programClass.u2constantPoolCount) + { + programClass.u2constantPoolCount = newConstantPoolCount; + + // Remap all constant pool references. + constantPoolRemapper.setConstantIndexMap(constantIndexMap); + constantPoolRemapper.visitProgramClass(programClass); + } + } + + + // Implementations for MemberVisitor. + + public void visitProgramMember(ProgramClass programClass, ProgramMember programMember) + { + // Mark the name and descriptor UTF-8 entries. + markCpUtf8Entry(programClass, programMember.u2nameIndex); + markCpUtf8Entry(programClass, programMember.u2descriptorIndex); + + // Mark the UTF-8 entries referenced by the attributes. + programMember.attributesAccept(programClass, this); + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + { + markCpUtf8Entry(clazz, stringConstant.u2stringIndex); + } + + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + markCpUtf8Entry(clazz, classConstant.u2nameIndex); + } + + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) + { + markCpUtf8Entry(clazz, nameAndTypeConstant.u2nameIndex); + markCpUtf8Entry(clazz, nameAndTypeConstant.u2descriptorIndex); + } + + + // Implementations for AttributeVisitor. + + public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) + { + // This is the best we can do for unknown attributes. + markCpUtf8Entry(clazz, unknownAttribute.u2attributeNameIndex); + } + + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) + { + markCpUtf8Entry(clazz, sourceFileAttribute.u2attributeNameIndex); + + markCpUtf8Entry(clazz, sourceFileAttribute.u2sourceFileIndex); + } + + + public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) + { + markCpUtf8Entry(clazz, sourceDirAttribute.u2attributeNameIndex); + + markCpUtf8Entry(clazz, sourceDirAttribute.u2sourceDirIndex); + } + + + public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) + { + markCpUtf8Entry(clazz, innerClassesAttribute.u2attributeNameIndex); + + // Mark the UTF-8 entries referenced by the inner classes. + innerClassesAttribute.innerClassEntriesAccept(clazz, this); + } + + + public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) + { + markCpUtf8Entry(clazz, enclosingMethodAttribute.u2attributeNameIndex); + + // These entries have already been marked in the constant pool. + //clazz.constantPoolEntryAccept(this, enclosingMethodAttribute.u2classIndex); + //clazz.constantPoolEntryAccept(this, enclosingMethodAttribute.u2nameAndTypeIndex); + } + + + public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) + { + markCpUtf8Entry(clazz, deprecatedAttribute.u2attributeNameIndex); + } + + + public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) + { + markCpUtf8Entry(clazz, syntheticAttribute.u2attributeNameIndex); + } + + + public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) + { + markCpUtf8Entry(clazz, signatureAttribute.u2attributeNameIndex); + + markCpUtf8Entry(clazz, signatureAttribute.u2signatureIndex); + } + + + public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) + { + markCpUtf8Entry(clazz, constantValueAttribute.u2attributeNameIndex); + } + + + public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) + { + markCpUtf8Entry(clazz, exceptionsAttribute.u2attributeNameIndex); + } + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + markCpUtf8Entry(clazz, codeAttribute.u2attributeNameIndex); + + // Mark the UTF-8 entries referenced by the attributes. + codeAttribute.attributesAccept(clazz, method, this); + } + + + public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) + { + markCpUtf8Entry(clazz, stackMapAttribute.u2attributeNameIndex); + } + + + public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) + { + markCpUtf8Entry(clazz, stackMapTableAttribute.u2attributeNameIndex); + } + + + public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) + { + markCpUtf8Entry(clazz, lineNumberTableAttribute.u2attributeNameIndex); + } + + + public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) + { + markCpUtf8Entry(clazz, localVariableTableAttribute.u2attributeNameIndex); + + // Mark the UTF-8 entries referenced by the local variables. + localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + } + + + public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) + { + markCpUtf8Entry(clazz, localVariableTypeTableAttribute.u2attributeNameIndex); + + // Mark the UTF-8 entries referenced by the local variable types. + localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + } + + + public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) + { + markCpUtf8Entry(clazz, annotationsAttribute.u2attributeNameIndex); + + // Mark the UTF-8 entries referenced by the annotations. + annotationsAttribute.annotationsAccept(clazz, this); + } + + + public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) + { + markCpUtf8Entry(clazz, parameterAnnotationsAttribute.u2attributeNameIndex); + + // Mark the UTF-8 entries referenced by the annotations. + parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); + } + + + public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) + { + markCpUtf8Entry(clazz, annotationDefaultAttribute.u2attributeNameIndex); + + // Mark the UTF-8 entries referenced by the element value. + annotationDefaultAttribute.defaultValueAccept(clazz, this); + } + + + // Implementations for InnerClassesInfoVisitor. + + public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) + { + if (innerClassesInfo.u2innerNameIndex != 0) + { + markCpUtf8Entry(clazz, innerClassesInfo.u2innerNameIndex); + } + } + + + // Implementations for LocalVariableInfoVisitor. + + public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) + { + markCpUtf8Entry(clazz, localVariableInfo.u2nameIndex); + markCpUtf8Entry(clazz, localVariableInfo.u2descriptorIndex); + } + + + // Implementations for LocalVariableTypeInfoVisitor. + + public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) + { + markCpUtf8Entry(clazz, localVariableTypeInfo.u2nameIndex); + markCpUtf8Entry(clazz, localVariableTypeInfo.u2signatureIndex); + } + + + // Implementations for AnnotationVisitor. + + public void visitAnnotation(Clazz clazz, Annotation annotation) + { + markCpUtf8Entry(clazz, annotation.u2typeIndex); + + // Mark the UTF-8 entries referenced by the element values. + annotation.elementValuesAccept(clazz, this); + } + + + // Implementations for ElementValueVisitor. + + public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) + { + if (constantElementValue.u2elementNameIndex != 0) + { + markCpUtf8Entry(clazz, constantElementValue.u2elementNameIndex); + } + + // Only the string constant element value refers to a UTF-8 entry. + if (constantElementValue.u1tag == ClassConstants.ELEMENT_VALUE_STRING_CONSTANT) + { + markCpUtf8Entry(clazz, constantElementValue.u2constantValueIndex); + } + } + + + public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) + { + if (enumConstantElementValue.u2elementNameIndex != 0) + { + markCpUtf8Entry(clazz, enumConstantElementValue.u2elementNameIndex); + } + + markCpUtf8Entry(clazz, enumConstantElementValue.u2typeNameIndex); + markCpUtf8Entry(clazz, enumConstantElementValue.u2constantNameIndex); + } + + + public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) + { + if (classElementValue.u2elementNameIndex != 0) + { + markCpUtf8Entry(clazz, classElementValue.u2elementNameIndex); + } + + markCpUtf8Entry(clazz, classElementValue.u2classInfoIndex); + } + + + public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) + { + if (annotationElementValue.u2elementNameIndex != 0) + { + markCpUtf8Entry(clazz, annotationElementValue.u2elementNameIndex); + } + + // Mark the UTF-8 entries referenced by the annotation. + annotationElementValue.annotationAccept(clazz, this); + } + + + public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) + { + if (arrayElementValue.u2elementNameIndex != 0) + { + markCpUtf8Entry(clazz, arrayElementValue.u2elementNameIndex); + } + + // Mark the UTF-8 entries referenced by the element values. + arrayElementValue.elementValuesAccept(clazz, annotation, this); + } + + + // Small utility methods. + + /** + * Marks the given UTF-8 constant pool entry of the given class. + */ + private void markCpUtf8Entry(Clazz clazz, int index) + { + markAsUsed((Utf8Constant)((ProgramClass)clazz).getConstant(index)); + } + + + /** + * Marks the given VisitorAccepter as being used. + * In this context, the VisitorAccepter will be a Utf8Constant object. + */ + private void markAsUsed(VisitorAccepter visitorAccepter) + { + visitorAccepter.setVisitorInfo(USED); + } + + + /** + * Returns whether the given VisitorAccepter has been marked as being used. + * In this context, the VisitorAccepter will be a Utf8Constant object. + */ + private boolean isUsed(VisitorAccepter visitorAccepter) + { + return visitorAccepter.getVisitorInfo() == USED; + } + + + /** + * Removes all UTF-8 entries that are not marked as being used + * from the given constant pool. + * @return the new number of entries. + */ + private int shrinkConstantPool(Constant[] constantPool, int length) + { + // Create a new index map, if necessary. + if (constantIndexMap.length < length) + { + constantIndexMap = new int[length]; + } + + int counter = 1; + boolean isUsed = false; + + // Shift the used constant pool entries together. + for (int index = 1; index < length; index++) + { + constantIndexMap[index] = counter; + + Constant constant = constantPool[index]; + + // Don't update the flag if this is the second half of a long entry. + if (constant != null) + { + isUsed = constant.getTag() != ClassConstants.CONSTANT_Utf8 || + isUsed(constant); + } + + if (isUsed) + { + constantPool[counter++] = constant; + } + } + + // Clear the remaining constant pool elements. + Arrays.fill(constantPool, counter, length, null); + + return counter; + } +} diff --git a/src/proguard/classfile/editor/VariableCleaner.java b/src/proguard/classfile/editor/VariableCleaner.java index 1e93c15..af51403 100644 --- a/src/proguard/classfile/editor/VariableCleaner.java +++ b/src/proguard/classfile/editor/VariableCleaner.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -22,15 +22,15 @@ package proguard.classfile.editor; import proguard.classfile.*; import proguard.classfile.attribute.*; -import proguard.classfile.attribute.visitor.*; -import proguard.classfile.instruction.*; -import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.attribute.visitor.AttributeVisitor; import proguard.classfile.util.SimplifiedVisitor; -import proguard.optimize.info.VariableUsageMarker; + +import java.util.Arrays; /** - * This AttributeVisitor cleans up unused variables in all attributes that it - * visits. + * This AttributeVisitor cleans up variable tables in all code attributes that + * it visits. It trims overlapping local variables. It removes empty local + * variables and empty local variable tables. * * @author Eric Lafortune */ @@ -38,7 +38,8 @@ public class VariableCleaner extends SimplifiedVisitor implements AttributeVisitor { - private final VariableUsageMarker variableUsageMarker = new VariableUsageMarker(); + private boolean deleteLocalVariableTableAttribute; + private boolean deleteLocalVariableTypeTableAttribute; // Implementations for AttributeVisitor. @@ -48,11 +49,35 @@ implements AttributeVisitor public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { - // Figure out the local variables that are used by the code. - variableUsageMarker.visitCodeAttribute(clazz, method, codeAttribute); + deleteLocalVariableTableAttribute = false; + deleteLocalVariableTypeTableAttribute = false; - // Clean up the variables of the attributes. + // Trim the local variable table and the local variable type table. codeAttribute.attributesAccept(clazz, method, this); + + // Delete the local variable table if it ended up empty. + if (deleteLocalVariableTableAttribute) + { + AttributesEditor editor = + new AttributesEditor((ProgramClass)clazz, + (ProgramMember)method, + codeAttribute, + true); + + editor.deleteAttribute(ClassConstants.ATTR_LocalVariableTable); + } + + // Delete the local variable type table if it ended up empty. + if (deleteLocalVariableTypeTableAttribute) + { + AttributesEditor editor = + new AttributesEditor((ProgramClass)clazz, + (ProgramMember)method, + codeAttribute, + true); + + editor.deleteAttribute(ClassConstants.ATTR_LocalVariableTypeTable); + } } @@ -60,9 +85,20 @@ implements AttributeVisitor { // Clean up local variables that aren't used. localVariableTableAttribute.u2localVariableTableLength = - removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable, - localVariableTableAttribute.u2localVariableTableLength, - codeAttribute.u2maxLocals); + removeUnusedLocalVariables(localVariableTableAttribute.localVariableTable, + localVariableTableAttribute.u2localVariableTableLength, + codeAttribute.u2maxLocals); + + // Trim the code blocks of the local variables. + trimLocalVariables(localVariableTableAttribute.localVariableTable, + localVariableTableAttribute.u2localVariableTableLength, + codeAttribute.u2maxLocals); + + // Delete the attribute in a moment, if it is empty. + if (localVariableTableAttribute.u2localVariableTableLength == 0) + { + deleteLocalVariableTableAttribute = true; + } } @@ -70,9 +106,20 @@ implements AttributeVisitor { // Clean up local variables that aren't used. localVariableTypeTableAttribute.u2localVariableTypeTableLength = - removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, - localVariableTypeTableAttribute.u2localVariableTypeTableLength, - codeAttribute.u2maxLocals); + removeUnusedLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, + localVariableTypeTableAttribute.u2localVariableTypeTableLength, + codeAttribute.u2maxLocals); + + // Trim the code blocks of the local variables. + trimLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, + localVariableTypeTableAttribute.u2localVariableTypeTableLength, + codeAttribute.u2maxLocals); + + // Delete the attribute in a moment, if it is empty. + if (localVariableTypeTableAttribute.u2localVariableTypeTableLength == 0) + { + deleteLocalVariableTypeTableAttribute = true; + } } @@ -80,27 +127,28 @@ implements AttributeVisitor /** * Returns the given list of local variables, without the ones that aren't - * used + * used. */ - private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, - int localVariableInfoCount, - int maxLocals) + private int removeUnusedLocalVariables(LocalVariableInfo[] localVariableInfos, + int localVariableInfoCount, + int maxLocals) { // Overwrite all empty local variable entries. int newIndex = 0; - for (int index = 0; index < localVariableInfoCount && index < maxLocals; index++) + for (int index = 0; index < localVariableInfoCount; index++) { - if (variableUsageMarker.isVariableUsed(index)) + LocalVariableInfo localVariableInfo = localVariableInfos[index]; + + if (localVariableInfo.u2index >= 0 && + localVariableInfo.u2index < maxLocals && + localVariableInfo.u2length > 0) { localVariableInfos[newIndex++] = localVariableInfos[index]; } } // Clean up any remaining array elements. - for (int index = newIndex; index < localVariableInfoCount; index++) - { - localVariableInfos[index] = null; - } + Arrays.fill(localVariableInfos, newIndex, localVariableInfoCount, null); return newIndex; } @@ -108,28 +156,112 @@ implements AttributeVisitor /** * Returns the given list of local variable types, without the ones that - * aren't used + * aren't used. */ - private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, - int localVariableTypeInfoCount, - int maxLocals) + private int removeUnusedLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, + int localVariableTypeInfoCount, + int maxLocals) { // Overwrite all empty local variable type entries. int newIndex = 0; - for (int index = 0; index < localVariableTypeInfoCount && index < maxLocals; index++) + for (int index = 0; index < localVariableTypeInfoCount; index++) { - if (variableUsageMarker.isVariableUsed(index)) + LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; + + if (localVariableTypeInfo.u2index >= 0 && + localVariableTypeInfo.u2index < maxLocals && + localVariableTypeInfo.u2length > 0) { localVariableTypeInfos[newIndex++] = localVariableTypeInfos[index]; } } // Clean up any remaining array elements. - for (int index = newIndex; index < localVariableTypeInfoCount; index++) + Arrays.fill(localVariableTypeInfos, newIndex, localVariableTypeInfoCount, null); + + return newIndex; + } + + + /** + * Sorts the given list of local variables and trims their code blocks + * when necessary. The block is trimmed at the end, which is a bit + * arbitrary. + */ + private void trimLocalVariables(LocalVariableInfo[] localVariableInfos, + int localVariableInfoCount, + int maxLocals) + { + // Sort the local variable entries. + Arrays.sort(localVariableInfos, 0, localVariableInfoCount); + + int[] startPCs = createMaxArray(maxLocals); + + // Trim the local variable entries, starting at the last one. + for (int index = localVariableInfoCount-1; index >= 0; index--) { - localVariableTypeInfos[index] = null; + LocalVariableInfo localVariableInfo = localVariableInfos[index]; + + // Make sure the variable's code block doesn't overlap with the + // next one for the same variable. + int maxLength = startPCs[localVariableInfo.u2index] - + localVariableInfo.u2startPC; + + if (localVariableInfo.u2length > maxLength) + { + localVariableInfo.u2length = maxLength; + } + + startPCs[localVariableInfo.u2index] = localVariableInfo.u2startPC; } + } - return newIndex; + + /** + * Sorts the given list of local variable types and trims their code blocks + * when necessary. The block is trimmed at the end, which is a bit + * arbitrary. + */ + private void trimLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, + int localVariableTypeInfoCount, + int maxLocals) + { + // Sort the local variable entries. + Arrays.sort(localVariableTypeInfos, 0, localVariableTypeInfoCount); + + int[] startPCs = createMaxArray(maxLocals); + + // Trim the local variable entries, starting at the last one. + for (int index = localVariableTypeInfoCount-1; index >= 0; index--) + { + LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; + + // Make sure the variable's code block doesn't overlap with the + // next one for the same variable. + int maxLength = startPCs[localVariableTypeInfo.u2index] - + localVariableTypeInfo.u2startPC; + + if (localVariableTypeInfo.u2length > maxLength) + { + localVariableTypeInfo.u2length = maxLength; + } + + startPCs[localVariableTypeInfo.u2index] = localVariableTypeInfo.u2startPC; + } + } + + + /** + * Creates an integer array of the given length, initialized with + * Integer.MAX_VALUE. + */ + private int[] createMaxArray(int length) + { + int[] startPCs = new int[length]; + for (int index = 0; index < length; index++) + { + startPCs[index] = Integer.MAX_VALUE; + } + return startPCs; } }
\ No newline at end of file diff --git a/src/proguard/classfile/editor/VariableEditor.java b/src/proguard/classfile/editor/VariableEditor.java index a583b49..8c99ff8 100644 --- a/src/proguard/classfile/editor/VariableEditor.java +++ b/src/proguard/classfile/editor/VariableEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -25,6 +25,8 @@ import proguard.classfile.attribute.*; import proguard.classfile.attribute.visitor.AttributeVisitor; import proguard.classfile.util.SimplifiedVisitor; +import java.util.Arrays; + /** * This AttributeVisitor accumulates specified changes to local variables, and * then applies these accumulated changes to the code attributes that it visits. @@ -53,14 +55,13 @@ implements AttributeVisitor // Try to reuse the previous array. if (deleted.length < maxLocals) { + // Create a new array. deleted = new boolean[maxLocals]; } else { - for (int index = 0; index < maxLocals; index++) - { - deleted[index] = false; - } + // Reset the array. + Arrays.fill(deleted, 0, maxLocals, false); } modified = false; diff --git a/src/proguard/classfile/editor/VariableRemapper.java b/src/proguard/classfile/editor/VariableRemapper.java index 590cd4e..df26534 100644 --- a/src/proguard/classfile/editor/VariableRemapper.java +++ b/src/proguard/classfile/editor/VariableRemapper.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -40,6 +40,9 @@ implements AttributeVisitor, LocalVariableInfoVisitor, LocalVariableTypeInfoVisitor { + private static final boolean DEBUG = false; + + private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); private int[] variableMap; @@ -62,6 +65,19 @@ implements AttributeVisitor, public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { + if (DEBUG) + { + System.out.println("VariableRemapper: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)); + for (int index= 0; index < codeAttribute.u2maxLocals; index++) + { + System.out.println(" v"+index+" -> "+variableMap[index]); + } + } + + // Remap the variables of the attributes, before editing the code and + // cleaning up its local variable frame. + codeAttribute.attributesAccept(clazz, method, this); + // Initially, the code attribute editor doesn't contain any changes. codeAttributeEditor.reset(codeAttribute.u4codeLength); @@ -70,9 +86,6 @@ implements AttributeVisitor, // Apply the code atribute editor. codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); - - // Remap the variables of the attributes. - codeAttribute.attributesAccept(clazz, method, this); } @@ -80,11 +93,6 @@ implements AttributeVisitor, { // Remap the variable references of the local variables. localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - - // Remove local variables that haven't been mapped. - localVariableTableAttribute.u2localVariableTableLength = - removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable, - localVariableTableAttribute.u2localVariableTableLength); } @@ -92,11 +100,6 @@ implements AttributeVisitor, { // Remap the variable references of the local variables. localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - - // Remove local variables that haven't been mapped. - localVariableTypeTableAttribute.u2localVariableTypeTableLength = - removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, - localVariableTypeTableAttribute.u2localVariableTypeTableLength); } @@ -150,48 +153,4 @@ implements AttributeVisitor, { return variableMap[variableIndex]; } - - - /** - * Returns the given list of local variables, without the ones that have - * been removed. - */ - private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, - int localVariableInfoCount) - { - // Overwrite all empty local variable entries. - int newIndex = 0; - for (int index = 0; index < localVariableInfoCount; index++) - { - LocalVariableInfo localVariableInfo = localVariableInfos[index]; - if (localVariableInfo.u2index >= 0) - { - localVariableInfos[newIndex++] = localVariableInfo; - } - } - - return newIndex; - } - - - /** - * Returns the given list of local variable types, without the ones that - * have been removed. - */ - private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, - int localVariableTypeInfoCount) - { - // Overwrite all empty local variable type entries. - int newIndex = 0; - for (int index = 0; index < localVariableTypeInfoCount; index++) - { - LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; - if (localVariableTypeInfo.u2index >= 0) - { - localVariableTypeInfos[newIndex++] = localVariableTypeInfo; - } - } - - return newIndex; - } } diff --git a/src/proguard/classfile/editor/VariableSizeUpdater.java b/src/proguard/classfile/editor/VariableSizeUpdater.java index 18958c5..bb87151 100644 --- a/src/proguard/classfile/editor/VariableSizeUpdater.java +++ b/src/proguard/classfile/editor/VariableSizeUpdater.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -29,7 +29,8 @@ import proguard.classfile.util.*; /** * This AttributeVisitor computes and updates the maximum local variable frame - * size of the code attributes that it visits. + * size of the code attributes that it visits. It also cleans up the local + * variable tables. * * @author Eric Lafortune */ @@ -45,6 +46,9 @@ implements AttributeVisitor, //*/ + private VariableCleaner variableCleaner = new VariableCleaner(); + + // Implementations for AttributeVisitor. public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} @@ -69,6 +73,9 @@ implements AttributeVisitor, // Go over all instructions. codeAttribute.instructionsAccept(clazz, method, this); + + // Remove the unused variables of the attributes. + variableCleaner.visitCodeAttribute(clazz, method, codeAttribute); } @@ -91,7 +98,7 @@ implements AttributeVisitor, if (DEBUG) { - System.out.println("Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset)); + System.out.println(" Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset)); } } } diff --git a/src/proguard/classfile/instruction/BranchInstruction.java b/src/proguard/classfile/instruction/BranchInstruction.java index 2baa917..54f583b 100644 --- a/src/proguard/classfile/instruction/BranchInstruction.java +++ b/src/proguard/classfile/instruction/BranchInstruction.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/ConstantInstruction.java b/src/proguard/classfile/instruction/ConstantInstruction.java index 6c2d1a3..900a8d5 100644 --- a/src/proguard/classfile/instruction/ConstantInstruction.java +++ b/src/proguard/classfile/instruction/ConstantInstruction.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -93,13 +93,9 @@ implements ConstantVisitor public byte canonicalOpcode() { // Remove the _w extension, if any. - switch (opcode) - { - case InstructionConstants.OP_LDC_W: - case InstructionConstants.OP_LDC2_W: return InstructionConstants.OP_LDC; - - default: return opcode; - } + return + opcode == InstructionConstants.OP_LDC_W ? InstructionConstants.OP_LDC : + opcode; } public Instruction shrink() @@ -185,7 +181,8 @@ implements ConstantVisitor case InstructionConstants.OP_INVOKESPECIAL: case InstructionConstants.OP_INVOKESTATIC: case InstructionConstants.OP_INVOKEINTERFACE: - // The some parameters may be popped from the stack. + case InstructionConstants.OP_INVOKEDYNAMIC: + // Some parameters may be popped from the stack. clazz.constantPoolEntryAccept(constantIndex, this); stackPopCount += parameterStackDelta; break; @@ -208,6 +205,7 @@ implements ConstantVisitor case InstructionConstants.OP_INVOKESPECIAL: case InstructionConstants.OP_INVOKESTATIC: case InstructionConstants.OP_INVOKEINTERFACE: + case InstructionConstants.OP_INVOKEDYNAMIC: // The field value or a return value may be pushed onto the stack. clazz.constantPoolEntryAccept(constantIndex, this); stackPushCount += typeStackDelta; @@ -226,8 +224,9 @@ implements ConstantVisitor public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) {} public void visitStringConstant(Clazz clazz, StringConstant stringConstant) {} public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) {} + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) {} public void visitClassConstant(Clazz clazz, ClassConstant classConstant) {} - public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) {} + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) {} public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) @@ -238,21 +237,27 @@ implements ConstantVisitor } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this); + } + + public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) { - visitRefConstant(clazz, interfaceMethodrefConstant); + clazz.constantPoolEntryAccept(interfaceMethodrefConstant.u2nameAndTypeIndex, this); } public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) { - visitRefConstant(clazz, methodrefConstant); + clazz.constantPoolEntryAccept(methodrefConstant.u2nameAndTypeIndex, this); } - private void visitRefConstant(Clazz clazz, RefConstant methodrefConstant) + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { - String type = methodrefConstant.getType(clazz); + String type = nameAndTypeConstant.getType(clazz); parameterStackDelta = ClassUtil.internalMethodParameterSize(type); typeStackDelta = ClassUtil.internalTypeSize(ClassUtil.internalMethodReturnType(type)); @@ -285,6 +290,7 @@ implements ConstantVisitor private int constantSize() { return opcode == InstructionConstants.OP_MULTIANEWARRAY ? 1 : + opcode == InstructionConstants.OP_INVOKEDYNAMIC || opcode == InstructionConstants.OP_INVOKEINTERFACE ? 2 : 0; } diff --git a/src/proguard/classfile/instruction/Instruction.java b/src/proguard/classfile/instruction/Instruction.java index 8437495..77b0e20 100644 --- a/src/proguard/classfile/instruction/Instruction.java +++ b/src/proguard/classfile/instruction/Instruction.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -220,7 +220,7 @@ public abstract class Instruction false, // invokespecial false, // invokestatic false, // invokeinterface - false, // unused + false, // invokedynamic false, // new false, // newarray false, // anewarray @@ -429,7 +429,7 @@ public abstract class Instruction 1, // invokespecial 0, // invokestatic 1, // invokeinterface - 0, // unused + 0, // invokedynamic 0, // new 1, // newarray 1, // anewarray @@ -638,7 +638,7 @@ public abstract class Instruction 0, // invokespecial 0, // invokestatic 0, // invokeinterface - 0, // unused + 0, // invokedynamic 1, // new 1, // newarray 1, // anewarray diff --git a/src/proguard/classfile/instruction/InstructionConstants.java b/src/proguard/classfile/instruction/InstructionConstants.java index 78730b3..8ca03cc 100644 --- a/src/proguard/classfile/instruction/InstructionConstants.java +++ b/src/proguard/classfile/instruction/InstructionConstants.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -213,22 +213,22 @@ public interface InstructionConstants public static final byte OP_INVOKESPECIAL = -73; public static final byte OP_INVOKESTATIC = -72; public static final byte OP_INVOKEINTERFACE = -71; -// public static final byte OP_UNUSED = -70; - public static final byte OP_NEW = -69; - public static final byte OP_NEWARRAY = -68; - public static final byte OP_ANEWARRAY = -67; - public static final byte OP_ARRAYLENGTH = -66; - public static final byte OP_ATHROW = -65; - public static final byte OP_CHECKCAST = -64; - public static final byte OP_INSTANCEOF = -63; - public static final byte OP_MONITORENTER = -62; - public static final byte OP_MONITOREXIT = -61; - public static final byte OP_WIDE = -60; - public static final byte OP_MULTIANEWARRAY = -59; - public static final byte OP_IFNULL = -58; - public static final byte OP_IFNONNULL = -57; - public static final byte OP_GOTO_W = -56; - public static final byte OP_JSR_W = -55; + public static final byte OP_INVOKEDYNAMIC = -70; + public static final byte OP_NEW = -69; + public static final byte OP_NEWARRAY = -68; + public static final byte OP_ANEWARRAY = -67; + public static final byte OP_ARRAYLENGTH = -66; + public static final byte OP_ATHROW = -65; + public static final byte OP_CHECKCAST = -64; + public static final byte OP_INSTANCEOF = -63; + public static final byte OP_MONITORENTER = -62; + public static final byte OP_MONITOREXIT = -61; + public static final byte OP_WIDE = -60; + public static final byte OP_MULTIANEWARRAY = -59; + public static final byte OP_IFNULL = -58; + public static final byte OP_IFNONNULL = -57; + public static final byte OP_GOTO_W = -56; + public static final byte OP_JSR_W = -55; public static final String[] NAMES = @@ -419,7 +419,7 @@ public interface InstructionConstants "invokespecial", "invokestatic", "invokeinterface", - "unused", + "invokedynamic", "new", "newarray", "anewarray", diff --git a/src/proguard/classfile/instruction/InstructionFactory.java b/src/proguard/classfile/instruction/InstructionFactory.java index f898471..288acc2 100644 --- a/src/proguard/classfile/instruction/InstructionFactory.java +++ b/src/proguard/classfile/instruction/InstructionFactory.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -182,6 +182,7 @@ public class InstructionFactory case InstructionConstants.OP_INVOKESPECIAL: case InstructionConstants.OP_INVOKESTATIC: case InstructionConstants.OP_INVOKEINTERFACE: + case InstructionConstants.OP_INVOKEDYNAMIC: case InstructionConstants.OP_NEW: case InstructionConstants.OP_ANEWARRAY: diff --git a/src/proguard/classfile/instruction/InstructionUtil.java b/src/proguard/classfile/instruction/InstructionUtil.java index a3a328a..12d4d05 100644 --- a/src/proguard/classfile/instruction/InstructionUtil.java +++ b/src/proguard/classfile/instruction/InstructionUtil.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/LookUpSwitchInstruction.java b/src/proguard/classfile/instruction/LookUpSwitchInstruction.java index 178cce5..2da639b 100644 --- a/src/proguard/classfile/instruction/LookUpSwitchInstruction.java +++ b/src/proguard/classfile/instruction/LookUpSwitchInstruction.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/SimpleInstruction.java b/src/proguard/classfile/instruction/SimpleInstruction.java index 84e6344..83499dc 100644 --- a/src/proguard/classfile/instruction/SimpleInstruction.java +++ b/src/proguard/classfile/instruction/SimpleInstruction.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/SwitchInstruction.java b/src/proguard/classfile/instruction/SwitchInstruction.java index b98c2fb..11f05c4 100644 --- a/src/proguard/classfile/instruction/SwitchInstruction.java +++ b/src/proguard/classfile/instruction/SwitchInstruction.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/TableSwitchInstruction.java b/src/proguard/classfile/instruction/TableSwitchInstruction.java index ee81af5..a5e8c5e 100644 --- a/src/proguard/classfile/instruction/TableSwitchInstruction.java +++ b/src/proguard/classfile/instruction/TableSwitchInstruction.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/VariableInstruction.java b/src/proguard/classfile/instruction/VariableInstruction.java index 309f802..6cbd3de 100644 --- a/src/proguard/classfile/instruction/VariableInstruction.java +++ b/src/proguard/classfile/instruction/VariableInstruction.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java b/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java index 71b2cde..c355433 100644 --- a/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java +++ b/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/visitor/InstructionCounter.java b/src/proguard/classfile/instruction/visitor/InstructionCounter.java index 1d10980..64c0f65 100644 --- a/src/proguard/classfile/instruction/visitor/InstructionCounter.java +++ b/src/proguard/classfile/instruction/visitor/InstructionCounter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/visitor/InstructionVisitor.java b/src/proguard/classfile/instruction/visitor/InstructionVisitor.java index 11af131..d7d1b24 100644 --- a/src/proguard/classfile/instruction/visitor/InstructionVisitor.java +++ b/src/proguard/classfile/instruction/visitor/InstructionVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java b/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java index aada455..160ccd7 100644 --- a/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java +++ b/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/io/LibraryClassReader.java b/src/proguard/classfile/io/LibraryClassReader.java index f14471c..32bb569 100644 --- a/src/proguard/classfile/io/LibraryClassReader.java +++ b/src/proguard/classfile/io/LibraryClassReader.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -277,6 +277,18 @@ implements ClassVisitor, } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + dataInput.skipBytes(4); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + dataInput.skipBytes(3); + } + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { dataInput.skipBytes(4); @@ -289,6 +301,12 @@ implements ClassVisitor, } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + dataInput.skipBytes(2); + } + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { dataInput.skipBytes(4); @@ -325,16 +343,19 @@ implements ClassVisitor, switch (u1tag) { - case ClassConstants.CONSTANT_Utf8: return new Utf8Constant(); case ClassConstants.CONSTANT_Integer: return new IntegerConstant(); case ClassConstants.CONSTANT_Float: return new FloatConstant(); case ClassConstants.CONSTANT_Long: return new LongConstant(); case ClassConstants.CONSTANT_Double: return new DoubleConstant(); case ClassConstants.CONSTANT_String: return new StringConstant(); + case ClassConstants.CONSTANT_Utf8: return new Utf8Constant(); + case ClassConstants.CONSTANT_InvokeDynamic: return new InvokeDynamicConstant(); + case ClassConstants.CONSTANT_MethodHandle: return new MethodHandleConstant(); case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant(); case ClassConstants.CONSTANT_Methodref: return new MethodrefConstant(); case ClassConstants.CONSTANT_InterfaceMethodref: return new InterfaceMethodrefConstant(); case ClassConstants.CONSTANT_Class: return new ClassConstant(); + case ClassConstants.CONSTANT_MethodType : return new MethodTypeConstant(); case ClassConstants.CONSTANT_NameAndType: return new NameAndTypeConstant(); default: throw new RuntimeException("Unknown constant type ["+u1tag+"] in constant pool"); diff --git a/src/proguard/classfile/io/ProgramClassReader.java b/src/proguard/classfile/io/ProgramClassReader.java index 476a346..01f057f 100644 --- a/src/proguard/classfile/io/ProgramClassReader.java +++ b/src/proguard/classfile/io/ProgramClassReader.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -46,6 +46,7 @@ implements ClassVisitor, MemberVisitor, ConstantVisitor, AttributeVisitor, + BootstrapMethodInfoVisitor, InnerClassesInfoVisitor, ExceptionInfoVisitor, StackMapFrameVisitor, @@ -250,6 +251,20 @@ implements ClassVisitor, } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + invokeDynamicConstant.u2bootstrapMethodAttributeIndex = dataInput.readUnsignedShort(); + invokeDynamicConstant.u2nameAndTypeIndex = dataInput.readUnsignedShort(); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + methodHandleConstant.u1referenceKind = dataInput.readUnsignedByte(); + methodHandleConstant.u2referenceIndex = dataInput.readUnsignedShort(); + } + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { refConstant.u2classIndex = dataInput.readUnsignedShort(); @@ -263,6 +278,12 @@ implements ClassVisitor, } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + methodTypeConstant.u2descriptorIndex = dataInput.readUnsignedShort(); + } + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { nameAndTypeConstant.u2nameIndex = dataInput.readUnsignedShort(); @@ -281,6 +302,21 @@ implements ClassVisitor, } + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + // Read the bootstrap methods. + bootstrapMethodsAttribute.u2bootstrapMethodsCount = dataInput.readUnsignedShort(); + + bootstrapMethodsAttribute.bootstrapMethods = new BootstrapMethodInfo[bootstrapMethodsAttribute.u2bootstrapMethodsCount]; + for (int index = 0; index < bootstrapMethodsAttribute.u2bootstrapMethodsCount; index++) + { + BootstrapMethodInfo bootstrapMethodInfo = new BootstrapMethodInfo(); + visitBootstrapMethodInfo(clazz, bootstrapMethodInfo); + bootstrapMethodsAttribute.bootstrapMethods[index] = bootstrapMethodInfo; + } + } + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { sourceFileAttribute.u2sourceFileIndex = dataInput.readUnsignedShort(); @@ -302,7 +338,7 @@ implements ClassVisitor, for (int index = 0; index < innerClassesAttribute.u2classesCount; index++) { InnerClassesInfo innerClassesInfo = new InnerClassesInfo(); - this.visitInnerClassesInfo(clazz, innerClassesInfo); + visitInnerClassesInfo(clazz, innerClassesInfo); innerClassesAttribute.classes[index] = innerClassesInfo; } } @@ -372,7 +408,7 @@ implements ClassVisitor, for (int index = 0; index < codeAttribute.u2exceptionTableLength; index++) { ExceptionInfo exceptionInfo = new ExceptionInfo(); - this.visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo); + visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo); codeAttribute.exceptionTable[index] = exceptionInfo; } @@ -398,7 +434,7 @@ implements ClassVisitor, for (int index = 0; index < stackMapAttribute.u2stackMapFramesCount; index++) { FullFrame stackMapFrame = new FullFrame(); - this.visitFullFrame(clazz, method, codeAttribute, index, stackMapFrame); + visitFullFrame(clazz, method, codeAttribute, index, stackMapFrame); stackMapAttribute.stackMapFrames[index] = stackMapFrame; } } @@ -428,7 +464,7 @@ implements ClassVisitor, for (int index = 0; index < lineNumberTableAttribute.u2lineNumberTableLength; index++) { LineNumberInfo lineNumberInfo = new LineNumberInfo(); - this.visitLineNumberInfo(clazz, method, codeAttribute, lineNumberInfo); + visitLineNumberInfo(clazz, method, codeAttribute, lineNumberInfo); lineNumberTableAttribute.lineNumberTable[index] = lineNumberInfo; } } @@ -443,7 +479,7 @@ implements ClassVisitor, for (int index = 0; index < localVariableTableAttribute.u2localVariableTableLength; index++) { LocalVariableInfo localVariableInfo = new LocalVariableInfo(); - this.visitLocalVariableInfo(clazz, method, codeAttribute, localVariableInfo); + visitLocalVariableInfo(clazz, method, codeAttribute, localVariableInfo); localVariableTableAttribute.localVariableTable[index] = localVariableInfo; } } @@ -458,7 +494,7 @@ implements ClassVisitor, for (int index = 0; index < localVariableTypeTableAttribute.u2localVariableTypeTableLength; index++) { LocalVariableTypeInfo localVariableTypeInfo = new LocalVariableTypeInfo(); - this.visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeInfo); + visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeInfo); localVariableTypeTableAttribute.localVariableTypeTable[index] = localVariableTypeInfo; } } @@ -473,7 +509,7 @@ implements ClassVisitor, for (int index = 0; index < annotationsAttribute.u2annotationsCount; index++) { Annotation annotation = new Annotation(); - this.visitAnnotation(clazz, annotation); + visitAnnotation(clazz, annotation); annotationsAttribute.annotations[index] = annotation; } } @@ -508,7 +544,7 @@ implements ClassVisitor, for (int index = 0; index < u2annotationsCount; index++) { Annotation annotation = new Annotation(); - this.visitAnnotation(clazz, annotation); + visitAnnotation(clazz, annotation); annotations[index] = annotation; } @@ -527,6 +563,22 @@ implements ClassVisitor, } + // Implementations for BootstrapMethodInfoVisitor. + + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) + { + bootstrapMethodInfo.u2methodHandleIndex = dataInput.readUnsignedShort(); + + // Read the bootstrap method arguments. + bootstrapMethodInfo.u2methodArgumentCount = dataInput.readUnsignedShort(); + bootstrapMethodInfo.u2methodArguments = new int[bootstrapMethodInfo.u2methodArgumentCount]; + for (int index = 0; index < bootstrapMethodInfo.u2methodArgumentCount; index++) + { + bootstrapMethodInfo.u2methodArguments[index] = dataInput.readUnsignedShort(); + } + } + + // Implementations for InnerClassesInfoVisitor. public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) @@ -721,7 +773,7 @@ implements ClassVisitor, { // Read the annotation. Annotation annotationValue = new Annotation(); - this.visitAnnotation(clazz, annotationValue); + visitAnnotation(clazz, annotationValue); annotationElementValue.annotationValue = annotationValue; } @@ -749,16 +801,19 @@ implements ClassVisitor, switch (u1tag) { - case ClassConstants.CONSTANT_Utf8: return new Utf8Constant(); case ClassConstants.CONSTANT_Integer: return new IntegerConstant(); case ClassConstants.CONSTANT_Float: return new FloatConstant(); case ClassConstants.CONSTANT_Long: return new LongConstant(); case ClassConstants.CONSTANT_Double: return new DoubleConstant(); case ClassConstants.CONSTANT_String: return new StringConstant(); + case ClassConstants.CONSTANT_Utf8: return new Utf8Constant(); + case ClassConstants.CONSTANT_InvokeDynamic: return new InvokeDynamicConstant(); + case ClassConstants.CONSTANT_MethodHandle: return new MethodHandleConstant(); case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant(); case ClassConstants.CONSTANT_Methodref: return new MethodrefConstant(); case ClassConstants.CONSTANT_InterfaceMethodref: return new InterfaceMethodrefConstant(); case ClassConstants.CONSTANT_Class: return new ClassConstant(); + case ClassConstants.CONSTANT_MethodType : return new MethodTypeConstant(); case ClassConstants.CONSTANT_NameAndType: return new NameAndTypeConstant(); default: throw new RuntimeException("Unknown constant type ["+u1tag+"] in constant pool"); @@ -771,7 +826,9 @@ implements ClassVisitor, int u2attributeNameIndex = dataInput.readUnsignedShort(); int u4attributeLength = dataInput.readInt(); String attributeName = clazz.getString(u2attributeNameIndex); + Attribute attribute = + attributeName.equals(ClassConstants.ATTR_BootstrapMethods) ? (Attribute)new BootstrapMethodsAttribute(): attributeName.equals(ClassConstants.ATTR_SourceFile) ? (Attribute)new SourceFileAttribute(): attributeName.equals(ClassConstants.ATTR_SourceDir) ? (Attribute)new SourceDirAttribute(): attributeName.equals(ClassConstants.ATTR_InnerClasses) ? (Attribute)new InnerClassesAttribute(): diff --git a/src/proguard/classfile/io/ProgramClassWriter.java b/src/proguard/classfile/io/ProgramClassWriter.java index e56f08a..53995d4 100644 --- a/src/proguard/classfile/io/ProgramClassWriter.java +++ b/src/proguard/classfile/io/ProgramClassWriter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -57,7 +57,7 @@ implements ClassVisitor, /** - * Creates a new ProgramClassWriter for reading from the given DataOutput. + * Creates a new ProgramClassWriter for writing to the given DataOutput. */ public ProgramClassWriter(DataOutput dataOutput) { @@ -208,6 +208,20 @@ implements ClassVisitor, } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + dataOutput.writeShort(invokeDynamicConstant.u2bootstrapMethodAttributeIndex); + dataOutput.writeShort(invokeDynamicConstant.u2nameAndTypeIndex); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + dataOutput.writeByte(methodHandleConstant.u1referenceKind); + dataOutput.writeShort(methodHandleConstant.u2referenceIndex); + } + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { dataOutput.writeShort(refConstant.u2classIndex); @@ -221,6 +235,12 @@ implements ClassVisitor, } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + dataOutput.writeShort(methodTypeConstant.u2descriptorIndex); + } + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { dataOutput.writeShort(nameAndTypeConstant.u2nameIndex); @@ -263,6 +283,7 @@ implements ClassVisitor, private class AttributeBodyWriter extends SimplifiedVisitor implements AttributeVisitor, + BootstrapMethodInfoVisitor, InnerClassesInfoVisitor, ExceptionInfoVisitor, StackMapFrameVisitor, @@ -282,6 +303,15 @@ implements ClassVisitor, } + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + // Write the bootstrap methods. + dataOutput.writeShort(bootstrapMethodsAttribute.u2bootstrapMethodsCount); + + bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); + } + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { dataOutput.writeShort(sourceFileAttribute.u2sourceFileIndex); @@ -438,8 +468,7 @@ implements ClassVisitor, for (int index = 0; index < u2annotationsCount; index++) { - Annotation annotation = annotations[index]; - this.visitAnnotation(clazz, annotation); + visitAnnotation(clazz, annotations[index]); } } @@ -453,6 +482,22 @@ implements ClassVisitor, } + // Implementations for BootstrapMethodInfoVisitor. + + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) + { + dataOutput.writeShort(bootstrapMethodInfo.u2methodHandleIndex); + + // Write the bootstrap method arguments. + dataOutput.writeShort(bootstrapMethodInfo.u2methodArgumentCount); + + for (int index = 0; index < bootstrapMethodInfo.u2methodArgumentCount; index++) + { + dataOutput.writeShort(bootstrapMethodInfo.u2methodArguments[index]); + } + } + + // Implementations for InnerClassesInfoVisitor. public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) diff --git a/src/proguard/classfile/io/RuntimeDataInput.java b/src/proguard/classfile/io/RuntimeDataInput.java index 104b7c9..7225ec9 100644 --- a/src/proguard/classfile/io/RuntimeDataInput.java +++ b/src/proguard/classfile/io/RuntimeDataInput.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/io/RuntimeDataOutput.java b/src/proguard/classfile/io/RuntimeDataOutput.java index ffde3af..75d0642 100644 --- a/src/proguard/classfile/io/RuntimeDataOutput.java +++ b/src/proguard/classfile/io/RuntimeDataOutput.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/util/AccessUtil.java b/src/proguard/classfile/util/AccessUtil.java index 3ad6961..068a89e 100644 --- a/src/proguard/classfile/util/AccessUtil.java +++ b/src/proguard/classfile/util/AccessUtil.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/util/ClassReferenceInitializer.java b/src/proguard/classfile/util/ClassReferenceInitializer.java index b1f2c27..e7709ab 100644 --- a/src/proguard/classfile/util/ClassReferenceInitializer.java +++ b/src/proguard/classfile/util/ClassReferenceInitializer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -166,17 +166,30 @@ implements ClassVisitor, } + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + // Fill out the MethodHandle class. + methodHandleConstant.javaLangInvokeMethodHandleClass = + findClass(clazz.getName(), ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE); + } + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { String className = refConstant.getClassName(clazz); + // Methods for array types should be found in the Object class. + if (ClassUtil.isInternalArrayType(className)) + { + className = ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT; + } + // See if we can find the referenced class. // Unresolved references are assumed to refer to library classes // that will not change anyway. Clazz referencedClass = findClass(clazz.getName(), className); - if (referencedClass != null && - !ClassUtil.isInternalArrayType(className)) + if (referencedClass != null) { String name = refConstant.getName(clazz); String type = refConstant.getType(clazz); @@ -194,7 +207,7 @@ implements ClassVisitor, if (refConstant.referencedMember == null) { - // We've haven't found the class member anywhere in the hierarchy. + // We haven't found the class member anywhere in the hierarchy. missingMemberWarningPrinter.print(clazz.getName(), className, "Warning: " + @@ -216,7 +229,7 @@ implements ClassVisitor, // Fill out the referenced class. classConstant.referencedClass = - findClass(className, classConstant.getName(clazz)); + findClass(className, ClassUtil.internalClassNameFromClassType(classConstant.getName(clazz))); // Fill out the Class class. classConstant.javaLangClassClass = @@ -224,6 +237,14 @@ implements ClassVisitor, } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + // Fill out the MethodType class. + methodTypeConstant.javaLangInvokeMethodTypeClass = + findClass(clazz.getName(), ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE); + } + + // Implementations for AttributeVisitor. public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} @@ -235,49 +256,36 @@ implements ClassVisitor, String enclosingClassName = enclosingMethodAttribute.getClassName(clazz); // See if we can find the referenced class. - Clazz referencedClass = findClass(className, enclosingClassName); + enclosingMethodAttribute.referencedClass = + findClass(className, enclosingClassName); - if (referencedClass == null) + if (enclosingMethodAttribute.referencedClass != null) { - // We couldn't find the enclosing class. - missingClassWarningPrinter.print(className, - enclosingClassName, - "Warning: " + - ClassUtil.externalClassName(className) + - ": can't find enclosing class " + - ClassUtil.externalClassName(enclosingClassName)); - return; - } - - // Make sure there is actually an enclosed method. - if (enclosingMethodAttribute.u2nameAndTypeIndex == 0) - { - return; - } - - String name = enclosingMethodAttribute.getName(clazz); - String type = enclosingMethodAttribute.getType(clazz); + // Is there an enclosing method? Otherwise it's just initialization + // code outside of the constructors. + if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) + { + String name = enclosingMethodAttribute.getName(clazz); + String type = enclosingMethodAttribute.getType(clazz); - // See if we can find the method in the referenced class. - Method referencedMethod = referencedClass.findMethod(name, type); + // See if we can find the method in the referenced class. + enclosingMethodAttribute.referencedMethod = + enclosingMethodAttribute.referencedClass.findMethod(name, type); - if (referencedMethod == null) - { - // We couldn't find the enclosing method. - missingMemberWarningPrinter.print(className, - enclosingClassName, - "Warning: " + - ClassUtil.externalClassName(className) + - ": can't find enclosing method '" + - ClassUtil.externalFullMethodDescription(enclosingClassName, 0, name, type) + - "' in class " + - ClassUtil.externalClassName(enclosingClassName)); - return; + if (enclosingMethodAttribute.referencedMethod == null) + { + // We couldn't find the enclosing method. + missingMemberWarningPrinter.print(className, + enclosingClassName, + "Warning: " + + ClassUtil.externalClassName(className) + + ": can't find enclosing method '" + + ClassUtil.externalFullMethodDescription(enclosingClassName, 0, name, type) + + "' in class " + + ClassUtil.externalClassName(enclosingClassName)); + } + } } - - // Save the references. - enclosingMethodAttribute.referencedClass = referencedClass; - enclosingMethodAttribute.referencedMethod = referencedMethod; } @@ -501,11 +509,17 @@ implements ClassVisitor, */ private Clazz findClass(String referencingClassName, String name) { - // Ignore any primitive array types. - if (ClassUtil.isInternalArrayType(name) && - !ClassUtil.isInternalClassType(name)) + // Is it an array type? + if (ClassUtil.isInternalArrayType(name)) { - return null; + // Ignore any primitive array types. + if (!ClassUtil.isInternalClassType(name)) + { + return null; + } + + // Strip the array part. + name = ClassUtil.internalClassNameFromClassType(name); } // First look for the class in the program class pool. diff --git a/src/proguard/classfile/util/ClassSubHierarchyInitializer.java b/src/proguard/classfile/util/ClassSubHierarchyInitializer.java index 30fd526..304efd7 100644 --- a/src/proguard/classfile/util/ClassSubHierarchyInitializer.java +++ b/src/proguard/classfile/util/ClassSubHierarchyInitializer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java b/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java index af2a209..de95250 100644 --- a/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java +++ b/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -106,11 +106,6 @@ implements ClassVisitor, libraryClass.interfaceClasses = interfaceClasses; } - - // Discard the name Strings. From now on, we'll use the object - // references. - libraryClass.superClassName = null; - libraryClass.interfaceNames = null; } diff --git a/src/proguard/classfile/util/ClassUtil.java b/src/proguard/classfile/util/ClassUtil.java index 5f25f01..e92a022 100644 --- a/src/proguard/classfile/util/ClassUtil.java +++ b/src/proguard/classfile/util/ClassUtil.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -100,6 +100,8 @@ public class ClassUtil classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_5) ? ClassConstants.INTERNAL_CLASS_VERSION_1_5 : classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6_ALIAS) || classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6) ? ClassConstants.INTERNAL_CLASS_VERSION_1_6 : + classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_7_ALIAS) || + classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_7) ? ClassConstants.INTERNAL_CLASS_VERSION_1_7 : 0; } @@ -119,6 +121,7 @@ public class ClassUtil case ClassConstants.INTERNAL_CLASS_VERSION_1_4: return ClassConstants.EXTERNAL_CLASS_VERSION_1_4; case ClassConstants.INTERNAL_CLASS_VERSION_1_5: return ClassConstants.EXTERNAL_CLASS_VERSION_1_5; case ClassConstants.INTERNAL_CLASS_VERSION_1_6: return ClassConstants.EXTERNAL_CLASS_VERSION_1_6; + case ClassConstants.INTERNAL_CLASS_VERSION_1_7: return ClassConstants.EXTERNAL_CLASS_VERSION_1_7; default: return null; } } @@ -132,11 +135,14 @@ public class ClassUtil public static void checkVersionNumbers(int classVersion) throws UnsupportedOperationException { if (classVersion < ClassConstants.INTERNAL_CLASS_VERSION_1_0 || - classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_6) + classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_7) { - throw new UnsupportedOperationException("Unsupported version number ["+ + throw new UnsupportedOperationException("Unsupported class version number ["+ internalMajorClassVersion(classVersion)+"."+ - internalMinorClassVersion(classVersion)+"] for class format"); + internalMinorClassVersion(classVersion)+"] (maximum "+ + ClassConstants.INTERNAL_CLASS_VERSION_1_7_MAJOR+"."+ + ClassConstants.INTERNAL_CLASS_VERSION_1_7_MINOR+", Java "+ + ClassConstants.EXTERNAL_CLASS_VERSION_1_7+")"); } } @@ -189,8 +195,25 @@ public class ClassUtil /** - * Converts an internal class name into an external short class name, without - * package specification. + * Returns the external base type of an external array type, dropping any + * array brackets. + * @param externalArrayType the external array type, + * e.g. "<code>java.lang.Object[][]</code>" + * @return the external base type, + * e.g. "<code>java.lang.Object</code>". + */ + public static String externalBaseType(String externalArrayType) + { + int index = externalArrayType.indexOf(ClassConstants.EXTERNAL_TYPE_ARRAY); + return index >= 0 ? + externalArrayType.substring(0, index) : + externalArrayType; + } + + + /** + * Returns the external short class name of an external class name, dropping + * the package specification. * @param externalClassName the external class name, * e.g. "<code>java.lang.Object</code>" * @return the external short class name, @@ -410,6 +433,21 @@ public class ClassUtil /** + * Returns whether the given method name refers to a class initializer or + * an instance initializer. + * @param internalMethodName the internal method name, + * e.g. "<code><clinit></code>". + * @return whether the method name refers to an initializer, + * e.g. <code>true</code>. + */ + public static boolean isInitializer(String internalMethodName) + { + return internalMethodName.equals(ClassConstants.INTERNAL_METHOD_NAME_CLINIT) || + internalMethodName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT); + } + + + /** * Returns the internal type of the given internal method descriptor. * @param internalMethodDescriptor the internal method descriptor, * e.g. "<code>(II)Z</code>". @@ -869,6 +907,21 @@ public class ClassUtil { string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(' '); } + if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0) + { + // Only in InnerClasses attributes. + string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(' '); + } + if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0) + { + // Only in InnerClasses attributes. + string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(' '); + } + if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0) + { + // Only in InnerClasses attributes. + string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STATIC).append(' '); + } if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0) { string.append(prefix).append(ClassConstants.EXTERNAL_ACC_FINAL).append(' '); @@ -889,6 +942,10 @@ public class ClassUtil { string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ABSTRACT).append(' '); } + else if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0) + { + string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' '); + } return string.toString(); } @@ -950,6 +1007,10 @@ public class ClassUtil { string.append(prefix).append(ClassConstants.EXTERNAL_ACC_TRANSIENT).append(' '); } + if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0) + { + string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' '); + } return string.toString(); } @@ -1007,6 +1068,14 @@ public class ClassUtil { string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED).append(' '); } + if ((accessFlags & ClassConstants.INTERNAL_ACC_BRIDGE) != 0) + { + string.append(prefix).append(ClassConstants.EXTERNAL_ACC_BRIDGE).append(' '); + } + if ((accessFlags & ClassConstants.INTERNAL_ACC_VARARGS) != 0) + { + string.append(prefix).append(ClassConstants.EXTERNAL_ACC_VARARGS).append(' '); + } if ((accessFlags & ClassConstants.INTERNAL_ACC_NATIVE) != 0) { string.append(prefix).append(ClassConstants.EXTERNAL_ACC_NATIVE).append(' '); @@ -1019,6 +1088,10 @@ public class ClassUtil { string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STRICT).append(' '); } + if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0) + { + string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' '); + } return string.toString(); } diff --git a/src/proguard/classfile/util/DescriptorClassEnumeration.java b/src/proguard/classfile/util/DescriptorClassEnumeration.java index 0bee2d5..bb08f08 100644 --- a/src/proguard/classfile/util/DescriptorClassEnumeration.java +++ b/src/proguard/classfile/util/DescriptorClassEnumeration.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/util/DynamicClassReferenceInitializer.java b/src/proguard/classfile/util/DynamicClassReferenceInitializer.java index 09ffdd0..bdf2102 100644 --- a/src/proguard/classfile/util/DynamicClassReferenceInitializer.java +++ b/src/proguard/classfile/util/DynamicClassReferenceInitializer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -301,7 +301,8 @@ implements InstructionVisitor, { // Save a reference to the corresponding class. String externalClassName = stringConstant.getString(clazz); - String internalClassName = ClassUtil.internalClassName(externalClassName); + String internalClassName = ClassUtil.internalClassName( + ClassUtil.externalBaseType(externalClassName)); stringConstant.referencedClass = findClass(clazz.getName(), internalClassName); } @@ -350,7 +351,7 @@ implements InstructionVisitor, return; } - String className = methodrefConstant.getClassName(clazz); + String className = methodrefConstant.getClassName(clazz); // Note that we look for the class by name, since the referenced // class has not been initialized yet. @@ -434,11 +435,17 @@ implements InstructionVisitor, */ private Clazz findClass(String referencingClassName, String name) { - // Ignore any primitive array types. - if (ClassUtil.isInternalArrayType(name) && - !ClassUtil.isInternalClassType(name)) + // Is it an array type? + if (ClassUtil.isInternalArrayType(name)) { - return null; + // Ignore any primitive array types. + if (!ClassUtil.isInternalClassType(name)) + { + return null; + } + + // Strip the array part. + name = ClassUtil.internalClassNameFromClassType(name); } // First look for the class in the program class pool. diff --git a/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java b/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java index 1f57708..110dc43 100644 --- a/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java +++ b/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -55,14 +55,20 @@ implements InstructionVisitor, AttributeVisitor, MemberVisitor { - public static final int X = InstructionSequenceMatcher.X; - public static final int Y = InstructionSequenceMatcher.Y; - public static final int Z = InstructionSequenceMatcher.Z; + /* + private static boolean DEBUG = true; + /*/ + private static final boolean DEBUG = false; + //*/ - public static final int A = InstructionSequenceMatcher.A; - public static final int B = InstructionSequenceMatcher.B; - public static final int C = InstructionSequenceMatcher.C; - public static final int D = InstructionSequenceMatcher.D; + public static final int CLASS_INDEX = InstructionSequenceMatcher.X; + public static final int MEMBER_NAME_INDEX = InstructionSequenceMatcher.Y; + public static final int TYPE_CLASS_INDEX = InstructionSequenceMatcher.Z; + + public static final int PARAMETER0_CLASS_INDEX = InstructionSequenceMatcher.A; + public static final int PARAMETER1_CLASS_INDEX = InstructionSequenceMatcher.B; + public static final int PARAMETER2_CLASS_INDEX = InstructionSequenceMatcher.C; + public static final int PARAMETER3_CLASS_INDEX = InstructionSequenceMatcher.D; private final Constant[] GET_FIELD_CONSTANTS = new Constant[] @@ -85,6 +91,26 @@ implements InstructionVisitor, new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD), }; + private final Constant[] GET_CONSTRUCTOR_CONSTANTS = new Constant[] + { + new MethodrefConstant(1, 2, null, null), + new ClassConstant(3, null), + new NameAndTypeConstant(4, 5), + new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS), + new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_CONSTRUCTOR), + new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_CONSTRUCTOR), + }; + + private final Constant[] GET_DECLARED_CONSTRUCTOR_CONSTANTS = new Constant[] + { + new MethodrefConstant(1, 2, null, null), + new ClassConstant(3, null), + new NameAndTypeConstant(4, 5), + new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS), + new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_DECLARED_CONSTRUCTOR), + new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_DECLARED_CONSTRUCTOR), + }; + private final Constant[] GET_METHOD_CONSTANTS = new Constant[] { new MethodrefConstant(1, 2, null, null), @@ -105,19 +131,88 @@ implements InstructionVisitor, new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD), }; + private final Constant[] NEW_INTEGER_UPDATER_CONSTANTS = new Constant[] + { + new MethodrefConstant(1, 2, null, null), + new ClassConstant(3, null), + new NameAndTypeConstant(4, 5), + new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_INTEGER_FIELD_UPDATER), + new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER), + new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_INTEGER_UPDATER), + }; + + private final Constant[] NEW_LONG_UPDATER_CONSTANTS = new Constant[] + { + new MethodrefConstant(1, 2, null, null), + new ClassConstant(3, null), + new NameAndTypeConstant(4, 5), + new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_LONG_FIELD_UPDATER), + new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER), + new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_LONG_UPDATER), + }; + + private final Constant[] NEW_REFERENCE_UPDATER_CONSTANTS = new Constant[] + { + new MethodrefConstant(1, 2, null, null), + new ClassConstant(3, null), + new NameAndTypeConstant(4, 5), + new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_REFERENCE_FIELD_UPDATER), + new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER), + new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_REFERENCE_UPDATER), + }; + // SomeClass.class.get[Declared]Field("someField"). private final Instruction[] CONSTANT_GET_FIELD_INSTRUCTIONS = new Instruction[] { - new ConstantInstruction(InstructionConstants.OP_LDC, X), - new ConstantInstruction(InstructionConstants.OP_LDC, Y), + new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), }; +// // SomeClass.class.get[Declared]Constructor(new Class[] {}). +// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0 = new Instruction[] +// { +// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), +// new SimpleInstruction(InstructionConstants.OP_ICONST_0), +// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), +// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), +// }; +// +// // SomeClass.class.get[Declared]Constructor(new Class[] { A.class }). +// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1 = new Instruction[] +// { +// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), +// new SimpleInstruction(InstructionConstants.OP_ICONST_1), +// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), +// new SimpleInstruction(InstructionConstants.OP_DUP), +// new SimpleInstruction(InstructionConstants.OP_ICONST_0), +// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX), +// new SimpleInstruction(InstructionConstants.OP_AASTORE), +// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), +// }; +// +// // SomeClass.class.get[Declared]Constructor(new Class[] { A.class, B.class }). +// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2 = new Instruction[] +// { +// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), +// new SimpleInstruction(InstructionConstants.OP_ICONST_2), +// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), +// new SimpleInstruction(InstructionConstants.OP_DUP), +// new SimpleInstruction(InstructionConstants.OP_ICONST_0), +// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX), +// new SimpleInstruction(InstructionConstants.OP_AASTORE), +// new SimpleInstruction(InstructionConstants.OP_DUP), +// new SimpleInstruction(InstructionConstants.OP_ICONST_1), +// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX), +// new SimpleInstruction(InstructionConstants.OP_AASTORE), +// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), +// }; + // SomeClass.class.get[Declared]Method("someMethod", new Class[] {}). private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS0 = new Instruction[] { - new ConstantInstruction(InstructionConstants.OP_LDC, X), - new ConstantInstruction(InstructionConstants.OP_LDC, Y), + new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), new SimpleInstruction(InstructionConstants.OP_ICONST_0), new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), @@ -126,13 +221,13 @@ implements InstructionVisitor, // SomeClass.class.get[Declared]Method("someMethod", new Class[] { A.class }). private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS1 = new Instruction[] { - new ConstantInstruction(InstructionConstants.OP_LDC, X), - new ConstantInstruction(InstructionConstants.OP_LDC, Y), + new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), new SimpleInstruction(InstructionConstants.OP_ICONST_1), new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), new SimpleInstruction(InstructionConstants.OP_DUP), new SimpleInstruction(InstructionConstants.OP_ICONST_0), - new ConstantInstruction(InstructionConstants.OP_LDC, A), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX), new SimpleInstruction(InstructionConstants.OP_AASTORE), new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), }; @@ -140,32 +235,86 @@ implements InstructionVisitor, // SomeClass.class.get[Declared]Method("someMethod", new Class[] { A.class, B.class }). private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS2 = new Instruction[] { - new ConstantInstruction(InstructionConstants.OP_LDC, X), - new ConstantInstruction(InstructionConstants.OP_LDC, Y), + new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), new SimpleInstruction(InstructionConstants.OP_ICONST_2), new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), new SimpleInstruction(InstructionConstants.OP_DUP), new SimpleInstruction(InstructionConstants.OP_ICONST_0), - new ConstantInstruction(InstructionConstants.OP_LDC, A), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX), new SimpleInstruction(InstructionConstants.OP_AASTORE), new SimpleInstruction(InstructionConstants.OP_DUP), new SimpleInstruction(InstructionConstants.OP_ICONST_1), - new ConstantInstruction(InstructionConstants.OP_LDC, B), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX), new SimpleInstruction(InstructionConstants.OP_AASTORE), new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), }; + // AtomicIntegerFieldUpdater.newUpdater(A.class, "someField"). + // AtomicLongFieldUpdater.newUpdater(A.class, "someField"). + private final Instruction[] CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS = new Instruction[] + { + new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), + new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0), + }; + + // AtomicReferenceFieldUpdater.newUpdater(A.class, B.class, "someField"). + private final Instruction[] CONSTANT_NEW_REFERENCE_UPDATER_INSTRUCTIONS = new Instruction[] + { + new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX), + new ConstantInstruction(InstructionConstants.OP_LDC, TYPE_CLASS_INDEX), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), + new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0), + }; + // get[Declared]Field("someField"). private final Instruction[] GET_FIELD_INSTRUCTIONS = new Instruction[] { - new ConstantInstruction(InstructionConstants.OP_LDC, Y), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), + new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), + }; + +// // get[Declared]Constructor(new Class[] {}). +// private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS0 = new Instruction[] +// { +// new SimpleInstruction(InstructionConstants.OP_ICONST_0), +// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), +// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), +// }; + + // get[Declared]Constructor(new Class[] { A.class }). + private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS1 = new Instruction[] + { + new SimpleInstruction(InstructionConstants.OP_ICONST_1), + new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), + new SimpleInstruction(InstructionConstants.OP_DUP), + new SimpleInstruction(InstructionConstants.OP_ICONST_0), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX), + new SimpleInstruction(InstructionConstants.OP_AASTORE), + new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), + }; + + // get[Declared]Constructor(new Class[] { A.class, B.class }). + private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS2 = new Instruction[] + { + new SimpleInstruction(InstructionConstants.OP_ICONST_2), + new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), + new SimpleInstruction(InstructionConstants.OP_DUP), + new SimpleInstruction(InstructionConstants.OP_ICONST_0), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX), + new SimpleInstruction(InstructionConstants.OP_AASTORE), + new SimpleInstruction(InstructionConstants.OP_DUP), + new SimpleInstruction(InstructionConstants.OP_ICONST_1), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX), + new SimpleInstruction(InstructionConstants.OP_AASTORE), new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), }; // get[Declared]Method("someMethod", new Class[] {}). private final Instruction[] GET_METHOD_INSTRUCTIONS0 = new Instruction[] { - new ConstantInstruction(InstructionConstants.OP_LDC, Y), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), new SimpleInstruction(InstructionConstants.OP_ICONST_0), new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), @@ -174,12 +323,12 @@ implements InstructionVisitor, // get[Declared]Method("someMethod", new Class[] { A.class }). private final Instruction[] GET_METHOD_INSTRUCTIONS1 = new Instruction[] { - new ConstantInstruction(InstructionConstants.OP_LDC, Y), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), new SimpleInstruction(InstructionConstants.OP_ICONST_1), new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), new SimpleInstruction(InstructionConstants.OP_DUP), new SimpleInstruction(InstructionConstants.OP_ICONST_0), - new ConstantInstruction(InstructionConstants.OP_LDC, A), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX), new SimpleInstruction(InstructionConstants.OP_AASTORE), new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), }; @@ -187,20 +336,29 @@ implements InstructionVisitor, // get[Declared]Method("someMethod", new Class[] { A.class, B.class }). private final Instruction[] GET_METHOD_INSTRUCTIONS2 = new Instruction[] { - new ConstantInstruction(InstructionConstants.OP_LDC, Y), + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), new SimpleInstruction(InstructionConstants.OP_ICONST_2), new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1), new SimpleInstruction(InstructionConstants.OP_DUP), new SimpleInstruction(InstructionConstants.OP_ICONST_0), - new ConstantInstruction(InstructionConstants.OP_LDC, A), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX), new SimpleInstruction(InstructionConstants.OP_AASTORE), new SimpleInstruction(InstructionConstants.OP_DUP), new SimpleInstruction(InstructionConstants.OP_ICONST_1), - new ConstantInstruction(InstructionConstants.OP_LDC, B), + new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX), new SimpleInstruction(InstructionConstants.OP_AASTORE), new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0), }; + // AtomicIntegerFieldUpdater.newUpdater(..., "someField"). + // AtomicLongFieldUpdater.newUpdater(..., "someField"). + // AtomicReferenceFieldUpdater.newUpdater(..., "someField"). + private final Instruction[] NEW_UPDATER_INSTRUCTIONS = new Instruction[] + { + new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX), + new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0), + }; + private final ClassPool programClassPool; private final ClassPool libraryClassPool; @@ -217,6 +375,30 @@ implements InstructionVisitor, new InstructionSequenceMatcher(GET_DECLARED_FIELD_CONSTANTS, CONSTANT_GET_FIELD_INSTRUCTIONS); +// private final InstructionSequenceMatcher constantGetConstructorMatcher0 = +// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS, +// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0); +// +// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher0 = +// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS, +// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0); +// +// private final InstructionSequenceMatcher constantGetConstructorMatcher1 = +// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS, +// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1); +// +// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher1 = +// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS, +// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1); +// +// private final InstructionSequenceMatcher constantGetConstructorMatcher2 = +// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS, +// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2); +// +// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher2 = +// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS, +// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2); + private final InstructionSequenceMatcher constantGetMethodMatcher0 = new InstructionSequenceMatcher(GET_METHOD_CONSTANTS, CONSTANT_GET_METHOD_INSTRUCTIONS0); @@ -241,6 +423,18 @@ implements InstructionVisitor, new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS, CONSTANT_GET_METHOD_INSTRUCTIONS2); + private final InstructionSequenceMatcher constantGetIntegerUpdaterMatcher = + new InstructionSequenceMatcher(NEW_INTEGER_UPDATER_CONSTANTS, + CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS); + + private final InstructionSequenceMatcher constantGetLongUpdaterMatcher = + new InstructionSequenceMatcher(NEW_LONG_UPDATER_CONSTANTS, + CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS); + + private final InstructionSequenceMatcher constantGetReferenceUpdaterMatcher = + new InstructionSequenceMatcher(NEW_REFERENCE_UPDATER_CONSTANTS, + CONSTANT_NEW_REFERENCE_UPDATER_INSTRUCTIONS); + private final InstructionSequenceMatcher getFieldMatcher = new InstructionSequenceMatcher(GET_FIELD_CONSTANTS, GET_FIELD_INSTRUCTIONS); @@ -249,6 +443,30 @@ implements InstructionVisitor, new InstructionSequenceMatcher(GET_DECLARED_FIELD_CONSTANTS, GET_FIELD_INSTRUCTIONS); +// private final InstructionSequenceMatcher getConstructorMatcher0 = +// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS, +// GET_CONSTRUCTOR_INSTRUCTIONS0); +// +// private final InstructionSequenceMatcher getDeclaredConstructorMatcher0 = +// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS, +// GET_CONSTRUCTOR_INSTRUCTIONS0); + + private final InstructionSequenceMatcher getConstructorMatcher1 = + new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS, + GET_CONSTRUCTOR_INSTRUCTIONS1); + + private final InstructionSequenceMatcher getDeclaredConstructorMatcher1 = + new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS, + GET_CONSTRUCTOR_INSTRUCTIONS1); + + private final InstructionSequenceMatcher getConstructorMatcher2 = + new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS, + GET_CONSTRUCTOR_INSTRUCTIONS2); + + private final InstructionSequenceMatcher getDeclaredConstructorMatcher2 = + new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS, + GET_CONSTRUCTOR_INSTRUCTIONS2); + private final InstructionSequenceMatcher getMethodMatcher0 = new InstructionSequenceMatcher(GET_METHOD_CONSTANTS, GET_METHOD_INSTRUCTIONS0); @@ -273,11 +491,24 @@ implements InstructionVisitor, new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS, GET_METHOD_INSTRUCTIONS2); + private final InstructionSequenceMatcher getIntegerUpdaterMatcher = + new InstructionSequenceMatcher(NEW_INTEGER_UPDATER_CONSTANTS, + NEW_UPDATER_INSTRUCTIONS); + + private final InstructionSequenceMatcher getLongUpdaterMatcher = + new InstructionSequenceMatcher(NEW_LONG_UPDATER_CONSTANTS, + NEW_UPDATER_INSTRUCTIONS); + + private final InstructionSequenceMatcher getReferenceUpdaterMatcher = + new InstructionSequenceMatcher(NEW_REFERENCE_UPDATER_CONSTANTS, + NEW_UPDATER_INSTRUCTIONS); + private final MemberFinder memberFinder = new MemberFinder(); // Fields acting as parameters for the visitors. private Clazz referencedClass; + private String descriptor; private boolean isDeclared; private boolean isField; @@ -307,48 +538,110 @@ implements InstructionVisitor, // Try to match the SomeClass.class.getField("someField") construct. matchGetMember(clazz, method, codeAttribute, offset, instruction, constantGetFieldMatcher, - getFieldMatcher, true, false); + getFieldMatcher, true, false, null, null); // Try to match the SomeClass.class.getDeclaredField("someField") construct. matchGetMember(clazz, method, codeAttribute, offset, instruction, constantGetDeclaredFieldMatcher, - getDeclaredFieldMatcher, true, true); + getDeclaredFieldMatcher, true, true, null, null); + +// // Try to match the SomeClass.class.getConstructor(new Class[] +// // {}) construct. +// matchGetMember(clazz, method, codeAttribute, offset, instruction, +// cnull, //onstantGetConstructorMatcher0, +// getConstructorMatcher0, false, false, +// ClassConstants.INTERNAL_METHOD_NAME_INIT, null); +// +// // Try to match the SomeClass.class.getDeclaredConstructor(new Class[] +// // {}) construct. +// matchGetMember(clazz, method, codeAttribute, offset, instruction, +// null, //constantGetDeclaredConstructorMatcher0, +// getDeclaredConstructorMatcher0, false, true, +// ClassConstants.INTERNAL_METHOD_NAME_INIT, null); + + // Try to match the SomeClass.class.getConstructor(new Class[] + // { A.class }) construct. + matchGetMember(clazz, method, codeAttribute, offset, instruction, + null, //constantGetConstructorMatcher1, + getConstructorMatcher1, false, false, + ClassConstants.INTERNAL_METHOD_NAME_INIT, null); + + // Try to match the SomeClass.class.getDeclaredConstructor(new Class[] + // { A.class }) construct. + matchGetMember(clazz, method, codeAttribute, offset, instruction, + null, //constantGetDeclaredConstructorMatcher1, + getDeclaredConstructorMatcher1, false, true, + ClassConstants.INTERNAL_METHOD_NAME_INIT, null); + + // Try to match the SomeClass.class.getConstructor(new Class[] + // { A.class, B.class }) construct. + matchGetMember(clazz, method, codeAttribute, offset, instruction, + null, //constantGetConstructorMatcher2, + getConstructorMatcher2, false, false, + ClassConstants.INTERNAL_METHOD_NAME_INIT, null); + + // Try to match the SomeClass.class.getDeclaredConstructor(new Class[] + // { A.class, B.class }) construct. + matchGetMember(clazz, method, codeAttribute, offset, instruction, + null, //constantGetDeclaredConstructorMatcher2, + getDeclaredConstructorMatcher2, false, true, + ClassConstants.INTERNAL_METHOD_NAME_INIT, null); // Try to match the SomeClass.class.getMethod("someMethod", new Class[] // {}) construct. matchGetMember(clazz, method, codeAttribute, offset, instruction, constantGetMethodMatcher0, - getMethodMatcher0, false, false); + getMethodMatcher0, false, false, null, null); // Try to match the SomeClass.class.getDeclaredMethod("someMethod", - // new Class[] {}) construct. + // new Class[] {}) construct. matchGetMember(clazz, method, codeAttribute, offset, instruction, constantGetDeclaredMethodMatcher0, - getDeclaredMethodMatcher0, false, true); + getDeclaredMethodMatcher0, false, true, null, null); // Try to match the SomeClass.class.getMethod("someMethod", new Class[] // { A.class }) construct. matchGetMember(clazz, method, codeAttribute, offset, instruction, constantGetMethodMatcher1, - getMethodMatcher1, false, false); + getMethodMatcher1, false, false, null, null); // Try to match the SomeClass.class.getDeclaredMethod("someMethod", // new Class[] { A.class }) construct. matchGetMember(clazz, method, codeAttribute, offset, instruction, constantGetDeclaredMethodMatcher1, - getDeclaredMethodMatcher1, false, true); + getDeclaredMethodMatcher1, false, true, null, null); // Try to match the SomeClass.class.getMethod("someMethod", new Class[] // { A.class, B.class }) construct. matchGetMember(clazz, method, codeAttribute, offset, instruction, constantGetMethodMatcher2, - getMethodMatcher2, false, false); + getMethodMatcher2, false, false, null, null); // Try to match the SomeClass.class.getDeclaredMethod("someMethod", - // new Class[] { A.class, B.class }) construct. + // new Class[] { A.class, B.class }) construct. matchGetMember(clazz, method, codeAttribute, offset, instruction, constantGetDeclaredMethodMatcher2, - getDeclaredMethodMatcher2, false, true); + getDeclaredMethodMatcher2, false, true, null, null); + + // Try to match the AtomicIntegerFieldUpdater.newUpdater( + // SomeClass.class, "someField") construct. + matchGetMember(clazz, method, codeAttribute, offset, instruction, + constantGetIntegerUpdaterMatcher, + getIntegerUpdaterMatcher, true, false, null, + "" + ClassConstants.INTERNAL_TYPE_INT); + + // Try to match the AtomicLongFieldUpdater.newUpdater( + // SomeClass.class, "someField") construct. + matchGetMember(clazz, method, codeAttribute, offset, instruction, + constantGetLongUpdaterMatcher, + getLongUpdaterMatcher, true, false, null, + "" + ClassConstants.INTERNAL_TYPE_LONG); + + // Try to match the AtomicReferenceFieldUpdater.newUpdater( + // SomeClass.class, SomeClass.class, "someField") construct. + matchGetMember(clazz, method, codeAttribute, offset, instruction, + constantGetReferenceUpdaterMatcher, + getReferenceUpdaterMatcher, true, false, null, null); } @@ -364,26 +657,28 @@ implements InstructionVisitor, InstructionSequenceMatcher constantSequenceMatcher, InstructionSequenceMatcher variableSequenceMatcher, boolean isField, - boolean isDeclared) + boolean isDeclared, + String defaultName, + String defaultDescriptor) { - // Try to match the next instruction in the constant sequence. - instruction.accept(clazz, method, codeAttribute, offset, - constantSequenceMatcher); - - // Did we find a match to fill out the string constant? - if (constantSequenceMatcher.isMatching()) + if (constantSequenceMatcher != null) { - this.isField = isField; - this.isDeclared = isDeclared; - - // Get the member's class. - clazz.constantPoolEntryAccept(constantSequenceMatcher.matchedConstantIndex(X), this); - - // Fill out the matched string constant. - clazz.constantPoolEntryAccept(constantSequenceMatcher.matchedConstantIndex(Y), this); + // Try to match the next instruction in the constant sequence. + instruction.accept(clazz, method, codeAttribute, offset, + constantSequenceMatcher); - // Don't look for the dynamic construct. - variableSequenceMatcher.reset(); + // Did we find a match to fill out the string constant? + if (constantSequenceMatcher.isMatching()) + { + initializeStringReference(clazz, + constantSequenceMatcher, + isField, + isDeclared, + defaultDescriptor); + + // Don't look for the dynamic construct. + variableSequenceMatcher.reset(); + } } // Try to match the next instruction in the variable sequence. @@ -397,11 +692,41 @@ implements InstructionVisitor, printDynamicInvocationNote(clazz, variableSequenceMatcher, isField, - isDeclared); + isDeclared, + defaultName, + defaultDescriptor); } } + /** + * Initializes the reference of the matched string constant to the + * referenced class member and its class. + */ + private void initializeStringReference(Clazz clazz, + InstructionSequenceMatcher constantSequenceMatcher, + boolean isField, + boolean isDeclared, + String defaultDescriptor) + { + this.isField = isField; + this.isDeclared = isDeclared; + + // Get the member's class. + int classIndex = constantSequenceMatcher.matchedConstantIndex(CLASS_INDEX); + clazz.constantPoolEntryAccept(classIndex, this); + + // Get the field's reference type, if applicable. + int typeClassIndex = constantSequenceMatcher.matchedConstantIndex(TYPE_CLASS_INDEX); + descriptor = typeClassIndex <= 0 ? defaultDescriptor : + ClassUtil.internalTypeFromClassName(clazz.getClassName(typeClassIndex)); + + // Fill out the matched string constant. + int memberNameIndex = constantSequenceMatcher.matchedConstantIndex(MEMBER_NAME_INDEX); + clazz.constantPoolEntryAccept(memberNameIndex, this); + } + + // Implementations for ConstantVisitor. /** @@ -409,6 +734,11 @@ implements InstructionVisitor, */ public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { + if (DEBUG) + { + System.out.println("DynamicMemberReferenceInitializer: ["+clazz.getName()+"] matched class ["+classConstant.getName(clazz)+"]"); + } + // Remember the referenced class. referencedClass = ClassUtil.isInternalArrayType(classConstant.getName(clazz)) ? null : @@ -425,15 +755,20 @@ implements InstructionVisitor, { String name = stringConstant.getString(clazz); + if (DEBUG) + { + System.out.println("DynamicMemberReferenceInitializer: ["+clazz.getName()+"] matched string ["+name+"]"); + } + // See if we can find the referenced class member locally, or // somewhere in the hierarchy. Member referencedMember = isDeclared ? isField ? - (Member)referencedClass.findField(name, null) : - (Member)referencedClass.findMethod(name, null) : + (Member)referencedClass.findField(name, descriptor) : + (Member)referencedClass.findMethod(name, descriptor) : (Member)memberFinder.findMember(clazz, referencedClass, name, - null, + descriptor, isField); if (referencedMember != null) { @@ -454,7 +789,9 @@ implements InstructionVisitor, private void printDynamicInvocationNote(Clazz clazz, InstructionSequenceMatcher noteSequenceMatcher, boolean isField, - boolean isDeclared) + boolean isDeclared, + String defaultName, + String defaultDescriptor) { // Print out a note about the dynamic invocation. if (notePrinter != null && @@ -465,8 +802,9 @@ implements InstructionVisitor, noteFieldExceptionMatcher : noteMethodExceptionMatcher; - int memberNameIndex = noteSequenceMatcher.matchedConstantIndex(Y); - String memberName = clazz.getStringString(memberNameIndex); + int memberNameIndex = noteSequenceMatcher.matchedConstantIndex(MEMBER_NAME_INDEX); + String memberName = memberNameIndex <= 0 ? defaultName : + clazz.getStringString(memberNameIndex); if (noteExceptionMatcher == null || !noteExceptionMatcher.matches(memberName)) @@ -479,7 +817,8 @@ implements InstructionVisitor, externalMemberDescription += '('; for (int count = 0; count < 2; count++) { - int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(A + count); + int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex( + PARAMETER0_CLASS_INDEX + count); if (memberArgumentIndex > 0) { if (count > 0) @@ -501,7 +840,9 @@ implements InstructionVisitor, ClassUtil.externalClassName(clazz.getName()) + " accesses a " + (isDeclared ? "declared " : "") + - (isField ? "field" : "method") + + (isField ? "field" : + memberName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ? + "constructor" : "method") + " '" + externalMemberDescription + "' dynamically"); @@ -511,9 +852,12 @@ implements InstructionVisitor, if (isField) { - classVisitor = + classVisitor = defaultDescriptor == null ? + new AllFieldVisitor( + new MemberNameFilter(memberName, this)) : new AllFieldVisitor( - new MemberNameFilter(memberName, this)); + new MemberNameFilter(memberName, + new MemberDescriptorFilter(defaultDescriptor, this))); } else { @@ -521,20 +865,16 @@ implements InstructionVisitor, String methodDescriptor = "("; for (int count = 0; count < 2; count++) { - int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(A + count); + int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(PARAMETER0_CLASS_INDEX + count); if (memberArgumentIndex > 0) { - if (count > 0) - { - methodDescriptor += ','; - } String className = clazz.getClassName(memberArgumentIndex); methodDescriptor += ClassUtil.isInternalArrayType(className) ? className : ClassUtil.internalTypeFromClassName(className); } } - methodDescriptor += ")L///;"; + methodDescriptor += ")L***;"; classVisitor = new AllMethodVisitor( @@ -571,7 +911,7 @@ implements InstructionVisitor, System.out.println(" Maybe this is program method '" + ClassUtil.externalFullClassDescription(0, programClass.getName()) + " { " + - ClassUtil.externalFullMethodDescription(null, 0, programMethod.getName(programClass), programMethod.getDescriptor(programClass)) + + ClassUtil.externalFullMethodDescription(programClass.getName(), 0, programMethod.getName(programClass), programMethod.getDescriptor(programClass)) + "; }'"); } } @@ -597,7 +937,7 @@ implements InstructionVisitor, System.out.println(" Maybe this is library method '" + ClassUtil.externalFullClassDescription(0, libraryClass.getName()) + " { " + - ClassUtil.externalFullMethodDescription(null, 0, libraryMethod.getName(libraryClass), libraryMethod.getDescriptor(libraryClass)) + + ClassUtil.externalFullMethodDescription(libraryClass.getName(), 0, libraryMethod.getName(libraryClass), libraryMethod.getDescriptor(libraryClass)) + "; }'"); } } diff --git a/src/proguard/classfile/util/ExternalTypeEnumeration.java b/src/proguard/classfile/util/ExternalTypeEnumeration.java index 6371888..7edfbc9 100644 --- a/src/proguard/classfile/util/ExternalTypeEnumeration.java +++ b/src/proguard/classfile/util/ExternalTypeEnumeration.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/util/InstructionSequenceMatcher.java b/src/proguard/classfile/util/InstructionSequenceMatcher.java index 8a689d5..51eb7bc 100644 --- a/src/proguard/classfile/util/InstructionSequenceMatcher.java +++ b/src/proguard/classfile/util/InstructionSequenceMatcher.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -27,6 +27,8 @@ import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; +import java.util.Arrays; + /** * This InstructionVisitor checks whether a given pattern instruction sequence * occurs in the instructions that are visited. The arguments of the @@ -40,8 +42,8 @@ implements InstructionVisitor, ConstantVisitor { /* - private static boolean DEBUG = false; - public static boolean DEBUG_MORE = false; + public static boolean DEBUG = true; + public static boolean DEBUG_MORE = true; /*/ private static final boolean DEBUG = false; private static final boolean DEBUG_MORE = false; @@ -60,14 +62,15 @@ implements InstructionVisitor, private final Constant[] patternConstants; private final Instruction[] patternInstructions; - private boolean matching; - private boolean matchingAnyWildCards; - private int patternInstructionIndex; - private final int[] matchedInstructionOffsets; - private int matchedArgumentFlags; - private final int[] matchedArguments = new int[7]; - private long matchedConstantFlags; - private final int[] matchedConstantIndices; + private boolean matching; + private int patternInstructionIndex; + private final int[] matchedInstructionOffsets; + private int matchedArgumentFlags; + private final int[] matchedArguments = new int[7]; + private final long[] matchedConstantFlags; + private final int[] matchedConstantIndices; + private int constantFlags; + private int previousConstantFlags; // Fields acting as a parameter and a return value for visitor methods. private Constant patternConstant; @@ -87,6 +90,7 @@ implements InstructionVisitor, this.patternInstructions = patternInstructions; matchedInstructionOffsets = new int[patternInstructions.length]; + matchedConstantFlags = new long[(patternConstants.length + 63) / 64]; matchedConstantIndices = new int[patternConstants.length]; } @@ -98,34 +102,55 @@ implements InstructionVisitor, { patternInstructionIndex = 0; matchedArgumentFlags = 0; - matchedConstantFlags = 0L; - } + Arrays.fill(matchedConstantFlags, 0L); - public boolean isMatching() - { - return matching; + previousConstantFlags = constantFlags; + constantFlags = 0; } - public boolean isMatchingAnyWildcards() + /** + * Returns whether the complete pattern sequence has been matched. + */ + public boolean isMatching() { - return matchingAnyWildCards; + return matching; } + /** + * Returns the number of instructions in the pattern sequence. + */ public int instructionCount() { return patternInstructions.length; } + /** + * Returns the matched instruction offset of the specified pattern + * instruction. + */ public int matchedInstructionOffset(int index) { return matchedInstructionOffsets[index]; } + /** + * Returns whether the specified wildcard argument was a constant from + * the constant pool in the most recent match. + */ + public boolean wasConstant(int argument) + { + return (previousConstantFlags & (1 << (argument - X))) != 0; + } + + + /** + * Returns the value of the specified matched argument (wildcard or not). + */ public int matchedArgument(int argument) { int argumentIndex = argument - X; @@ -135,6 +160,9 @@ implements InstructionVisitor, } + /** + * Returns the values of the specified matched arguments (wildcard or not). + */ public int[] matchedArguments(int[] arguments) { int[] matchedArguments = new int[arguments.length]; @@ -148,6 +176,9 @@ implements InstructionVisitor, } + /** + * Returns the index of the specified matched constant (wildcard or not). + */ public int matchedConstantIndex(int constantIndex) { int argumentIndex = constantIndex - X; @@ -157,6 +188,10 @@ implements InstructionVisitor, } + /** + * Returns the value of the specified matched branch offset (wildcard or + * not). + */ public int matchedBranchOffset(int offset, int branchOffset) { int argumentIndex = branchOffset - X; @@ -166,6 +201,10 @@ implements InstructionVisitor, } + /** + * Returns the values of the specified matched jump offsets (wildcard or + * not). + */ public int[] matchedJumpOffsets(int offset, int[] jumpOffsets) { int[] matchedJumpOffsets = new int[jumpOffsets.length]; @@ -387,6 +426,35 @@ implements InstructionVisitor, } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + InvokeDynamicConstant invokeDynamicPatternConstant = (InvokeDynamicConstant)patternConstant; + + // Check the bootstrap method and the name and type. + matchingConstant = + matchingConstantIndices(clazz, + invokeDynamicConstant.getBootstrapMethodAttributeIndex(), + invokeDynamicPatternConstant.getBootstrapMethodAttributeIndex()) && + matchingConstantIndices(clazz, + invokeDynamicConstant.getNameAndTypeIndex(), + invokeDynamicPatternConstant.getNameAndTypeIndex()); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + MethodHandleConstant methodHandlePatternConstant = (MethodHandleConstant)patternConstant; + + // Check the handle type and the name and type. + matchingConstant = + matchingArguments(methodHandleConstant.getReferenceKind(), + methodHandlePatternConstant.getReferenceKind()) && + matchingConstantIndices(clazz, + methodHandleConstant.getReferenceIndex(), + methodHandlePatternConstant.getReferenceIndex()); + } + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { RefConstant refPatternConstant = (RefConstant)patternConstant; @@ -414,6 +482,18 @@ implements InstructionVisitor, } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + MethodTypeConstant typePatternConstant = (MethodTypeConstant)patternConstant; + + // Check the descriptor. + matchingConstant = + matchingConstantIndices(clazz, + methodTypeConstant.u2descriptorIndex, + typePatternConstant.u2descriptorIndex); + } + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { NameAndTypeConstant typePatternConstant = (NameAndTypeConstant)patternConstant; @@ -449,11 +529,10 @@ implements InstructionVisitor, // Check the literal argument. return argument1 == argument2; } - else if ((matchedArgumentFlags & (1 << argumentIndex)) == 0) + else if (!isMatchingArgumentIndex(argumentIndex)) { - // Store a wildcard argument. - matchedArguments[argumentIndex] = argument1; - matchedArgumentFlags |= 1 << argumentIndex; + // Store the wildcard argument. + setMatchingArgument(argumentIndex, argument1); return true; } @@ -465,6 +544,28 @@ implements InstructionVisitor, } + /** + * Marks the specified argument (by index) as matching the specified + * argument value. + */ + private void setMatchingArgument(int argumentIndex, + int argument) + { + matchedArguments[argumentIndex] = argument; + matchedArgumentFlags |= 1 << argumentIndex; + } + + + /** + * Returns whether the specified wildcard argument (by index) has been + * matched. + */ + private boolean isMatchingArgumentIndex(int argumentIndex) + { + return (matchedArgumentFlags & (1 << argumentIndex)) != 0; + } + + private boolean matchingArguments(int[] arguments1, int[] arguments2) { @@ -491,10 +592,13 @@ implements InstructionVisitor, { if (constantIndex2 >= X) { + // Remember that we are trying to match a constant. + constantFlags |= 1 << (constantIndex2 - X); + // Check the constant index. return matchingArguments(constantIndex1, constantIndex2); } - else if ((matchedConstantFlags & (1L << constantIndex2)) == 0) + else if (!isMatchingConstantIndex(constantIndex2)) { // Check the actual constant. matchingConstant = false; @@ -507,8 +611,7 @@ implements InstructionVisitor, if (matchingConstant) { // Store the constant index. - matchedConstantIndices[constantIndex2] = constantIndex1; - matchedConstantFlags |= 1L << constantIndex2; + setMatchingConstant(constantIndex2, constantIndex1); } } @@ -522,6 +625,27 @@ implements InstructionVisitor, } + /** + * Marks the specified constant (by index) as matching the specified + * constant index value. + */ + private void setMatchingConstant(int constantIndex, + int constantIndex1) + { + matchedConstantIndices[constantIndex] = constantIndex1; + matchedConstantFlags[constantIndex / 64] |= 1L << constantIndex; + } + + + /** + * Returns whether the specified wildcard constant has been matched. + */ + private boolean isMatchingConstantIndex(int constantIndex) + { + return (matchedConstantFlags[constantIndex / 64] & (1L << constantIndex)) != 0; + } + + private boolean matchingBranchOffsets(int offset, int branchOffset1, int branchOffset2) @@ -532,11 +656,10 @@ implements InstructionVisitor, // Check the literal argument. return branchOffset1 == branchOffset2; } - else if ((matchedArgumentFlags & (1 << argumentIndex)) == 0) + else if (!isMatchingArgumentIndex(argumentIndex)) { // Store a wildcard argument. - matchedArguments[argumentIndex] = offset + branchOffset1; - matchedArgumentFlags |= 1 << argumentIndex; + setMatchingArgument(argumentIndex, offset + branchOffset1); return true; } @@ -595,9 +718,6 @@ implements InstructionVisitor, // Did we match all instructions in the sequence? matching = patternInstructionIndex == patternInstructions.length; - // Did we match any wildcards along the way? - matchingAnyWildCards = matchedArgumentFlags != 0; - if (matching) { if (DEBUG) diff --git a/src/proguard/classfile/util/InternalTypeEnumeration.java b/src/proguard/classfile/util/InternalTypeEnumeration.java index 76f7e84..8658be3 100644 --- a/src/proguard/classfile/util/InternalTypeEnumeration.java +++ b/src/proguard/classfile/util/InternalTypeEnumeration.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/util/MemberFinder.java b/src/proguard/classfile/util/MemberFinder.java index 0fdeec0..6108b6d 100644 --- a/src/proguard/classfile/util/MemberFinder.java +++ b/src/proguard/classfile/util/MemberFinder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/util/MethodLinker.java b/src/proguard/classfile/util/MethodLinker.java index 5f2ea6f..8aed77a 100644 --- a/src/proguard/classfile/util/MethodLinker.java +++ b/src/proguard/classfile/util/MethodLinker.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -26,16 +26,11 @@ import proguard.classfile.visitor.*; import java.util.*; /** - * This ClassVisitor links all corresponding non-private methods in the class - * hierarchies of all visited classes. Visited classes are typically all class - * files that are not being subclassed. Chains of links that have been created - * in previous invocations are merged with new chains of links, in order to - * create a consistent set of chains. - * <p> - * As a MemberVisitor, it links all corresponding class members that it visits, - * including fields and private class members. - * <p> - * Class initialization methods and constructors are always ignored. + * This ClassVisitor links all corresponding non-private, non-static, + * non-initializer methods in the class hierarchies of all visited classes. + * Visited classes are typically all class files that are not being subclassed. + * Chains of links that have been created in previous invocations are merged + * with new chains of links, in order to create a consistent set of chains. * * @author Eric Lafortune */ @@ -56,7 +51,7 @@ implements ClassVisitor, // Collect all non-private members in this class hierarchy. clazz.hierarchyAccept(true, true, true, false, new AllMethodVisitor( - new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, + new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE | ClassConstants.INTERNAL_ACC_STATIC, this))); // Clean up for the next class hierarchy. diff --git a/src/proguard/classfile/util/SimplifiedVisitor.java b/src/proguard/classfile/util/SimplifiedVisitor.java index 87b7fe4..55b3848 100644 --- a/src/proguard/classfile/util/SimplifiedVisitor.java +++ b/src/proguard/classfile/util/SimplifiedVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -42,7 +42,7 @@ public abstract class SimplifiedVisitor /** * Visits any type of class member of the given class. */ - public void visitAnyClass(Clazz Clazz) + public void visitAnyClass(Clazz clazz) { throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called"); } @@ -157,6 +157,18 @@ public abstract class SimplifiedVisitor } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + visitAnyConstant(clazz, invokeDynamicConstant); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + visitAnyConstant(clazz, methodHandleConstant); + } + + /** * Visits any type of RefConstant of the given class. */ @@ -199,6 +211,12 @@ public abstract class SimplifiedVisitor } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + visitAnyConstant(clazz, methodTypeConstant); + } + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { visitAnyConstant(clazz, nameAndTypeConstant); @@ -222,6 +240,12 @@ public abstract class SimplifiedVisitor } + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + visitAnyAttribute(clazz, bootstrapMethodsAttribute); + } + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { visitAnyAttribute(clazz, sourceFileAttribute); diff --git a/src/proguard/classfile/util/StringReferenceInitializer.java b/src/proguard/classfile/util/StringReferenceInitializer.java index 3884a04..aff9b9f 100644 --- a/src/proguard/classfile/util/StringReferenceInitializer.java +++ b/src/proguard/classfile/util/StringReferenceInitializer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -62,7 +62,8 @@ implements ConstantVisitor { // See if we can find the referenced class. stringConstant.referencedClass = - findClass(ClassUtil.internalClassName(stringConstant.getString(clazz))); + findClass(ClassUtil.internalClassName( + ClassUtil.externalBaseType(stringConstant.getString(clazz)))); } } diff --git a/src/proguard/classfile/util/StringSharer.java b/src/proguard/classfile/util/StringSharer.java index 56de7c5..04dc1d0 100644 --- a/src/proguard/classfile/util/StringSharer.java +++ b/src/proguard/classfile/util/StringSharer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -64,6 +64,23 @@ implements ClassVisitor, { libraryClass.superClassName = superClass.getName(); } + + // Replace the interface name strings by the shared name strings. + if (libraryClass.interfaceNames != null) + { + String[] interfaceNames = libraryClass.interfaceNames; + Clazz[] interfaceClasses = new Clazz[interfaceNames.length]; + + for (int index = 0; index < interfaceNames.length; index++) + { + // Keep a reference to the interface class. + Clazz interfaceClass = interfaceClasses[index]; + if (interfaceClass != null) + { + interfaceNames[index] = interfaceClass.getName(); + } + } + } } @@ -73,7 +90,7 @@ implements ClassVisitor, public void visitAnyConstant(Clazz clazz, Constant constant) {} - public void visitAnyStringConstant(Clazz clazz, StringConstant stringConstant) + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) { Member referencedMember = stringConstant.referencedMember; if (referencedMember != null) diff --git a/src/proguard/classfile/util/WarningPrinter.java b/src/proguard/classfile/util/WarningPrinter.java index 87d8978..de66bd6 100644 --- a/src/proguard/classfile/util/WarningPrinter.java +++ b/src/proguard/classfile/util/WarningPrinter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/AllClassVisitor.java b/src/proguard/classfile/visitor/AllClassVisitor.java index 06aca2c..ea6272d 100644 --- a/src/proguard/classfile/visitor/AllClassVisitor.java +++ b/src/proguard/classfile/visitor/AllClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/AllFieldVisitor.java b/src/proguard/classfile/visitor/AllFieldVisitor.java index 8bff7d4..40af76c 100644 --- a/src/proguard/classfile/visitor/AllFieldVisitor.java +++ b/src/proguard/classfile/visitor/AllFieldVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/AllMemberVisitor.java b/src/proguard/classfile/visitor/AllMemberVisitor.java index 448470e..2a6f34e 100644 --- a/src/proguard/classfile/visitor/AllMemberVisitor.java +++ b/src/proguard/classfile/visitor/AllMemberVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/AllMethodVisitor.java b/src/proguard/classfile/visitor/AllMethodVisitor.java index 75b919d..2526a6a 100644 --- a/src/proguard/classfile/visitor/AllMethodVisitor.java +++ b/src/proguard/classfile/visitor/AllMethodVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/BottomClassFilter.java b/src/proguard/classfile/visitor/BottomClassFilter.java index 8f5bdd1..6f442ac 100644 --- a/src/proguard/classfile/visitor/BottomClassFilter.java +++ b/src/proguard/classfile/visitor/BottomClassFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassAccessFilter.java b/src/proguard/classfile/visitor/ClassAccessFilter.java index a8815b6..cab208f 100644 --- a/src/proguard/classfile/visitor/ClassAccessFilter.java +++ b/src/proguard/classfile/visitor/ClassAccessFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassCleaner.java b/src/proguard/classfile/visitor/ClassCleaner.java index 36165ef..4dd1790 100644 --- a/src/proguard/classfile/visitor/ClassCleaner.java +++ b/src/proguard/classfile/visitor/ClassCleaner.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassCollector.java b/src/proguard/classfile/visitor/ClassCollector.java index a69fe76..07c6a15 100644 --- a/src/proguard/classfile/visitor/ClassCollector.java +++ b/src/proguard/classfile/visitor/ClassCollector.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassCounter.java b/src/proguard/classfile/visitor/ClassCounter.java index c58c090..3c2dac7 100644 --- a/src/proguard/classfile/visitor/ClassCounter.java +++ b/src/proguard/classfile/visitor/ClassCounter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassHierarchyTraveler.java b/src/proguard/classfile/visitor/ClassHierarchyTraveler.java index 2e1755e..116b0bf 100644 --- a/src/proguard/classfile/visitor/ClassHierarchyTraveler.java +++ b/src/proguard/classfile/visitor/ClassHierarchyTraveler.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassNameFilter.java b/src/proguard/classfile/visitor/ClassNameFilter.java index c016a34..64f5a61 100644 --- a/src/proguard/classfile/visitor/ClassNameFilter.java +++ b/src/proguard/classfile/visitor/ClassNameFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassPoolFiller.java b/src/proguard/classfile/visitor/ClassPoolFiller.java index e1773de..c9efaa0 100644 --- a/src/proguard/classfile/visitor/ClassPoolFiller.java +++ b/src/proguard/classfile/visitor/ClassPoolFiller.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassPoolVisitor.java b/src/proguard/classfile/visitor/ClassPoolVisitor.java index 0b659dc..da2876f 100644 --- a/src/proguard/classfile/visitor/ClassPoolVisitor.java +++ b/src/proguard/classfile/visitor/ClassPoolVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassPresenceFilter.java b/src/proguard/classfile/visitor/ClassPresenceFilter.java index 429c340..bb90e22 100644 --- a/src/proguard/classfile/visitor/ClassPresenceFilter.java +++ b/src/proguard/classfile/visitor/ClassPresenceFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassPrinter.java b/src/proguard/classfile/visitor/ClassPrinter.java index 1da7d16..8d35ab7 100644 --- a/src/proguard/classfile/visitor/ClassPrinter.java +++ b/src/proguard/classfile/visitor/ClassPrinter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -48,8 +48,9 @@ implements ClassVisitor, ConstantVisitor, MemberVisitor, AttributeVisitor, - ExceptionInfoVisitor, + BootstrapMethodInfoVisitor, InnerClassesInfoVisitor, + ExceptionInfoVisitor, StackMapFrameVisitor, VerificationTypeVisitor, LineNumberInfoVisitor, @@ -62,7 +63,8 @@ implements ClassVisitor, private static final String INDENTATION = " "; private final PrintStream ps; - private int indentation; + + private int indentation; /** @@ -222,10 +224,30 @@ implements ClassVisitor, } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + println(visitorInfo(invokeDynamicConstant) + " InvokeDynamic [bootstrap method index = " + invokeDynamicConstant.u2bootstrapMethodAttributeIndex + "]:"); + + indent(); + clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this); + outdent(); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + println(visitorInfo(methodHandleConstant) + " MethodHandle [kind = " + methodHandleConstant.u1referenceKind + "]:"); + + indent(); + clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); + outdent(); + } + + public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) { println(visitorInfo(fieldrefConstant) + " Fieldref [" + - clazz.getClassName(fieldrefConstant.u2classIndex) + "." + + clazz.getClassName(fieldrefConstant.u2classIndex) + "." + clazz.getName(fieldrefConstant.u2nameAndTypeIndex) + " " + clazz.getType(fieldrefConstant.u2nameAndTypeIndex) + "]"); } @@ -256,6 +278,13 @@ implements ClassVisitor, } + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + println(visitorInfo(methodTypeConstant) + " MethodType [" + + clazz.getString(methodTypeConstant.u2descriptorIndex) + "]"); + } + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { println(visitorInfo(nameAndTypeConstant) + " NameAndType [" + @@ -361,6 +390,17 @@ implements ClassVisitor, } + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + println(visitorInfo(bootstrapMethodsAttribute) + + " Bootstrap methods attribute (count = " + bootstrapMethodsAttribute.u2bootstrapMethodsCount + "):"); + + indent(); + bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); + outdent(); + } + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { println(visitorInfo(sourceFileAttribute) + @@ -595,6 +635,21 @@ implements ClassVisitor, } + // Implementations for BootstrapMethodInfoVisitor. + + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) + { + println(visitorInfo(bootstrapMethodInfo) + + " BootstrapMethodInfo (argument count = " + + bootstrapMethodInfo.u2methodArgumentCount+ "):"); + + indent(); + clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this); + bootstrapMethodInfo.methodArgumentsAccept(clazz, this); + outdent(); + } + + // Implementations for InnerClassesInfoVisitor. public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) @@ -603,6 +658,8 @@ implements ClassVisitor, " InnerClassesInfo:"); indent(); + println("Access flags: 0x" + Integer.toHexString(innerClassesInfo.u2innerClassAccessFlags) + " = " + + ClassUtil.externalClassAccessFlags(innerClassesInfo.u2innerClassAccessFlags)); innerClassesInfo.innerClassConstantAccept(clazz, this); innerClassesInfo.outerClassConstantAccept(clazz, this); innerClassesInfo.innerNameConstantAccept(clazz, this); @@ -816,7 +873,7 @@ implements ClassVisitor, public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) { - println("#" + localVariableInfo.u2index + ": " + + println("v" + localVariableInfo.u2index + ": " + localVariableInfo.u2startPC + " -> " + (localVariableInfo.u2startPC + localVariableInfo.u2length) + " [" + clazz.getString(localVariableInfo.u2descriptorIndex) + " " + @@ -828,7 +885,7 @@ implements ClassVisitor, public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) { - println("#" + localVariableTypeInfo.u2index + ": " + + println("v" + localVariableTypeInfo.u2index + ": " + localVariableTypeInfo.u2startPC + " -> " + (localVariableTypeInfo.u2startPC + localVariableTypeInfo.u2length) + " [" + clazz.getString(localVariableTypeInfo.u2signatureIndex) + " " + diff --git a/src/proguard/classfile/visitor/ClassVersionFilter.java b/src/proguard/classfile/visitor/ClassVersionFilter.java index 578cabf..4400ea3 100644 --- a/src/proguard/classfile/visitor/ClassVersionFilter.java +++ b/src/proguard/classfile/visitor/ClassVersionFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -39,6 +39,19 @@ public class ClassVersionFilter implements ClassVisitor /** * Creates a new ClassVersionFilter. * @param minimumClassVersion the minimum class version number. + * @param classVisitor the <code>ClassVisitor</code> to which visits + * will be delegated. + */ + public ClassVersionFilter(int minimumClassVersion, + ClassVisitor classVisitor) + { + this(minimumClassVersion, Integer.MAX_VALUE, classVisitor); + } + + + /** + * Creates a new ClassVersionFilter. + * @param minimumClassVersion the minimum class version number. * @param maximumClassVersion the maximum class version number. * @param classVisitor the <code>ClassVisitor</code> to which visits * will be delegated. diff --git a/src/proguard/classfile/visitor/ClassVersionSetter.java b/src/proguard/classfile/visitor/ClassVersionSetter.java index 34dfbc1..4090d44 100644 --- a/src/proguard/classfile/visitor/ClassVersionSetter.java +++ b/src/proguard/classfile/visitor/ClassVersionSetter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ClassVisitor.java b/src/proguard/classfile/visitor/ClassVisitor.java index fdba2df..989910c 100644 --- a/src/proguard/classfile/visitor/ClassVisitor.java +++ b/src/proguard/classfile/visitor/ClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java b/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java index ec3fe68..0c8a9bc 100644 --- a/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java +++ b/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/DotClassClassVisitor.java b/src/proguard/classfile/visitor/DotClassClassVisitor.java index 263dbd5..8289f42 100644 --- a/src/proguard/classfile/visitor/DotClassClassVisitor.java +++ b/src/proguard/classfile/visitor/DotClassClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -36,8 +36,6 @@ import proguard.classfile.util.SimplifiedVisitor; * Note that before JDK 1.5, <code>.class</code> constructs are actually * compiled differently, using <code>Class.forName</code> constructs. * - * @see ClassForNameClassVisitor - * * @author Eric Lafortune */ public class DotClassClassVisitor diff --git a/src/proguard/classfile/visitor/ExceptClassFilter.java b/src/proguard/classfile/visitor/ExceptClassFilter.java index 924485e..c9694e6 100644 --- a/src/proguard/classfile/visitor/ExceptClassFilter.java +++ b/src/proguard/classfile/visitor/ExceptClassFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ExceptClassesFilter.java b/src/proguard/classfile/visitor/ExceptClassesFilter.java index 7380c40..ae70ffe 100644 --- a/src/proguard/classfile/visitor/ExceptClassesFilter.java +++ b/src/proguard/classfile/visitor/ExceptClassesFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ExceptionCounter.java b/src/proguard/classfile/visitor/ExceptionCounter.java index c324129..e750b69 100644 --- a/src/proguard/classfile/visitor/ExceptionCounter.java +++ b/src/proguard/classfile/visitor/ExceptionCounter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java b/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java index 3911e39..27e1159 100644 --- a/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java +++ b/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java b/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java index e0fdec3..c77fb83 100644 --- a/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java +++ b/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ExceptionHandlerFilter.java b/src/proguard/classfile/visitor/ExceptionHandlerFilter.java index a90fb56..74ccbe5 100644 --- a/src/proguard/classfile/visitor/ExceptionHandlerFilter.java +++ b/src/proguard/classfile/visitor/ExceptionHandlerFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ExceptionOffsetFilter.java b/src/proguard/classfile/visitor/ExceptionOffsetFilter.java index e2a4fc9..d9fa3c7 100644 --- a/src/proguard/classfile/visitor/ExceptionOffsetFilter.java +++ b/src/proguard/classfile/visitor/ExceptionOffsetFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ExceptionRangeFilter.java b/src/proguard/classfile/visitor/ExceptionRangeFilter.java index c541b1f..b094907 100644 --- a/src/proguard/classfile/visitor/ExceptionRangeFilter.java +++ b/src/proguard/classfile/visitor/ExceptionRangeFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java b/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java index 6fe2e7d..574bbf1 100644 --- a/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java +++ b/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ImplementedClassFilter.java b/src/proguard/classfile/visitor/ImplementedClassFilter.java index 955a74e..d2b5ce0 100644 --- a/src/proguard/classfile/visitor/ImplementedClassFilter.java +++ b/src/proguard/classfile/visitor/ImplementedClassFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java b/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java index 9e9cea3..d052916 100644 --- a/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java +++ b/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/LibraryClassFilter.java b/src/proguard/classfile/visitor/LibraryClassFilter.java index 0e40f2f..1d00e1d 100644 --- a/src/proguard/classfile/visitor/LibraryClassFilter.java +++ b/src/proguard/classfile/visitor/LibraryClassFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/LibraryMemberFilter.java b/src/proguard/classfile/visitor/LibraryMemberFilter.java index 0ee80e5..d006d8d 100644 --- a/src/proguard/classfile/visitor/LibraryMemberFilter.java +++ b/src/proguard/classfile/visitor/LibraryMemberFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MemberAccessFilter.java b/src/proguard/classfile/visitor/MemberAccessFilter.java index 6fd32e3..baf5173 100644 --- a/src/proguard/classfile/visitor/MemberAccessFilter.java +++ b/src/proguard/classfile/visitor/MemberAccessFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MemberClassAccessFilter.java b/src/proguard/classfile/visitor/MemberClassAccessFilter.java index 85272ff..0c5bfdd 100644 --- a/src/proguard/classfile/visitor/MemberClassAccessFilter.java +++ b/src/proguard/classfile/visitor/MemberClassAccessFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MemberCollector.java b/src/proguard/classfile/visitor/MemberCollector.java index ec68b2d..1373409 100644 --- a/src/proguard/classfile/visitor/MemberCollector.java +++ b/src/proguard/classfile/visitor/MemberCollector.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MemberCounter.java b/src/proguard/classfile/visitor/MemberCounter.java index c2da72e..f6f1204 100644 --- a/src/proguard/classfile/visitor/MemberCounter.java +++ b/src/proguard/classfile/visitor/MemberCounter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MemberDescriptorFilter.java b/src/proguard/classfile/visitor/MemberDescriptorFilter.java index bd69304..81251e0 100644 --- a/src/proguard/classfile/visitor/MemberDescriptorFilter.java +++ b/src/proguard/classfile/visitor/MemberDescriptorFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MemberNameFilter.java b/src/proguard/classfile/visitor/MemberNameFilter.java index 0fe450e..f638f09 100644 --- a/src/proguard/classfile/visitor/MemberNameFilter.java +++ b/src/proguard/classfile/visitor/MemberNameFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MemberToClassVisitor.java b/src/proguard/classfile/visitor/MemberToClassVisitor.java index a405cfc..b5b0385 100644 --- a/src/proguard/classfile/visitor/MemberToClassVisitor.java +++ b/src/proguard/classfile/visitor/MemberToClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MemberVisitor.java b/src/proguard/classfile/visitor/MemberVisitor.java index 01fdf71..c0d48cb 100644 --- a/src/proguard/classfile/visitor/MemberVisitor.java +++ b/src/proguard/classfile/visitor/MemberVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MethodImplementationFilter.java b/src/proguard/classfile/visitor/MethodImplementationFilter.java index 57d923a..c4af8b0 100644 --- a/src/proguard/classfile/visitor/MethodImplementationFilter.java +++ b/src/proguard/classfile/visitor/MethodImplementationFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MethodImplementationTraveler.java b/src/proguard/classfile/visitor/MethodImplementationTraveler.java index dc0ea36..d696215 100644 --- a/src/proguard/classfile/visitor/MethodImplementationTraveler.java +++ b/src/proguard/classfile/visitor/MethodImplementationTraveler.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MultiClassPoolVisitor.java b/src/proguard/classfile/visitor/MultiClassPoolVisitor.java index 044d55a..a52c1d6 100644 --- a/src/proguard/classfile/visitor/MultiClassPoolVisitor.java +++ b/src/proguard/classfile/visitor/MultiClassPoolVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MultiClassVisitor.java b/src/proguard/classfile/visitor/MultiClassVisitor.java index d34d91e..d8ac3d7 100644 --- a/src/proguard/classfile/visitor/MultiClassVisitor.java +++ b/src/proguard/classfile/visitor/MultiClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/MultiMemberVisitor.java b/src/proguard/classfile/visitor/MultiMemberVisitor.java index cc4629c..609b6a9 100644 --- a/src/proguard/classfile/visitor/MultiMemberVisitor.java +++ b/src/proguard/classfile/visitor/MultiMemberVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/NamedClassVisitor.java b/src/proguard/classfile/visitor/NamedClassVisitor.java index a14d04a..a0d9fc5 100644 --- a/src/proguard/classfile/visitor/NamedClassVisitor.java +++ b/src/proguard/classfile/visitor/NamedClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/NamedFieldVisitor.java b/src/proguard/classfile/visitor/NamedFieldVisitor.java index 76b66c6..7ccf0fe 100644 --- a/src/proguard/classfile/visitor/NamedFieldVisitor.java +++ b/src/proguard/classfile/visitor/NamedFieldVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/NamedMethodVisitor.java b/src/proguard/classfile/visitor/NamedMethodVisitor.java index d4611c1..3f94680 100644 --- a/src/proguard/classfile/visitor/NamedMethodVisitor.java +++ b/src/proguard/classfile/visitor/NamedMethodVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ProgramClassFilter.java b/src/proguard/classfile/visitor/ProgramClassFilter.java index fba3b21..98e4e15 100644 --- a/src/proguard/classfile/visitor/ProgramClassFilter.java +++ b/src/proguard/classfile/visitor/ProgramClassFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ProgramMemberFilter.java b/src/proguard/classfile/visitor/ProgramMemberFilter.java index 048a1e6..dd21cea 100644 --- a/src/proguard/classfile/visitor/ProgramMemberFilter.java +++ b/src/proguard/classfile/visitor/ProgramMemberFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/ReferencedClassVisitor.java b/src/proguard/classfile/visitor/ReferencedClassVisitor.java index 986c3f9..5b4ee20 100644 --- a/src/proguard/classfile/visitor/ReferencedClassVisitor.java +++ b/src/proguard/classfile/visitor/ReferencedClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -123,6 +123,13 @@ implements ClassVisitor, } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + // Let the visitor visit the class referenced in the reference constant. + invokeDynamicConstant.referencedClassesAccept(classVisitor); + } + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { // Let the visitor visit the class referenced in the class constant. diff --git a/src/proguard/classfile/visitor/ReferencedMemberVisitor.java b/src/proguard/classfile/visitor/ReferencedMemberVisitor.java index c4d34b8..762cb06 100644 --- a/src/proguard/classfile/visitor/ReferencedMemberVisitor.java +++ b/src/proguard/classfile/visitor/ReferencedMemberVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/SimilarMemberVisitor.java b/src/proguard/classfile/visitor/SimilarMemberVisitor.java index 6dc06af..9df79cb 100644 --- a/src/proguard/classfile/visitor/SimilarMemberVisitor.java +++ b/src/proguard/classfile/visitor/SimilarMemberVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/SimpleClassPrinter.java b/src/proguard/classfile/visitor/SimpleClassPrinter.java index a661110..b025ebf 100644 --- a/src/proguard/classfile/visitor/SimpleClassPrinter.java +++ b/src/proguard/classfile/visitor/SimpleClassPrinter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/SubclassFilter.java b/src/proguard/classfile/visitor/SubclassFilter.java index 69ea1a1..cecb0b6 100644 --- a/src/proguard/classfile/visitor/SubclassFilter.java +++ b/src/proguard/classfile/visitor/SubclassFilter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/SubclassTraveler.java b/src/proguard/classfile/visitor/SubclassTraveler.java index 4170341..505510d 100644 --- a/src/proguard/classfile/visitor/SubclassTraveler.java +++ b/src/proguard/classfile/visitor/SubclassTraveler.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/VariableClassVisitor.java b/src/proguard/classfile/visitor/VariableClassVisitor.java index 2f575c4..b9a40f1 100644 --- a/src/proguard/classfile/visitor/VariableClassVisitor.java +++ b/src/proguard/classfile/visitor/VariableClassVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/visitor/VariableMemberVisitor.java b/src/proguard/classfile/visitor/VariableMemberVisitor.java index c58cff3..7b93a62 100644 --- a/src/proguard/classfile/visitor/VariableMemberVisitor.java +++ b/src/proguard/classfile/visitor/VariableMemberVisitor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free |