diff options
Diffstat (limited to 'src/proguard/classfile/editor/MemberReferenceFixer.java')
-rw-r--r-- | src/proguard/classfile/editor/MemberReferenceFixer.java | 447 |
1 files changed, 0 insertions, 447 deletions
diff --git a/src/proguard/classfile/editor/MemberReferenceFixer.java b/src/proguard/classfile/editor/MemberReferenceFixer.java deleted file mode 100644 index 3a32963..0000000 --- a/src/proguard/classfile/editor/MemberReferenceFixer.java +++ /dev/null @@ -1,447 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.classfile.editor; - -import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.annotation.*; -import proguard.classfile.attribute.annotation.visitor.*; -import proguard.classfile.attribute.visitor.AttributeVisitor; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.util.*; -import proguard.classfile.visitor.*; - -/** - * This ClassVisitor fixes constant pool field and method references to fields - * and methods whose names or descriptors have changed. - * - * @author Eric Lafortune - */ -public class MemberReferenceFixer -extends SimplifiedVisitor -implements ClassVisitor, - ConstantVisitor, - MemberVisitor, - AttributeVisitor, - AnnotationVisitor, - ElementValueVisitor -{ - private static final boolean DEBUG = false; - - - private final StackSizeUpdater stackSizeUpdater = new StackSizeUpdater(); - - // Parameter for the visitor methods. - private int constantIndex; - - // Return values for the visitor methods. - private boolean isInterfaceMethod; - private boolean stackSizesMayHaveChanged; - - - // Implementations for ClassVisitor. - - public void visitProgramClass(ProgramClass programClass) - { - stackSizesMayHaveChanged = false; - - // Fix the constant pool entries. - for (int index = 1; index < programClass.u2constantPoolCount; index++) - { - Constant constant = programClass.constantPool[index]; - if (constant != null) - { - // Fix the entry, replacing it entirely if needed. - this.constantIndex = index; - - constant.accept(programClass, this); - } - } - - // Fix the class members. - programClass.fieldsAccept(this); - programClass.methodsAccept(this); - - // Fix the attributes. - programClass.attributesAccept(this); - } - - - // Implementations for ConstantVisitor. - - public void visitAnyConstant(Clazz clazz, Constant constant) {} - - - public void visitStringConstant(Clazz clazz, StringConstant stringConstant) - { - // Does the string refer to a class member, due to a - // Class.get[Declared]{Field,Method} construct? - Member referencedMember = stringConstant.referencedMember; - if (referencedMember != null) - { - Clazz referencedClass = stringConstant.referencedClass; - - // Does it have a new name? - String newName = referencedMember.getName(referencedClass); - - if (!stringConstant.getString(clazz).equals(newName)) - { - if (DEBUG) - { - debug(clazz, stringConstant, referencedClass, referencedMember); - } - - // Update the name. - stringConstant.u2stringIndex = - new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newName); - } - } - } - - - public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) - { - // Do we know the referenced field? - Member referencedMember = fieldrefConstant.referencedMember; - if (referencedMember != null) - { - Clazz referencedClass = fieldrefConstant.referencedClass; - - // Does it have a new name or type? - String newName = referencedMember.getName(referencedClass); - String newType = referencedMember.getDescriptor(referencedClass); - - if (!fieldrefConstant.getName(clazz).equals(newName) || - !fieldrefConstant.getType(clazz).equals(newType)) - { - if (DEBUG) - { - debug(clazz, fieldrefConstant, referencedClass, referencedMember); - } - - // Update the name and type index. - fieldrefConstant.u2nameAndTypeIndex = - new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(newName, newType); - } - } - } - - - public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) - { - // Do we know the referenced interface method? - Member referencedMember = interfaceMethodrefConstant.referencedMember; - if (referencedMember != null) - { - Clazz referencedClass = interfaceMethodrefConstant.referencedClass; - - // Does it have a new name or type? - String newName = referencedMember.getName(referencedClass); - String newType = referencedMember.getDescriptor(referencedClass); - - if (!interfaceMethodrefConstant.getName(clazz).equals(newName) || - !interfaceMethodrefConstant.getType(clazz).equals(newType)) - { - if (DEBUG) - { - debug(clazz, interfaceMethodrefConstant, referencedClass, referencedMember); - } - - // Update the name and type index. - interfaceMethodrefConstant.u2nameAndTypeIndex = - new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(newName, newType); - - // Remember that the stack sizes of the methods in this class - // may have changed. - stackSizesMayHaveChanged = true; - } - - // Check if this is an interface method. - isInterfaceMethod = true; - clazz.constantPoolEntryAccept(interfaceMethodrefConstant.u2classIndex, this); - - // Has the method become a non-interface method? - if (!isInterfaceMethod) - { - if (DEBUG) - { - System.out.println("MemberReferenceFixer:"); - System.out.println(" Class file = "+clazz.getName()); - System.out.println(" Ref class = "+referencedClass.getName()); - System.out.println(" Ref method = "+interfaceMethodrefConstant.getName(clazz)+interfaceMethodrefConstant.getType(clazz)); - System.out.println(" -> ordinary method"); - } - - // Replace the interface method reference by a method reference. - ((ProgramClass)clazz).constantPool[this.constantIndex] = - new MethodrefConstant(interfaceMethodrefConstant.u2classIndex, - interfaceMethodrefConstant.u2nameAndTypeIndex, - referencedClass, - referencedMember); - } - } - } - - - public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) - { - // Do we know the referenced method? - Member referencedMember = methodrefConstant.referencedMember; - if (referencedMember != null) - { - Clazz referencedClass = methodrefConstant.referencedClass; - - // Does it have a new name or type? - String newName = referencedMember.getName(referencedClass); - String newType = referencedMember.getDescriptor(referencedClass); - - if (!methodrefConstant.getName(clazz).equals(newName) || - !methodrefConstant.getType(clazz).equals(newType)) - { - if (DEBUG) - { - debug(clazz, methodrefConstant, referencedClass, referencedMember); - } - - // Update the name and type index. - methodrefConstant.u2nameAndTypeIndex = - new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(newName, newType); - - // Remember that the stack sizes of the methods in this class - // may have changed. - stackSizesMayHaveChanged = true; - } - - // Check if this is an interface method. - isInterfaceMethod = false; - clazz.constantPoolEntryAccept(methodrefConstant.u2classIndex, this); - - // Has the method become an interface method? - if (isInterfaceMethod) - { - if (DEBUG) - { - System.out.println("MemberReferenceFixer:"); - System.out.println(" Class file = "+clazz.getName()); - System.out.println(" Ref class = "+referencedClass.getName()); - System.out.println(" Ref method = "+methodrefConstant.getName(clazz)+methodrefConstant.getType(clazz)); - System.out.println(" -> interface method"); - } - - // Replace the method reference by an interface method reference. - ((ProgramClass)clazz).constantPool[this.constantIndex] = - new InterfaceMethodrefConstant(methodrefConstant.u2classIndex, - methodrefConstant.u2nameAndTypeIndex, - referencedClass, - referencedMember); - } - } - } - - - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) - { - // Check if this class entry is an array type. - if (ClassUtil.isInternalArrayType(classConstant.getName(clazz))) - { - isInterfaceMethod = false; - } - else - { - // Check if this class entry refers to an interface class. - Clazz referencedClass = classConstant.referencedClass; - if (referencedClass != null) - { - isInterfaceMethod = (referencedClass.getAccessFlags() & ClassConstants.ACC_INTERFACE) != 0; - } - } - } - - - // Implementations for MemberVisitor. - - public void visitProgramMember(ProgramClass programClass, ProgramMember programMember) - { - // Fix the attributes. - programMember.attributesAccept(programClass, this); - } - - - // Implementations for AttributeVisitor. - - public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} - - - public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) - { - Member referencedMember = enclosingMethodAttribute.referencedMethod; - if (referencedMember != null) - { - Clazz referencedClass = enclosingMethodAttribute.referencedClass; - - // Does it have a new name or type? - 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(newName, - newType); - } - } - } - - - public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) - { - // Recompute the maximum stack size if necessary. - if (stackSizesMayHaveChanged) - { - stackSizeUpdater.visitCodeAttribute(clazz, method, codeAttribute); - } - - // Fix the nested attributes. - codeAttribute.attributesAccept(clazz, method, this); - } - - - public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) - { - // Fix the annotations. - annotationsAttribute.annotationsAccept(clazz, this); - } - - - public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) - { - // Fix the annotations. - parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); - } - - - public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) - { - // Fix the annotation. - annotationDefaultAttribute.defaultValueAccept(clazz, this); - } - - - // Implementations for AnnotationVisitor. - - public void visitAnnotation(Clazz clazz, Annotation annotation) - { - // Fix the element values. - annotation.elementValuesAccept(clazz, this); - } - - - // Implementations for ElementValueVisitor. - - public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) - { - fixElementValue(clazz, annotation, constantElementValue); - } - - - public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) - { - fixElementValue(clazz, annotation, enumConstantElementValue); - } - - - public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) - { - fixElementValue(clazz, annotation, classElementValue); - } - - - public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) - { - fixElementValue(clazz, annotation, annotationElementValue); - - // Fix the annotation. - annotationElementValue.annotationAccept(clazz, this); - } - - - public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) - { - fixElementValue(clazz, annotation, arrayElementValue); - - // Fix the element values. - arrayElementValue.elementValuesAccept(clazz, annotation, this); - } - - - // Small utility methods. - - /** - * Fixes the method reference of the element value, if any. - */ - private void fixElementValue(Clazz clazz, - Annotation annotation, - ElementValue elementValue) - { - // Do we know the referenced method? - Member referencedMember = elementValue.referencedMethod; - if (referencedMember != null) - { - // Does it have a new name or type? - String methodName = elementValue.getMethodName(clazz); - String newMethodName = referencedMember.getName(elementValue.referencedClass); - - if (!methodName.equals(newMethodName)) - { - // Update the element name index. - elementValue.u2elementNameIndex = - new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newMethodName); - } - } - } - - - private void debug(Clazz clazz, - StringConstant stringConstant, - Clazz referencedClass, - Member referencedMember) - { - System.out.println("MemberReferenceFixer:"); - System.out.println(" ["+clazz.getName()+"]: String ["+ - stringConstant.getString(clazz)+"] -> ["+ - referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]"); - } - - - private void debug(Clazz clazz, - RefConstant refConstant, - Clazz referencedClass, - Member referencedMember) - { - System.out.println("MemberReferenceFixer:"); - System.out.println(" ["+clazz.getName()+"]: ["+ - refConstant.getClassName(clazz)+"."+refConstant.getName(clazz)+" "+refConstant.getType(clazz)+"] -> ["+ - referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]"); - } -} |