diff options
Diffstat (limited to 'src/proguard/classfile/editor/MemberAdder.java')
-rw-r--r-- | src/proguard/classfile/editor/MemberAdder.java | 294 |
1 files changed, 0 insertions, 294 deletions
diff --git a/src/proguard/classfile/editor/MemberAdder.java b/src/proguard/classfile/editor/MemberAdder.java deleted file mode 100644 index 2a93016..0000000 --- a/src/proguard/classfile/editor/MemberAdder.java +++ /dev/null @@ -1,294 +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.Attribute; -import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.MemberVisitor; - -/** - * 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 - */ -public class MemberAdder -extends SimplifiedVisitor -implements MemberVisitor -{ - //* - private static final boolean DEBUG = false; - /*/ - private static boolean DEBUG = true; - //*/ - - - private static final Attribute[] EMPTY_ATTRIBUTES = new Attribute[0]; - - - private final ProgramClass targetClass; -// private final boolean addFields; - private final MemberVisitor extraMemberVisitor; - - private final ConstantAdder constantAdder; - private final ClassEditor classEditor; - private final ConstantPoolEditor constantPoolEditor; - - - /** - * 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. - */ - 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, - MemberVisitor extraMemberVisitor) - { - this.targetClass = targetClass; -// this.addFields = addFields; - this.extraMemberVisitor = extraMemberVisitor; - - constantAdder = new ConstantAdder(targetClass); - classEditor = new ClassEditor(targetClass); - constantPoolEditor = new ConstantPoolEditor(targetClass); - } - - - // Implementations for MemberVisitor. - - public void visitProgramField(ProgramClass programClass, ProgramField programField) - { - //String name = programField.getName(programClass); - //String descriptor = programField.getDescriptor(programClass); - int accessFlags = programField.getAccessFlags(); - - // TODO: Handle field with the same name and descriptor in the target class. - // We currently avoid this case, since renaming the identical field - // still causes confused field references. - //// Does the target class already have such a field? - //ProgramField targetField = (ProgramField)targetClass.findField(name, descriptor); - //if (targetField != null) - //{ - // // Is the field private or static? - // int targetAccessFlags = targetField.getAccessFlags(); - // if ((targetAccessFlags & - // (ClassConstants.ACC_PRIVATE | - // ClassConstants.ACC_STATIC)) != 0) - // { - // if (DEBUG) - // { - // System.out.println("MemberAdder: renaming field ["+targetClass+"."+targetField.getName(targetClass)+" "+targetField.getDescriptor(targetClass)+"]"); - // } - // - // // Rename the private or static field. - // targetField.u2nameIndex = - // constantPoolEditor.addUtf8Constant(newUniqueMemberName(name, targetClass.getName())); - // } - // else - // { - // // Keep the non-private and non-static field, but update its - // // contents, in order to keep any references to it valid. - // if (DEBUG) - // { - // System.out.println("MemberAdder: updating field ["+programClass+"."+programField.getName(programClass)+" "+programField.getDescriptor(programClass)+"] into ["+targetClass.getName()+"]"); - // } - // - // // Combine the access flags. - // targetField.u2accessFlags = accessFlags | targetAccessFlags; - // - // // Add and replace any attributes. - // programField.attributesAccept(programClass, - // new AttributeAdder(targetClass, - // targetField, - // true)); - // - // // Don't add a new field. - // return; - // } - //} - - if (DEBUG) - { - System.out.println("MemberAdder: copying field ["+programClass+"."+programField.getName(programClass)+" "+programField.getDescriptor(programClass)+"] into ["+targetClass.getName()+"]"); - } - - // Create a copy of the field. - ProgramField newProgramField = - new ProgramField(accessFlags, - constantAdder.addConstant(programClass, programField.u2nameIndex), - constantAdder.addConstant(programClass, programField.u2descriptorIndex), - 0, - programField.u2attributesCount > 0 ? - new Attribute[programField.u2attributesCount] : - EMPTY_ATTRIBUTES, - programField.referencedClass); - - // Link to its visitor info. - newProgramField.setVisitorInfo(programField); - - // Copy its attributes. - programField.attributesAccept(programClass, - new AttributeAdder(targetClass, - newProgramField, - false)); - - // Add the completed field. - classEditor.addField(newProgramField); - - // Visit the newly added field, if necessary. - if (extraMemberVisitor != null) - { - extraMemberVisitor.visitProgramField(targetClass, newProgramField); - } - } - - - public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) - { - String name = programMethod.getName(programClass); - String descriptor = programMethod.getDescriptor(programClass); - int accessFlags = programMethod.getAccessFlags(); - - // Does the target class already have such a method? - ProgramMethod targetMethod = (ProgramMethod)targetClass.findMethod(name, descriptor); - if (targetMethod != null) - { - // is this source method abstract? - if ((accessFlags & ClassConstants.ACC_ABSTRACT) != 0) - { - // Keep the target method. - if (DEBUG) - { - System.out.println("MemberAdder: skipping abstract method ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] into ["+targetClass.getName()+"]"); - } - - // Don't add a new method. - return; - } - - // Is the target method abstract? - int targetAccessFlags = targetMethod.getAccessFlags(); - if ((targetAccessFlags & ClassConstants.ACC_ABSTRACT) != 0) - { - // Keep the abstract method, but update its contents, in order - // to keep any references to it valid. - if (DEBUG) - { - System.out.println("MemberAdder: updating method ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] into ["+targetClass.getName()+"]"); - } - - // Replace the access flags. - targetMethod.u2accessFlags = - accessFlags & ~ClassConstants.ACC_FINAL; - - // Add and replace the attributes. - programMethod.attributesAccept(programClass, - new AttributeAdder(targetClass, - targetMethod, - true)); - - // Don't add a new method. - return; - } - - if (DEBUG) - { - System.out.println("MemberAdder: renaming method ["+targetClass.getName()+"."+targetMethod.getName(targetClass)+targetMethod.getDescriptor(targetClass)+"]"); - } - - // TODO: Handle non-abstract method with the same name and descriptor in the target class. - // We currently avoid this case, since renaming the identical method - // still causes confused method references. - //// Rename the private (non-abstract) or static method. - //targetMethod.u2nameIndex = - // constantPoolEditor.addUtf8Constant(newUniqueMemberName(name, descriptor)); - } - - if (DEBUG) - { - System.out.println("MemberAdder: copying method ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] into ["+targetClass.getName()+"]"); - } - - // Create a copy of the method. - ProgramMethod newProgramMethod = - new ProgramMethod(accessFlags & ~ClassConstants.ACC_FINAL, - constantAdder.addConstant(programClass, programMethod.u2nameIndex), - constantAdder.addConstant(programClass, programMethod.u2descriptorIndex), - 0, - programMethod.u2attributesCount > 0 ? - new Attribute[programMethod.u2attributesCount] : - EMPTY_ATTRIBUTES, - programMethod.referencedClasses != null ? - (Clazz[])programMethod.referencedClasses.clone() : - null); - - // Link to its visitor info. - newProgramMethod.setVisitorInfo(programMethod); - - // Copy its attributes. - programMethod.attributesAccept(programClass, - new AttributeAdder(targetClass, - newProgramMethod, - false)); - - // Add the completed method. - classEditor.addMethod(newProgramMethod); - - // Visit the newly added method, if necessary. - if (extraMemberVisitor != null) - { - extraMemberVisitor.visitProgramMethod(targetClass, newProgramMethod); - } - } - - - // Small utility methods. - - /** - * Returns a unique class member name, based on the given name and descriptor. - */ - private String newUniqueMemberName(String name, String descriptor) - { - return name.equals(ClassConstants.METHOD_NAME_INIT) ? - ClassConstants.METHOD_NAME_INIT : - name + ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode())); - } -} |