blob: e955e533f6584c8f1208f774aac1a38c4a63f726 [file] [log] [blame]
/*
* 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.obfuscate;
import proguard.classfile.*;
import proguard.classfile.util.*;
import proguard.util.ListUtil;
/**
* This MappingKeeper applies the mappings that it receives to its class pool,
* so these mappings are ensured in a subsequent obfuscation step.
*
* @author Eric Lafortune
*/
public class MappingKeeper implements MappingProcessor
{
private final ClassPool classPool;
private final WarningPrinter warningPrinter;
// A field acting as a parameter.
private Clazz clazz;
/**
* Creates a new MappingKeeper.
* @param classPool the class pool in which class names and class
* member names have to be mapped.
* @param warningPrinter the optional warning printer to which warnings
* can be printed.
*/
public MappingKeeper(ClassPool classPool,
WarningPrinter warningPrinter)
{
this.classPool = classPool;
this.warningPrinter = warningPrinter;
}
// Implementations for MappingProcessor.
public boolean processClassMapping(String className,
String newClassName)
{
// Find the class.
String name = ClassUtil.internalClassName(className);
clazz = classPool.getClass(name);
if (clazz != null)
{
String newName = ClassUtil.internalClassName(newClassName);
// Print out a warning if the mapping conflicts with a name that
// was set before.
if (warningPrinter != null)
{
String currentNewName = ClassObfuscator.newClassName(clazz);
if (currentNewName != null &&
!currentNewName.equals(newName))
{
warningPrinter.print(name,
currentNewName,
"Warning: " +
className +
" is not being kept as '" +
ClassUtil.externalClassName(currentNewName) +
"', but remapped to '" +
newClassName + "'");
}
}
ClassObfuscator.setNewClassName(clazz, newName);
// The class members have to be kept as well.
return true;
}
return false;
}
public void processFieldMapping(String className,
String fieldType,
String fieldName,
String newFieldName)
{
if (clazz != null)
{
// Find the field.
String name = fieldName;
String descriptor = ClassUtil.internalType(fieldType);
Field field = clazz.findField(name, descriptor);
if (field != null)
{
// Print out a warning if the mapping conflicts with a name that
// was set before.
if (warningPrinter != null)
{
String currentNewName = MemberObfuscator.newMemberName(field);
if (currentNewName != null &&
!currentNewName.equals(newFieldName))
{
warningPrinter.print(ClassUtil.internalClassName(className),
"Warning: " +
className +
": field '" + fieldType + " " + fieldName +
"' is not being kept as '" + currentNewName +
"', but remapped to '" + newFieldName + "'");
}
}
// Make sure the mapping name will be kept.
MemberObfuscator.setFixedNewMemberName(field, newFieldName);
}
}
}
public void processMethodMapping(String className,
int firstLineNumber,
int lastLineNumber,
String methodReturnType,
String methodName,
String methodArguments,
String newMethodName)
{
if (clazz != null)
{
// Find the method.
String descriptor = ClassUtil.internalMethodDescriptor(methodReturnType,
ListUtil.commaSeparatedList(methodArguments));
Method method = clazz.findMethod(methodName, descriptor);
if (method != null)
{
// Print out a warning if the mapping conflicts with a name that
// was set before.
if (warningPrinter != null)
{
String currentNewName = MemberObfuscator.newMemberName(method);
if (currentNewName != null &&
!currentNewName.equals(newMethodName))
{
warningPrinter.print(ClassUtil.internalClassName(className),
"Warning: " +
className +
": method '" + methodReturnType + " " + methodName + JavaConstants.METHOD_ARGUMENTS_OPEN + methodArguments + JavaConstants.METHOD_ARGUMENTS_CLOSE +
"' is not being kept as '" + currentNewName +
"', but remapped to '" + newMethodName + "'");
}
}
// Make sure the mapping name will be kept.
MemberObfuscator.setFixedNewMemberName(method, newMethodName);
}
}
}
}