proguard4.8/ 0000775 0001750 0001750 00000000000 11760503015 011561 5 ustar eric eric proguard4.8/src/ 0000775 0001750 0001750 00000000000 11760503005 012347 5 ustar eric eric proguard4.8/src/proguard/ 0000775 0001750 0001750 00000000000 11760503005 014172 5 ustar eric eric proguard4.8/src/proguard/package.html 0000644 0001750 0001750 00000000242 11736333522 016457 0 ustar eric eric
This package contains the main ProGuard application. ProGuard can read jar files, shrink and obfuscate them, and write out the resulting jar file. proguard4.8/src/proguard/shrink/ 0000775 0001750 0001750 00000000000 11760503005 015470 5 ustar eric eric proguard4.8/src/proguard/shrink/package.html 0000644 0001750 0001750 00000000122 11736333522 017752 0 ustar eric eric This package contains classes to perform shrinking of class files. proguard4.8/src/proguard/shrink/ShortestUsageMarker.java 0000644 0001750 0001750 00000021763 11736333522 022314 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package proguard.shrink; import proguard.classfile.*; import proguard.classfile.visitor.*; /** * This ClassVisitor and MemberVisitor recursively marks all classes * and class elements that are being used. For each element, it finds the * shortest chain of dependencies. * * @see ClassShrinker * * @author Eric Lafortune */ public class ShortestUsageMarker extends UsageMarker { private static final ShortestUsageMark INITIAL_MARK = new ShortestUsageMark("is kept by a directive in the configuration.\n\n"); // A field acting as a parameter to the visitor methods. private ShortestUsageMark currentUsageMark = INITIAL_MARK; // A utility object to check for recursive causes. private final MyRecursiveCauseChecker recursiveCauseChecker = new MyRecursiveCauseChecker(); // Overriding implementations for UsageMarker. protected void markProgramClassBody(ProgramClass programClass) { ShortestUsageMark previousUsageMark = currentUsageMark; currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programClass), "is extended by ", 10000, programClass); super.markProgramClassBody(programClass); currentUsageMark = previousUsageMark; } protected void markProgramFieldBody(ProgramClass programClass, ProgramField programField) { ShortestUsageMark previousUsageMark = currentUsageMark; currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programField), "is referenced by ", 1, programClass, programField); super.markProgramFieldBody(programClass, programField); currentUsageMark = previousUsageMark; } protected void markProgramMethodBody(ProgramClass programClass, ProgramMethod programMethod) { ShortestUsageMark previousUsageMark = currentUsageMark; currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programMethod), "is invoked by ", 1, programClass, programMethod); super.markProgramMethodBody(programClass, programMethod); currentUsageMark = previousUsageMark; } protected void markMethodHierarchy(Clazz clazz, Method method) { ShortestUsageMark previousUsageMark = currentUsageMark; currentUsageMark = new ShortestUsageMark(getShortestUsageMark(method), "implements ", 100, clazz, method); super.markMethodHierarchy(clazz, method); currentUsageMark = previousUsageMark; } // Small utility methods. protected void markAsUsed(VisitorAccepter visitorAccepter) { Object visitorInfo = visitorAccepter.getVisitorInfo(); ShortestUsageMark shortestUsageMark = visitorInfo != null && visitorInfo instanceof ShortestUsageMark && !((ShortestUsageMark)visitorInfo).isCertain() && !currentUsageMark.isShorter((ShortestUsageMark)visitorInfo) ? new ShortestUsageMark((ShortestUsageMark)visitorInfo, true): currentUsageMark; visitorAccepter.setVisitorInfo(shortestUsageMark); } protected boolean shouldBeMarkedAsUsed(VisitorAccepter visitorAccepter) { Object visitorInfo = visitorAccepter.getVisitorInfo(); return //!(visitorAccepter instanceof Clazz && // isCausedBy(currentUsageMark, (Clazz)visitorAccepter)) && (visitorInfo == null || !(visitorInfo instanceof ShortestUsageMark) || !((ShortestUsageMark)visitorInfo).isCertain() || currentUsageMark.isShorter((ShortestUsageMark)visitorInfo)); } protected boolean isUsed(VisitorAccepter visitorAccepter) { Object visitorInfo = visitorAccepter.getVisitorInfo(); return visitorInfo != null && visitorInfo instanceof ShortestUsageMark && ((ShortestUsageMark)visitorInfo).isCertain(); } protected void markAsPossiblyUsed(VisitorAccepter visitorAccepter) { visitorAccepter.setVisitorInfo(new ShortestUsageMark(currentUsageMark, false)); } protected boolean shouldBeMarkedAsPossiblyUsed(VisitorAccepter visitorAccepter) { Object visitorInfo = visitorAccepter.getVisitorInfo(); return visitorInfo == null || !(visitorInfo instanceof ShortestUsageMark) || (!((ShortestUsageMark)visitorInfo).isCertain() && currentUsageMark.isShorter((ShortestUsageMark)visitorInfo)); } protected boolean isPossiblyUsed(VisitorAccepter visitorAccepter) { Object visitorInfo = visitorAccepter.getVisitorInfo(); return visitorInfo != null && visitorInfo instanceof ShortestUsageMark && !((ShortestUsageMark)visitorInfo).isCertain(); } protected ShortestUsageMark getShortestUsageMark(VisitorAccepter visitorAccepter) { Object visitorInfo = visitorAccepter.getVisitorInfo(); return (ShortestUsageMark)visitorInfo; } // Small utility methods. private boolean isCausedBy(ShortestUsageMark shortestUsageMark, Clazz clazz) { return recursiveCauseChecker.check(shortestUsageMark, clazz); } private class MyRecursiveCauseChecker implements ClassVisitor, MemberVisitor { private Clazz checkClass; private boolean isRecursing; public boolean check(ShortestUsageMark shortestUsageMark, Clazz clazz) { checkClass = clazz; isRecursing = false; shortestUsageMark.acceptClassVisitor(this); shortestUsageMark.acceptMemberVisitor(this); return isRecursing; } // Implementations for ClassVisitor. public void visitProgramClass(ProgramClass programClass) { checkCause(programClass); } public void visitLibraryClass(LibraryClass libraryClass) { checkCause(libraryClass); } // Implementations for MemberVisitor. public void visitProgramField(ProgramClass programClass, ProgramField programField) { checkCause(programField); } public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) { checkCause(programMethod); } public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) { checkCause(libraryField); } public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) { checkCause(libraryMethod); } // Small utility methods. private void checkCause(VisitorAccepter visitorAccepter) { if (ShortestUsageMarker.this.isUsed(visitorAccepter)) { ShortestUsageMark shortestUsageMark = ShortestUsageMarker.this.getShortestUsageMark(visitorAccepter); // Check the class of this mark, if any isRecursing = shortestUsageMark.isCausedBy(checkClass); // Check the causing class or method, if still necessary. if (!isRecursing) { shortestUsageMark.acceptClassVisitor(this); shortestUsageMark.acceptMemberVisitor(this); } } } } } proguard4.8/src/proguard/shrink/ShortestUsagePrinter.java 0000644 0001750 0001750 00000016356 11736333522 022520 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package proguard.shrink; import proguard.classfile.*; import proguard.classfile.util.ClassUtil; import proguard.classfile.visitor.*; import java.io.PrintStream; /** * This ClassVisitor and MemberVisitor prints out the reasons why * classes and class members have been marked as being used. * * @see UsageMarker * * @author Eric Lafortune */ public class ShortestUsagePrinter implements ClassVisitor, MemberVisitor { private final ShortestUsageMarker shortestUsageMarker; private final boolean verbose; private final PrintStream ps; /** * Creates a new UsagePrinter that prints verbosely toSystem.out
.
* @param shortestUsageMarker the usage marker that was used to mark the
* classes and class members.
*/
public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker)
{
this(shortestUsageMarker, true);
}
/**
* Creates a new UsagePrinter that prints to the given stream.
* @param shortestUsageMarker the usage marker that was used to mark the
* classes and class members.
* @param verbose specifies whether the output should be verbose.
*/
public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker,
boolean verbose)
{
this(shortestUsageMarker, verbose, System.out);
}
/**
* Creates a new UsagePrinter that prints to the given stream.
* @param shortestUsageMarker the usage marker that was used to mark the
* classes and class members.
* @param verbose specifies whether the output should be verbose.
* @param printStream the stream to which to print.
*/
public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker,
boolean verbose,
PrintStream printStream)
{
this.shortestUsageMarker = shortestUsageMarker;
this.verbose = verbose;
this.ps = printStream;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Print the name of this class.
ps.println(ClassUtil.externalClassName(programClass.getName()));
// Print the reason for keeping this class.
printReason(programClass);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Print the name of this class.
ps.println(ClassUtil.externalClassName(libraryClass.getName()));
// Print the reason for keeping this class.
ps.println(" is a library class.\n");
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
// Print the name of this field.
String name = programField.getName(programClass);
String type = programField.getDescriptor(programClass);
ps.println(ClassUtil.externalClassName(programClass.getName()) +
(verbose ?
": " + ClassUtil.externalFullFieldDescription(0, name, type):
"." + name) +
lineNumberRange(programClass, programField));
// Print the reason for keeping this method.
printReason(programField);
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
// Print the name of this method.
String name = programMethod.getName(programClass);
String type = programMethod.getDescriptor(programClass);
ps.println(ClassUtil.externalClassName(programClass.getName()) +
(verbose ?
": " + ClassUtil.externalFullMethodDescription(programClass.getName(), 0, name, type):
"." + name) +
lineNumberRange(programClass, programMethod));
// Print the reason for keeping this method.
printReason(programMethod);
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
// Print the name of this field.
String name = libraryField.getName(libraryClass);
String type = libraryField.getDescriptor(libraryClass);
ps.println(ClassUtil.externalClassName(libraryClass.getName()) +
(verbose ?
": " + ClassUtil.externalFullFieldDescription(0, name, type):
"." + name));
// Print the reason for keeping this field.
ps.println(" is a library field.\n");
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
// Print the name of this method.
String name = libraryMethod.getName(libraryClass);
String type = libraryMethod.getDescriptor(libraryClass);
ps.println(ClassUtil.externalClassName(libraryClass.getName()) +
(verbose ?
": " + ClassUtil.externalFullMethodDescription(libraryClass.getName(), 0, name, type):
"." + name));
// Print the reason for keeping this method.
ps.println(" is a library method.\n");
}
// Small utility methods.
private void printReason(VisitorAccepter visitorAccepter)
{
if (shortestUsageMarker.isUsed(visitorAccepter))
{
ShortestUsageMark shortestUsageMark = shortestUsageMarker.getShortestUsageMark(visitorAccepter);
// Print the reason for keeping this class.
ps.print(" " + shortestUsageMark.getReason());
// Print the class or method that is responsible, with its reasons.
shortestUsageMark.acceptClassVisitor(this);
shortestUsageMark.acceptMemberVisitor(this);
}
else
{
ps.println(" is not being kept.\n");
}
}
/**
* Returns the line number range of the given class member, followed by a
* colon, or just an empty String if no range is available.
*/
private static String lineNumberRange(ProgramClass programClass, ProgramMember programMember)
{
String range = programMember.getLineNumberRange(programClass);
return range != null ?
(" (" + range + ")") :
"";
}
}
proguard4.8/src/proguard/shrink/UsedMemberFilter.java 0000644 0001750 0001750 00000005500 11736333522 021537 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package proguard.shrink;
import proguard.classfile.*;
import proguard.classfile.visitor.MemberVisitor;
/**
* This MemberVisitor delegates all its method calls to another MemberVisitor,
* but only for Member objects that are marked as used.
*
* @see UsageMarker
*
* @author Eric Lafortune
*/
public class UsedMemberFilter
implements MemberVisitor
{
private final UsageMarker usageMarker;
private final MemberVisitor memberVisitor;
/**
* Creates a new UsedMemberFilter.
* @param usageMarker the usage marker that is used to mark the classes
* and class members.
* @param memberVisitor the member visitor to which the visiting will be
* delegated.
*/
public UsedMemberFilter(UsageMarker usageMarker,
MemberVisitor memberVisitor)
{
this.usageMarker = usageMarker;
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (usageMarker.isUsed(programField))
{
memberVisitor.visitProgramField(programClass, programField);
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (usageMarker.isUsed(programMethod))
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
if (usageMarker.isUsed(libraryField))
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (usageMarker.isUsed(libraryMethod))
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
}
}
proguard4.8/src/proguard/shrink/UsedClassFilter.java 0000644 0001750 0001750 00000004345 11736333522 021403 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package proguard.shrink;
import proguard.classfile.*;
import proguard.classfile.visitor.ClassVisitor;
/**
* This ClassVisitor delegates all its method calls to another ClassVisitor,
* but only for Clazz objects that are marked as used.
*
* @see UsageMarker
*
* @author Eric Lafortune
*/
public class UsedClassFilter
implements ClassVisitor
{
private final UsageMarker usageMarker;
private final ClassVisitor classVisitor;
/**
* Creates a new UsedClassFilter.
* @param usageMarker the usage marker that is used to mark the classes
* and class members.
* @param classVisitor the class visitor to which the visiting will be
* delegated.
*/
public UsedClassFilter(UsageMarker usageMarker,
ClassVisitor classVisitor)
{
this.usageMarker = usageMarker;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (usageMarker.isUsed(programClass))
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
if (usageMarker.isUsed(libraryClass))
{
classVisitor.visitLibraryClass(libraryClass);
}
}
}
proguard4.8/src/proguard/shrink/UsageMarker.java 0000644 0001750 0001750 00000105606 11736333522 020557 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package proguard.shrink;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
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.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
/**
* This ClassVisitor and MemberVisitor recursively marks all classes and class
* elements that are being used.
*
* @see ClassShrinker
*
* @author Eric Lafortune
*/
class UsageMarker
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
ConstantVisitor,
AttributeVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
// AnnotationVisitor,
// ElementValueVisitor,
InstructionVisitor
{
// A visitor info flag to indicate the ProgramMember object is being used,
// if its Clazz can be determined as being used as well.
private static final Object POSSIBLY_USED = new Object();
// A visitor info flag to indicate the visitor accepter is being used.
private static final Object USED = new Object();
private final MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
private final MyPossiblyUsedMemberUsageMarker possiblyUsedMemberUsageMarker = new MyPossiblyUsedMemberUsageMarker();
private final MemberVisitor nonEmptyMethodUsageMarker = new AllAttributeVisitor(
new MyNonEmptyMethodUsageMarker());
private final ConstantVisitor parameterlessConstructorMarker = new ConstantTagFilter(new int[] { ClassConstants.CONSTANT_String, ClassConstants.CONSTANT_Class },
new ReferencedClassVisitor(
new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
ClassConstants.INTERNAL_METHOD_TYPE_INIT,
this)));
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (shouldBeMarkedAsUsed(programClass))
{
// Mark this class.
markAsUsed(programClass);
markProgramClassBody(programClass);
}
}
protected void markProgramClassBody(ProgramClass programClass)
{
// Mark this class's name.
markConstant(programClass, programClass.u2thisClass);
// Mark the superclass.
if (programClass.u2superClass != 0)
{
markConstant(programClass, programClass.u2superClass);
}
// Give the interfaces preliminary marks.
programClass.hierarchyAccept(false, false, true, false,
interfaceUsageMarker);
// Explicitly mark the System.out
.
* @param usageMarker the usage marker that was used to mark the
* classes and class members.
* @param printUnusedItems a flag that indicates whether only unused items
* should be printed, or alternatively, only used
* items.
*/
public UsagePrinter(UsageMarker usageMarker,
boolean printUnusedItems)
{
this(usageMarker, printUnusedItems, System.out);
}
/**
* Creates a new UsagePrinter that prints to the given stream.
* @param usageMarker the usage marker that was used to mark the
* classes and class members.
* @param printUnusedItems a flag that indicates whether only unused items
* should be printed, or alternatively, only used
* items.
* @param printStream the stream to which to print.
*/
public UsagePrinter(UsageMarker usageMarker,
boolean printUnusedItems,
PrintStream printStream)
{
this.usageMarker = usageMarker;
this.printUnusedItems = printUnusedItems;
this.ps = printStream;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (usageMarker.isUsed(programClass))
{
if (printUnusedItems)
{
className = programClass.getName();
programClass.fieldsAccept(this);
programClass.methodsAccept(this);
className = null;
}
else
{
ps.println(ClassUtil.externalClassName(programClass.getName()));
}
}
else
{
if (printUnusedItems)
{
ps.println(ClassUtil.externalClassName(programClass.getName()));
}
}
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (usageMarker.isUsed(programField) ^ printUnusedItems)
{
printClassNameHeader();
ps.println(" " +
lineNumberRange(programClass, programField) +
ClassUtil.externalFullFieldDescription(
programField.getAccessFlags(),
programField.getName(programClass),
programField.getDescriptor(programClass)));
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (usageMarker.isUsed(programMethod) ^ printUnusedItems)
{
printClassNameHeader();
ps.println(" " +
lineNumberRange(programClass, programMethod) +
ClassUtil.externalFullMethodDescription(
programClass.getName(),
programMethod.getAccessFlags(),
programMethod.getName(programClass),
programMethod.getDescriptor(programClass)));
}
}
// Small utility methods.
/**
* Prints the class name field. The field is then cleared, so it is not
* printed again.
*/
private void printClassNameHeader()
{
if (className != null)
{
ps.println(ClassUtil.externalClassName(className) + ":");
className = null;
}
}
/**
* Returns the line number range of the given class member, followed by a
* colon, or just an empty String if no range is available.
*/
private static String lineNumberRange(ProgramClass programClass, ProgramMember programMember)
{
String range = programMember.getLineNumberRange(programClass);
return range != null ?
(range + ":") :
"";
}
}
proguard4.8/src/proguard/shrink/Shrinker.java 0000644 0001750 0001750 00000015121 11736333522 020126 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package proguard.shrink;
import proguard.*;
import proguard.classfile.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.visitor.*;
import java.io.*;
/**
* This class shrinks class pools according to a given configuration.
*
* @author Eric Lafortune
*/
public class Shrinker
{
private final Configuration configuration;
/**
* Creates a new Shrinker.
*/
public Shrinker(Configuration configuration)
{
this.configuration = configuration;
}
/**
* Performs shrinking of the given program class pool.
*/
public ClassPool execute(ClassPool programClassPool,
ClassPool libraryClassPool) throws IOException
{
// Check if we have at least some keep commands.
if (configuration.keep == null)
{
throw new IOException("You have to specify '-keep' options for the shrinking step.");
}
// Clean up any old visitor info.
programClassPool.classesAccept(new ClassCleaner());
libraryClassPool.classesAccept(new ClassCleaner());
// Create a visitor for marking the seeds.
UsageMarker usageMarker = configuration.whyAreYouKeeping == null ?
new UsageMarker() :
new ShortestUsageMarker();
// Automatically mark the parameterless constructors of seed classes,
// mainly for convenience and for backward compatibility.
ClassVisitor classUsageMarker =
new MultiClassVisitor(new ClassVisitor[]
{
usageMarker,
new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
ClassConstants.INTERNAL_METHOD_TYPE_INIT,
usageMarker)
});
ClassPoolVisitor classPoolvisitor =
ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
classUsageMarker,
usageMarker,
true,
false,
false);
// Mark the seeds.
programClassPool.accept(classPoolvisitor);
libraryClassPool.accept(classPoolvisitor);
// Mark interfaces that have to be kept.
programClassPool.classesAccept(new InterfaceUsageMarker(usageMarker));
// Mark the inner class and annotation information that has to be kept.
programClassPool.classesAccept(
new UsedClassFilter(usageMarker,
new AllAttributeVisitor(true,
new MultiAttributeVisitor(new AttributeVisitor[]
{
new InnerUsageMarker(usageMarker),
new AnnotationUsageMarker(usageMarker),
}))));
// Should we explain ourselves?
if (configuration.whyAreYouKeeping != null)
{
System.out.println();
// Create a visitor for explaining classes and class members.
ShortestUsagePrinter shortestUsagePrinter =
new ShortestUsagePrinter((ShortestUsageMarker)usageMarker,
configuration.verbose);
ClassPoolVisitor whyClassPoolvisitor =
ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.whyAreYouKeeping,
shortestUsagePrinter,
shortestUsagePrinter);
// Mark the seeds.
programClassPool.accept(whyClassPoolvisitor);
libraryClassPool.accept(whyClassPoolvisitor);
}
if (configuration.printUsage != null)
{
PrintStream ps = isFile(configuration.printUsage) ?
new PrintStream(new BufferedOutputStream(new FileOutputStream(configuration.printUsage))) :
System.out;
// Print out items that will be removed.
programClassPool.classesAcceptAlphabetically(
new UsagePrinter(usageMarker, true, ps));
if (ps != System.out)
{
ps.close();
}
}
// Discard unused program classes.
int originalProgramClassPoolSize = programClassPool.size();
ClassPool newProgramClassPool = new ClassPool();
programClassPool.classesAccept(
new UsedClassFilter(usageMarker,
new MultiClassVisitor(
new ClassVisitor[] {
new ClassShrinker(usageMarker),
new ClassPoolFiller(newProgramClassPool)
})));
programClassPool.clear();
// Check if we have at least some output classes.
int newProgramClassPoolSize = newProgramClassPool.size();
if (newProgramClassPoolSize == 0)
{
throw new IOException("The output jar is empty. Did you specify the proper '-keep' options?");
}
if (configuration.verbose)
{
System.out.println("Removing unused program classes and class elements...");
System.out.println(" Original number of program classes: " + originalProgramClassPoolSize);
System.out.println(" Final number of program classes: " + newProgramClassPoolSize);
}
return newProgramClassPool;
}
/**
* Returns whether the given file is actually a file, or just a placeholder
* for the standard output.
*/
private boolean isFile(File file)
{
return file.getPath().length() > 0;
}
}
proguard4.8/src/proguard/evaluation/ 0000775 0001750 0001750 00000000000 11760503005 016341 5 ustar eric eric proguard4.8/src/proguard/evaluation/value/ 0000775 0001750 0001750 00000000000 11760503005 017455 5 ustar eric eric proguard4.8/src/proguard/evaluation/value/package.html 0000644 0001750 0001750 00000000127 11736333522 021744 0 ustar eric eric
This package contains classes that represent partial evaluation values.
proguard4.8/src/proguard/evaluation/value/IntegerValue.java 0000644 0001750 0001750 00000066641 11736333522 022735 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.ClassConstants;
/**
* This class represents a partially evaluated integer value.
*
* @author Eric Lafortune
*/
public abstract class IntegerValue extends Category1Value
{
/**
* Returns the specific integer value, if applicable.
*/
public int value()
{
return 0;
}
// Basic unary methods.
/**
* Returns the negated value of this IntegerValue.
*/
public abstract IntegerValue negate();
/**
* Converts this IntegerValue to a byte IntegerValue.
*/
public abstract IntegerValue convertToByte();
/**
* Converts this IntegerValue to a character IntegerValue.
*/
public abstract IntegerValue convertToCharacter();
/**
* Converts this IntegerValue to a short IntegerValue.
*/
public abstract IntegerValue convertToShort();
/**
* Converts this IntegerValue to a LongValue.
*/
public abstract LongValue convertToLong();
/**
* Converts this IntegerValue to a FloatValue.
*/
public abstract FloatValue convertToFloat();
/**
* Converts this IntegerValue to a DoubleValue.
*/
public abstract DoubleValue convertToDouble();
// Basic binary methods.
/**
* Returns the generalization of this IntegerValue and the given other
* IntegerValue.
*/
public abstract IntegerValue generalize(IntegerValue other);
/**
* Returns the sum of this IntegerValue and the given IntegerValue.
*/
public abstract IntegerValue add(IntegerValue other);
/**
* Returns the difference of this IntegerValue and the given IntegerValue.
*/
public abstract IntegerValue subtract(IntegerValue other);
/**
* Returns the difference of the given IntegerValue and this IntegerValue.
*/
public abstract IntegerValue subtractFrom(IntegerValue other);
/**
* Returns the product of this IntegerValue and the given IntegerValue.
*/
public abstract IntegerValue multiply(IntegerValue other)
throws ArithmeticException;
/**
* Returns the quotient of this IntegerValue and the given IntegerValue.
*/
public abstract IntegerValue divide(IntegerValue other)
throws ArithmeticException;
/**
* Returns the quotient of the given IntegerValue and this IntegerValue.
*/
public abstract IntegerValue divideOf(IntegerValue other)
throws ArithmeticException;
/**
* Returns the remainder of this IntegerValue divided by the given
* IntegerValue.
*/
public abstract IntegerValue remainder(IntegerValue other)
throws ArithmeticException;
/**
* Returns the remainder of the given IntegerValue divided by this
* IntegerValue.
*/
public abstract IntegerValue remainderOf(IntegerValue other)
throws ArithmeticException;
/**
* Returns this IntegerValue, shifted left by the given IntegerValue.
*/
public abstract IntegerValue shiftLeft(IntegerValue other);
/**
* Returns this IntegerValue, shifted right by the given IntegerValue.
*/
public abstract IntegerValue shiftRight(IntegerValue other);
/**
* Returns this unsigned IntegerValue, shifted left by the given
* IntegerValue.
*/
public abstract IntegerValue unsignedShiftRight(IntegerValue other);
/**
* Returns the given IntegerValue, shifted left by this IntegerValue.
*/
public abstract IntegerValue shiftLeftOf(IntegerValue other);
/**
* Returns the given IntegerValue, shifted right by this IntegerValue.
*/
public abstract IntegerValue shiftRightOf(IntegerValue other);
/**
* Returns the given unsigned IntegerValue, shifted left by this
* IntegerValue.
*/
public abstract IntegerValue unsignedShiftRightOf(IntegerValue other);
/**
* Returns the given LongValue, shifted left by this IntegerValue.
*/
public abstract LongValue shiftLeftOf(LongValue other);
/**
* Returns the given LongValue, shifted right by this IntegerValue.
*/
public abstract LongValue shiftRightOf(LongValue other);
/**
* Returns the given unsigned LongValue, shifted right by this IntegerValue.
*/
public abstract LongValue unsignedShiftRightOf(LongValue other);
/**
* Returns the logical and of this IntegerValue and the given
* IntegerValue.
*/
public abstract IntegerValue and(IntegerValue other);
/**
* Returns the logical or of this IntegerValue and the given
* IntegerValue.
*/
public abstract IntegerValue or(IntegerValue other);
/**
* Returns the logical xor of this IntegerValue and the given
* IntegerValue.
*/
public abstract IntegerValue xor(IntegerValue other);
/**
* Returns whether this IntegerValue and the given IntegerValue are equal:
* NEVER
, MAYBE
, or ALWAYS
.
*/
public abstract int equal(IntegerValue other);
/**
* Returns whether this IntegerValue is less than the given IntegerValue:
* NEVER
, MAYBE
, or ALWAYS
.
*/
public abstract int lessThan(IntegerValue other);
/**
* Returns whether this IntegerValue is less than or equal to the given
* IntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public abstract int lessThanOrEqual(IntegerValue other);
// Derived binary methods.
/**
* Returns whether this IntegerValue and the given IntegerValue are different:
* NEVER
, MAYBE
, or ALWAYS
.
*/
public final int notEqual(IntegerValue other)
{
return -equal(other);
}
/**
* Returns whether this IntegerValue is greater than the given IntegerValue:
* NEVER
, MAYBE
, or ALWAYS
.
*/
public final int greaterThan(IntegerValue other)
{
return -lessThanOrEqual(other);
}
/**
* Returns whether this IntegerValue is greater than or equal to the given IntegerValue:
* NEVER
, MAYBE
, or ALWAYS
.
*/
public final int greaterThanOrEqual(IntegerValue other)
{
return -lessThan(other);
}
// Similar binary methods, but this time with unknown arguments.
/**
* Returns the generalization of this IntegerValue and the given other
* UnknownIntegerValue.
*/
public IntegerValue generalize(UnknownIntegerValue other)
{
return generalize((IntegerValue)other);
}
/**
* Returns the sum of this IntegerValue and the given UnknownIntegerValue.
*/
public IntegerValue add(UnknownIntegerValue other)
{
return add((IntegerValue)other);
}
/**
* Returns the difference of this IntegerValue and the given UnknownIntegerValue.
*/
public IntegerValue subtract(UnknownIntegerValue other)
{
return subtract((IntegerValue)other);
}
/**
* Returns the difference of the given UnknownIntegerValue and this IntegerValue.
*/
public IntegerValue subtractFrom(UnknownIntegerValue other)
{
return subtractFrom((IntegerValue)other);
}
/**
* Returns the product of this IntegerValue and the given UnknownIntegerValue.
*/
public IntegerValue multiply(UnknownIntegerValue other)
{
return multiply((IntegerValue)other);
}
/**
* Returns the quotient of this IntegerValue and the given
* UnknownIntegerValue.
*/
public IntegerValue divide(UnknownIntegerValue other)
{
return divide((IntegerValue)other);
}
/**
* Returns the quotient of the given UnknownIntegerValue and this
* IntegerValue.
*/
public IntegerValue divideOf(UnknownIntegerValue other)
{
return divideOf((IntegerValue)other);
}
/**
* Returns the remainder of this IntegerValue divided by the given
* UnknownIntegerValue.
*/
public IntegerValue remainder(UnknownIntegerValue other)
{
return remainder((IntegerValue)other);
}
/**
* Returns the remainder of the given UnknownIntegerValue divided by this
* IntegerValue.
*/
public IntegerValue remainderOf(UnknownIntegerValue other)
{
return remainderOf((IntegerValue)other);
}
/**
* Returns this IntegerValue, shifted left by the given UnknownIntegerValue.
*/
public IntegerValue shiftLeft(UnknownIntegerValue other)
{
return shiftLeft((IntegerValue)other);
}
/**
* Returns this IntegerValue, shifted right by the given UnknownIntegerValue.
*/
public IntegerValue shiftRight(UnknownIntegerValue other)
{
return shiftRight((IntegerValue)other);
}
/**
* Returns this unsigned IntegerValue, shifted right by the given
* UnknownIntegerValue.
*/
public IntegerValue unsignedShiftRight(UnknownIntegerValue other)
{
return unsignedShiftRight((IntegerValue)other);
}
/**
* Returns the given UnknownIntegerValue, shifted left by this IntegerValue.
*/
public IntegerValue shiftLeftOf(UnknownIntegerValue other)
{
return shiftLeftOf((IntegerValue)other);
}
/**
* Returns the given UnknownIntegerValue, shifted right by this IntegerValue.
*/
public IntegerValue shiftRightOf(UnknownIntegerValue other)
{
return shiftRightOf((IntegerValue)other);
}
/**
* Returns the given unsigned UnknownIntegerValue, shifted right by this
* IntegerValue.
*/
public IntegerValue unsignedShiftRightOf(UnknownIntegerValue other)
{
return unsignedShiftRightOf((IntegerValue)other);
}
/**
* Returns the given UnknownLongValue, shifted left by this IntegerValue.
*/
public LongValue shiftLeftOf(UnknownLongValue other)
{
return shiftLeftOf((LongValue)other);
}
/**
* Returns the given UnknownLongValue, shifted right by this IntegerValue.
*/
public LongValue shiftRightOf(UnknownLongValue other)
{
return shiftRightOf((LongValue)other);
}
/**
* Returns the given unsigned UnknownLongValue, shifted right by this
* IntegerValue.
*/
public LongValue unsignedShiftRightOf(UnknownLongValue other)
{
return unsignedShiftRightOf((LongValue)other);
}
/**
* Returns the logical and of this IntegerValue and the given
* UnknownIntegerValue.
*/
public IntegerValue and(UnknownIntegerValue other)
{
return and((IntegerValue)other);
}
/**
* Returns the logical or of this IntegerValue and the given
* UnknownIntegerValue.
*/
public IntegerValue or(UnknownIntegerValue other)
{
return or((IntegerValue)other);
}
/**
* Returns the logical xor of this IntegerValue and the given
* UnknownIntegerValue.
*/
public IntegerValue xor(UnknownIntegerValue other)
{
return xor((IntegerValue)other);
}
/**
* Returns whether this IntegerValue and the given UnknownIntegerValue are
* equal: NEVER
, MAYBE
, or ALWAYS
.
*/
public int equal(UnknownIntegerValue other)
{
return equal((IntegerValue)other);
}
/**
* Returns whether this IntegerValue is less than the given
* UnknownIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public int lessThan(UnknownIntegerValue other)
{
return lessThan((IntegerValue)other);
}
/**
* Returns whether this IntegerValue is less than or equal to the given
* UnknownIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public int lessThanOrEqual(UnknownIntegerValue other)
{
return lessThanOrEqual((IntegerValue)other);
}
// Derived binary methods.
/**
* Returns whether this IntegerValue and the given UnknownIntegerValue are
* different: NEVER
, MAYBE
, or ALWAYS
.
*/
public final int notEqual(UnknownIntegerValue other)
{
return -equal(other);
}
/**
* Returns whether this IntegerValue is greater than the given
* UnknownIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public final int greaterThan(UnknownIntegerValue other)
{
return -lessThanOrEqual(other);
}
/**
* Returns whether this IntegerValue is greater than or equal to the given
* UnknownIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public final int greaterThanOrEqual(UnknownIntegerValue other)
{
return -lessThan(other);
}
// Similar binary methods, but this time with specific arguments.
/**
* Returns the generalization of this IntegerValue and the given other
* SpecificIntegerValue.
*/
public IntegerValue generalize(SpecificIntegerValue other)
{
return generalize((IntegerValue)other);
}
/**
* Returns the sum of this IntegerValue and the given SpecificIntegerValue.
*/
public IntegerValue add(SpecificIntegerValue other)
{
return add((IntegerValue)other);
}
/**
* Returns the difference of this IntegerValue and the given SpecificIntegerValue.
*/
public IntegerValue subtract(SpecificIntegerValue other)
{
return subtract((IntegerValue)other);
}
/**
* Returns the difference of the given SpecificIntegerValue and this IntegerValue.
*/
public IntegerValue subtractFrom(SpecificIntegerValue other)
{
return subtractFrom((IntegerValue)other);
}
/**
* Returns the product of this IntegerValue and the given SpecificIntegerValue.
*/
public IntegerValue multiply(SpecificIntegerValue other)
{
return multiply((IntegerValue)other);
}
/**
* Returns the quotient of this IntegerValue and the given
* SpecificIntegerValue.
*/
public IntegerValue divide(SpecificIntegerValue other)
{
return divide((IntegerValue)other);
}
/**
* Returns the quotient of the given SpecificIntegerValue and this
* IntegerValue.
*/
public IntegerValue divideOf(SpecificIntegerValue other)
{
return divideOf((IntegerValue)other);
}
/**
* Returns the remainder of this IntegerValue divided by the given
* SpecificIntegerValue.
*/
public IntegerValue remainder(SpecificIntegerValue other)
{
return remainder((IntegerValue)other);
}
/**
* Returns the remainder of the given SpecificIntegerValue divided by this
* IntegerValue.
*/
public IntegerValue remainderOf(SpecificIntegerValue other)
{
return remainderOf((IntegerValue)other);
}
/**
* Returns this IntegerValue, shifted left by the given SpecificIntegerValue.
*/
public IntegerValue shiftLeft(SpecificIntegerValue other)
{
return shiftLeft((IntegerValue)other);
}
/**
* Returns this IntegerValue, shifted right by the given SpecificIntegerValue.
*/
public IntegerValue shiftRight(SpecificIntegerValue other)
{
return shiftRight((IntegerValue)other);
}
/**
* Returns this unsigned IntegerValue, shifted right by the given
* SpecificIntegerValue.
*/
public IntegerValue unsignedShiftRight(SpecificIntegerValue other)
{
return unsignedShiftRight((IntegerValue)other);
}
/**
* Returns the given SpecificIntegerValue, shifted left by this IntegerValue.
*/
public IntegerValue shiftLeftOf(SpecificIntegerValue other)
{
return shiftLeftOf((IntegerValue)other);
}
/**
* Returns the given SpecificIntegerValue, shifted right by this IntegerValue.
*/
public IntegerValue shiftRightOf(SpecificIntegerValue other)
{
return shiftRightOf((IntegerValue)other);
}
/**
* Returns the given unsigned SpecificIntegerValue, shifted right by this
* IntegerValue.
*/
public IntegerValue unsignedShiftRightOf(SpecificIntegerValue other)
{
return unsignedShiftRightOf((IntegerValue)other);
}
/**
* Returns the given SpecificLongValue, shifted left by this IntegerValue.
*/
public LongValue shiftLeftOf(SpecificLongValue other)
{
return shiftLeftOf((LongValue)other);
}
/**
* Returns the given SpecificLongValue, shifted right by this IntegerValue.
*/
public LongValue shiftRightOf(SpecificLongValue other)
{
return shiftRightOf((LongValue)other);
}
/**
* Returns the given unsigned SpecificLongValue, shifted right by this
* IntegerValue.
*/
public LongValue unsignedShiftRightOf(SpecificLongValue other)
{
return unsignedShiftRightOf((LongValue)other);
}
/**
* Returns the logical and of this IntegerValue and the given
* SpecificIntegerValue.
*/
public IntegerValue and(SpecificIntegerValue other)
{
return and((IntegerValue)other);
}
/**
* Returns the logical or of this IntegerValue and the given
* SpecificIntegerValue.
*/
public IntegerValue or(SpecificIntegerValue other)
{
return or((IntegerValue)other);
}
/**
* Returns the logical xor of this IntegerValue and the given
* SpecificIntegerValue.
*/
public IntegerValue xor(SpecificIntegerValue other)
{
return xor((IntegerValue)other);
}
/**
* Returns whether this IntegerValue and the given SpecificIntegerValue are
* equal: NEVER
, MAYBE
, or ALWAYS
.
*/
public int equal(SpecificIntegerValue other)
{
return equal((IntegerValue)other);
}
/**
* Returns whether this IntegerValue is less than the given
* SpecificIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public int lessThan(SpecificIntegerValue other)
{
return lessThan((IntegerValue)other);
}
/**
* Returns whether this IntegerValue is less than or equal to the given
* SpecificIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public int lessThanOrEqual(SpecificIntegerValue other)
{
return lessThanOrEqual((IntegerValue)other);
}
// Derived binary methods.
/**
* Returns whether this IntegerValue and the given SpecificIntegerValue are
* different: NEVER
, MAYBE
, or ALWAYS
.
*/
public final int notEqual(SpecificIntegerValue other)
{
return -equal(other);
}
/**
* Returns whether this IntegerValue is greater than the given
* SpecificIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public final int greaterThan(SpecificIntegerValue other)
{
return -lessThanOrEqual(other);
}
/**
* Returns whether this IntegerValue is greater than or equal to the given
* SpecificIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public final int greaterThanOrEqual(SpecificIntegerValue other)
{
return -lessThan(other);
}
// Similar binary methods, but this time with particular arguments.
/**
* Returns the generalization of this IntegerValue and the given other
* ParticularIntegerValue.
*/
public IntegerValue generalize(ParticularIntegerValue other)
{
return generalize((SpecificIntegerValue)other);
}
/**
* Returns the sum of this IntegerValue and the given ParticularIntegerValue.
*/
public IntegerValue add(ParticularIntegerValue other)
{
return add((SpecificIntegerValue)other);
}
/**
* Returns the difference of this IntegerValue and the given ParticularIntegerValue.
*/
public IntegerValue subtract(ParticularIntegerValue other)
{
return subtract((SpecificIntegerValue)other);
}
/**
* Returns the difference of the given ParticularIntegerValue and this IntegerValue.
*/
public IntegerValue subtractFrom(ParticularIntegerValue other)
{
return subtractFrom((SpecificIntegerValue)other);
}
/**
* Returns the product of this IntegerValue and the given ParticularIntegerValue.
*/
public IntegerValue multiply(ParticularIntegerValue other)
{
return multiply((SpecificIntegerValue)other);
}
/**
* Returns the quotient of this IntegerValue and the given
* ParticularIntegerValue.
*/
public IntegerValue divide(ParticularIntegerValue other)
{
return divide((SpecificIntegerValue)other);
}
/**
* Returns the quotient of the given ParticularIntegerValue and this
* IntegerValue.
*/
public IntegerValue divideOf(ParticularIntegerValue other)
{
return divideOf((SpecificIntegerValue)other);
}
/**
* Returns the remainder of this IntegerValue divided by the given
* ParticularIntegerValue.
*/
public IntegerValue remainder(ParticularIntegerValue other)
{
return remainder((SpecificIntegerValue)other);
}
/**
* Returns the remainder of the given ParticularIntegerValue divided by this
* IntegerValue.
*/
public IntegerValue remainderOf(ParticularIntegerValue other)
{
return remainderOf((SpecificIntegerValue)other);
}
/**
* Returns this IntegerValue, shifted left by the given ParticularIntegerValue.
*/
public IntegerValue shiftLeft(ParticularIntegerValue other)
{
return shiftLeft((SpecificIntegerValue)other);
}
/**
* Returns this IntegerValue, shifted right by the given ParticularIntegerValue.
*/
public IntegerValue shiftRight(ParticularIntegerValue other)
{
return shiftRight((SpecificIntegerValue)other);
}
/**
* Returns this unsigned IntegerValue, shifted right by the given
* ParticularIntegerValue.
*/
public IntegerValue unsignedShiftRight(ParticularIntegerValue other)
{
return unsignedShiftRight((SpecificIntegerValue)other);
}
/**
* Returns the given ParticularIntegerValue, shifted left by this IntegerValue.
*/
public IntegerValue shiftLeftOf(ParticularIntegerValue other)
{
return shiftLeftOf((SpecificIntegerValue)other);
}
/**
* Returns the given ParticularIntegerValue, shifted right by this IntegerValue.
*/
public IntegerValue shiftRightOf(ParticularIntegerValue other)
{
return shiftRightOf((SpecificIntegerValue)other);
}
/**
* Returns the given unsigned ParticularIntegerValue, shifted right by this
* IntegerValue.
*/
public IntegerValue unsignedShiftRightOf(ParticularIntegerValue other)
{
return unsignedShiftRightOf((SpecificIntegerValue)other);
}
/**
* Returns the given ParticularLongValue, shifted left by this IntegerValue.
*/
public LongValue shiftLeftOf(ParticularLongValue other)
{
return shiftLeftOf((SpecificLongValue)other);
}
/**
* Returns the given ParticularLongValue, shifted right by this IntegerValue.
*/
public LongValue shiftRightOf(ParticularLongValue other)
{
return shiftRightOf((SpecificLongValue)other);
}
/**
* Returns the given unsigned ParticularLongValue, shifted right by this
* IntegerValue.
*/
public LongValue unsignedShiftRightOf(ParticularLongValue other)
{
return unsignedShiftRightOf((SpecificLongValue)other);
}
/**
* Returns the logical and of this IntegerValue and the given
* ParticularIntegerValue.
*/
public IntegerValue and(ParticularIntegerValue other)
{
return and((SpecificIntegerValue)other);
}
/**
* Returns the logical or of this IntegerValue and the given
* ParticularIntegerValue.
*/
public IntegerValue or(ParticularIntegerValue other)
{
return or((SpecificIntegerValue)other);
}
/**
* Returns the logical xor of this IntegerValue and the given
* ParticularIntegerValue.
*/
public IntegerValue xor(ParticularIntegerValue other)
{
return xor((SpecificIntegerValue)other);
}
/**
* Returns whether this IntegerValue and the given ParticularIntegerValue are
* equal: NEVER
, MAYBE
, or ALWAYS
.
*/
public int equal(ParticularIntegerValue other)
{
return equal((SpecificIntegerValue)other);
}
/**
* Returns whether this IntegerValue is less than the given
* ParticularIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public int lessThan(ParticularIntegerValue other)
{
return lessThan((SpecificIntegerValue)other);
}
/**
* Returns whether this IntegerValue is less than or equal to the given
* ParticularIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public int lessThanOrEqual(ParticularIntegerValue other)
{
return lessThanOrEqual((SpecificIntegerValue)other);
}
// Derived binary methods.
/**
* Returns whether this IntegerValue and the given ParticularIntegerValue are
* different: NEVER
, MAYBE
, or ALWAYS
.
*/
public final int notEqual(ParticularIntegerValue other)
{
return -equal(other);
}
/**
* Returns whether this IntegerValue is greater than the given
* ParticularIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public final int greaterThan(ParticularIntegerValue other)
{
return -lessThanOrEqual(other);
}
/**
* Returns whether this IntegerValue is greater than or equal to the given
* ParticularIntegerValue: NEVER
, MAYBE
, or
* ALWAYS
.
*/
public final int greaterThanOrEqual(ParticularIntegerValue other)
{
return -lessThan(other);
}
// Implementations for Value.
public final IntegerValue integerValue()
{
return this;
}
public final Value generalize(Value other)
{
return this.generalize(other.integerValue());
}
public final int computationalType()
{
return TYPE_INTEGER;
}
public final String internalType()
{
return String.valueOf(ClassConstants.INTERNAL_TYPE_INT);
}
}
proguard4.8/src/proguard/evaluation/value/SpecificFloatValue.java 0000644 0001750 0001750 00000011130 11736333522 024032 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This FloatValue represents a specific float value.
*
* @author Eric Lafortune
*/
abstract class SpecificFloatValue extends FloatValue
{
// Implementations of unary methods of FloatValue.
public FloatValue negate()
{
return new NegatedFloatValue(this);
}
public IntegerValue convertToInteger()
{
return new ConvertedIntegerValue(this);
}
public LongValue convertToLong()
{
return new ConvertedLongValue(this);
}
public DoubleValue convertToDouble()
{
return new ConvertedDoubleValue(this);
}
// Implementations of binary methods of FloatValue.
public FloatValue generalize(FloatValue other)
{
return other.generalize(this);
}
public FloatValue add(FloatValue other)
{
return other.add(this);
}
public FloatValue subtract(FloatValue other)
{
return other.subtractFrom(this);
}
public FloatValue subtractFrom(FloatValue other)
{
return other.subtract(this);
}
public FloatValue multiply(FloatValue other)
{
return other.multiply(this);
}
public FloatValue divide(FloatValue other)
{
return other.divideOf(this);
}
public FloatValue divideOf(FloatValue other)
{
return other.divide(this);
}
public FloatValue remainder(FloatValue other)
{
return other.remainderOf(this);
}
public FloatValue remainderOf(FloatValue other)
{
return other.remainder(this);
}
public IntegerValue compare(FloatValue other)
{
return other.compareReverse(this);
}
// Implementations of binary FloatValue methods with SpecificFloatValue
// arguments.
public FloatValue generalize(SpecificFloatValue other)
{
return this.equals(other) ? this : ValueFactory.FLOAT_VALUE;
}
public FloatValue add(SpecificFloatValue other)
{
return new CompositeFloatValue(this, CompositeFloatValue.ADD, other);
}
public FloatValue subtract(SpecificFloatValue other)
{
return new CompositeFloatValue(this, CompositeFloatValue.SUBTRACT, other);
}
public FloatValue subtractFrom(SpecificFloatValue other)
{
return new CompositeFloatValue(other, CompositeFloatValue.SUBTRACT, this);
}
public FloatValue multiply(SpecificFloatValue other)
{
return new CompositeFloatValue(this, CompositeFloatValue.MULTIPLY, other);
}
public FloatValue divide(SpecificFloatValue other)
{
return new CompositeFloatValue(this, CompositeFloatValue.DIVIDE, other);
}
public FloatValue divideOf(SpecificFloatValue other)
{
return new CompositeFloatValue(other, CompositeFloatValue.DIVIDE, this);
}
public FloatValue remainder(SpecificFloatValue other)
{
return new CompositeFloatValue(this, CompositeFloatValue.REMAINDER, other);
}
public FloatValue remainderOf(SpecificFloatValue other)
{
return new CompositeFloatValue(other, CompositeFloatValue.REMAINDER, this);
}
public IntegerValue compare(SpecificFloatValue other)
{
return ValueFactory.INTEGER_VALUE;
// Not handling NaN properly.
//return this.equals(other) ?
// SpecificValueFactory.INTEGER_VALUE_0 :
// new ComparisonValue(this, other);
}
// Implementations for Value.
public boolean isSpecific()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
}
proguard4.8/src/proguard/evaluation/value/IdentifiedFloatValue.java 0000644 0001750 0001750 00000003611 11736333522 024356 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This FloatValue represents a float value that is identified by a unique ID.
*
* @author Eric Lafortune
*/
final class IdentifiedFloatValue extends SpecificFloatValue
{
private final ValueFactory valuefactory;
private final int id;
/**
* Creates a new float value with the given ID.
*/
public IdentifiedFloatValue(ValueFactory valuefactory, int id)
{
this.valuefactory = valuefactory;
this.id = id;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.valuefactory.equals(((IdentifiedFloatValue)object).valuefactory) &&
this.id == ((IdentifiedFloatValue)object).id;
}
public int hashCode()
{
return super.hashCode() ^
valuefactory.hashCode() ^
id;
}
public String toString()
{
return "f"+id;
}
} proguard4.8/src/proguard/evaluation/value/IdentifiedReferenceValue.java 0000644 0001750 0001750 00000005457 11736333522 025221 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.Clazz;
/**
* This LongValue represents a reference value that is identified by a unique ID.
*
* @author Eric Lafortune
*/
final class IdentifiedReferenceValue extends ReferenceValue
{
private final ValueFactory valuefactory;
private final int id;
/**
* Creates a new long value with the given ID.
*/
public IdentifiedReferenceValue(String type,
Clazz referencedClass,
boolean mayBeNull,
ValueFactory valuefactory,
int id)
{
super(type, referencedClass, mayBeNull);
this.valuefactory = valuefactory;
this.id = id;
}
// Implementations for ReferenceValue.
public int equal(ReferenceValue other)
{
return this.equals(other) ? ALWAYS : MAYBE;
}
// Implementations of binary methods of ReferenceValue.
public ReferenceValue generalize(ReferenceValue other)
{
// Remove the ID if both values don't share the same ID.
return this.equals(other) ?
this :
new ReferenceValue(type, referencedClass, mayBeNull).generalize(other);
}
// Implementations for Value.
public boolean isSpecific()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.valuefactory.equals(((IdentifiedReferenceValue)object).valuefactory) &&
this.id == ((IdentifiedReferenceValue)object).id;
}
public int hashCode()
{
return super.hashCode() ^
valuefactory.hashCode() ^
id;
}
public String toString()
{
return super.toString()+'#'+id;
}
} proguard4.8/src/proguard/evaluation/value/InstructionOffsetValue.java 0000644 0001750 0001750 00000016337 11736333522 025025 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.ClassConstants;
/**
* This class represents a partially evaluated instruction offset. It can
* contain 0 or more specific instruction offsets.
*
* @author Eric Lafortune
*/
public class InstructionOffsetValue extends Category1Value
{
public static final InstructionOffsetValue EMPTY_VALUE = new InstructionOffsetValue();
private int[] values;
private InstructionOffsetValue()
{
}
public InstructionOffsetValue(int value)
{
this.values = new int[] { value };
}
public InstructionOffsetValue(int[] values)
{
this.values = values;
}
public int instructionOffsetCount()
{
return values == null ? 0 : values.length;
}
public int instructionOffset(int index)
{
return values[index];
}
/**
* Returns whether the given value is present in this list of instruction
* offsets.
*/
public boolean contains(int value)
{
if (values != null)
{
for (int index = 0; index < values.length; index++)
{
if (values[index] == value)
{
return true;
}
}
}
return false;
}
/**
* Returns the minimum value from this list of instruction offsets.
* Returns Integer.MAX_VALUE
if the list is empty.
*/
public int minimumValue()
{
int minimumValue = Integer.MAX_VALUE;
if (values != null)
{
for (int index = 0; index < values.length; index++)
{
int value = values[index];
if (minimumValue > value)
{
minimumValue = value;
}
}
}
return minimumValue;
}
/**
* Returns the maximum value from this list of instruction offsets.
* Returns Integer.MIN_VALUE
if the list is empty.
*/
public int maximumValue()
{
int maximumValue = Integer.MIN_VALUE;
if (values != null)
{
for (int index = 0; index < values.length; index++)
{
int value = values[index];
if (maximumValue < value)
{
maximumValue = value;
}
}
}
return maximumValue;
}
/**
* Returns the generalization of this InstructionOffsetValue and the given
* other InstructionOffsetValue. The values of the other InstructionOffsetValue
* are guaranteed to remain at the end of the list, in the same order.
*/
public final Value generalize(InstructionOffsetValue other)
{
// If the values array of either is null, return the other one.
if (this.values == null)
{
return other;
}
if (other.values == null)
{
return this;
}
// Compute the length of the union of the arrays.
int newLength = this.values.length;
for (int index = 0; index < other.values.length; index++)
{
if (!this.contains(other.values[index]))
{
newLength++;
}
}
// If the length of the union array is equal to the length of the values
// array of either, return it.
if (newLength == other.values.length)
{
return other;
}
// The ordering of the this array may not be right, so we can't just
// use it.
//if (newLength == this.values.length)
//{
// return this;
//}
// Create the union array.
int[] newValues = new int[newLength];
int newIndex = 0;
// Copy the values that are different from the other array.
for (int index = 0; index < this.values.length; index++)
{
if (!other.contains(this.values[index]))
{
newValues[newIndex++] = this.values[index];
}
}
// Copy the values from the other array.
for (int index = 0; index < other.values.length; index++)
{
newValues[newIndex++] = other.values[index];
}
return new InstructionOffsetValue(newValues);
}
// Implementations for Value.
public final InstructionOffsetValue instructionOffsetValue()
{
return this;
}
public boolean isSpecific()
{
return true;
}
public boolean isParticular()
{
return true;
}
public final Value generalize(Value other)
{
return this.generalize(other.instructionOffsetValue());
}
public final int computationalType()
{
return TYPE_INSTRUCTION_OFFSET;
}
public final String internalType()
{
return String.valueOf(ClassConstants.INTERNAL_TYPE_INT);
}
// Implementations for Object.
public boolean equals(Object object)
{
if (object == null ||
this.getClass() != object.getClass())
{
return false;
}
InstructionOffsetValue other = (InstructionOffsetValue)object;
if (this.values == other.values)
{
return true;
}
if (this.values == null ||
other.values == null ||
this.values.length != other.values.length)
{
return false;
}
for (int index = 0; index < other.values.length; index++)
{
if (!this.contains(other.values[index]))
{
return false;
}
}
return true;
}
public int hashCode()
{
int hashCode = this.getClass().hashCode();
if (values != null)
{
for (int index = 0; index < values.length; index++)
{
hashCode ^= values[index];
}
}
return hashCode;
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
if (values != null)
{
for (int index = 0; index < values.length; index++)
{
if (index > 0)
{
buffer.append(',');
}
buffer.append(values[index]);
}
}
return buffer.append(':').toString();
}
}
proguard4.8/src/proguard/evaluation/value/IdentifiedValueFactory.java 0000644 0001750 0001750 00000004226 11736333522 024723 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.*;
import proguard.classfile.util.ClassUtil;
/**
* This class provides methods to create and reuse IntegerValue objects.
*
* @author Eric Lafortune
*/
public class IdentifiedValueFactory
extends SpecificValueFactory
{
private int integerID;
private int longID;
private int floatID;
private int doubleID;
private int referenceID;
// Implementations for ValueFactory.
public IntegerValue createIntegerValue()
{
return new IdentifiedIntegerValue(this, integerID++);
}
public LongValue createLongValue()
{
return new IdentifiedLongValue(this, longID++);
}
public FloatValue createFloatValue()
{
return new IdentifiedFloatValue(this, floatID++);
}
public DoubleValue createDoubleValue()
{
return new IdentifiedDoubleValue(this, doubleID++);
}
public ReferenceValue createReferenceValue(String type,
Clazz referencedClass,
boolean mayBeNull)
{
return type == null ?
REFERENCE_VALUE_NULL :
new IdentifiedReferenceValue(type, referencedClass, mayBeNull, this, referenceID++);
}
} proguard4.8/src/proguard/evaluation/value/ConvertedIntegerValue.java 0000644 0001750 0001750 00000003333 11736333522 024574 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents a integer value that is converted from another
* scalar value.
*
* @author Eric Lafortune
*/
final class ConvertedIntegerValue extends SpecificIntegerValue
{
private final Value value;
/**
* Creates a new converted integer value of the given value.
*/
public ConvertedIntegerValue(Value value)
{
this.value = value;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.value.equals(((ConvertedIntegerValue)object).value);
}
public int hashCode()
{
return super.hashCode() ^
value.hashCode();
}
public String toString()
{
return "(int)("+value+")";
}
} proguard4.8/src/proguard/evaluation/value/UnknownLongValue.java 0000644 0001750 0001750 00000006344 11736333522 023611 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This class represents a partially evaluated long value.
*
* @author Eric Lafortune
*/
public class UnknownLongValue extends LongValue
{
// Basic unary methods.
public LongValue negate()
{
return this;
}
public IntegerValue convertToInteger()
{
return ValueFactory.INTEGER_VALUE;
}
public FloatValue convertToFloat()
{
return ValueFactory.FLOAT_VALUE;
}
public DoubleValue convertToDouble()
{
return ValueFactory.DOUBLE_VALUE;
}
// Basic binary methods.
public LongValue generalize(LongValue other)
{
return this;
}
public LongValue add(LongValue other)
{
return this;
}
public LongValue subtract(LongValue other)
{
return this;
}
public LongValue subtractFrom(LongValue other)
{
return this;
}
public LongValue multiply(LongValue other)
throws ArithmeticException
{
return this;
}
public LongValue divide(LongValue other)
throws ArithmeticException
{
return this;
}
public LongValue divideOf(LongValue other)
throws ArithmeticException
{
return this;
}
public LongValue remainder(LongValue other)
throws ArithmeticException
{
return this;
}
public LongValue remainderOf(LongValue other)
throws ArithmeticException
{
return this;
}
public LongValue shiftLeft(IntegerValue other)
{
return this;
}
public LongValue shiftRight(IntegerValue other)
{
return this;
}
public LongValue unsignedShiftRight(IntegerValue other)
{
return this;
}
public LongValue and(LongValue other)
{
return this;
}
public LongValue or(LongValue other)
{
return this;
}
public LongValue xor(LongValue other)
{
return this;
}
public IntegerValue compare(LongValue other)
{
return ValueFactory.INTEGER_VALUE;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
public String toString()
{
return "l";
}
} proguard4.8/src/proguard/evaluation/value/FloatValue.java 0000644 0001750 0001750 00000022623 11736333522 022375 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.ClassConstants;
/**
* This class represents a partially evaluated float value.
*
* @author Eric Lafortune
*/
public abstract class FloatValue extends Category1Value
{
/**
* Returns the specific float value, if applicable.
*/
public float value()
{
return 0f;
}
// Basic unary methods.
/**
* Returns the negated value of this FloatValue.
*/
public abstract FloatValue negate();
/**
* Converts this FloatValue to an IntegerValue.
*/
public abstract IntegerValue convertToInteger();
/**
* Converts this FloatValue to a LongValue.
*/
public abstract LongValue convertToLong();
/**
* Converts this FloatValue to a DoubleValue.
*/
public abstract DoubleValue convertToDouble();
// Basic binary methods.
/**
* Returns the generalization of this FloatValue and the given other
* FloatValue.
*/
public abstract FloatValue generalize(FloatValue other);
/**
* Returns the sum of this FloatValue and the given FloatValue.
*/
public abstract FloatValue add(FloatValue other);
/**
* Returns the difference of this FloatValue and the given FloatValue.
*/
public abstract FloatValue subtract(FloatValue other);
/**
* Returns the difference of the given FloatValue and this FloatValue.
*/
public abstract FloatValue subtractFrom(FloatValue other);
/**
* Returns the product of this FloatValue and the given FloatValue.
*/
public abstract FloatValue multiply(FloatValue other);
/**
* Returns the quotient of this FloatValue and the given FloatValue.
*/
public abstract FloatValue divide(FloatValue other);
/**
* Returns the quotient of the given FloatValue and this FloatValue.
*/
public abstract FloatValue divideOf(FloatValue other);
/**
* Returns the remainder of this FloatValue divided by the given FloatValue.
*/
public abstract FloatValue remainder(FloatValue other);
/**
* Returns the remainder of the given FloatValue divided by this FloatValue.
*/
public abstract FloatValue remainderOf(FloatValue other);
/**
* Returns an IntegerValue with value -1, 0, or 1, if this FloatValue is
* less than, equal to, or greater than the given FloatValue, respectively.
*/
public abstract IntegerValue compare(FloatValue other);
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this FloatValue is
* less than, equal to, or greater than the given FloatValue, respectively.
*/
public final IntegerValue compareReverse(FloatValue other)
{
return compare(other).negate();
}
// Similar binary methods, but this time with more specific arguments.
/**
* Returns the generalization of this FloatValue and the given other
* SpecificFloatValue.
*/
public FloatValue generalize(SpecificFloatValue other)
{
return generalize((FloatValue)other);
}
/**
* Returns the sum of this FloatValue and the given SpecificFloatValue.
*/
public FloatValue add(SpecificFloatValue other)
{
return add((FloatValue)other);
}
/**
* Returns the difference of this FloatValue and the given SpecificFloatValue.
*/
public FloatValue subtract(SpecificFloatValue other)
{
return subtract((FloatValue)other);
}
/**
* Returns the difference of the given SpecificFloatValue and this FloatValue.
*/
public FloatValue subtractFrom(SpecificFloatValue other)
{
return subtractFrom((FloatValue)other);
}
/**
* Returns the product of this FloatValue and the given SpecificFloatValue.
*/
public FloatValue multiply(SpecificFloatValue other)
{
return multiply((FloatValue)other);
}
/**
* Returns the quotient of this FloatValue and the given SpecificFloatValue.
*/
public FloatValue divide(SpecificFloatValue other)
{
return divide((FloatValue)other);
}
/**
* Returns the quotient of the given SpecificFloatValue and this
* FloatValue.
*/
public FloatValue divideOf(SpecificFloatValue other)
{
return divideOf((FloatValue)other);
}
/**
* Returns the remainder of this FloatValue divided by the given
* SpecificFloatValue.
*/
public FloatValue remainder(SpecificFloatValue other)
{
return remainder((FloatValue)other);
}
/**
* Returns the remainder of the given SpecificFloatValue and this
* FloatValue.
*/
public FloatValue remainderOf(SpecificFloatValue other)
{
return remainderOf((FloatValue)other);
}
/**
* Returns an IntegerValue with value -1, 0, or 1, if this FloatValue is
* less than, equal to, or greater than the given SpecificFloatValue,
* respectively.
*/
public IntegerValue compare(SpecificFloatValue other)
{
return compare((FloatValue)other);
}
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this FloatValue is
* less than, equal to, or greater than the given SpecificFloatValue,
* respectively.
*/
public final IntegerValue compareReverse(SpecificFloatValue other)
{
return compare(other).negate();
}
// Similar binary methods, but this time with particular arguments.
/**
* Returns the generalization of this FloatValue and the given other
* ParticularFloatValue.
*/
public FloatValue generalize(ParticularFloatValue other)
{
return generalize((SpecificFloatValue)other);
}
/**
* Returns the sum of this FloatValue and the given ParticularFloatValue.
*/
public FloatValue add(ParticularFloatValue other)
{
return add((SpecificFloatValue)other);
}
/**
* Returns the difference of this FloatValue and the given ParticularFloatValue.
*/
public FloatValue subtract(ParticularFloatValue other)
{
return subtract((SpecificFloatValue)other);
}
/**
* Returns the difference of the given ParticularFloatValue and this FloatValue.
*/
public FloatValue subtractFrom(ParticularFloatValue other)
{
return subtractFrom((SpecificFloatValue)other);
}
/**
* Returns the product of this FloatValue and the given ParticularFloatValue.
*/
public FloatValue multiply(ParticularFloatValue other)
{
return multiply((SpecificFloatValue)other);
}
/**
* Returns the quotient of this FloatValue and the given ParticularFloatValue.
*/
public FloatValue divide(ParticularFloatValue other)
{
return divide((SpecificFloatValue)other);
}
/**
* Returns the quotient of the given ParticularFloatValue and this
* FloatValue.
*/
public FloatValue divideOf(ParticularFloatValue other)
{
return divideOf((SpecificFloatValue)other);
}
/**
* Returns the remainder of this FloatValue divided by the given
* ParticularFloatValue.
*/
public FloatValue remainder(ParticularFloatValue other)
{
return remainder((SpecificFloatValue)other);
}
/**
* Returns the remainder of the given ParticularFloatValue and this
* FloatValue.
*/
public FloatValue remainderOf(ParticularFloatValue other)
{
return remainderOf((SpecificFloatValue)other);
}
/**
* Returns an IntegerValue with value -1, 0, or 1, if this FloatValue is
* less than, equal to, or greater than the given ParticularFloatValue,
* respectively.
*/
public IntegerValue compare(ParticularFloatValue other)
{
return compare((SpecificFloatValue)other);
}
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this FloatValue is
* less than, equal to, or greater than the given ParticularFloatValue,
* respectively.
*/
public final IntegerValue compareReverse(ParticularFloatValue other)
{
return compare(other).negate();
}
// Implementations for Value.
public final FloatValue floatValue()
{
return this;
}
public final Value generalize(Value other)
{
return this.generalize(other.floatValue());
}
public final int computationalType()
{
return TYPE_FLOAT;
}
public final String internalType()
{
return String.valueOf(ClassConstants.INTERNAL_TYPE_FLOAT);
}
}
proguard4.8/src/proguard/evaluation/value/ComparisonValue.java 0000644 0001750 0001750 00000003654 11736333522 023445 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents the result of a comparisons of two scalar
* values.
*
* @author Eric Lafortune
*/
final class ComparisonValue extends SpecificIntegerValue
{
private final Value value1;
private final Value value2;
/**
* Creates a new comparison integer value of the two given scalar values.
*/
public ComparisonValue(Value value1,
Value value2)
{
this.value1 = value1;
this.value2 = value2;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.value1.equals(((ComparisonValue)object).value1) &&
this.value2.equals(((ComparisonValue)object).value2);
}
public int hashCode()
{
return super.hashCode() ^
value1.hashCode() ^
value2.hashCode();
}
public String toString()
{
return "("+value1+"~"+ value2 +")";
}
} proguard4.8/src/proguard/evaluation/value/UnknownIntegerValue.java 0000644 0001750 0001750 00000010374 11736333523 024306 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This class represents a partially evaluated integer value.
*
* @author Eric Lafortune
*/
public class UnknownIntegerValue extends IntegerValue
{
// Basic unary methods.
public IntegerValue negate()
{
return this;
}
public IntegerValue convertToByte()
{
return this;
}
public IntegerValue convertToCharacter()
{
return this;
}
public IntegerValue convertToShort()
{
return this;
}
public LongValue convertToLong()
{
return ValueFactory.LONG_VALUE;
}
public FloatValue convertToFloat()
{
return ValueFactory.FLOAT_VALUE;
}
public DoubleValue convertToDouble()
{
return ValueFactory.DOUBLE_VALUE;
}
// Basic binary methods.
public IntegerValue generalize(IntegerValue other)
{
return this;
}
public IntegerValue add(IntegerValue other)
{
return this;
}
public IntegerValue subtract(IntegerValue other)
{
return this;
}
public IntegerValue subtractFrom(IntegerValue other)
{
return this;
}
public IntegerValue multiply(IntegerValue other)
throws ArithmeticException
{
return this;
}
public IntegerValue divide(IntegerValue other)
throws ArithmeticException
{
return this;
}
public IntegerValue divideOf(IntegerValue other)
throws ArithmeticException
{
return this;
}
public IntegerValue remainder(IntegerValue other)
throws ArithmeticException
{
return this;
}
public IntegerValue remainderOf(IntegerValue other)
throws ArithmeticException
{
return this;
}
public IntegerValue shiftLeft(IntegerValue other)
{
return this;
}
public IntegerValue shiftLeftOf(IntegerValue other)
{
return this;
}
public IntegerValue shiftRight(IntegerValue other)
{
return this;
}
public IntegerValue shiftRightOf(IntegerValue other)
{
return this;
}
public IntegerValue unsignedShiftRight(IntegerValue other)
{
return this;
}
public IntegerValue unsignedShiftRightOf(IntegerValue other)
{
return this;
}
public LongValue shiftLeftOf(LongValue other)
{
return ValueFactory.LONG_VALUE;
}
public LongValue shiftRightOf(LongValue other)
{
return ValueFactory.LONG_VALUE;
}
public LongValue unsignedShiftRightOf(LongValue other)
{
return ValueFactory.LONG_VALUE;
}
public IntegerValue and(IntegerValue other)
{
return this;
}
public IntegerValue or(IntegerValue other)
{
return this;
}
public IntegerValue xor(IntegerValue other)
{
return this;
}
public int equal(IntegerValue other)
{
return MAYBE;
}
public int lessThan(IntegerValue other)
{
return MAYBE;
}
public int lessThanOrEqual(IntegerValue other)
{
return MAYBE;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
public String toString()
{
return "i";
}
} proguard4.8/src/proguard/evaluation/value/CompositeFloatValue.java 0000644 0001750 0001750 00000005013 11736333523 024253 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This FloatValue represents the result of a binary operation on two float
* values.
*
* @author Eric Lafortune
*/
final class CompositeFloatValue extends SpecificFloatValue
{
public static final byte ADD = '+';
public static final byte SUBTRACT = '-';
public static final byte MULTIPLY = '*';
public static final byte DIVIDE = '/';
public static final byte REMAINDER = '%';
private final FloatValue floatValue1;
private final byte operation;
private final FloatValue floatValue2;
/**
* Creates a new composite float value of the two given float values
* and the given operation.
*/
public CompositeFloatValue(FloatValue floatValue1,
byte operation,
FloatValue floatValue2)
{
this.floatValue1 = floatValue1;
this.operation = operation;
this.floatValue2 = floatValue2;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.floatValue1.equals(((CompositeFloatValue)object).floatValue1) &&
this.operation == ((CompositeFloatValue)object).operation &&
this.floatValue2.equals(((CompositeFloatValue)object).floatValue2);
}
public int hashCode()
{
return super.hashCode() ^
floatValue1.hashCode() ^
floatValue2.hashCode();
}
public String toString()
{
return "("+floatValue1+((char)operation)+floatValue2+")";
}
} proguard4.8/src/proguard/evaluation/value/Category1Value.java 0000644 0001750 0001750 00000002414 11736333523 023163 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This abstract class represents a partially evaluated Category 1 value.
*
* @author Eric Lafortune
*/
public abstract class Category1Value extends Value
{
// Implementations for Value.
public final Category1Value category1Value()
{
return this;
}
public final boolean isCategory2()
{
return false;
}
}
proguard4.8/src/proguard/evaluation/value/NegatedLongValue.java 0000644 0001750 0001750 00000003500 11736333523 023511 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This LongValue represents a long value that is negated.
*
* @author Eric Lafortune
*/
final class NegatedLongValue extends SpecificLongValue
{
private final LongValue longValue;
/**
* Creates a new negated long value of the given long value.
*/
public NegatedLongValue(LongValue longValue)
{
this.longValue = longValue;
}
// Implementations of unary methods of LongValue.
public LongValue negate()
{
return longValue;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.longValue.equals(((NegatedLongValue)object).longValue);
}
public int hashCode()
{
return super.hashCode() ^
longValue.hashCode();
}
public String toString()
{
return "-"+longValue;
}
} proguard4.8/src/proguard/evaluation/value/IdentifiedDoubleValue.java 0000644 0001750 0001750 00000003621 11736333523 024525 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This DoubleValue represents a double value that is identified by a unique ID.
*
* @author Eric Lafortune
*/
final class IdentifiedDoubleValue extends SpecificDoubleValue
{
private final ValueFactory valuefactory;
private final int id;
/**
* Creates a new double value with the given ID.
*/
public IdentifiedDoubleValue(ValueFactory valuefactory, int id)
{
this.valuefactory = valuefactory;
this.id = id;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.valuefactory.equals(((IdentifiedDoubleValue)object).valuefactory) &&
this.id == ((IdentifiedDoubleValue)object).id;
}
public int hashCode()
{
return super.hashCode() ^
valuefactory.hashCode() ^
id;
}
public String toString()
{
return "d"+id;
}
} proguard4.8/src/proguard/evaluation/value/ParticularLongValue.java 0000644 0001750 0001750 00000014303 11736333523 024253 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This LongValue represents a particular long value.
*
* @author Eric Lafortune
*/
final class ParticularLongValue extends SpecificLongValue
{
private final long value;
/**
* Creates a new particular long value.
*/
public ParticularLongValue(long value)
{
this.value = value;
}
// Implementations for LongValue.
public long value()
{
return value;
}
// Implementations of unary methods of LongValue.
public LongValue negate()
{
return new ParticularLongValue(-value);
}
public IntegerValue convertToInteger()
{
return new ParticularIntegerValue((int)value);
}
public FloatValue convertToFloat()
{
return new ParticularFloatValue((float)value);
}
public DoubleValue convertToDouble()
{
return new ParticularDoubleValue((double)value);
}
// Implementations of binary methods of LongValue.
public LongValue generalize(LongValue other)
{
return other.generalize(this);
}
public LongValue add(LongValue other)
{
return other.add(this);
}
public LongValue subtract(LongValue other)
{
return other.subtractFrom(this);
}
public LongValue subtractFrom(LongValue other)
{
return other.subtract(this);
}
public LongValue multiply(LongValue other)
{
return other.multiply(this);
}
public LongValue divide(LongValue other)
throws ArithmeticException
{
return other.divideOf(this);
}
public LongValue divideOf(LongValue other)
throws ArithmeticException
{
return other.divide(this);
}
public LongValue remainder(LongValue other)
throws ArithmeticException
{
return other.remainderOf(this);
}
public LongValue remainderOf(LongValue other)
throws ArithmeticException
{
return other.remainder(this);
}
public LongValue shiftLeft(IntegerValue other)
{
return other.shiftLeftOf(this);
}
public LongValue shiftRight(IntegerValue other)
{
return other.shiftRightOf(this);
}
public LongValue unsignedShiftRight(IntegerValue other)
{
return other.unsignedShiftRightOf(this);
}
public LongValue and(LongValue other)
{
return other.and(this);
}
public LongValue or(LongValue other)
{
return other.or(this);
}
public LongValue xor(LongValue other)
{
return other.xor(this);
}
public IntegerValue compare(LongValue other)
{
return other.compareReverse(this);
}
// Implementations of binary LongValue methods with ParticularLongValue
// arguments.
public LongValue generalize(ParticularLongValue other)
{
return generalize((SpecificLongValue)other);
}
public LongValue add(ParticularLongValue other)
{
return new ParticularLongValue(this.value + other.value);
}
public LongValue subtract(ParticularLongValue other)
{
return new ParticularLongValue(this.value - other.value);
}
public LongValue subtractFrom(ParticularLongValue other)
{
return new ParticularLongValue(other.value - this.value);
}
public LongValue multiply(ParticularLongValue other)
{
return new ParticularLongValue(this.value * other.value);
}
public LongValue divide(ParticularLongValue other)
throws ArithmeticException
{
return new ParticularLongValue(this.value / other.value);
}
public LongValue divideOf(ParticularLongValue other)
throws ArithmeticException
{
return new ParticularLongValue(other.value / this.value);
}
public LongValue remainder(ParticularLongValue other)
throws ArithmeticException
{
return new ParticularLongValue(this.value % other.value);
}
public LongValue remainderOf(ParticularLongValue other)
throws ArithmeticException
{
return new ParticularLongValue(other.value % this.value);
}
public LongValue shiftLeft(ParticularIntegerValue other)
{
return new ParticularLongValue(this.value << other.value());
}
public LongValue shiftRight(ParticularIntegerValue other)
{
return new ParticularLongValue(this.value >> other.value());
}
public LongValue unsignedShiftRight(ParticularIntegerValue other)
{
return new ParticularLongValue(this.value >>> other.value());
}
public LongValue and(ParticularLongValue other)
{
return new ParticularLongValue(this.value & other.value);
}
public LongValue or(ParticularLongValue other)
{
return new ParticularLongValue(this.value | other.value);
}
public LongValue xor(ParticularLongValue other)
{
return new ParticularLongValue(this.value ^ other.value);
}
// Implementations for Value.
public boolean isParticular()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return super.equals(object) &&
this.value == ((ParticularLongValue)object).value;
}
public int hashCode()
{
return this.getClass().hashCode() ^
(int)value;
}
public String toString()
{
return value+"L";
}
} proguard4.8/src/proguard/evaluation/value/ConvertedFloatValue.java 0000644 0001750 0001750 00000003317 11736333523 024247 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This FloatValue represents a float value that is converted from another
* scalar value.
*
* @author Eric Lafortune
*/
final class ConvertedFloatValue extends SpecificFloatValue
{
private final Value value;
/**
* Creates a new converted float value of the given value.
*/
public ConvertedFloatValue(Value value)
{
this.value = value;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.value.equals(((ConvertedFloatValue)object).value);
}
public int hashCode()
{
return super.hashCode() ^
value.hashCode();
}
public String toString()
{
return "(float)("+value+")";
}
} proguard4.8/src/proguard/evaluation/value/SpecificValueFactory.java 0000644 0001750 0001750 00000007620 11736333523 024406 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This class provides methods to create and reuse IntegerValue objects.
*
* @author Eric Lafortune
*/
public class SpecificValueFactory
extends ValueFactory
{
// Shared copies of Value objects, to avoid creating a lot of objects.
static final IntegerValue INTEGER_VALUE_M1 = new ParticularIntegerValue(-1);
static final IntegerValue INTEGER_VALUE_0 = new ParticularIntegerValue(0);
static final IntegerValue INTEGER_VALUE_1 = new ParticularIntegerValue(1);
static final IntegerValue INTEGER_VALUE_2 = new ParticularIntegerValue(2);
static final IntegerValue INTEGER_VALUE_3 = new ParticularIntegerValue(3);
static final IntegerValue INTEGER_VALUE_4 = new ParticularIntegerValue(4);
static final IntegerValue INTEGER_VALUE_5 = new ParticularIntegerValue(5);
static final LongValue LONG_VALUE_0 = new ParticularLongValue(0);
static final LongValue LONG_VALUE_1 = new ParticularLongValue(1);
static final FloatValue FLOAT_VALUE_0 = new ParticularFloatValue(0.0f);
static final FloatValue FLOAT_VALUE_1 = new ParticularFloatValue(1.0f);
static final FloatValue FLOAT_VALUE_2 = new ParticularFloatValue(2.0f);
static final DoubleValue DOUBLE_VALUE_0 = new ParticularDoubleValue(0.0);
static final DoubleValue DOUBLE_VALUE_1 = new ParticularDoubleValue(1.0);
private static int POS_ZERO_FLOAT_BITS = Float.floatToIntBits(0.0f);
private static long POS_ZERO_DOUBLE_BITS = Double.doubleToLongBits(0.0);
// Implementations for ValueFactory.
public IntegerValue createIntegerValue(int value)
{
switch (value)
{
case -1: return INTEGER_VALUE_M1;
case 0: return INTEGER_VALUE_0;
case 1: return INTEGER_VALUE_1;
case 2: return INTEGER_VALUE_2;
case 3: return INTEGER_VALUE_3;
case 4: return INTEGER_VALUE_4;
case 5: return INTEGER_VALUE_5;
default: return new ParticularIntegerValue(value);
}
}
public LongValue createLongValue(long value)
{
return value == 0 ? LONG_VALUE_0 :
value == 1 ? LONG_VALUE_1 :
new ParticularLongValue(value);
}
public FloatValue createFloatValue(float value)
{
// Make sure to distinguish between +0.0 and -0.0.
return value == 0.0f && Float.floatToIntBits(value) == POS_ZERO_FLOAT_BITS
? FLOAT_VALUE_0 :
value == 1.0f ? FLOAT_VALUE_1 :
value == 2.0f ? FLOAT_VALUE_2 :
new ParticularFloatValue(value);
}
public DoubleValue createDoubleValue(double value)
{
// Make sure to distinguish between +0.0 and -0.0.
return value == 0.0 && Double.doubleToLongBits(value) == POS_ZERO_DOUBLE_BITS
? DOUBLE_VALUE_0 :
value == 1.0 ? DOUBLE_VALUE_1 :
new ParticularDoubleValue(value);
}
}
proguard4.8/src/proguard/evaluation/value/NegatedFloatValue.java 0000644 0001750 0001750 00000003525 11736333523 023666 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This FloatValue represents a float value that is negated.
*
* @author Eric Lafortune
*/
final class NegatedFloatValue extends SpecificFloatValue
{
private final FloatValue floatValue;
/**
* Creates a new negated float value of the given float value.
*/
public NegatedFloatValue(FloatValue floatValue)
{
this.floatValue = floatValue;
}
// Implementations of unary methods of FloatValue.
public FloatValue negate()
{
return floatValue;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.floatValue.equals(((NegatedFloatValue)object).floatValue);
}
public int hashCode()
{
return super.hashCode() ^
floatValue.hashCode();
}
public String toString()
{
return "-"+floatValue;
}
} proguard4.8/src/proguard/evaluation/value/NegatedIntegerValue.java 0000644 0001750 0001750 00000003577 11736333523 024225 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents a integer value that is negated.
*
* @author Eric Lafortune
*/
final class NegatedIntegerValue extends SpecificIntegerValue
{
private final IntegerValue integerValue;
/**
* Creates a new negated integer value of the given integer value.
*/
public NegatedIntegerValue(IntegerValue integerValue)
{
this.integerValue = integerValue;
}
// Implementations of unary methods of IntegerValue.
public IntegerValue negate()
{
return integerValue;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.integerValue.equals(((NegatedIntegerValue)object).integerValue);
}
public int hashCode()
{
return super.hashCode() ^
integerValue.hashCode();
}
public String toString()
{
return "-"+integerValue;
}
} proguard4.8/src/proguard/evaluation/value/ParticularDoubleValue.java 0000644 0001750 0001750 00000012514 11736333523 024570 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This DoubleValue represents a particular double value.
*
* @author Eric Lafortune
*/
final class ParticularDoubleValue extends SpecificDoubleValue
{
private final double value;
/**
* Creates a new particular double value.
*/
public ParticularDoubleValue(double value)
{
this.value = value;
}
// Implementations for DoubleValue.
public double value()
{
return value;
}
// Implementations of unary methods of DoubleValue.
public DoubleValue negate()
{
return new ParticularDoubleValue(-value);
}
public IntegerValue convertToInteger()
{
return new ParticularIntegerValue((int)value);
}
public LongValue convertToLong()
{
return new ParticularLongValue((long)value);
}
public FloatValue convertToFloat()
{
return new ParticularFloatValue((float)value);
}
// Implementations of binary methods of DoubleValue.
public DoubleValue generalize(DoubleValue other)
{
return other.generalize(this);
}
public DoubleValue add(DoubleValue other)
{
// Careful: -0.0 + 0.0 == 0.0
//return value == 0.0 ? other : other.add(this);
return other.add(this);
}
public DoubleValue subtract(DoubleValue other)
{
// Careful: -0.0 + 0.0 == 0.0
//return value == 0.0 ? other.negate() : other.subtractFrom(this);
return other.subtractFrom(this);
}
public DoubleValue subtractFrom(DoubleValue other)
{
// Careful: -0.0 + 0.0 == 0.0
//return value == 0.0 ? other : other.subtract(this);
return other.subtract(this);
}
public DoubleValue multiply(DoubleValue other)
{
return other.multiply(this);
}
public DoubleValue divide(DoubleValue other)
{
return other.divideOf(this);
}
public DoubleValue divideOf(DoubleValue other)
{
return other.divide(this);
}
public DoubleValue remainder(DoubleValue other)
{
return other.remainderOf(this);
}
public DoubleValue remainderOf(DoubleValue other)
{
return other.remainder(this);
}
public IntegerValue compare(DoubleValue other)
{
return other.compareReverse(this);
}
// Implementations of binary DoubleValue methods with ParticularDoubleValue
// arguments.
public DoubleValue generalize(ParticularDoubleValue other)
{
return this.value == other.value ? this : ValueFactory.DOUBLE_VALUE;
}
public DoubleValue add(ParticularDoubleValue other)
{
return new ParticularDoubleValue(this.value + other.value);
}
public DoubleValue subtract(ParticularDoubleValue other)
{
return new ParticularDoubleValue(this.value - other.value);
}
public DoubleValue subtractFrom(ParticularDoubleValue other)
{
return new ParticularDoubleValue(other.value - this.value);
}
public DoubleValue multiply(ParticularDoubleValue other)
{
return new ParticularDoubleValue(this.value * other.value);
}
public DoubleValue divide(ParticularDoubleValue other)
{
return new ParticularDoubleValue(this.value / other.value);
}
public DoubleValue divideOf(ParticularDoubleValue other)
{
return new ParticularDoubleValue(other.value / this.value);
}
public DoubleValue remainder(ParticularDoubleValue other)
{
return new ParticularDoubleValue(this.value % other.value);
}
public DoubleValue remainderOf(ParticularDoubleValue other)
{
return new ParticularDoubleValue(other.value % this.value);
}
public IntegerValue compare(ParticularDoubleValue other)
{
return this.value < other.value ? SpecificValueFactory.INTEGER_VALUE_M1 :
this.value == other.value ? SpecificValueFactory.INTEGER_VALUE_0 :
SpecificValueFactory.INTEGER_VALUE_1;
}
// Implementations for Value.
public boolean isParticular()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return super.equals(object) &&
this.value == ((ParticularDoubleValue)object).value;
}
public int hashCode()
{
return super.hashCode() ^
(int)Double.doubleToLongBits(value);
}
public String toString()
{
return value+"d";
}
} proguard4.8/src/proguard/evaluation/value/SpecificDoubleValue.java 0000644 0001750 0001750 00000011226 11736333523 024206 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This DoubleValue represents a specific double value.
*
* @author Eric Lafortune
*/
abstract class SpecificDoubleValue extends DoubleValue
{
// Implementations of unary methods of DoubleValue.
public DoubleValue negate()
{
return new NegatedDoubleValue(this);
}
public IntegerValue convertToInteger()
{
return new ConvertedIntegerValue(this);
}
public LongValue convertToLong()
{
return new ConvertedLongValue(this);
}
public FloatValue convertToFloat()
{
return new ConvertedFloatValue(this);
}
// Implementations of binary methods of DoubleValue.
public DoubleValue generalize(DoubleValue other)
{
return other.generalize(this);
}
public DoubleValue add(DoubleValue other)
{
return other.add(this);
}
public DoubleValue subtract(DoubleValue other)
{
return other.subtractFrom(this);
}
public DoubleValue subtractFrom(DoubleValue other)
{
return other.subtract(this);
}
public DoubleValue multiply(DoubleValue other)
{
return other.multiply(this);
}
public DoubleValue divide(DoubleValue other)
{
return other.divideOf(this);
}
public DoubleValue divideOf(DoubleValue other)
{
return other.divide(this);
}
public DoubleValue remainder(DoubleValue other)
{
return other.remainderOf(this);
}
public DoubleValue remainderOf(DoubleValue other)
{
return other.remainder(this);
}
public IntegerValue compare(DoubleValue other)
{
return other.compareReverse(this);
}
// Implementations of binary DoubleValue methods with SpecificDoubleValue
// arguments.
public DoubleValue generalize(SpecificDoubleValue other)
{
return this.equals(other) ? this : ValueFactory.DOUBLE_VALUE;
}
public DoubleValue add(SpecificDoubleValue other)
{
return new CompositeDoubleValue(this, CompositeDoubleValue.ADD, other);
}
public DoubleValue subtract(SpecificDoubleValue other)
{
return new CompositeDoubleValue(this, CompositeDoubleValue.SUBTRACT, other);
}
public DoubleValue subtractFrom(SpecificDoubleValue other)
{
return new CompositeDoubleValue(other, CompositeDoubleValue.SUBTRACT, this);
}
public DoubleValue multiply(SpecificDoubleValue other)
{
return new CompositeDoubleValue(this, CompositeDoubleValue.MULTIPLY, other);
}
public DoubleValue divide(SpecificDoubleValue other)
{
return new CompositeDoubleValue(this, CompositeDoubleValue.DIVIDE, other);
}
public DoubleValue divideOf(SpecificDoubleValue other)
{
return new CompositeDoubleValue(other, CompositeDoubleValue.DIVIDE, this);
}
public DoubleValue remainder(SpecificDoubleValue other)
{
return new CompositeDoubleValue(this, CompositeDoubleValue.REMAINDER, other);
}
public DoubleValue remainderOf(SpecificDoubleValue other)
{
return new CompositeDoubleValue(other, CompositeDoubleValue.REMAINDER, this);
}
public IntegerValue compare(SpecificDoubleValue other)
{
return ValueFactory.INTEGER_VALUE;
// Not handling NaN properly.
//return this.equals(other) ?
// SpecificValueFactory.INTEGER_VALUE_0 :
// new ComparisonValue(this, other);
}
// Implementations for Value.
public boolean isSpecific()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
}
proguard4.8/src/proguard/evaluation/value/LongValue.java 0000644 0001750 0001750 00000032426 11736333523 022232 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.ClassConstants;
/**
* This class represents a partially evaluated long value.
*
* @author Eric Lafortune
*/
public abstract class LongValue extends Category2Value
{
/**
* Returns the specific long value, if applicable.
*/
public long value()
{
return 0;
}
// Basic unary methods.
/**
* Returns the negated value of this LongValue.
*/
public abstract LongValue negate();
/**
* Converts this LongValue to an IntegerValue.
*/
public abstract IntegerValue convertToInteger();
/**
* Converts this LongValue to a FloatValue.
*/
public abstract FloatValue convertToFloat();
/**
* Converts this LongValue to a DoubleValue.
*/
public abstract DoubleValue convertToDouble();
// Basic binary methods.
/**
* Returns the generalization of this LongValue and the given other
* LongValue.
*/
public LongValue generalize(LongValue other)
{
return other.generalize(this);
}
/**
* Returns the sum of this LongValue and the given LongValue.
*/
public LongValue add(LongValue other)
{
return other.add(this);
}
/**
* Returns the difference of this LongValue and the given LongValue.
*/
public LongValue subtract(LongValue other)
{
return other.subtractFrom(this);
}
/**
* Returns the difference of the given LongValue and this LongValue.
*/
public LongValue subtractFrom(LongValue other)
{
return other.subtract(this);
}
/**
* Returns the product of this LongValue and the given LongValue.
*/
public LongValue multiply(LongValue other)
throws ArithmeticException
{
return other.multiply(this);
}
/**
* Returns the quotient of this LongValue and the given LongValue.
*/
public LongValue divide(LongValue other)
throws ArithmeticException
{
return other.divideOf(this);
}
/**
* Returns the quotient of the given LongValue and this LongValue.
*/
public LongValue divideOf(LongValue other)
throws ArithmeticException
{
return other.divide(this);
}
/**
* Returns the remainder of this LongValue divided by the given
* LongValue.
*/
public LongValue remainder(LongValue other)
throws ArithmeticException
{
return other.remainderOf(this);
}
/**
* Returns the remainder of the given LongValue divided by this
* LongValue.
*/
public LongValue remainderOf(LongValue other)
throws ArithmeticException
{
return other.remainder(this);
}
/**
* Returns this LongValue, shifted left by the given IntegerValue.
*/
public LongValue shiftLeft(IntegerValue other)
{
return other.shiftLeftOf(this);
}
/**
* Returns this LongValue, shifted right by the given IntegerValue.
*/
public LongValue shiftRight(IntegerValue other)
{
return other.shiftRightOf(this);
}
/**
* Returns this unsigned LongValue, shifted left by the given
* IntegerValue.
*/
public LongValue unsignedShiftRight(IntegerValue other)
{
return other.unsignedShiftRightOf(this);
}
/**
* Returns the logical and of this LongValue and the given
* LongValue.
*/
public LongValue and(LongValue other)
{
return other.and(this);
}
/**
* Returns the logical or of this LongValue and the given
* LongValue.
*/
public LongValue or(LongValue other)
{
return other.or(this);
}
/**
* Returns the logical xor of this LongValue and the given
* LongValue.
*/
public LongValue xor(LongValue other)
{
return other.xor(this);
}
/**
* Returns an IntegerValue with value -1, 0, or 1, if this LongValue is
* less than, equal to, or greater than the given LongValue, respectively.
*/
public IntegerValue compare(LongValue other)
{
return other.compareReverse(this);
}
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this LongValue is
* less than, equal to, or greater than the given LongValue, respectively.
*/
public final IntegerValue compareReverse(LongValue other)
{
return compare(other).negate();
}
// Similar binary methods, but this time with more specific arguments.
/**
* Returns the generalization of this LongValue and the given other
* SpecificLongValue.
*/
public LongValue generalize(SpecificLongValue other)
{
return this;
}
/**
* Returns the sum of this LongValue and the given SpecificLongValue.
*/
public LongValue add(SpecificLongValue other)
{
return this;
}
/**
* Returns the difference of this LongValue and the given SpecificLongValue.
*/
public LongValue subtract(SpecificLongValue other)
{
return this;
}
/**
* Returns the difference of the given SpecificLongValue and this LongValue.
*/
public LongValue subtractFrom(SpecificLongValue other)
{
return this;
}
/**
* Returns the product of this LongValue and the given SpecificLongValue.
*/
public LongValue multiply(SpecificLongValue other)
{
return this;
}
/**
* Returns the quotient of this LongValue and the given
* SpecificLongValue.
*/
public LongValue divide(SpecificLongValue other)
{
return this;
}
/**
* Returns the quotient of the given SpecificLongValue and this
* LongValue.
*/
public LongValue divideOf(SpecificLongValue other)
{
return this;
}
/**
* Returns the remainder of this LongValue divided by the given
* SpecificLongValue.
*/
public LongValue remainder(SpecificLongValue other)
{
return this;
}
/**
* Returns the remainder of the given SpecificLongValue divided by this
* LongValue.
*/
public LongValue remainderOf(SpecificLongValue other)
{
return this;
}
/**
* Returns this LongValue, shifted left by the given SpecificLongValue.
*/
public LongValue shiftLeft(SpecificLongValue other)
{
return this;
}
/**
* Returns this LongValue, shifted right by the given SpecificLongValue.
*/
public LongValue shiftRight(SpecificLongValue other)
{
return this;
}
/**
* Returns this unsigned LongValue, shifted right by the given
* SpecificLongValue.
*/
public LongValue unsignedShiftRight(SpecificLongValue other)
{
return this;
}
/**
* Returns the logical and of this LongValue and the given
* SpecificLongValue.
*/
public LongValue and(SpecificLongValue other)
{
return this;
}
/**
* Returns the logical or of this LongValue and the given
* SpecificLongValue.
*/
public LongValue or(SpecificLongValue other)
{
return this;
}
/**
* Returns the logical xor of this LongValue and the given
* SpecificLongValue.
*/
public LongValue xor(SpecificLongValue other)
{
return this;
}
/**
* Returns an IntegerValue with value -1, 0, or 1, if this LongValue is
* less than, equal to, or greater than the given SpecificLongValue,
* respectively.
*/
public IntegerValue compare(SpecificLongValue other)
{
return new ComparisonValue(this, other);
}
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this LongValue is
* less than, equal to, or greater than the given SpecificLongValue,
* respectively.
*/
public final IntegerValue compareReverse(SpecificLongValue other)
{
return compare(other).negate();
}
// Similar binary methods, but this time with particular arguments.
/**
* Returns the generalization of this LongValue and the given other
* ParticularLongValue.
*/
public LongValue generalize(ParticularLongValue other)
{
return generalize((SpecificLongValue)other);
}
/**
* Returns the sum of this LongValue and the given ParticularLongValue.
*/
public LongValue add(ParticularLongValue other)
{
return add((SpecificLongValue)other);
}
/**
* Returns the difference of this LongValue and the given ParticularLongValue.
*/
public LongValue subtract(ParticularLongValue other)
{
return subtract((SpecificLongValue)other);
}
/**
* Returns the difference of the given ParticularLongValue and this LongValue.
*/
public LongValue subtractFrom(ParticularLongValue other)
{
return subtractFrom((SpecificLongValue)other);
}
/**
* Returns the product of this LongValue and the given ParticularLongValue.
*/
public LongValue multiply(ParticularLongValue other)
{
return multiply((SpecificLongValue)other);
}
/**
* Returns the quotient of this LongValue and the given
* ParticularLongValue.
*/
public LongValue divide(ParticularLongValue other)
{
return divide((SpecificLongValue)other);
}
/**
* Returns the quotient of the given ParticularLongValue and this
* LongValue.
*/
public LongValue divideOf(ParticularLongValue other)
{
return divideOf((SpecificLongValue)other);
}
/**
* Returns the remainder of this LongValue divided by the given
* ParticularLongValue.
*/
public LongValue remainder(ParticularLongValue other)
{
return remainder((SpecificLongValue)other);
}
/**
* Returns the remainder of the given ParticularLongValue divided by this
* LongValue.
*/
public LongValue remainderOf(ParticularLongValue other)
{
return remainderOf((SpecificLongValue)other);
}
/**
* Returns this LongValue, shifted left by the given ParticularIntegerValue.
*/
public LongValue shiftLeft(ParticularIntegerValue other)
{
return shiftLeft((SpecificIntegerValue)other);
}
/**
* Returns this LongValue, shifted right by the given ParticularIntegerValue.
*/
public LongValue shiftRight(ParticularIntegerValue other)
{
return shiftRight((SpecificIntegerValue)other);
}
/**
* Returns this unsigned LongValue, shifted right by the given
* ParticularIntegerValue.
*/
public LongValue unsignedShiftRight(ParticularIntegerValue other)
{
return unsignedShiftRight((SpecificIntegerValue)other);
}
/**
* Returns the logical and of this LongValue and the given
* ParticularLongValue.
*/
public LongValue and(ParticularLongValue other)
{
return and((SpecificLongValue)other);
}
/**
* Returns the logical or of this LongValue and the given
* ParticularLongValue.
*/
public LongValue or(ParticularLongValue other)
{
return or((SpecificLongValue)other);
}
/**
* Returns the logical xor of this LongValue and the given
* ParticularLongValue.
*/
public LongValue xor(ParticularLongValue other)
{
return xor((SpecificLongValue)other);
}
/**
* Returns an IntegerValue with value -1, 0, or 1, if this LongValue is
* less than, equal to, or greater than the given ParticularLongValue,
* respectively.
*/
public IntegerValue compare(ParticularLongValue other)
{
return compare((SpecificLongValue)other);
}
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this LongValue is
* less than, equal to, or greater than the given ParticularLongValue,
* respectively.
*/
public final IntegerValue compareReverse(ParticularLongValue other)
{
return compare(other).negate();
}
// Implementations for Value.
public final LongValue longValue()
{
return this;
}
public final Value generalize(Value other)
{
return this.generalize(other.longValue());
}
public final int computationalType()
{
return TYPE_LONG;
}
public final String internalType()
{
return String.valueOf(ClassConstants.INTERNAL_TYPE_INT);
}
}
proguard4.8/src/proguard/evaluation/value/CompositeIntegerValue.java 0000644 0001750 0001750 00000005742 11736333523 024614 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents the result of a binary operation on two integer
* values.
*
* @author Eric Lafortune
*/
final class CompositeIntegerValue extends SpecificIntegerValue
{
public static final byte ADD = '+';
public static final byte SUBTRACT = '-';
public static final byte MULTIPLY = '*';
public static final byte DIVIDE = '/';
public static final byte REMAINDER = '%';
public static final byte SHIFT_LEFT = '<';
public static final byte SHIFT_RIGHT = '>';
public static final byte UNSIGNED_SHIFT_RIGHT = '}';
public static final byte AND = '&';
public static final byte OR = '|';
public static final byte XOR = '^';
private final IntegerValue integerValue1;
private final byte operation;
private final IntegerValue integerValue2;
/**
* Creates a new composite integer value of the two given integer values
* and the given operation.
*/
public CompositeIntegerValue(IntegerValue integerValue1,
byte operation,
IntegerValue integerValue2)
{
this.integerValue1 = integerValue1;
this.operation = operation;
this.integerValue2 = integerValue2;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.integerValue1.equals(((CompositeIntegerValue)object).integerValue1) &&
this.operation == ((CompositeIntegerValue)object).operation &&
this.integerValue2.equals(((CompositeIntegerValue)object).integerValue2);
}
public int hashCode()
{
return super.hashCode() ^
integerValue1.hashCode() ^
integerValue2.hashCode();
}
public String toString()
{
return "("+integerValue1+((char)operation)+integerValue2+")";
}
} proguard4.8/src/proguard/evaluation/value/ValueFactory.java 0000644 0001750 0001750 00000016205 11736333523 022737 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.*;
import proguard.classfile.util.ClassUtil;
/**
* This class provides methods to create and reuse Value objects.
*
* @author Eric Lafortune
*/
public class ValueFactory
{
// Shared copies of Value objects, to avoid creating a lot of objects.
static final IntegerValue INTEGER_VALUE = new UnknownIntegerValue();
static final LongValue LONG_VALUE = new UnknownLongValue();
static final FloatValue FLOAT_VALUE = new UnknownFloatValue();
static final DoubleValue DOUBLE_VALUE = new UnknownDoubleValue();
static final ReferenceValue REFERENCE_VALUE_NULL = new ReferenceValue(null, null, true);
static final ReferenceValue REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL = new ReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT, null, true);
static final ReferenceValue REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL = new ReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT, null, false);
/**
* Creates a new Value of the given type.
* The type must be a fully specified internal type for primitives, classes,
* or arrays.
*/
public Value createValue(String type, Clazz referencedClass, boolean mayBeNull)
{
switch (type.charAt(0))
{
case ClassConstants.INTERNAL_TYPE_VOID: return null;
case ClassConstants.INTERNAL_TYPE_BOOLEAN:
case ClassConstants.INTERNAL_TYPE_BYTE:
case ClassConstants.INTERNAL_TYPE_CHAR:
case ClassConstants.INTERNAL_TYPE_SHORT:
case ClassConstants.INTERNAL_TYPE_INT: return createIntegerValue();
case ClassConstants.INTERNAL_TYPE_LONG: return createLongValue();
case ClassConstants.INTERNAL_TYPE_FLOAT: return createFloatValue();
case ClassConstants.INTERNAL_TYPE_DOUBLE: return createDoubleValue();
default: return createReferenceValue(ClassUtil.isInternalArrayType(type) ?
type :
ClassUtil.internalClassNameFromClassType(type),
referencedClass,
mayBeNull);
}
}
/**
* Creates a new IntegerValue with an undefined value.
*/
public IntegerValue createIntegerValue()
{
return INTEGER_VALUE;
}
/**
* Creates a new IntegerValue with a given particular value.
*/
public IntegerValue createIntegerValue(int value)
{
return createIntegerValue();
}
/**
* Creates a new LongValue with an undefined value.
*/
public LongValue createLongValue()
{
return LONG_VALUE;
}
/**
* Creates a new LongValue with a given particular value.
*/
public LongValue createLongValue(long value)
{
return createLongValue();
}
/**
* Creates a new FloatValue with an undefined value.
*/
public FloatValue createFloatValue()
{
return FLOAT_VALUE;
}
/**
* Creates a new FloatValue with a given particular value.
*/
public FloatValue createFloatValue(float value)
{
return createFloatValue();
}
/**
* Creates a new DoubleValue with an undefined value.
*/
public DoubleValue createDoubleValue()
{
return DOUBLE_VALUE;
}
/**
* Creates a new DoubleValue with a given particular value.
*/
public DoubleValue createDoubleValue(double value)
{
return createDoubleValue();
}
/**
* Creates a new ReferenceValue that represents null
.
*/
public ReferenceValue createReferenceValueNull()
{
return REFERENCE_VALUE_NULL;
}
/**
* Creates a new ReferenceValue of the given type. The type must be an
* internal class name or an array type. If the type is null
,
* the ReferenceValue represents null
.
*/
public ReferenceValue createReferenceValue(String type,
Clazz referencedClass,
boolean mayBeNull)
{
return type == null ? REFERENCE_VALUE_NULL :
!type.equals(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT) ? new ReferenceValue(type, referencedClass, mayBeNull) :
mayBeNull ? REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL;
}
/**
* Creates a new ReferenceValue for arrays of the given type and length.
* The type must be a fully specified internal type for primitives, classes,
* or arrays.
*/
public ReferenceValue createArrayReferenceValue(String type,
Clazz referencedClass,
IntegerValue arrayLength)
{
return createArrayReferenceValue(type,
referencedClass,
arrayLength,
createValue(type, referencedClass, false));
}
/**
* Creates a new ReferenceValue for arrays of the given type and length,
* containing the given element. The type must be a fully specified internal
* type for primitives, classes, or arrays.
*/
public ReferenceValue createArrayReferenceValue(String type,
Clazz referencedClass,
IntegerValue arrayLength,
Value elementValue)
{
return createReferenceValue(ClassConstants.INTERNAL_TYPE_ARRAY + type,
referencedClass,
false);
}
}
proguard4.8/src/proguard/evaluation/value/DoubleValue.java 0000644 0001750 0001750 00000023061 11736333523 022540 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.ClassConstants;
/**
* This class represents a partially evaluated double value.
*
* @author Eric Lafortune
*/
public abstract class DoubleValue extends Category2Value
{
/**
* Returns the specific double value, if applicable.
*/
public double value()
{
return 0.0;
}
// Basic unary methods.
/**
* Returns the negated value of this DoubleValue.
*/
public abstract DoubleValue negate();
/**
* Converts this DoubleValue to an IntegerValue.
*/
public abstract IntegerValue convertToInteger();
/**
* Converts this DoubleValue to a LongValue.
*/
public abstract LongValue convertToLong();
/**
* Converts this DoubleValue to a FloatValue.
*/
public abstract FloatValue convertToFloat();
// Basic binary methods.
/**
* Returns the generalization of this DoubleValue and the given other
* DoubleValue.
*/
public abstract DoubleValue generalize(DoubleValue other);
/**
* Returns the sum of this DoubleValue and the given DoubleValue.
*/
public abstract DoubleValue add(DoubleValue other);
/**
* Returns the difference of this DoubleValue and the given DoubleValue.
*/
public abstract DoubleValue subtract(DoubleValue other);
/**
* Returns the difference of the given DoubleValue and this DoubleValue.
*/
public abstract DoubleValue subtractFrom(DoubleValue other);
/**
* Returns the product of this DoubleValue and the given DoubleValue.
*/
public abstract DoubleValue multiply(DoubleValue other);
/**
* Returns the quotient of this DoubleValue and the given DoubleValue.
*/
public abstract DoubleValue divide(DoubleValue other);
/**
* Returns the quotient of the given DoubleValue and this DoubleValue.
*/
public abstract DoubleValue divideOf(DoubleValue other);
/**
* Returns the remainder of this DoubleValue divided by the given DoubleValue.
*/
public abstract DoubleValue remainder(DoubleValue other);
/**
* Returns the remainder of the given DoubleValue divided by this DoubleValue.
*/
public abstract DoubleValue remainderOf(DoubleValue other);
/**
* Returns an IntegerValue with value -1, 0, or 1, if this DoubleValue is
* less than, equal to, or greater than the given DoubleValue, respectively.
*/
public abstract IntegerValue compare(DoubleValue other);
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this DoubleValue is
* less than, equal to, or greater than the given DoubleValue, respectively.
*/
public final IntegerValue compareReverse(DoubleValue other)
{
return compare(other).negate();
}
// Similar binary methods, but this time with more specific arguments.
/**
* Returns the generalization of this DoubleValue and the given other
* SpecificDoubleValue.
*/
public DoubleValue generalize(SpecificDoubleValue other)
{
return generalize((DoubleValue)other);
}
/**
* Returns the sum of this DoubleValue and the given SpecificDoubleValue.
*/
public DoubleValue add(SpecificDoubleValue other)
{
return add((DoubleValue)other);
}
/**
* Returns the difference of this DoubleValue and the given SpecificDoubleValue.
*/
public DoubleValue subtract(SpecificDoubleValue other)
{
return subtract((DoubleValue)other);
}
/**
* Returns the difference of the given SpecificDoubleValue and this DoubleValue.
*/
public DoubleValue subtractFrom(SpecificDoubleValue other)
{
return subtractFrom((DoubleValue)other);
}
/**
* Returns the product of this DoubleValue and the given SpecificDoubleValue.
*/
public DoubleValue multiply(SpecificDoubleValue other)
{
return multiply((DoubleValue)other);
}
/**
* Returns the quotient of this DoubleValue and the given SpecificDoubleValue.
*/
public DoubleValue divide(SpecificDoubleValue other)
{
return divide((DoubleValue)other);
}
/**
* Returns the quotient of the given SpecificDoubleValue and this
* DoubleValue.
*/
public DoubleValue divideOf(SpecificDoubleValue other)
{
return divideOf((DoubleValue)other);
}
/**
* Returns the remainder of this DoubleValue divided by the given
* SpecificDoubleValue.
*/
public DoubleValue remainder(SpecificDoubleValue other)
{
return remainder((DoubleValue)other);
}
/**
* Returns the remainder of the given SpecificDoubleValue and this
* DoubleValue.
*/
public DoubleValue remainderOf(SpecificDoubleValue other)
{
return remainderOf((DoubleValue)other);
}
/**
* Returns an IntegerValue with value -1, 0, or 1, if this DoubleValue is
* less than, equal to, or greater than the given SpecificDoubleValue,
* respectively.
*/
public IntegerValue compare(SpecificDoubleValue other)
{
return compare((DoubleValue)other);
}
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this DoubleValue is
* less than, equal to, or greater than the given SpecificDoubleValue,
* respectively.
*/
public final IntegerValue compareReverse(SpecificDoubleValue other)
{
return compare(other).negate();
}
// Similar binary methods, but this time with particular arguments.
/**
* Returns the generalization of this DoubleValue and the given other
* ParticularDoubleValue.
*/
public DoubleValue generalize(ParticularDoubleValue other)
{
return generalize((SpecificDoubleValue)other);
}
/**
* Returns the sum of this DoubleValue and the given ParticularDoubleValue.
*/
public DoubleValue add(ParticularDoubleValue other)
{
return add((SpecificDoubleValue)other);
}
/**
* Returns the difference of this DoubleValue and the given ParticularDoubleValue.
*/
public DoubleValue subtract(ParticularDoubleValue other)
{
return subtract((SpecificDoubleValue)other);
}
/**
* Returns the difference of the given ParticularDoubleValue and this DoubleValue.
*/
public DoubleValue subtractFrom(ParticularDoubleValue other)
{
return subtractFrom((SpecificDoubleValue)other);
}
/**
* Returns the product of this DoubleValue and the given ParticularDoubleValue.
*/
public DoubleValue multiply(ParticularDoubleValue other)
{
return multiply((SpecificDoubleValue)other);
}
/**
* Returns the quotient of this DoubleValue and the given ParticularDoubleValue.
*/
public DoubleValue divide(ParticularDoubleValue other)
{
return divide((SpecificDoubleValue)other);
}
/**
* Returns the quotient of the given ParticularDoubleValue and this
* DoubleValue.
*/
public DoubleValue divideOf(ParticularDoubleValue other)
{
return divideOf((SpecificDoubleValue)other);
}
/**
* Returns the remainder of this DoubleValue divided by the given
* ParticularDoubleValue.
*/
public DoubleValue remainder(ParticularDoubleValue other)
{
return remainder((SpecificDoubleValue)other);
}
/**
* Returns the remainder of the given ParticularDoubleValue and this
* DoubleValue.
*/
public DoubleValue remainderOf(ParticularDoubleValue other)
{
return remainderOf((SpecificDoubleValue)other);
}
/**
* Returns an IntegerValue with value -1, 0, or 1, if this DoubleValue is
* less than, equal to, or greater than the given ParticularDoubleValue,
* respectively.
*/
public IntegerValue compare(ParticularDoubleValue other)
{
return compare((SpecificDoubleValue)other);
}
// Derived binary methods.
/**
* Returns an IntegerValue with value 1, 0, or -1, if this DoubleValue is
* less than, equal to, or greater than the given ParticularDoubleValue,
* respectively.
*/
public final IntegerValue compareReverse(ParticularDoubleValue other)
{
return compare(other).negate();
}
// Implementations for Value.
public final DoubleValue doubleValue()
{
return this;
}
public final Value generalize(Value other)
{
return this.generalize(other.doubleValue());
}
public final int computationalType()
{
return TYPE_DOUBLE;
}
public final String internalType()
{
return String.valueOf(ClassConstants.INTERNAL_TYPE_DOUBLE);
}
}
proguard4.8/src/proguard/evaluation/value/ConvertedCharacterValue.java 0000644 0001750 0001750 00000003370 11736333523 025075 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents a character value that is converted from an
* integer value.
*
* @author Eric Lafortune
*/
final class ConvertedCharacterValue extends SpecificIntegerValue
{
private final IntegerValue value;
/**
* Creates a new converted character value of the given integer value.
*/
public ConvertedCharacterValue(IntegerValue value)
{
this.value = value;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.value.equals(((ConvertedCharacterValue)object).value);
}
public int hashCode()
{
return super.hashCode() ^
value.hashCode();
}
public String toString()
{
return "(char)("+value+")";
}
} proguard4.8/src/proguard/evaluation/value/SpecificLongValue.java 0000644 0001750 0001750 00000014614 11736333523 023677 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This LongValue represents a specific long value.
*
* @author Eric Lafortune
*/
abstract class SpecificLongValue extends LongValue
{
// Implementations of unary methods of LongValue.
public LongValue negate()
{
return new NegatedLongValue(this);
}
public IntegerValue convertToInteger()
{
return new ConvertedIntegerValue(this);
}
public FloatValue convertToFloat()
{
return new ConvertedFloatValue(this);
}
public DoubleValue convertToDouble()
{
return new ConvertedDoubleValue(this);
}
// Implementations of binary methods of LongValue.
public LongValue generalize(LongValue other)
{
return other.generalize(this);
}
public LongValue add(LongValue other)
{
return other.add(this);
}
public LongValue subtract(LongValue other)
{
return other.subtractFrom(this);
}
public LongValue subtractFrom(LongValue other)
{
return other.subtract(this);
}
public LongValue multiply(LongValue other)
{
return other.multiply(this);
}
public LongValue divide(LongValue other)
throws ArithmeticException
{
return other.divideOf(this);
}
public LongValue divideOf(LongValue other)
throws ArithmeticException
{
return other.divide(this);
}
public LongValue remainder(LongValue other)
throws ArithmeticException
{
return other.remainderOf(this);
}
public LongValue remainderOf(LongValue other)
throws ArithmeticException
{
return other.remainder(this);
}
public LongValue shiftLeft(IntegerValue other)
{
return other.shiftLeftOf(this);
}
public LongValue shiftRight(IntegerValue other)
{
return other.shiftRightOf(this);
}
public LongValue unsignedShiftRight(IntegerValue other)
{
return other.unsignedShiftRightOf(this);
}
public LongValue and(LongValue other)
{
return other.and(this);
}
public LongValue or(LongValue other)
{
return other.or(this);
}
public LongValue xor(LongValue other)
{
return other.xor(this);
}
public IntegerValue compare(LongValue other)
{
return other.compareReverse(this);
}
// Implementations of binary LongValue methods with SpecificLongValue
// arguments.
public LongValue generalize(SpecificLongValue other)
{
return this.equals(other) ? this : ValueFactory.LONG_VALUE;
}
public LongValue add(SpecificLongValue other)
{
return new CompositeLongValue(this, CompositeLongValue.ADD, other);
}
public LongValue subtract(SpecificLongValue other)
{
return this.equals(other) ?
SpecificValueFactory.LONG_VALUE_0 :
new CompositeLongValue(this, CompositeLongValue.SUBTRACT, other);
}
public LongValue subtractFrom(SpecificLongValue other)
{
return this.equals(other) ?
SpecificValueFactory.LONG_VALUE_0 :
new CompositeLongValue(other, CompositeLongValue.SUBTRACT, this);
}
public LongValue multiply(SpecificLongValue other)
{
return new CompositeLongValue(this, CompositeLongValue.MULTIPLY, other);
}
public LongValue divide(SpecificLongValue other)
throws ArithmeticException
{
return new CompositeLongValue(this, CompositeLongValue.DIVIDE, other);
}
public LongValue divideOf(SpecificLongValue other)
throws ArithmeticException
{
return new CompositeLongValue(other, CompositeLongValue.DIVIDE, this);
}
public LongValue remainder(SpecificLongValue other)
throws ArithmeticException
{
return new CompositeLongValue(this, CompositeLongValue.REMAINDER, other);
}
public LongValue remainderOf(SpecificLongValue other)
throws ArithmeticException
{
return new CompositeLongValue(other, CompositeLongValue.REMAINDER, this);
}
public LongValue shiftLeft(SpecificLongValue other)
{
return new CompositeLongValue(this, CompositeLongValue.SHIFT_LEFT, other);
}
public LongValue shiftRight(SpecificLongValue other)
{
return new CompositeLongValue(this, CompositeLongValue.SHIFT_RIGHT, other);
}
public LongValue unsignedShiftRight(SpecificLongValue other)
{
return new CompositeLongValue(this, CompositeLongValue.UNSIGNED_SHIFT_RIGHT, other);
}
public LongValue and(SpecificLongValue other)
{
return this.equals(other) ?
this :
new CompositeLongValue(other, CompositeLongValue.AND, this);
}
public LongValue or(SpecificLongValue other)
{
return this.equals(other) ?
this :
new CompositeLongValue(other, CompositeLongValue.OR, this);
}
public LongValue xor(SpecificLongValue other)
{
return this.equals(other) ?
SpecificValueFactory.LONG_VALUE_0 :
new CompositeLongValue(other, CompositeLongValue.XOR, this);
}
public IntegerValue compare(SpecificLongValue other)
{
return new ComparisonValue(this, other);
}
// Implementations for Value.
public boolean isSpecific()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
}
proguard4.8/src/proguard/evaluation/value/SpecificIntegerValue.java 0000644 0001750 0001750 00000022012 11736333523 024364 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents a specific integer value.
*
* @author Eric Lafortune
*/
abstract class SpecificIntegerValue extends IntegerValue
{
// Implementations of unary methods of IntegerValue.
public IntegerValue negate()
{
return new NegatedIntegerValue(this);
}
public IntegerValue convertToByte()
{
return new ConvertedByteValue(this);
}
public IntegerValue convertToCharacter()
{
return new ConvertedCharacterValue(this);
}
public IntegerValue convertToShort()
{
return new ConvertedShortValue(this);
}
public LongValue convertToLong()
{
return new ConvertedLongValue(this);
}
public FloatValue convertToFloat()
{
return new ConvertedFloatValue(this);
}
public DoubleValue convertToDouble()
{
return new ConvertedDoubleValue(this);
}
// Implementations of binary methods of IntegerValue.
public IntegerValue generalize(IntegerValue other)
{
return other.generalize(this);
}
public IntegerValue add(IntegerValue other)
{
return other.add(this);
}
public IntegerValue subtract(IntegerValue other)
{
return other.subtractFrom(this);
}
public IntegerValue subtractFrom(IntegerValue other)
{
return other.subtract(this);
}
public IntegerValue multiply(IntegerValue other)
{
return other.multiply(this);
}
public IntegerValue divide(IntegerValue other)
throws ArithmeticException
{
return other.divideOf(this);
}
public IntegerValue divideOf(IntegerValue other)
throws ArithmeticException
{
return other.divide(this);
}
public IntegerValue remainder(IntegerValue other)
throws ArithmeticException
{
return other.remainderOf(this);
}
public IntegerValue remainderOf(IntegerValue other)
throws ArithmeticException
{
return other.remainder(this);
}
public IntegerValue shiftLeft(IntegerValue other)
{
return other.shiftLeftOf(this);
}
public IntegerValue shiftLeftOf(IntegerValue other)
{
return other.shiftLeft(this);
}
public IntegerValue shiftRight(IntegerValue other)
{
return other.shiftRightOf(this);
}
public IntegerValue shiftRightOf(IntegerValue other)
{
return other.shiftRight(this);
}
public IntegerValue unsignedShiftRight(IntegerValue other)
{
return other.unsignedShiftRightOf(this);
}
public IntegerValue unsignedShiftRightOf(IntegerValue other)
{
return other.unsignedShiftRight(this);
}
public LongValue shiftLeftOf(LongValue other)
{
return other.shiftLeft(this);
}
public LongValue shiftRightOf(LongValue other)
{
return other.shiftRight(this);
}
public LongValue unsignedShiftRightOf(LongValue other)
{
return other.unsignedShiftRight(this);
}
public IntegerValue and(IntegerValue other)
{
return other.and(this);
}
public IntegerValue or(IntegerValue other)
{
return other.or(this);
}
public IntegerValue xor(IntegerValue other)
{
return other.xor(this);
}
public int equal(IntegerValue other)
{
return other.equal(this);
}
public int lessThan(IntegerValue other)
{
return other.greaterThan(this);
}
public int lessThanOrEqual(IntegerValue other)
{
return other.greaterThanOrEqual(this);
}
// Implementations of binary IntegerValue methods with SpecificIntegerValue
// arguments.
public IntegerValue generalize(SpecificIntegerValue other)
{
return this.equals(other) ? this : ValueFactory.INTEGER_VALUE;
}
public IntegerValue add(SpecificIntegerValue other)
{
return new CompositeIntegerValue(this, CompositeIntegerValue.ADD, other);
}
public IntegerValue subtract(SpecificIntegerValue other)
{
return this.equals(other) ?
SpecificValueFactory.INTEGER_VALUE_0 :
new CompositeIntegerValue(this, CompositeIntegerValue.SUBTRACT, other);
}
public IntegerValue subtractFrom(SpecificIntegerValue other)
{
return this.equals(other) ?
SpecificValueFactory.INTEGER_VALUE_0 :
new CompositeIntegerValue(other, CompositeIntegerValue.SUBTRACT, this);
}
public IntegerValue multiply(SpecificIntegerValue other)
{
return new CompositeIntegerValue(this, CompositeIntegerValue.MULTIPLY, other);
}
public IntegerValue divide(SpecificIntegerValue other)
throws ArithmeticException
{
return new CompositeIntegerValue(this, CompositeIntegerValue.DIVIDE, other);
}
public IntegerValue divideOf(SpecificIntegerValue other)
throws ArithmeticException
{
return new CompositeIntegerValue(other, CompositeIntegerValue.DIVIDE, this);
}
public IntegerValue remainder(SpecificIntegerValue other)
throws ArithmeticException
{
return new CompositeIntegerValue(this, CompositeIntegerValue.REMAINDER, other);
}
public IntegerValue remainderOf(SpecificIntegerValue other)
throws ArithmeticException
{
return new CompositeIntegerValue(other, CompositeIntegerValue.REMAINDER, this);
}
public IntegerValue shiftLeft(SpecificIntegerValue other)
{
return new CompositeIntegerValue(this, CompositeIntegerValue.SHIFT_LEFT, other);
}
public IntegerValue shiftRight(SpecificIntegerValue other)
{
return new CompositeIntegerValue(this, CompositeIntegerValue.SHIFT_RIGHT, other);
}
public IntegerValue unsignedShiftRight(SpecificIntegerValue other)
{
return new CompositeIntegerValue(this, CompositeIntegerValue.UNSIGNED_SHIFT_RIGHT, other);
}
public IntegerValue shiftLeftOf(SpecificIntegerValue other)
{
return new CompositeIntegerValue(other, CompositeIntegerValue.SHIFT_LEFT, this);
}
public IntegerValue shiftRightOf(SpecificIntegerValue other)
{
return new CompositeIntegerValue(other, CompositeIntegerValue.SHIFT_RIGHT, this);
}
public IntegerValue unsignedShiftRightOf(SpecificIntegerValue other)
{
return new CompositeIntegerValue(other, CompositeIntegerValue.UNSIGNED_SHIFT_RIGHT, this);
}
public LongValue shiftLeftOf(SpecificLongValue other)
{
return new CompositeLongValue(other, CompositeLongValue.SHIFT_LEFT, this);
}
public LongValue shiftRightOf(SpecificLongValue other)
{
return new CompositeLongValue(other, CompositeLongValue.SHIFT_RIGHT, this);
}
public LongValue unsignedShiftRightOf(SpecificLongValue other)
{
return new CompositeLongValue(other, CompositeLongValue.UNSIGNED_SHIFT_RIGHT, this);
}
public IntegerValue and(SpecificIntegerValue other)
{
return this.equals(other) ?
this :
new CompositeIntegerValue(other, CompositeIntegerValue.AND, this);
}
public IntegerValue or(SpecificIntegerValue other)
{
return this.equals(other) ?
this :
new CompositeIntegerValue(other, CompositeIntegerValue.OR, this);
}
public IntegerValue xor(SpecificIntegerValue other)
{
return this.equals(other) ?
SpecificValueFactory.INTEGER_VALUE_0 :
new CompositeIntegerValue(other, CompositeIntegerValue.XOR, this);
}
public int equal(SpecificIntegerValue other)
{
return this.equals(other) ? ALWAYS : MAYBE;
}
public int lessThan(SpecificIntegerValue other)
{
return this.equals(other) ? NEVER : MAYBE;
}
public int lessThanOrEqual(SpecificIntegerValue other)
{
return this.equals(other) ? ALWAYS : MAYBE;
}
// Implementations for Value.
public boolean isSpecific()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
}
proguard4.8/src/proguard/evaluation/value/ConvertedLongValue.java 0000644 0001750 0001750 00000003307 11736333523 024100 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This LongValue represents a long value that is converted from another
* scalar value.
*
* @author Eric Lafortune
*/
final class ConvertedLongValue extends SpecificLongValue
{
private final Value value;
/**
* Creates a new converted long value of the given value.
*/
public ConvertedLongValue(Value value)
{
this.value = value;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.value.equals(((ConvertedLongValue)object).value);
}
public int hashCode()
{
return super.hashCode() ^
value.hashCode();
}
public String toString()
{
return "(long)("+value+")";
}
} proguard4.8/src/proguard/evaluation/value/IdentifiedLongValue.java 0000644 0001750 0001750 00000003601 11736333523 024210 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This LongValue represents a long value that is identified by a unique ID.
*
* @author Eric Lafortune
*/
final class IdentifiedLongValue extends SpecificLongValue
{
private final ValueFactory valuefactory;
private final int id;
/**
* Creates a new long value with the given ID.
*/
public IdentifiedLongValue(ValueFactory valuefactory, int id)
{
this.valuefactory = valuefactory;
this.id = id;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.valuefactory.equals(((IdentifiedLongValue)object).valuefactory) &&
this.id == ((IdentifiedLongValue)object).id;
}
public int hashCode()
{
return super.hashCode() ^
valuefactory.hashCode() ^
id;
}
public String toString()
{
return "l"+id;
}
} proguard4.8/src/proguard/evaluation/value/UnknownDoubleValue.java 0000644 0001750 0001750 00000005205 11736333523 024120 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This class represents a partially evaluated double value.
*
* @author Eric Lafortune
*/
public class UnknownDoubleValue extends DoubleValue
{
// Basic unary methods.
public DoubleValue negate()
{
return this;
}
public IntegerValue convertToInteger()
{
return ValueFactory.INTEGER_VALUE;
}
public LongValue convertToLong()
{
return ValueFactory.LONG_VALUE;
}
public FloatValue convertToFloat()
{
return ValueFactory.FLOAT_VALUE;
}
// Basic binary methods.
public DoubleValue generalize(DoubleValue other)
{
return this;
}
public DoubleValue add(DoubleValue other)
{
return this;
}
public DoubleValue subtract(DoubleValue other)
{
return this;
}
public DoubleValue subtractFrom(DoubleValue other)
{
return this;
}
public DoubleValue multiply(DoubleValue other)
{
return this;
}
public DoubleValue divide(DoubleValue other)
{
return this;
}
public DoubleValue divideOf(DoubleValue other)
{
return this;
}
public DoubleValue remainder(DoubleValue other)
{
return this;
}
public DoubleValue remainderOf(DoubleValue other)
{
return this;
}
public IntegerValue compare(DoubleValue other)
{
return ValueFactory.INTEGER_VALUE;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
public String toString()
{
return "d";
}
} proguard4.8/src/proguard/evaluation/value/ParticularFloatValue.java 0000644 0001750 0001750 00000012407 11736333523 024424 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This FloatValue represents a particular float value.
*
* @author Eric Lafortune
*/
final class ParticularFloatValue extends SpecificFloatValue
{
private final float value;
/**
* Creates a new particular float value.
*/
public ParticularFloatValue(float value)
{
this.value = value;
}
// Implementations for FloatValue.
public float value()
{
return value;
}
// Implementations of unary methods of FloatValue.
public FloatValue negate()
{
return new ParticularFloatValue(-value);
}
public IntegerValue convertToInteger()
{
return new ParticularIntegerValue((int)value);
}
public LongValue convertToLong()
{
return new ParticularLongValue((long)value);
}
public DoubleValue convertToDouble()
{
return new ParticularDoubleValue((float)value);
}
// Implementations of binary methods of FloatValue.
public FloatValue generalize(FloatValue other)
{
return other.generalize(this);
}
public FloatValue add(FloatValue other)
{
// Careful: -0.0 + 0.0 == 0.0
//return value == 0.0 ? other : other.add(this);
return other.add(this);
}
public FloatValue subtract(FloatValue other)
{
// Careful: -0.0 + 0.0 == 0.0
//return value == 0.0 ? other.negate() : other.subtractFrom(this);
return other.subtractFrom(this);
}
public FloatValue subtractFrom(FloatValue other)
{
// Careful: -0.0 + 0.0 == 0.0
//return value == 0.0 ? other : other.subtract(this);
return other.subtract(this);
}
public FloatValue multiply(FloatValue other)
{
return other.multiply(this);
}
public FloatValue divide(FloatValue other)
{
return other.divideOf(this);
}
public FloatValue divideOf(FloatValue other)
{
return other.divide(this);
}
public FloatValue remainder(FloatValue other)
{
return other.remainderOf(this);
}
public FloatValue remainderOf(FloatValue other)
{
return other.remainder(this);
}
public IntegerValue compare(FloatValue other)
{
return other.compareReverse(this);
}
// Implementations of binary FloatValue methods with ParticularFloatValue
// arguments.
public FloatValue generalize(ParticularFloatValue other)
{
return this.value == other.value ? this : ValueFactory.FLOAT_VALUE;
}
public FloatValue add(ParticularFloatValue other)
{
return new ParticularFloatValue(this.value + other.value);
}
public FloatValue subtract(ParticularFloatValue other)
{
return new ParticularFloatValue(this.value - other.value);
}
public FloatValue subtractFrom(ParticularFloatValue other)
{
return new ParticularFloatValue(other.value - this.value);
}
public FloatValue multiply(ParticularFloatValue other)
{
return new ParticularFloatValue(this.value * other.value);
}
public FloatValue divide(ParticularFloatValue other)
{
return new ParticularFloatValue(this.value / other.value);
}
public FloatValue divideOf(ParticularFloatValue other)
{
return new ParticularFloatValue(other.value / this.value);
}
public FloatValue remainder(ParticularFloatValue other)
{
return new ParticularFloatValue(this.value % other.value);
}
public FloatValue remainderOf(ParticularFloatValue other)
{
return new ParticularFloatValue(other.value % this.value);
}
public IntegerValue compare(ParticularFloatValue other)
{
return this.value < other.value ? SpecificValueFactory.INTEGER_VALUE_M1 :
this.value == other.value ? SpecificValueFactory.INTEGER_VALUE_0 :
SpecificValueFactory.INTEGER_VALUE_1;
}
// Implementations for Value.
public boolean isParticular()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return super.equals(object) &&
this.value == ((ParticularFloatValue)object).value;
}
public int hashCode()
{
return super.hashCode() ^
Float.floatToIntBits(value);
}
public String toString()
{
return value+"f";
}
} proguard4.8/src/proguard/evaluation/value/ConvertedDoubleValue.java 0000644 0001750 0001750 00000003327 11736333523 024415 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This DoubleValue represents a double value that is converted from another
* scalar value.
*
* @author Eric Lafortune
*/
final class ConvertedDoubleValue extends SpecificDoubleValue
{
private final Value value;
/**
* Creates a new converted double value of the given value.
*/
public ConvertedDoubleValue(Value value)
{
this.value = value;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.value.equals(((ConvertedDoubleValue)object).value);
}
public int hashCode()
{
return super.hashCode() ^
value.hashCode();
}
public String toString()
{
return "(double)("+value+")";
}
} proguard4.8/src/proguard/evaluation/value/ReferenceValue.java 0000644 0001750 0001750 00000044675 11736333523 023242 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
import proguard.classfile.*;
import proguard.classfile.util.ClassUtil;
import proguard.classfile.visitor.ClassCollector;
import java.util.*;
/**
* This class represents a partially evaluated reference value. It has a type
* and a flag that indicates whether the value could be null
. If
* the type is null
, the value is null
.
*
* @author Eric Lafortune
*/
public class ReferenceValue extends Category1Value
{
private static final boolean DEBUG = false;
protected final String type;
protected final Clazz referencedClass;
protected final boolean mayBeNull;
/**
* Creates a new ReferenceValue.
*/
public ReferenceValue(String type,
Clazz referencedClass,
boolean mayBeNull)
{
this.type = type;
this.referencedClass = referencedClass;
this.mayBeNull = mayBeNull;
}
/**
* Returns the type.
*/
public String getType()
{
return type;
}
/**
* Returns the class that is referenced by the type.
*/
public Clazz getReferencedClass()
{
return referencedClass;
}
// Basic unary methods.
/**
* Returns whether the type is null
.
*/
public int isNull()
{
return type == null ? ALWAYS :
mayBeNull ? MAYBE :
NEVER;
}
/**
* Returns whether the type is an instance of the given type.
*/
public int instanceOf(String otherType, Clazz otherReferencedClass)
{
String thisType = this.type;
// If this type is null, it is never an instance of any class.
if (thisType == null)
{
return NEVER;
}
// Start taking into account the type dimensions.
int thisDimensionCount = ClassUtil.internalArrayTypeDimensionCount(thisType);
int otherDimensionCount = ClassUtil.internalArrayTypeDimensionCount(otherType);
int commonDimensionCount = Math.min(thisDimensionCount, otherDimensionCount);
// Strip any common array prefixes.
thisType = thisType.substring(commonDimensionCount);
otherType = otherType.substring(commonDimensionCount);
// If either stripped type is a primitive type, we can tell right away.
if (commonDimensionCount > 0 &&
(ClassUtil.isInternalPrimitiveType(thisType.charAt(0)) ||
ClassUtil.isInternalPrimitiveType(otherType.charAt(0))))
{
return !thisType.equals(otherType) ? NEVER :
mayBeNull ? MAYBE :
ALWAYS;
}
// Strip the class type prefix and suffix of this type, if any.
if (thisDimensionCount == commonDimensionCount)
{
thisType = ClassUtil.internalClassNameFromClassType(thisType);
}
// Strip the class type prefix and suffix of the other type, if any.
if (otherDimensionCount == commonDimensionCount)
{
otherType = ClassUtil.internalClassNameFromClassType(otherType);
}
// If this type is an array type, and the other type is not
// java.lang.Object, java.lang.Cloneable, or java.io.Serializable,
// this type can never be an instance.
if (thisDimensionCount > otherDimensionCount &&
!ClassUtil.isInternalArrayInterfaceName(otherType))
{
return NEVER;
}
// If the other type is an array type, and this type is not
// java.lang.Object, java.lang.Cloneable, or java.io.Serializable,
// this type can never be an instance.
if (thisDimensionCount < otherDimensionCount &&
!ClassUtil.isInternalArrayInterfaceName(thisType))
{
return NEVER;
}
// If this type may be null, it might not be an instance of any class.
if (mayBeNull)
{
return MAYBE;
}
// If this type is equal to the other type, or if the other type is
// java.lang.Object, this type is always an instance.
if (thisType.equals(otherType) ||
ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT.equals(otherType))
{
return ALWAYS;
}
// If this type is an array type, it's ok.
if (thisDimensionCount > otherDimensionCount)
{
return ALWAYS;
}
// If the other type is an array type, it might be ok.
if (thisDimensionCount < otherDimensionCount)
{
return MAYBE;
}
// If the value extends the type, we're sure.
return referencedClass != null &&
otherReferencedClass != null &&
referencedClass.extendsOrImplements(otherReferencedClass) ?
ALWAYS :
MAYBE;
}
/**
* Returns the length of the array, assuming this type is an array.
*/
public IntegerValue arrayLength(ValueFactory valueFactory)
{
return valueFactory.createIntegerValue();
}
/**
* Returns the value of the array at the given index, assuming this type
* is an array.
*/
public Value arrayLoad(IntegerValue integerValue, ValueFactory valueFactory)
{
return
type == null ? ValueFactory.REFERENCE_VALUE_NULL :
!ClassUtil.isInternalArrayType(type) ? ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
valueFactory.createValue(type.substring(1),
referencedClass,
true);
}
// Basic binary methods.
/**
* Returns the generalization of this ReferenceValue and the given other
* ReferenceValue.
*/
public ReferenceValue generalize(ReferenceValue other)
{
// If both types are identical, the generalization is the same too.
if (this.equals(other))
{
return this;
}
String thisType = this.type;
String otherType = other.type;
// If both types are nul, the generalization is null too.
if (thisType == null && otherType == null)
{
return ValueFactory.REFERENCE_VALUE_NULL;
}
// If this type is null, the generalization is the other type, maybe null.
if (thisType == null)
{
return other.generalizeMayBeNull(true);
}
// If the other type is null, the generalization is this type, maybe null.
if (otherType == null)
{
return this.generalizeMayBeNull(true);
}
boolean mayBeNull = this.mayBeNull || other.mayBeNull;
// If the two types are equal, the generalization remains the same, maybe null.
if (thisType.equals(otherType))
{
return this.generalizeMayBeNull(mayBeNull);
}
// Start taking into account the type dimensions.
int thisDimensionCount = ClassUtil.internalArrayTypeDimensionCount(thisType);
int otherDimensionCount = ClassUtil.internalArrayTypeDimensionCount(otherType);
int commonDimensionCount = Math.min(thisDimensionCount, otherDimensionCount);
if (thisDimensionCount == otherDimensionCount)
{
// See if we can take into account the referenced classes.
Clazz thisReferencedClass = this.referencedClass;
Clazz otherReferencedClass = other.referencedClass;
if (thisReferencedClass != null &&
otherReferencedClass != null)
{
if (thisReferencedClass.extendsOrImplements(otherReferencedClass))
{
return other.generalizeMayBeNull(mayBeNull);
}
if (otherReferencedClass.extendsOrImplements(thisReferencedClass))
{
return this.generalizeMayBeNull(mayBeNull);
}
// Collect the superclasses and interfaces of this class.
Set thisSuperClasses = new HashSet();
thisReferencedClass.hierarchyAccept(false, true, true, false,
new ClassCollector(thisSuperClasses));
int thisSuperClassesCount = thisSuperClasses.size();
if (thisSuperClassesCount == 0 &&
thisReferencedClass.getSuperName() != null)
{
throw new IllegalArgumentException("Can't find any super classes of ["+thisType+"] (not even immediate super class ["+thisReferencedClass.getSuperName()+"])");
}
// Collect the superclasses and interfaces of the other class.
Set otherSuperClasses = new HashSet();
otherReferencedClass.hierarchyAccept(false, true, true, false,
new ClassCollector(otherSuperClasses));
int otherSuperClassesCount = otherSuperClasses.size();
if (otherSuperClassesCount == 0 &&
otherReferencedClass.getSuperName() != null)
{
throw new IllegalArgumentException("Can't find any super classes of ["+otherType+"] (not even immediate super class ["+otherReferencedClass.getSuperName()+"])");
}
if (DEBUG)
{
System.out.println("ReferenceValue.generalize this ["+thisReferencedClass.getName()+"] with other ["+otherReferencedClass.getName()+"]");
System.out.println(" This super classes: "+thisSuperClasses);
System.out.println(" Other super classes: "+otherSuperClasses);
}
// Find the common superclasses.
thisSuperClasses.retainAll(otherSuperClasses);
if (DEBUG)
{
System.out.println(" Common super classes: "+thisSuperClasses);
}
// Find a class that is a subclass of all common superclasses,
// or that at least has the maximum number of common superclasses.
Clazz commonClass = null;
int maximumSuperClassCount = -1;
// Go over all common superclasses to find it. In case of
// multiple subclasses, keep the lowest one alphabetically,
// in order to ensure that the choice is deterministic.
Iterator commonSuperClasses = thisSuperClasses.iterator();
while (commonSuperClasses.hasNext())
{
Clazz commonSuperClass = (Clazz)commonSuperClasses.next();
int superClassCount = superClassCount(commonSuperClass, thisSuperClasses);
if (maximumSuperClassCount < superClassCount ||
(maximumSuperClassCount == superClassCount &&
commonClass != null &&
commonClass.getName().compareTo(commonSuperClass.getName()) > 0))
{
commonClass = commonSuperClass;
maximumSuperClassCount = superClassCount;
}
}
if (commonClass == null)
{
throw new IllegalArgumentException("Can't find common super class of ["+
thisType +"] (with "+thisSuperClassesCount +" known super classes) and ["+
otherType+"] (with "+otherSuperClassesCount+" known super classes)");
}
if (DEBUG)
{
System.out.println(" Best common class: ["+commonClass.getName()+"]");
}
// TODO: Handle more difficult cases, with multiple global subclasses.
return new ReferenceValue(commonDimensionCount == 0 ?
commonClass.getName() :
ClassUtil.internalArrayTypeFromClassName(commonClass.getName(),
commonDimensionCount),
commonClass,
mayBeNull);
}
}
else if (thisDimensionCount > otherDimensionCount)
{
// See if the other type is an interface type of arrays.
if (ClassUtil.isInternalArrayInterfaceName(ClassUtil.internalClassNameFromClassType(otherType)))
{
return other.generalizeMayBeNull(mayBeNull);
}
}
else if (thisDimensionCount < otherDimensionCount)
{
// See if this type is an interface type of arrays.
if (ClassUtil.isInternalArrayInterfaceName(ClassUtil.internalClassNameFromClassType(thisType)))
{
return this.generalizeMayBeNull(mayBeNull);
}
}
// Reduce the common dimension count if either type is an array of
// primitives type of this dimension.
if (commonDimensionCount > 0 &&
(ClassUtil.isInternalPrimitiveType(otherType.charAt(commonDimensionCount))) ||
ClassUtil.isInternalPrimitiveType(thisType.charAt(commonDimensionCount)))
{
commonDimensionCount--;
}
// Fall back on a basic Object or array of Objects type.
return commonDimensionCount == 0 ?
mayBeNull ?
ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL :
new ReferenceValue(ClassUtil.internalArrayTypeFromClassName(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT,
commonDimensionCount),
null,
mayBeNull);
}
/**
* Returns if the number of superclasses of the given class in the given
* set of classes.
*/
private int superClassCount(Clazz subClass, Set classes)
{
int count = 0;
Iterator iterator = classes.iterator();
while (iterator.hasNext())
{
Clazz clazz = (Clazz)iterator.next();
if (subClass.extendsOrImplements(clazz))
{
count++;
}
}
return count;
}
/**
* Returns whether this ReferenceValue is equal to the given other
* ReferenceValue.
* @return NEVER
, MAYBE
, or ALWAYS
.
*/
public int equal(ReferenceValue other)
{
return this.type == null && other.type == null ? ALWAYS : MAYBE;
}
// Derived unary methods.
/**
* Returns whether this ReferenceValue is not null
.
* @return NEVER
, MAYBE
, or ALWAYS
.
*/
public final int isNotNull()
{
return -isNull();
}
/**
* Returns the generalization of this ReferenceValue and the given other
* ReferenceValue.
*/
private ReferenceValue generalizeMayBeNull(boolean mayBeNull)
{
return this.mayBeNull || !mayBeNull ?
this :
new ReferenceValue(this.type, this.referencedClass, true);
}
// Derived binary methods.
/**
* Returns whether this ReferenceValue and the given ReferenceValue are different.
* @return NEVER
, MAYBE
, or ALWAYS
.
*/
public final int notEqual(ReferenceValue other)
{
return -equal(other);
}
// Implementations for Value.
public final ReferenceValue referenceValue()
{
return this;
}
public final Value generalize(Value other)
{
return this.generalize(other.referenceValue());
}
public boolean isParticular()
{
return type == null;
}
public final int computationalType()
{
return TYPE_REFERENCE;
}
public final String internalType()
{
return
type == null ? ClassConstants.INTERNAL_TYPE_JAVA_LANG_OBJECT :
ClassUtil.isInternalArrayType(type) ? type :
ClassConstants.INTERNAL_TYPE_CLASS_START +
type +
ClassConstants.INTERNAL_TYPE_CLASS_END;
}
// Implementations for Object.
public boolean equals(Object object)
{
if (this == object)
{
return true;
}
if (object == null ||
this.getClass() != object.getClass())
{
return false;
}
ReferenceValue other = (ReferenceValue)object;
return this.type == null ? other.type == null :
(this.mayBeNull == other.mayBeNull &&
this.type.equals(other.type));
}
public int hashCode()
{
return this.getClass().hashCode() ^
(type == null ? 0 : type.hashCode() ^ (mayBeNull ? 0 : 1));
}
public String toString()
{
return type == null ?
"null" :
type + (referencedClass == null ? "?" : "") + (mayBeNull ? "" : "!");
}
}
proguard4.8/src/proguard/evaluation/value/ParticularIntegerValue.java 0000644 0001750 0001750 00000022141 11736333523 024750 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents a particular integer value.
*
* @author Eric Lafortune
*/
final class ParticularIntegerValue extends SpecificIntegerValue
{
private final int value;
/**
* Creates a new particular integer value.
*/
public ParticularIntegerValue(int value)
{
this.value = value;
}
// Implementations for IntegerValue.
public int value()
{
return value;
}
// Implementations of unary methods of IntegerValue.
public IntegerValue negate()
{
return new ParticularIntegerValue(-value);
}
public IntegerValue convertToByte()
{
int byteValue = (byte)value;
return byteValue == value ?
this :
new ParticularIntegerValue(byteValue);
}
public IntegerValue convertToCharacter()
{
int charValue = (char)value;
return charValue == value ?
this :
new ParticularIntegerValue(charValue);
}
public IntegerValue convertToShort()
{
int shortValue = (short)value;
return shortValue == value ?
this :
new ParticularIntegerValue(shortValue);
}
public LongValue convertToLong()
{
return new ParticularLongValue((long)value);
}
public FloatValue convertToFloat()
{
return new ParticularFloatValue((float)value);
}
public DoubleValue convertToDouble()
{
return new ParticularDoubleValue((double)value);
}
// Implementations of binary methods of IntegerValue.
public IntegerValue generalize(IntegerValue other)
{
return other.generalize(this);
}
public IntegerValue add(IntegerValue other)
{
return other.add(this);
}
public IntegerValue subtract(IntegerValue other)
{
return other.subtractFrom(this);
}
public IntegerValue subtractFrom(IntegerValue other)
{
return other.subtract(this);
}
public IntegerValue multiply(IntegerValue other)
{
return other.multiply(this);
}
public IntegerValue divide(IntegerValue other)
throws ArithmeticException
{
return other.divideOf(this);
}
public IntegerValue divideOf(IntegerValue other)
throws ArithmeticException
{
return other.divide(this);
}
public IntegerValue remainder(IntegerValue other)
throws ArithmeticException
{
return other.remainderOf(this);
}
public IntegerValue remainderOf(IntegerValue other)
throws ArithmeticException
{
return other.remainder(this);
}
public IntegerValue shiftLeft(IntegerValue other)
{
return other.shiftLeftOf(this);
}
public IntegerValue shiftLeftOf(IntegerValue other)
{
return other.shiftLeft(this);
}
public IntegerValue shiftRight(IntegerValue other)
{
return other.shiftRightOf(this);
}
public IntegerValue shiftRightOf(IntegerValue other)
{
return other.shiftRight(this);
}
public IntegerValue unsignedShiftRight(IntegerValue other)
{
return other.unsignedShiftRightOf(this);
}
public IntegerValue unsignedShiftRightOf(IntegerValue other)
{
return other.unsignedShiftRight(this);
}
public LongValue shiftLeftOf(LongValue other)
{
return other.shiftLeft(this);
}
public LongValue shiftRightOf(LongValue other)
{
return other.shiftRight(this);
}
public LongValue unsignedShiftRightOf(LongValue other)
{
return other.unsignedShiftRight(this);
}
public IntegerValue and(IntegerValue other)
{
return other.and(this);
}
public IntegerValue or(IntegerValue other)
{
return other.or(this);
}
public IntegerValue xor(IntegerValue other)
{
return other.xor(this);
}
public int equal(IntegerValue other)
{
return other.equal(this);
}
public int lessThan(IntegerValue other)
{
return other.greaterThan(this);
}
public int lessThanOrEqual(IntegerValue other)
{
return other.greaterThanOrEqual(this);
}
// Implementations of binary IntegerValue methods with ParticularIntegerValue
// arguments.
public IntegerValue generalize(ParticularIntegerValue other)
{
return generalize((SpecificIntegerValue)other);
}
public IntegerValue add(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value + other.value);
}
public IntegerValue subtract(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value - other.value);
}
public IntegerValue subtractFrom(ParticularIntegerValue other)
{
return new ParticularIntegerValue(other.value - this.value);
}
public IntegerValue multiply(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value * other.value);
}
public IntegerValue divide(ParticularIntegerValue other)
throws ArithmeticException
{
return new ParticularIntegerValue(this.value / other.value);
}
public IntegerValue divideOf(ParticularIntegerValue other)
throws ArithmeticException
{
return new ParticularIntegerValue(other.value / this.value);
}
public IntegerValue remainder(ParticularIntegerValue other)
throws ArithmeticException
{
return new ParticularIntegerValue(this.value % other.value);
}
public IntegerValue remainderOf(ParticularIntegerValue other)
throws ArithmeticException
{
return new ParticularIntegerValue(other.value % this.value);
}
public IntegerValue shiftLeft(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value << other.value);
}
public IntegerValue shiftRight(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value >> other.value);
}
public IntegerValue unsignedShiftRight(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value >>> other.value);
}
public IntegerValue shiftLeftOf(ParticularIntegerValue other)
{
return new ParticularIntegerValue(other.value << this.value);
}
public IntegerValue shiftRightOf(ParticularIntegerValue other)
{
return new ParticularIntegerValue(other.value >> this.value);
}
public IntegerValue unsignedShiftRightOf(ParticularIntegerValue other)
{
return new ParticularIntegerValue(other.value >>> this.value);
}
public LongValue shiftLeftOf(ParticularLongValue other)
{
return new ParticularLongValue(other.value() << this.value);
}
public LongValue shiftRightOf(ParticularLongValue other)
{
return new ParticularLongValue(other.value() >> this.value);
}
public LongValue unsignedShiftRightOf(ParticularLongValue other)
{
return new ParticularLongValue(other.value() >>> this.value);
}
public IntegerValue and(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value & other.value);
}
public IntegerValue or(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value | other.value);
}
public IntegerValue xor(ParticularIntegerValue other)
{
return new ParticularIntegerValue(this.value ^ other.value);
}
public int equal(ParticularIntegerValue other)
{
return this.value == other.value ? ALWAYS : NEVER;
}
public int lessThan(ParticularIntegerValue other)
{
return this.value < other.value ? ALWAYS : NEVER;
}
public int lessThanOrEqual(ParticularIntegerValue other)
{
return this.value <= other.value ? ALWAYS : NEVER;
}
// Implementations for Value.
public boolean isParticular()
{
return true;
}
// Implementations for Object.
public boolean equals(Object object)
{
return super.equals(object) &&
this.value == ((ParticularIntegerValue)object).value;
}
public int hashCode()
{
return this.getClass().hashCode() ^
value;
}
public String toString()
{
return Integer.toString(value);
}
} proguard4.8/src/proguard/evaluation/value/TopValue.java 0000644 0001750 0001750 00000003650 11736333523 022072 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This class represents a partially evaluated top value. A top value is the
* dummy value that takes up the extra space when storing a long value or a
* double value.
*
* @author Eric Lafortune
*/
public class TopValue extends Category1Value
{
// Implementations for Value.
public boolean isSpecific()
{
return true;
}
public boolean isParticular()
{
return true;
}
public final Value generalize(Value other)
{
return this.getClass() == other.getClass() ? this : null;
}
public final int computationalType()
{
return TYPE_TOP;
}
public final String internalType()
{
return null;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
public String toString()
{
return "T";
}
}
proguard4.8/src/proguard/evaluation/value/IdentifiedIntegerValue.java 0000644 0001750 0001750 00000003631 11736333523 024711 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents a integer value that is identified by a unique ID.
*
* @author Eric Lafortune
*/
final class IdentifiedIntegerValue extends SpecificIntegerValue
{
private final ValueFactory valuefactory;
private final int id;
/**
* Creates a new integer value with the given ID.
*/
public IdentifiedIntegerValue(ValueFactory valuefactory, int id)
{
this.valuefactory = valuefactory;
this.id = id;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.valuefactory.equals(((IdentifiedIntegerValue)object).valuefactory) &&
this.id == ((IdentifiedIntegerValue)object).id;
}
public int hashCode()
{
return super.hashCode() ^
valuefactory.hashCode() ^
id;
}
public String toString()
{
return "i"+id;
}
} proguard4.8/src/proguard/evaluation/value/UnknownFloatValue.java 0000644 0001750 0001750 00000005161 11736333523 023754 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This class represents a partially evaluated float value.
*
* @author Eric Lafortune
*/
public class UnknownFloatValue extends FloatValue
{
// Basic unary methods.
public FloatValue negate()
{
return this;
}
public IntegerValue convertToInteger()
{
return ValueFactory.INTEGER_VALUE;
}
public LongValue convertToLong()
{
return ValueFactory.LONG_VALUE;
}
public DoubleValue convertToDouble()
{
return ValueFactory.DOUBLE_VALUE;
}
// Basic binary methods.
public FloatValue generalize(FloatValue other)
{
return this;
}
public FloatValue add(FloatValue other)
{
return this;
}
public FloatValue subtract(FloatValue other)
{
return this;
}
public FloatValue subtractFrom(FloatValue other)
{
return this;
}
public FloatValue multiply(FloatValue other)
{
return this;
}
public FloatValue divide(FloatValue other)
{
return this;
}
public FloatValue divideOf(FloatValue other)
{
return this;
}
public FloatValue remainder(FloatValue other)
{
return this;
}
public FloatValue remainderOf(FloatValue other)
{
return this;
}
public IntegerValue compare(FloatValue other)
{
return ValueFactory.INTEGER_VALUE;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
public String toString()
{
return "d";
}
} proguard4.8/src/proguard/evaluation/value/NegatedDoubleValue.java 0000644 0001750 0001750 00000003552 11736333523 024033 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This DoubleValue represents a double value that is negated.
*
* @author Eric Lafortune
*/
final class NegatedDoubleValue extends SpecificDoubleValue
{
private final DoubleValue doubleValue;
/**
* Creates a new negated double value of the given double value.
*/
public NegatedDoubleValue(DoubleValue doubleValue)
{
this.doubleValue = doubleValue;
}
// Implementations of unary methods of DoubleValue.
public DoubleValue negate()
{
return doubleValue;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.doubleValue.equals(((NegatedDoubleValue)object).doubleValue);
}
public int hashCode()
{
return super.hashCode() ^
doubleValue.hashCode();
}
public String toString()
{
return "-"+doubleValue;
}
} proguard4.8/src/proguard/evaluation/value/CompositeLongValue.java 0000644 0001750 0001750 00000005563 11736333523 024117 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This LongValue represents the result of a binary operation on two long
* values.
*
* @author Eric Lafortune
*/
final class CompositeLongValue extends SpecificLongValue
{
public static final byte ADD = '+';
public static final byte SUBTRACT = '-';
public static final byte MULTIPLY = '*';
public static final byte DIVIDE = '/';
public static final byte REMAINDER = '%';
public static final byte SHIFT_LEFT = '<';
public static final byte SHIFT_RIGHT = '>';
public static final byte UNSIGNED_SHIFT_RIGHT = '}';
public static final byte AND = '&';
public static final byte OR = '|';
public static final byte XOR = '^';
private final LongValue longValue1;
private final byte operation;
private final Value longValue2;
/**
* Creates a new composite long value of the two given long values
* and the given operation.
*/
public CompositeLongValue(LongValue longValue1,
byte operation,
Value longValue2)
{
this.longValue1 = longValue1;
this.operation = operation;
this.longValue2 = longValue2;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.longValue1.equals(((CompositeLongValue)object).longValue1) &&
this.operation == ((CompositeLongValue)object).operation &&
this.longValue2.equals(((CompositeLongValue)object).longValue2);
}
public int hashCode()
{
return super.hashCode() ^
longValue1.hashCode() ^
longValue2.hashCode();
}
public String toString()
{
return "("+longValue1+((char)operation)+longValue2+")";
}
} proguard4.8/src/proguard/evaluation/value/ConvertedShortValue.java 0000644 0001750 0001750 00000003345 11736333523 024302 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents a short value that is converted from an
* integer value.
*
* @author Eric Lafortune
*/
final class ConvertedShortValue extends SpecificIntegerValue
{
private final IntegerValue value;
/**
* Creates a new converted short value of the given integer value.
*/
public ConvertedShortValue(IntegerValue value)
{
this.value = value;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.value.equals(((ConvertedShortValue)object).value);
}
public int hashCode()
{
return super.hashCode() ^
value.hashCode();
}
public String toString()
{
return "(short)("+value+")";
}
} proguard4.8/src/proguard/evaluation/value/Value.java 0000644 0001750 0001750 00000012401 11736333523 021401 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This abstract class represents a partially evaluated value.
*
* @author Eric Lafortune
*/
public abstract class Value
{
public static final int NEVER = -1;
public static final int MAYBE = 0;
public static final int ALWAYS = 1;
public static final int TYPE_INTEGER = 1;
public static final int TYPE_LONG = 2;
public static final int TYPE_FLOAT = 3;
public static final int TYPE_DOUBLE = 4;
public static final int TYPE_REFERENCE = 5;
public static final int TYPE_INSTRUCTION_OFFSET = 6;
public static final int TYPE_TOP = 7;
/**
* Returns this Value as a Category1Value.
*/
public Category1Value category1Value()
{
throw new IllegalArgumentException("Value is not a Category 1 value [" + this.getClass().getName() + "]");
}
/**
* Returns this Value as a Category2Value.
*/
public Category2Value category2Value()
{
throw new IllegalArgumentException("Value is not a Category 2 value [" + this.getClass().getName() + "]");
}
/**
* Returns this Value as an IntegerValue.
*/
public IntegerValue integerValue()
{
throw new IllegalArgumentException("Value is not an integer value [" + this.getClass().getName() + "]");
}
/**
* Returns this Value as a LongValue.
*/
public LongValue longValue()
{
throw new IllegalArgumentException("Value is not a long value [" + this.getClass().getName() + "]");
}
/**
* Returns this Value as a FloatValue.
*/
public FloatValue floatValue()
{
throw new IllegalArgumentException("Value is not a float value [" + this.getClass().getName() + "]");
}
/**
* Returns this Value as a DoubleValue.
*/
public DoubleValue doubleValue()
{
throw new IllegalArgumentException("Value is not a double value [" + this.getClass().getName() + "]");
}
/**
* Returns this Value as a ReferenceValue.
*/
public ReferenceValue referenceValue()
{
throw new IllegalArgumentException("Value is not a reference value [" + this.getClass().getName() + "]");
}
/**
* Returns this Value as an InstructionOffsetValue.
*/
public InstructionOffsetValue instructionOffsetValue()
{
throw new IllegalArgumentException("Value is not an instruction offset value [" + this.getClass().getName() + "]");
}
/**
* Returns whether this Value represents a single specific (but possibly
* unknown) value.
*/
public boolean isSpecific()
{
return false;
}
/**
* Returns whether this Value represents a single particular (known)
* value.
*/
public boolean isParticular()
{
return false;
}
/**
* Returns the generalization of this Value and the given other Value.
*/
public abstract Value generalize(Value other);
/**
* Returns whether the computational type of this Value is a category 2 type.
* This means that it takes up the space of two category 1 types on the
* stack, for instance.
*/
public abstract boolean isCategory2();
/**
* Returns the computational type of this Value.
* @return TYPE_INTEGER
,
* TYPE_LONG
,
* TYPE_FLOAT
,
* TYPE_DOUBLE
,
* TYPE_REFERENCE
, or
* TYPE_INSTRUCTION_OFFSET
.
*/
public abstract int computationalType();
/**
* Returns the internal type of this Value.
* @return ClassConstants.INTERNAL_TYPE_BOOLEAN
,
* ClassConstants.INTERNAL_TYPE_BYTE
,
* ClassConstants.INTERNAL_TYPE_CHAR
,
* ClassConstants.INTERNAL_TYPE_SHORT
,
* ClassConstants.INTERNAL_TYPE_INT
,
* ClassConstants.INTERNAL_TYPE_LONG
,
* ClassConstants.INTERNAL_TYPE_FLOAT
,
* ClassConstants.INTERNAL_TYPE_DOUBLE
,
* ClassConstants.INTERNAL_TYPE_CLASS_START ... ClassConstants.INTERNAL_TYPE_CLASS_END
, or
* an array type containing any of these types (always as String).
*/
public abstract String internalType();
}
proguard4.8/src/proguard/evaluation/value/Category2Value.java 0000644 0001750 0001750 00000002413 11736333523 023163 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This abstract class represents a partially evaluated Category 2 value.
*
* @author Eric Lafortune
*/
public abstract class Category2Value extends Value
{
// Implementations for Value.
public final Category2Value category2Value()
{
return this;
}
public final boolean isCategory2()
{
return true;
}
}
proguard4.8/src/proguard/evaluation/value/ConvertedByteValue.java 0000644 0001750 0001750 00000003337 11736333523 024107 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This IntegerValue represents a byte value that is converted from an
* integer value.
*
* @author Eric Lafortune
*/
final class ConvertedByteValue extends SpecificIntegerValue
{
private final IntegerValue value;
/**
* Creates a new converted byte value of the given integer value.
*/
public ConvertedByteValue(IntegerValue value)
{
this.value = value;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.value.equals(((ConvertedByteValue)object).value);
}
public int hashCode()
{
return super.hashCode() ^
value.hashCode();
}
public String toString()
{
return "(byte)("+value+")";
}
} proguard4.8/src/proguard/evaluation/value/CompositeDoubleValue.java 0000644 0001750 0001750 00000005060 11736333523 024422 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation.value;
/**
* This DoubleValue represents the result of a binary operation on two double
* values.
*
* @author Eric Lafortune
*/
final class CompositeDoubleValue extends SpecificDoubleValue
{
public static final byte ADD = '+';
public static final byte SUBTRACT = '-';
public static final byte MULTIPLY = '*';
public static final byte DIVIDE = '/';
public static final byte REMAINDER = '%';
private final DoubleValue doubleValue1;
private final byte operation;
private final DoubleValue doubleValue2;
/**
* Creates a new composite double value of the two given double values
* and the given operation.
*/
public CompositeDoubleValue(DoubleValue doubleValue1,
byte operation,
DoubleValue doubleValue2)
{
this.doubleValue1 = doubleValue1;
this.operation = operation;
this.doubleValue2 = doubleValue2;
}
// Implementations for Object.
public boolean equals(Object object)
{
return this == object ||
super.equals(object) &&
this.doubleValue1.equals(((CompositeDoubleValue)object).doubleValue1) &&
this.operation == ((CompositeDoubleValue)object).operation &&
this.doubleValue2.equals(((CompositeDoubleValue)object).doubleValue2);
}
public int hashCode()
{
return super.hashCode() ^
doubleValue1.hashCode() ^
doubleValue2.hashCode();
}
public String toString()
{
return "("+doubleValue1+((char)operation)+doubleValue2+")";
}
} proguard4.8/src/proguard/evaluation/ClassConstantValueFactory.java 0000644 0001750 0001750 00000003606 11736333523 024324 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.evaluation.value.*;
/**
* This class creates java.lang.Class ReferenceValue instances that correspond
* to specified constant pool entries.
*
* @author Eric Lafortune
*/
public class ClassConstantValueFactory
extends ConstantValueFactory
{
public ClassConstantValueFactory(ValueFactory valueFactory)
{
super(valueFactory);
}
// Implementations for ConstantVisitor.
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Create a Class reference instead of a reference to the class.
value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS,
classConstant.javaLangClassClass,
false);
}
} proguard4.8/src/proguard/evaluation/Processor.java 0000644 0001750 0001750 00000105235 11736333523 021200 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.evaluation.value.*;
/**
* This InstructionVisitor executes the instructions that it visits on a given
* local variable frame and stack.
*
* @author Eric Lafortune
*/
public class Processor
implements InstructionVisitor
{
private final Variables variables;
private final Stack stack;
private final ValueFactory valueFactory;
private final BranchUnit branchUnit;
private final InvocationUnit invocationUnit;
private final ConstantValueFactory constantValueFactory;
private final ClassConstantValueFactory classConstantValueFactory;
/**
* Creates a new processor that operates on the given environment.
* @param variables the local variable frame.
* @param stack the local stack.
* @param branchUnit the class that can affect the program counter.
* @param invocationUnit the class that can access other program members.
*/
public Processor(Variables variables,
Stack stack,
ValueFactory valueFactory,
BranchUnit branchUnit,
InvocationUnit invocationUnit)
{
this.variables = variables;
this.stack = stack;
this.valueFactory = valueFactory;
this.branchUnit = branchUnit;
this.invocationUnit = invocationUnit;
constantValueFactory = new ConstantValueFactory(valueFactory);
classConstantValueFactory = new ClassConstantValueFactory(valueFactory);
}
// Implementations for InstructionVisitor.
public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
{
switch (simpleInstruction.opcode)
{
case InstructionConstants.OP_NOP:
break;
case InstructionConstants.OP_ACONST_NULL:
stack.push(valueFactory.createReferenceValueNull());
break;
case InstructionConstants.OP_ICONST_M1:
case InstructionConstants.OP_ICONST_0:
case InstructionConstants.OP_ICONST_1:
case InstructionConstants.OP_ICONST_2:
case InstructionConstants.OP_ICONST_3:
case InstructionConstants.OP_ICONST_4:
case InstructionConstants.OP_ICONST_5:
case InstructionConstants.OP_BIPUSH:
case InstructionConstants.OP_SIPUSH:
stack.push(valueFactory.createIntegerValue(simpleInstruction.constant));
break;
case InstructionConstants.OP_LCONST_0:
case InstructionConstants.OP_LCONST_1:
stack.push(valueFactory.createLongValue(simpleInstruction.constant));
break;
case InstructionConstants.OP_FCONST_0:
case InstructionConstants.OP_FCONST_1:
case InstructionConstants.OP_FCONST_2:
stack.push(valueFactory.createFloatValue((float)simpleInstruction.constant));
break;
case InstructionConstants.OP_DCONST_0:
case InstructionConstants.OP_DCONST_1:
stack.push(valueFactory.createDoubleValue((double)simpleInstruction.constant));
break;
case InstructionConstants.OP_IALOAD:
case InstructionConstants.OP_BALOAD:
case InstructionConstants.OP_CALOAD:
case InstructionConstants.OP_SALOAD:
stack.ipop();
stack.apop();
stack.push(valueFactory.createIntegerValue());
break;
case InstructionConstants.OP_LALOAD:
stack.ipop();
stack.apop();
stack.push(valueFactory.createLongValue());
break;
case InstructionConstants.OP_FALOAD:
stack.ipop();
stack.apop();
stack.push(valueFactory.createFloatValue());
break;
case InstructionConstants.OP_DALOAD:
stack.ipop();
stack.apop();
stack.push(valueFactory.createDoubleValue());
break;
case InstructionConstants.OP_AALOAD:
{
IntegerValue arrayIndex = stack.ipop();
ReferenceValue arrayReference = stack.apop();
stack.push(arrayReference.arrayLoad(arrayIndex, valueFactory));
break;
}
case InstructionConstants.OP_IASTORE:
case InstructionConstants.OP_BASTORE:
case InstructionConstants.OP_CASTORE:
case InstructionConstants.OP_SASTORE:
stack.ipop();
stack.ipop();
stack.apop();
break;
case InstructionConstants.OP_LASTORE:
stack.lpop();
stack.ipop();
stack.apop();
break;
case InstructionConstants.OP_FASTORE:
stack.fpop();
stack.ipop();
stack.apop();
break;
case InstructionConstants.OP_DASTORE:
stack.dpop();
stack.ipop();
stack.apop();
break;
case InstructionConstants.OP_AASTORE:
stack.apop();
stack.ipop();
stack.apop();
break;
case InstructionConstants.OP_POP:
stack.pop1();
break;
case InstructionConstants.OP_POP2:
stack.pop2();
break;
case InstructionConstants.OP_DUP:
stack.dup();
break;
case InstructionConstants.OP_DUP_X1:
stack.dup_x1();
break;
case InstructionConstants.OP_DUP_X2:
stack.dup_x2();
break;
case InstructionConstants.OP_DUP2:
stack.dup2();
break;
case InstructionConstants.OP_DUP2_X1:
stack.dup2_x1();
break;
case InstructionConstants.OP_DUP2_X2:
stack.dup2_x2();
break;
case InstructionConstants.OP_SWAP:
stack.swap();
break;
case InstructionConstants.OP_IADD:
stack.push(stack.ipop().add(stack.ipop()));
break;
case InstructionConstants.OP_LADD:
stack.push(stack.lpop().add(stack.lpop()));
break;
case InstructionConstants.OP_FADD:
stack.push(stack.fpop().add(stack.fpop()));
break;
case InstructionConstants.OP_DADD:
stack.push(stack.dpop().add(stack.dpop()));
break;
case InstructionConstants.OP_ISUB:
stack.push(stack.ipop().subtractFrom(stack.ipop()));
break;
case InstructionConstants.OP_LSUB:
stack.push(stack.lpop().subtractFrom(stack.lpop()));
break;
case InstructionConstants.OP_FSUB:
stack.push(stack.fpop().subtractFrom(stack.fpop()));
break;
case InstructionConstants.OP_DSUB:
stack.push(stack.dpop().subtractFrom(stack.dpop()));
break;
case InstructionConstants.OP_IMUL:
stack.push(stack.ipop().multiply(stack.ipop()));
break;
case InstructionConstants.OP_LMUL:
stack.push(stack.lpop().multiply(stack.lpop()));
break;
case InstructionConstants.OP_FMUL:
stack.push(stack.fpop().multiply(stack.fpop()));
break;
case InstructionConstants.OP_DMUL:
stack.push(stack.dpop().multiply(stack.dpop()));
break;
case InstructionConstants.OP_IDIV:
try
{
stack.push(stack.ipop().divideOf(stack.ipop()));
}
catch (ArithmeticException ex)
{
stack.push(valueFactory.createIntegerValue());
// TODO: Forward ArithmeticExceptions.
//stack.clear();
//stack.push(valueFactory.createReference(false));
//branchUnit.throwException();
}
break;
case InstructionConstants.OP_LDIV:
try
{
stack.push(stack.lpop().divideOf(stack.lpop()));
}
catch (ArithmeticException ex)
{
stack.push(valueFactory.createLongValue());
// TODO: Forward ArithmeticExceptions.
//stack.clear();
//stack.push(valueFactory.createReference(false));
//branchUnit.throwException();
}
break;
case InstructionConstants.OP_FDIV:
stack.push(stack.fpop().divideOf(stack.fpop()));
break;
case InstructionConstants.OP_DDIV:
stack.push(stack.dpop().divideOf(stack.dpop()));
break;
case InstructionConstants.OP_IREM:
try
{
stack.push(stack.ipop().remainderOf(stack.ipop()));
}
catch (ArithmeticException ex)
{
stack.push(valueFactory.createIntegerValue());
// TODO: Forward ArithmeticExceptions.
//stack.clear();
//stack.push(valueFactory.createReference(false));
//branchUnit.throwException();
}
break;
case InstructionConstants.OP_LREM:
try
{
stack.push(stack.lpop().remainderOf(stack.lpop()));
}
catch (ArithmeticException ex)
{
stack.push(valueFactory.createLongValue());
// TODO: Forward ArithmeticExceptions.
//stack.clear();
//stack.push(valueFactory.createReference(false));
//branchUnit.throwException();
}
break;
case InstructionConstants.OP_FREM:
stack.push(stack.fpop().remainderOf(stack.fpop()));
break;
case InstructionConstants.OP_DREM:
stack.push(stack.dpop().remainderOf(stack.dpop()));
break;
case InstructionConstants.OP_INEG:
stack.push(stack.ipop().negate());
break;
case InstructionConstants.OP_LNEG:
stack.push(stack.lpop().negate());
break;
case InstructionConstants.OP_FNEG:
stack.push(stack.fpop().negate());
break;
case InstructionConstants.OP_DNEG:
stack.push(stack.dpop().negate());
break;
case InstructionConstants.OP_ISHL:
stack.push(stack.ipop().shiftLeftOf(stack.ipop()));
break;
case InstructionConstants.OP_LSHL:
stack.push(stack.ipop().shiftLeftOf(stack.lpop()));
break;
case InstructionConstants.OP_ISHR:
stack.push(stack.ipop().shiftRightOf(stack.ipop()));
break;
case InstructionConstants.OP_LSHR:
stack.push(stack.ipop().shiftRightOf(stack.lpop()));
break;
case InstructionConstants.OP_IUSHR:
stack.push(stack.ipop().unsignedShiftRightOf(stack.ipop()));
break;
case InstructionConstants.OP_LUSHR:
stack.push(stack.ipop().unsignedShiftRightOf(stack.lpop()));
break;
case InstructionConstants.OP_IAND:
stack.push(stack.ipop().and(stack.ipop()));
break;
case InstructionConstants.OP_LAND:
stack.push(stack.lpop().and(stack.lpop()));
break;
case InstructionConstants.OP_IOR:
stack.push(stack.ipop().or(stack.ipop()));
break;
case InstructionConstants.OP_LOR:
stack.push(stack.lpop().or(stack.lpop()));
break;
case InstructionConstants.OP_IXOR:
stack.push(stack.ipop().xor(stack.ipop()));
break;
case InstructionConstants.OP_LXOR:
stack.push(stack.lpop().xor(stack.lpop()));
break;
case InstructionConstants.OP_I2L:
stack.push(stack.ipop().convertToLong());
break;
case InstructionConstants.OP_I2F:
stack.push(stack.ipop().convertToFloat());
break;
case InstructionConstants.OP_I2D:
stack.push(stack.ipop().convertToDouble());
break;
case InstructionConstants.OP_L2I:
stack.push(stack.lpop().convertToInteger());
break;
case InstructionConstants.OP_L2F:
stack.push(stack.lpop().convertToFloat());
break;
case InstructionConstants.OP_L2D:
stack.push(stack.lpop().convertToDouble());
break;
case InstructionConstants.OP_F2I:
stack.push(stack.fpop().convertToInteger());
break;
case InstructionConstants.OP_F2L:
stack.push(stack.fpop().convertToLong());
break;
case InstructionConstants.OP_F2D:
stack.push(stack.fpop().convertToDouble());
break;
case InstructionConstants.OP_D2I:
stack.push(stack.dpop().convertToInteger());
break;
case InstructionConstants.OP_D2L:
stack.push(stack.dpop().convertToLong());
break;
case InstructionConstants.OP_D2F:
stack.push(stack.dpop().convertToFloat());
break;
case InstructionConstants.OP_I2B:
stack.push(stack.ipop().convertToByte());
break;
case InstructionConstants.OP_I2C:
stack.push(stack.ipop().convertToCharacter());
break;
case InstructionConstants.OP_I2S:
stack.push(stack.ipop().convertToShort());
break;
case InstructionConstants.OP_LCMP:
// stack.push(stack.lpop().compareReverse(stack.lpop()));
LongValue longValue1 = stack.lpop();
LongValue longValue2 = stack.lpop();
stack.push(longValue2.compare(longValue1));
break;
case InstructionConstants.OP_FCMPL:
FloatValue floatValue1 = stack.fpop();
FloatValue floatValue2 = stack.fpop();
stack.push(floatValue2.compare(floatValue1));
break;
case InstructionConstants.OP_FCMPG:
stack.push(stack.fpop().compareReverse(stack.fpop()));
break;
case InstructionConstants.OP_DCMPL:
DoubleValue doubleValue1 = stack.dpop();
DoubleValue doubleValue2 = stack.dpop();
stack.push(doubleValue2.compare(doubleValue1));
break;
case InstructionConstants.OP_DCMPG:
stack.push(stack.dpop().compareReverse(stack.dpop()));
break;
case InstructionConstants.OP_IRETURN:
invocationUnit.exitMethod(clazz, method, stack.ipop());
branchUnit.returnFromMethod();
break;
case InstructionConstants.OP_LRETURN:
invocationUnit.exitMethod(clazz, method, stack.lpop());
branchUnit.returnFromMethod();
break;
case InstructionConstants.OP_FRETURN:
invocationUnit.exitMethod(clazz, method, stack.fpop());
branchUnit.returnFromMethod();
break;
case InstructionConstants.OP_DRETURN:
invocationUnit.exitMethod(clazz, method, stack.dpop());
branchUnit.returnFromMethod();
break;
case InstructionConstants.OP_ARETURN:
invocationUnit.exitMethod(clazz, method, stack.apop());
branchUnit.returnFromMethod();
break;
case InstructionConstants.OP_RETURN:
branchUnit.returnFromMethod();
break;
case InstructionConstants.OP_NEWARRAY:
IntegerValue arrayLength = stack.ipop();
stack.push(valueFactory.createArrayReferenceValue(String.valueOf(InstructionUtil.internalTypeFromArrayType((byte)simpleInstruction.constant)),
null,
arrayLength));
break;
case InstructionConstants.OP_ARRAYLENGTH:
stack.apop();
stack.push(valueFactory.createIntegerValue());
break;
case InstructionConstants.OP_ATHROW:
ReferenceValue exceptionReferenceValue = stack.apop();
stack.clear();
stack.push(exceptionReferenceValue);
branchUnit.throwException();
break;
case InstructionConstants.OP_MONITORENTER:
case InstructionConstants.OP_MONITOREXIT:
stack.apop();
break;
default:
throw new IllegalArgumentException("Unknown simple instruction ["+simpleInstruction.opcode+"]");
}
}
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
int constantIndex = constantInstruction.constantIndex;
switch (constantInstruction.opcode)
{
case InstructionConstants.OP_LDC:
case InstructionConstants.OP_LDC_W:
case InstructionConstants.OP_LDC2_W:
stack.push(classConstantValueFactory.constantValue(clazz, constantIndex));
break;
case InstructionConstants.OP_GETSTATIC:
case InstructionConstants.OP_PUTSTATIC:
case InstructionConstants.OP_GETFIELD:
case InstructionConstants.OP_PUTFIELD:
case InstructionConstants.OP_INVOKEVIRTUAL:
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
case InstructionConstants.OP_INVOKEDYNAMIC:
invocationUnit.invokeMember(clazz, method, codeAttribute, offset, constantInstruction, stack);
break;
case InstructionConstants.OP_NEW:
stack.push(constantValueFactory.constantValue(clazz, constantIndex).referenceValue());
break;
case InstructionConstants.OP_ANEWARRAY:
{
ReferenceValue referenceValue = constantValueFactory.constantValue(clazz, constantIndex).referenceValue();
stack.push(valueFactory.createArrayReferenceValue(referenceValue.internalType(),
referenceValue.getReferencedClass(),
stack.ipop()));
break;
}
case InstructionConstants.OP_CHECKCAST:
// TODO: Check cast.
ReferenceValue castValue = stack.apop();
ReferenceValue castResultValue =
castValue.isNull() == Value.ALWAYS ? castValue :
castValue.isNull() == Value.NEVER ? constantValueFactory.constantValue(clazz, constantIndex).referenceValue() :
constantValueFactory.constantValue(clazz, constantIndex).referenceValue().generalize(valueFactory.createReferenceValueNull());
stack.push(castResultValue);
break;
case InstructionConstants.OP_INSTANCEOF:
{
ReferenceValue referenceValue = constantValueFactory.constantValue(clazz, constantIndex).referenceValue();
int instanceOf = stack.apop().instanceOf(referenceValue.getType(),
referenceValue.getReferencedClass());
stack.push(instanceOf == Value.NEVER ? valueFactory.createIntegerValue(0) :
instanceOf == Value.ALWAYS ? valueFactory.createIntegerValue(1) :
valueFactory.createIntegerValue());
break;
}
case InstructionConstants.OP_MULTIANEWARRAY:
{
int dimensionCount = constantInstruction.constant;
for (int dimension = 0; dimension < dimensionCount; dimension++)
{
// TODO: Use array lengths.
IntegerValue arrayLength = stack.ipop();
}
stack.push(constantValueFactory.constantValue(clazz, constantIndex).referenceValue());
break;
}
default:
throw new IllegalArgumentException("Unknown constant pool instruction ["+constantInstruction.opcode+"]");
}
}
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
{
int variableIndex = variableInstruction.variableIndex;
switch (variableInstruction.opcode)
{
case InstructionConstants.OP_ILOAD:
case InstructionConstants.OP_ILOAD_0:
case InstructionConstants.OP_ILOAD_1:
case InstructionConstants.OP_ILOAD_2:
case InstructionConstants.OP_ILOAD_3:
stack.push(variables.iload(variableIndex));
break;
case InstructionConstants.OP_LLOAD:
case InstructionConstants.OP_LLOAD_0:
case InstructionConstants.OP_LLOAD_1:
case InstructionConstants.OP_LLOAD_2:
case InstructionConstants.OP_LLOAD_3:
stack.push(variables.lload(variableIndex));
break;
case InstructionConstants.OP_FLOAD:
case InstructionConstants.OP_FLOAD_0:
case InstructionConstants.OP_FLOAD_1:
case InstructionConstants.OP_FLOAD_2:
case InstructionConstants.OP_FLOAD_3:
stack.push(variables.fload(variableIndex));
break;
case InstructionConstants.OP_DLOAD:
case InstructionConstants.OP_DLOAD_0:
case InstructionConstants.OP_DLOAD_1:
case InstructionConstants.OP_DLOAD_2:
case InstructionConstants.OP_DLOAD_3:
stack.push(variables.dload(variableIndex));
break;
case InstructionConstants.OP_ALOAD:
case InstructionConstants.OP_ALOAD_0:
case InstructionConstants.OP_ALOAD_1:
case InstructionConstants.OP_ALOAD_2:
case InstructionConstants.OP_ALOAD_3:
stack.push(variables.aload(variableIndex));
break;
case InstructionConstants.OP_ISTORE:
case InstructionConstants.OP_ISTORE_0:
case InstructionConstants.OP_ISTORE_1:
case InstructionConstants.OP_ISTORE_2:
case InstructionConstants.OP_ISTORE_3:
variables.store(variableIndex, stack.ipop());
break;
case InstructionConstants.OP_LSTORE:
case InstructionConstants.OP_LSTORE_0:
case InstructionConstants.OP_LSTORE_1:
case InstructionConstants.OP_LSTORE_2:
case InstructionConstants.OP_LSTORE_3:
variables.store(variableIndex, stack.lpop());
break;
case InstructionConstants.OP_FSTORE:
case InstructionConstants.OP_FSTORE_0:
case InstructionConstants.OP_FSTORE_1:
case InstructionConstants.OP_FSTORE_2:
case InstructionConstants.OP_FSTORE_3:
variables.store(variableIndex, stack.fpop());
break;
case InstructionConstants.OP_DSTORE:
case InstructionConstants.OP_DSTORE_0:
case InstructionConstants.OP_DSTORE_1:
case InstructionConstants.OP_DSTORE_2:
case InstructionConstants.OP_DSTORE_3:
variables.store(variableIndex, stack.dpop());
break;
case InstructionConstants.OP_ASTORE:
case InstructionConstants.OP_ASTORE_0:
case InstructionConstants.OP_ASTORE_1:
case InstructionConstants.OP_ASTORE_2:
case InstructionConstants.OP_ASTORE_3:
// The operand on the stack can be a reference or a return
// address, so we'll relax the pop operation.
//variables.store(variableIndex, stack.apop());
variables.store(variableIndex, stack.pop());
break;
case InstructionConstants.OP_IINC:
variables.store(variableIndex,
variables.iload(variableIndex).add(
valueFactory.createIntegerValue(variableInstruction.constant)));
break;
case InstructionConstants.OP_RET:
// The return address should be in the last offset of the
// given instruction offset variable (even though there may
// be other offsets).
InstructionOffsetValue instructionOffsetValue = variables.oload(variableIndex);
branchUnit.branch(clazz,
codeAttribute,
offset,
instructionOffsetValue.instructionOffset(instructionOffsetValue.instructionOffsetCount()-1));
break;
default:
throw new IllegalArgumentException("Unknown variable instruction ["+variableInstruction.opcode+"]");
}
}
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
{
int branchTarget = offset + branchInstruction.branchOffset;
switch (branchInstruction.opcode)
{
case InstructionConstants.OP_IFEQ:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().equal(valueFactory.createIntegerValue(0)));
break;
case InstructionConstants.OP_IFNE:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().notEqual(valueFactory.createIntegerValue(0)));
break;
case InstructionConstants.OP_IFLT:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().lessThan(valueFactory.createIntegerValue(0)));
break;
case InstructionConstants.OP_IFGE:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().greaterThanOrEqual(valueFactory.createIntegerValue(0)));
break;
case InstructionConstants.OP_IFGT:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().greaterThan(valueFactory.createIntegerValue(0)));
break;
case InstructionConstants.OP_IFLE:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().lessThanOrEqual(valueFactory.createIntegerValue(0)));
break;
case InstructionConstants.OP_IFICMPEQ:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().equal(stack.ipop()));
break;
case InstructionConstants.OP_IFICMPNE:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().notEqual(stack.ipop()));
break;
case InstructionConstants.OP_IFICMPLT:
// Note that the stack entries are popped in reverse order.
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().greaterThan(stack.ipop()));
break;
case InstructionConstants.OP_IFICMPGE:
// Note that the stack entries are popped in reverse order.
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().lessThanOrEqual(stack.ipop()));
break;
case InstructionConstants.OP_IFICMPGT:
// Note that the stack entries are popped in reverse order.
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().lessThan(stack.ipop()));
break;
case InstructionConstants.OP_IFICMPLE:
// Note that the stack entries are popped in reverse order.
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.ipop().greaterThanOrEqual(stack.ipop()));
break;
case InstructionConstants.OP_IFACMPEQ:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.apop().equal(stack.apop()));
break;
case InstructionConstants.OP_IFACMPNE:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.apop().notEqual(stack.apop()));
break;
case InstructionConstants.OP_GOTO:
case InstructionConstants.OP_GOTO_W:
branchUnit.branch(clazz, codeAttribute, offset, branchTarget);
break;
case InstructionConstants.OP_JSR:
case InstructionConstants.OP_JSR_W:
stack.push(new InstructionOffsetValue(offset +
branchInstruction.length(offset)));
branchUnit.branch(clazz, codeAttribute, offset, branchTarget);
break;
case InstructionConstants.OP_IFNULL:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.apop().isNull());
break;
case InstructionConstants.OP_IFNONNULL:
branchUnit.branchConditionally(clazz, codeAttribute, offset, branchTarget,
stack.apop().isNotNull());
break;
default:
throw new IllegalArgumentException("Unknown branch instruction ["+branchInstruction.opcode+"]");
}
}
public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)
{
IntegerValue indexValue = stack.ipop();
// If there is no definite branch in any of the cases below,
// branch to the default offset.
branchUnit.branch(clazz, codeAttribute,
offset,
offset + tableSwitchInstruction.defaultOffset);
for (int index = 0; index < tableSwitchInstruction.jumpOffsets.length; index++)
{
int conditional = indexValue.equal(valueFactory.createIntegerValue(
tableSwitchInstruction.lowCase + index));
branchUnit.branchConditionally(clazz, codeAttribute,
offset,
offset + tableSwitchInstruction.jumpOffsets[index],
conditional);
// If this branch is always taken, we can skip the rest.
if (conditional == Value.ALWAYS)
{
break;
}
}
}
public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
{
IntegerValue indexValue = stack.ipop();
// If there is no definite branch in any of the cases below,
// branch to the default offset.
branchUnit.branch(clazz, codeAttribute,
offset,
offset + lookUpSwitchInstruction.defaultOffset);
for (int index = 0; index < lookUpSwitchInstruction.jumpOffsets.length; index++)
{
int conditional = indexValue.equal(valueFactory.createIntegerValue(
lookUpSwitchInstruction.cases[index]));
branchUnit.branchConditionally(clazz, codeAttribute,
offset,
offset + lookUpSwitchInstruction.jumpOffsets[index],
conditional);
// If this branch is always taken, we can skip the rest.
if (conditional == Value.ALWAYS)
{
break;
}
}
}
}
proguard4.8/src/proguard/evaluation/BranchUnit.java 0000644 0001750 0001750 00000003761 11736333523 021257 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.classfile.Clazz;
import proguard.classfile.attribute.CodeAttribute;
/**
* This InstructionVisitor evaluates the instructions that it visits.
*
* @author Eric Lafortune
*/
public interface BranchUnit
{
/**
* Sets the new instruction offset.
*/
public void branch(Clazz clazz,
CodeAttribute codeAttribute,
int offset,
int branchTarget);
/**
* Sets the new instruction offset, depending on the certainty of the
* conditional branch.
*/
public void branchConditionally(Clazz clazz,
CodeAttribute codeAttribute,
int offset,
int branchTarget,
int conditional);
/**
* Returns from the method with the given value.
*/
public void returnFromMethod();
/**
* Handles the throwing of an exception.
*/
public void throwException();
}
proguard4.8/src/proguard/evaluation/Variables.java 0000644 0001750 0001750 00000021734 11736333523 021132 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.evaluation.value.*;
import java.util.Arrays;
/**
* This class represents a local variable frame that contains Value
* objects. Values are generalizations of all values that have been stored in
* the respective variables.
*
* @author Eric Lafortune
*/
public class Variables
{
private static final TopValue TOP_VALUE = new TopValue();
protected Value[] values;
protected int size;
/**
* Creates a new Variables object with a given maximum number of variables.
*/
public Variables(int size)
{
this.values = new Value[size];
this.size = size;
}
/**
* Creates a Variables object that is a copy of the given Variables object.
*/
public Variables(Variables variables)
{
// Create the values array.
this(variables.size);
// Copy the values.
initialize(variables);
}
/**
* Resets this Variables object, so that it can be reused.
*/
public void reset(int size)
{
// Is the values array large enough?
if (size > values.length)
{
// Create a new one.
values = new Value[size];
}
else
{
// Clear the variables.
Arrays.fill(values, null);
}
this.size = size;
}
/**
* Initializes the values of this Variables object with the values of the
* given Variables object. The other object may have fewer values, in which
* case the remaining values are left unchanged.
*/
public void initialize(Variables other)
{
if (this.size < other.size)
{
throw new IllegalArgumentException("Variable frame is too small ["+this.size+"] compared to other frame ["+other.size+"]");
}
// Copy the values.
System.arraycopy(other.values, 0, this.values, 0, other.size);
}
/**
* Generalizes the values of this Variables object with the values of the
* given Variables object.
* @param clearConflictingOtherVariables specifies whether the other
* variables should be cleared too,
* in case of conflicts.
* @return whether the generalization has made any difference.
*/
public boolean generalize(Variables other,
boolean clearConflictingOtherVariables)
{
if (this.size != other.size)
{
throw new IllegalArgumentException("Variable frames have different sizes ["+this.size+"] and ["+other.size+"]");
}
boolean changed = false;
for (int index = 0; index < size; index++)
{
Value thisValue = this.values[index];
Value otherValue = other.values[index];
// Occasionally, two values of different types might be present
// in the same variable in a variable frame (corresponding to
// two local variables that share the same index), at some point
// outside of their scopes. Don't generalize the variable then,
// but let it clear instead.
if (thisValue != null &&
otherValue != null &&
thisValue.computationalType() == otherValue.computationalType())
{
Value newValue = thisValue.generalize(otherValue);
changed = changed || !thisValue.equals(newValue);
this.values[index] = newValue;
}
else
{
changed = changed || thisValue != null;
this.values[index] = null;
if (clearConflictingOtherVariables)
{
other.values[index] = null;
}
}
}
return changed;
}
/**
* Returns the number of variables.
*/
public int size()
{
return size;
}
/**
* Gets the Value of the variable with the given index, without disturbing it.
*/
public Value getValue(int index)
{
if (index < 0 ||
index >= size)
{
throw new IndexOutOfBoundsException("Variable index ["+index+"] out of bounds ["+size+"]");
}
return values[index];
}
/**
* Stores the given Value at the given variable index.
*/
public void store(int index, Value value)
{
if (index < 0 ||
index >= size)
{
throw new IndexOutOfBoundsException("Variable index ["+index+"] out of bounds ["+size+"]");
}
// Store the value.
values[index] = value;
// Account for the extra space required by Category 2 values.
if (value.isCategory2())
{
values[index + 1] = TOP_VALUE;
}
}
/**
* Loads the Value from the variable with the given index.
*/
public Value load(int index)
{
if (index < 0 ||
index >= size)
{
throw new IndexOutOfBoundsException("Variable index ["+index+"] out of bounds ["+size+"]");
}
return values[index];
}
// Load methods that provide convenient casts to the expected value types.
/**
* Loads the IntegerValue from the variable with the given index.
*/
public IntegerValue iload(int index)
{
return load(index).integerValue();
}
/**
* Loads the LongValue from the variable with the given index.
*/
public LongValue lload(int index)
{
return load(index).longValue();
}
/**
* Loads the FloatValue from the variable with the given index.
*/
public FloatValue fload(int index)
{
return load(index).floatValue();
}
/**
* Loads the DoubleValue from the variable with the given index.
*/
public DoubleValue dload(int index)
{
return load(index).doubleValue();
}
/**
* Loads the ReferenceValue from the variable with the given index.
*/
public ReferenceValue aload(int index)
{
return load(index).referenceValue();
}
/**
* Loads the InstructionOffsetValue from the variable with the given index.
*/
public InstructionOffsetValue oload(int index)
{
return load(index).instructionOffsetValue();
}
// Implementations for Object.
public boolean equals(Object object)
{
if (object == null ||
this.getClass() != object.getClass())
{
return false;
}
Variables other = (Variables)object;
if (this.size != other.size)
{
return false;
}
for (int index = 0; index < size; index++)
{
Value thisValue = this.values[index];
Value otherValue = other.values[index];
// Occasionally, two values of different types might be
// present in the same variable in a variable frame
// (corresponding to two local variables that share the
// same index), at some point outside of their scopes.
// We'll ignore these.
if (thisValue != null &&
otherValue != null &&
thisValue.computationalType() == otherValue.computationalType() &&
!thisValue.equals(otherValue))
{
return false;
}
}
return true;
}
public int hashCode()
{
int hashCode = size;
for (int index = 0; index < size; index++)
{
Value value = values[index];
if (value != null)
{
hashCode ^= value.hashCode();
}
}
return hashCode;
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
for (int index = 0; index < size; index++)
{
Value value = values[index];
buffer = buffer.append('[')
.append(value == null ? "empty" : value.toString())
.append(']');
}
return buffer.toString();
}
}
proguard4.8/src/proguard/evaluation/InvocationUnit.java 0000644 0001750 0001750 00000004302 11736333523 022163 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.instruction.ConstantInstruction;
import proguard.evaluation.value.Value;
/**
* This interface sets up the variables for entering a method,
* and it updates the stack for the invocation of a class member.
*
* @author Eric Lafortune
*/
public interface InvocationUnit
{
/**
* Sets up the given variables for entering the given method.
*/
public void enterMethod(Clazz clazz,
Method method,
Variables variables);
/**
* Exits the given method with the given return value.
*/
public void exitMethod(Clazz clazz,
Method method,
Value returnValue);
/**
* Updates the given stack corresponding to the execution of the given
* field or method reference instruction.
*/
public void invokeMember(Clazz clazz,
Method method,
CodeAttribute codeAttribute,
int offset,
ConstantInstruction constantInstruction,
Stack stack);
}
proguard4.8/src/proguard/evaluation/BasicBranchUnit.java 0000644 0001750 0001750 00000006745 11736333523 022226 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.classfile.Clazz;
import proguard.classfile.attribute.CodeAttribute;
import proguard.evaluation.value.InstructionOffsetValue;
/**
* This BranchUnit remembers the branch unit commands that are invoked on it.
* I doesn't consider conditions when branching.
*
* @author Eric Lafortune
*/
public class BasicBranchUnit
implements BranchUnit
{
private boolean wasCalled;
private InstructionOffsetValue traceBranchTargets;
/**
* Resets the flag that tells whether any of the branch unit commands was
* called.
*/
public void resetCalled()
{
wasCalled = false;
}
/**
* Sets the flag that tells whether any of the branch unit commands was
* called.
*/
protected void setCalled()
{
wasCalled = true;
}
/**
* Returns whether any of the branch unit commands was called.
*/
public boolean wasCalled()
{
return wasCalled;
}
/**
* Sets the initial branch targets, which will be updated as the branch
* methods of the branch unit are called.
*/
public void setTraceBranchTargets(InstructionOffsetValue branchTargets)
{
this.traceBranchTargets = branchTargets;
}
public InstructionOffsetValue getTraceBranchTargets()
{
return traceBranchTargets;
}
// Implementations for BranchUnit.
public void branch(Clazz clazz,
CodeAttribute codeAttribute,
int offset,
int branchTarget)
{
// Override the branch targets.
traceBranchTargets = new InstructionOffsetValue(branchTarget);
wasCalled = true;
}
public void branchConditionally(Clazz clazz,
CodeAttribute codeAttribute,
int offset,
int branchTarget,
int conditional)
{
// Accumulate the branch targets.
traceBranchTargets =
traceBranchTargets.generalize(new InstructionOffsetValue(branchTarget)).instructionOffsetValue();
wasCalled = true;
}
public void returnFromMethod()
{
// Stop processing this block.
traceBranchTargets = InstructionOffsetValue.EMPTY_VALUE;
wasCalled = true;
}
public void throwException()
{
// Stop processing this block.
traceBranchTargets = InstructionOffsetValue.EMPTY_VALUE;
wasCalled = true;
}
}
proguard4.8/src/proguard/evaluation/TracedVariables.java 0000644 0001750 0001750 00000013145 11736333523 022252 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.evaluation.value.Value;
/**
* This Variables class saves additional information with variables, to keep
* track of their origins.
*
* The Variables class stores a given producer Value along with each Value it
* stores. It then generalizes a given collected Value with the producer Value
* of each Value it loads. The producer Value and the initial collected Value
* can be set; the generalized collected Value can be retrieved.
*
* @author Eric Lafortune
*/
public class TracedVariables extends Variables
{
public static final int NONE = -1;
private Value producerValue;
private Variables producerVariables;
/**
* Creates a new TracedVariables with a given size.
*/
public TracedVariables(int size)
{
super(size);
producerVariables = new Variables(size);
}
/**
* Creates a new TracedVariables that is a copy of the given TracedVariables.
*/
public TracedVariables(TracedVariables tracedVariables)
{
super(tracedVariables);
producerVariables = new Variables(tracedVariables.producerVariables);
}
/**
* Sets the Value that will be stored along with all store instructions.
*/
public void setProducerValue(Value producerValue)
{
this.producerValue = producerValue;
}
/**
* Gets the producer Value for the specified variable, without disturbing it.
* @param index the variable index.
* @return the producer value of the given variable.
*/
public Value getProducerValue(int index)
{
return producerVariables.getValue(index);
}
/**
* Sets the given producer Value for the specified variable, without
* disturbing it.
* @param index the variable index.
* @param value the producer value to set.
*/
public void setProducerValue(int index, Value value)
{
producerVariables.store(index, value);
}
// Implementations for Variables.
public void reset(int size)
{
super.reset(size);
producerVariables.reset(size);
}
public void initialize(TracedVariables other)
{
super.initialize(other);
producerVariables.initialize(other.producerVariables);
}
public boolean generalize(TracedVariables other,
boolean clearConflictingOtherVariables)
{
boolean variablesChanged = super.generalize(other, clearConflictingOtherVariables);
boolean producersChanged = producerVariables.generalize(other.producerVariables, clearConflictingOtherVariables);
/* consumerVariables.generalize(other.consumerVariables)*/
// Clear any traces if a variable has become null.
if (variablesChanged)
{
for (int index = 0; index < size; index++)
{
if (values[index] == null)
{
producerVariables.values[index] = null;
if (clearConflictingOtherVariables)
{
other.producerVariables.values[index] = null;
}
}
}
}
return variablesChanged || producersChanged;
}
public void store(int index, Value value)
{
// Store the value itself in the variable.
super.store(index, value);
// Store the producer value in its producer variable.
producerVariables.store(index, producerValue);
// Account for the extra space required by Category 2 values.
if (value.isCategory2())
{
producerVariables.store(index+1, producerValue);
}
}
// Implementations for Object.
public boolean equals(Object object)
{
if (object == null ||
this.getClass() != object.getClass())
{
return false;
}
TracedVariables other = (TracedVariables)object;
return super.equals(object) &&
this.producerVariables.equals(other.producerVariables);
}
public int hashCode()
{
return super.hashCode() ^
producerVariables.hashCode();
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
for (int index = 0; index < this.size(); index++)
{
Value value = this.values[index];
Value producerValue = producerVariables.getValue(index);
buffer = buffer.append('[')
.append(producerValue == null ? "empty:" : producerValue.toString())
.append(value == null ? "empty" : value.toString())
.append(']');
}
return buffer.toString();
}
}
proguard4.8/src/proguard/evaluation/ConstantValueFactory.java 0000644 0001750 0001750 00000007763 11736333523 023346 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.evaluation.value.*;
/**
* This class creates Value instance that correspond to specified constant pool
* entries.
*
* @author Eric Lafortune
*/
public class ConstantValueFactory
extends SimplifiedVisitor
implements ConstantVisitor
{
protected final ValueFactory valueFactory;
// Field acting as a parameter for the ConstantVisitor methods.
protected Value value;
public ConstantValueFactory(ValueFactory valueFactory)
{
this.valueFactory = valueFactory;
}
/**
* Returns the Value of the constant pool element at the given index.
*/
public Value constantValue(Clazz clazz,
int constantIndex)
{
// Visit the constant pool entry to get its return value.
clazz.constantPoolEntryAccept(constantIndex, this);
return value;
}
// Implementations for ConstantVisitor.
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
value = valueFactory.createIntegerValue(integerConstant.getValue());
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
value = valueFactory.createLongValue(longConstant.getValue());
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
value = valueFactory.createFloatValue(floatConstant.getValue());
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
value = valueFactory.createDoubleValue(doubleConstant.getValue());
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING,
stringConstant.javaLangStringClass,
false);
}
public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
{
value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE,
methodHandleConstant.javaLangInvokeMethodHandleClass,
false);
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
value = valueFactory.createReferenceValue(classConstant.getName(clazz),
classConstant.referencedClass,
false);
}
public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
{
value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE,
methodTypeConstant.javaLangInvokeMethodTypeClass,
false);
}
} proguard4.8/src/proguard/evaluation/Stack.java 0000644 0001750 0001750 00000032654 11736333523 020272 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.evaluation.value.*;
import java.util.Arrays;
/**
* This class represents an operand stack that contains Value
* objects.
*
* @author Eric Lafortune
*/
public class Stack
{
private static final TopValue TOP_VALUE = new TopValue();
protected Value[] values;
protected int currentSize;
protected int actualMaxSize;
/**
* Creates a new Stack with a given maximum size, accounting for the double
* space required by Category 2 values.
*/
public Stack(int maxSize)
{
values = new Value[maxSize];
}
/**
* Creates a Stack that is a copy of the given Stack.
*/
public Stack(Stack stack)
{
// Create the values array.
this(stack.values.length);
// Copy the stack contents.
copy(stack);
}
/**
* Returns the actual maximum stack size that was required for all stack
* operations, accounting for the double space required by Category 2 values.
*/
public int getActualMaxSize()
{
return actualMaxSize;
}
/**
* Resets this Stack, so that it can be reused.
*/
public void reset(int maxSize)
{
// Is the values array large enough?
if (maxSize > values.length)
{
// Create a new one.
values = new Value[maxSize];
}
// Clear the sizes.
clear();
actualMaxSize = 0;
}
/**
* Copies the values of the given Stack into this Stack.
*/
public void copy(Stack other)
{
// Is the values array large enough?
if (other.values.length > values.length)
{
// Create a new one.
values = new Value[other.values.length];
}
// Copy the stack contents.
System.arraycopy(other.values, 0, this.values, 0, other.currentSize);
// Copy the sizes.
currentSize = other.currentSize;
actualMaxSize = other.actualMaxSize;
}
/**
* Generalizes the values of this Stack with the values of the given Stack.
* The stacks must have the same current sizes.
* @return whether the generalization has made any difference.
*/
public boolean generalize(Stack other)
{
if (this.currentSize != other.currentSize)
{
throw new IllegalArgumentException("Stacks have different current sizes ["+this.currentSize+"] and ["+other.currentSize+"]");
}
boolean changed = false;
// Generalize the stack values.
for (int index = 0; index < currentSize; index++)
{
Value thisValue = this.values[index];
if (thisValue != null)
{
Value newValue = null;
Value otherValue = other.values[index];
if (otherValue != null)
{
newValue = thisValue.generalize(otherValue);
}
changed = changed || !thisValue.equals(newValue);
values[index] = newValue;
}
}
// Check if the other stack extends beyond this one.
if (this.actualMaxSize < other.actualMaxSize)
{
this.actualMaxSize = other.actualMaxSize;
}
return changed;
}
/**
* Clears the stack.
*/
public void clear()
{
// Clear the stack contents.
Arrays.fill(values, 0, currentSize, null);
currentSize = 0;
}
/**
* Returns the number of elements currently on the stack, accounting for the
* double space required by Category 2 values.
*/
public int size()
{
return currentSize;
}
/**
* Gets the specified Value from the stack, without disturbing it.
* @param index the index of the stack element, counting from the bottom
* of the stack.
* @return the value at the specified position.
*/
public Value getBottom(int index)
{
return values[index];
}
/**
* Sets the specified Value on the stack, without disturbing it.
* @param index the index of the stack element, counting from the bottom
* of the stack.
* @param value the value to set.
*/
public void setBottom(int index, Value value)
{
values[index] = value;
}
/**
* Gets the specified Value from the stack, without disturbing it.
* @param index the index of the stack element, counting from the top
* of the stack.
* @return the value at the specified position.
*/
public Value getTop(int index)
{
return values[currentSize - index - 1];
}
/**
* Sets the specified Value on the stack, without disturbing it.
* @param index the index of the stack element, counting from the top
* of the stack.
* @param value the value to set.
*/
public void setTop(int index, Value value)
{
values[currentSize - index - 1] = value;
}
/**
* Removes the specified Value from the stack.
* @param index the index of the stack element, counting from the top
* of the stack.
*/
public void removeTop(int index)
{
System.arraycopy(values, currentSize - index,
values, currentSize - index - 1,
index);
currentSize--;
}
/**
* Pushes the given Value onto the stack.
*/
public void push(Value value)
{
// Account for the extra space required by Category 2 values.
if (value.isCategory2())
{
values[currentSize++] = TOP_VALUE;
}
// Push the value.
values[currentSize++] = value;
// Update the maximum actual size;
if (actualMaxSize < currentSize)
{
actualMaxSize = currentSize;
}
}
/**
* Pops the top Value from the stack.
*/
public Value pop()
{
Value value = values[--currentSize];
values[currentSize] = null;
// Account for the extra space required by Category 2 values.
if (value.isCategory2())
{
values[--currentSize] = null;
}
return value;
}
// Pop methods that provide convenient casts to the expected value types.
/**
* Pops the top IntegerValue from the stack.
*/
public IntegerValue ipop()
{
return pop().integerValue();
}
/**
* Pops the top LongValue from the stack.
*/
public LongValue lpop()
{
return pop().longValue();
}
/**
* Pops the top FloatValue from the stack.
*/
public FloatValue fpop()
{
return pop().floatValue();
}
/**
* Pops the top DoubleValue from the stack.
*/
public DoubleValue dpop()
{
return pop().doubleValue();
}
/**
* Pops the top ReferenceValue from the stack.
*/
public ReferenceValue apop()
{
return pop().referenceValue();
}
/**
* Pops the top InstructionOffsetValue from the stack.
*/
public InstructionOffsetValue opop()
{
return pop().instructionOffsetValue();
}
/**
* Pops the top category 1 value from the stack.
*/
public void pop1()
{
values[--currentSize] = null;
}
/**
* Pops the top category 2 value from the stack (or alternatively, two
* Category 1 stack elements).
*/
public void pop2()
{
values[--currentSize] = null;
values[--currentSize] = null;
}
/**
* Duplicates the top Category 1 value.
*/
public void dup()
{
values[currentSize] = values[currentSize - 1].category1Value();
currentSize++;
// Update the maximum actual size;
if (actualMaxSize < currentSize)
{
actualMaxSize = currentSize;
}
}
/**
* Duplicates the top Category 1 value, one Category 1 element down the
* stack.
*/
public void dup_x1()
{
values[currentSize] = values[currentSize - 1].category1Value();
values[currentSize - 1] = values[currentSize - 2].category1Value();
values[currentSize - 2] = values[currentSize ];
currentSize++;
// Update the maximum actual size;
if (actualMaxSize < currentSize)
{
actualMaxSize = currentSize;
}
}
/**
* Duplicates the top Category 1 value, two Category 1 elements (or one
* Category 2 element) down the stack.
*/
public void dup_x2()
{
values[currentSize] = values[currentSize - 1].category1Value();
values[currentSize - 1] = values[currentSize - 2];
values[currentSize - 2] = values[currentSize - 3];
values[currentSize - 3] = values[currentSize ];
currentSize++;
// Update the maximum actual size;
if (actualMaxSize < currentSize)
{
actualMaxSize = currentSize;
}
}
/**
* Duplicates the top Category 2 value (or alternatively, the equivalent
* Category 1 stack elements).
*/
public void dup2()
{
values[currentSize ] = values[currentSize - 2];
values[currentSize + 1] = values[currentSize - 1];
currentSize += 2;
// Update the maximum actual size;
if (actualMaxSize < currentSize)
{
actualMaxSize = currentSize;
}
}
/**
* Duplicates the top Category 2 value, one Category 1 element down the
* stack (or alternatively, the equivalent Category 1 stack values).
*/
public void dup2_x1()
{
values[currentSize + 1] = values[currentSize - 1];
values[currentSize ] = values[currentSize - 2];
values[currentSize - 1] = values[currentSize - 3];
values[currentSize - 2] = values[currentSize + 1];
values[currentSize - 3] = values[currentSize ];
currentSize += 2;
// Update the maximum actual size;
if (actualMaxSize < currentSize)
{
actualMaxSize = currentSize;
}
}
/**
* Duplicates the top Category 2 value, one Category 2 stack element down
* the stack (or alternatively, the equivalent Category 1 stack values).
*/
public void dup2_x2()
{
values[currentSize + 1] = values[currentSize - 1];
values[currentSize ] = values[currentSize - 2];
values[currentSize - 1] = values[currentSize - 3];
values[currentSize - 2] = values[currentSize - 4];
values[currentSize - 3] = values[currentSize + 1];
values[currentSize - 4] = values[currentSize ];
currentSize += 2;
// Update the maximum actual size;
if (actualMaxSize < currentSize)
{
actualMaxSize = currentSize;
}
}
/**
* Swaps the top two Category 1 values.
*/
public void swap()
{
Value value1 = values[currentSize - 1].category1Value();
Value value2 = values[currentSize - 2].category1Value();
values[currentSize - 1] = value2;
values[currentSize - 2] = value1;
}
// Implementations for Object.
public boolean equals(Object object)
{
if (object == null ||
this.getClass() != object.getClass())
{
return false;
}
Stack other = (Stack)object;
if (this.currentSize != other.currentSize)
{
return false;
}
for (int index = 0; index < currentSize; index++)
{
Value thisValue = this.values[index];
Value otherValue = other.values[index];
if (thisValue == null ? otherValue != null :
!thisValue.equals(otherValue))
{
return false;
}
}
return true;
}
public int hashCode()
{
int hashCode = currentSize;
for (int index = 0; index < currentSize; index++)
{
Value value = values[index];
if (value != null)
{
hashCode ^= value.hashCode();
}
}
return hashCode;
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
for (int index = 0; index < currentSize; index++)
{
Value value = values[index];
buffer = buffer.append('[')
.append(value == null ? "empty" : value.toString())
.append(']');
}
return buffer.toString();
}
}
proguard4.8/src/proguard/evaluation/BasicInvocationUnit.java 0000644 0001750 0001750 00000033267 11736333523 023141 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
import proguard.evaluation.value.*;
/**
* This InvocationUnit sets up the variables for entering a method,
* and it updates the stack for the invocation of a class member,
* using simple values.
*
* @author Eric Lafortune
*/
public class BasicInvocationUnit
extends SimplifiedVisitor
implements InvocationUnit,
ConstantVisitor,
MemberVisitor
{
protected final ValueFactory valueFactory;
// Fields acting as parameters between the visitor methods.
private boolean isStatic;
private boolean isLoad;
private Stack stack;
private Clazz returnTypeClass;
/**
* Creates a new BasicInvocationUnit with the given value factory.
*/
public BasicInvocationUnit(ValueFactory valueFactory)
{
this.valueFactory = valueFactory;
}
// Implementations for InvocationUnit.
public void enterMethod(Clazz clazz, Method method, Variables variables)
{
String descriptor = method.getDescriptor(clazz);
// Initialize the parameters.
boolean isStatic =
(method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0;
// Count the number of parameters, taking into account their categories.
int parameterSize = ClassUtil.internalMethodParameterSize(descriptor, isStatic);
// Reuse the existing parameters object, ensuring the right size.
variables.reset(parameterSize);
// Go over the parameters again.
InternalTypeEnumeration internalTypeEnumeration =
new InternalTypeEnumeration(descriptor);
int parameterIndex = 0;
int variableIndex = 0;
// Put the 'this' reference in variable 0.
if (!isStatic)
{
// Get the reference value.
Value value = getMethodParameterValue(clazz,
method,
parameterIndex++,
ClassUtil.internalTypeFromClassName(clazz.getName()),
clazz);
// Store the value in variable 0.
variables.store(variableIndex++, value);
}
Clazz[] referencedClasses = ((ProgramMethod)method).referencedClasses;
int referencedClassIndex = 0;
// Set up the variables corresponding to the parameter types and values.
while (internalTypeEnumeration.hasMoreTypes())
{
String type = internalTypeEnumeration.nextType();
Clazz referencedClass = referencedClasses != null &&
ClassUtil.isInternalClassType(type) ?
referencedClasses[referencedClassIndex++] :
null;
// Get the parameter value.
Value value = getMethodParameterValue(clazz,
method,
parameterIndex++,
type,
referencedClass);
// Store the value in the corresponding variable.
variables.store(variableIndex++, value);
// Increment the variable index again for Category 2 values.
if (value.isCategory2())
{
variableIndex++;
}
}
}
public void exitMethod(Clazz clazz, Method method, Value returnValue)
{
setMethodReturnValue(clazz, method, returnValue);
}
public void invokeMember(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction, Stack stack)
{
int constantIndex = constantInstruction.constantIndex;
switch (constantInstruction.opcode)
{
case InstructionConstants.OP_GETSTATIC:
isStatic = true;
isLoad = true;
break;
case InstructionConstants.OP_PUTSTATIC:
isStatic = true;
isLoad = false;
break;
case InstructionConstants.OP_GETFIELD:
isStatic = false;
isLoad = true;
break;
case InstructionConstants.OP_PUTFIELD:
isStatic = false;
isLoad = false;
break;
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEDYNAMIC:
isStatic = true;
break;
case InstructionConstants.OP_INVOKEVIRTUAL:
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKEINTERFACE:
isStatic = false;
break;
}
// Pop the parameters and push the return value.
this.stack = stack;
clazz.constantPoolEntryAccept(constantIndex, this);
this.stack = null;
}
// Implementations for ConstantVisitor.
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
// Pop the field value, if applicable.
if (!isLoad)
{
setFieldValue(clazz, fieldrefConstant, stack.pop());
}
// Pop the reference value, if applicable.
if (!isStatic)
{
setFieldClassValue(clazz, fieldrefConstant, stack.apop());
}
// Push the field value, if applicable.
if (isLoad)
{
String type = fieldrefConstant.getType(clazz);
stack.push(getFieldValue(clazz, fieldrefConstant, type));
}
}
public void visitAnyMethodrefConstant(Clazz clazz, RefConstant methodrefConstant)
{
String type = methodrefConstant.getType(clazz);
// Count the number of parameters.
int parameterCount = ClassUtil.internalMethodParameterCount(type);
if (!isStatic)
{
parameterCount++;
}
// Pop the parameters and the class reference, in reverse order.
for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--)
{
setMethodParameterValue(clazz, methodrefConstant, parameterIndex, stack.pop());
}
// Push the return value, if applicable.
String returnType = ClassUtil.internalMethodReturnType(type);
if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID)
{
stack.push(getMethodReturnValue(clazz, methodrefConstant, returnType));
}
}
public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
{
String type = invokeDynamicConstant.getType(clazz);
// Count the number of parameters.
int parameterCount = ClassUtil.internalMethodParameterCount(type);
if (!isStatic)
{
parameterCount++;
}
// Pop the parameters and the class reference, in reverse order.
for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--)
{
stack.pop();
}
// Push the return value, if applicable.
String returnType = ClassUtil.internalMethodReturnType(type);
if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID)
{
stack.push(getMethodReturnValue(clazz, invokeDynamicConstant, returnType));
}
}
/**
* Sets the class through which the specified field is accessed.
*/
protected void setFieldClassValue(Clazz clazz,
RefConstant refConstant,
ReferenceValue value)
{
// We don't care about the new value.
}
/**
* Returns the class though which the specified field is accessed.
*/
protected Value getFieldClassValue(Clazz clazz,
RefConstant refConstant,
String type)
{
// Try to figure out the class of the return type.
returnTypeClass = null;
refConstant.referencedMemberAccept(this);
return valueFactory.createValue(type,
returnTypeClass,
true);
}
/**
* Sets the value of the specified field.
*/
protected void setFieldValue(Clazz clazz,
RefConstant refConstant,
Value value)
{
// We don't care about the new field value.
}
/**
* Returns the value of the specified field.
*/
protected Value getFieldValue(Clazz clazz,
RefConstant refConstant,
String type)
{
// Try to figure out the class of the return type.
returnTypeClass = null;
refConstant.referencedMemberAccept(this);
return valueFactory.createValue(type,
returnTypeClass,
true);
}
/**
* Sets the value of the specified method parameter.
*/
protected void setMethodParameterValue(Clazz clazz,
RefConstant refConstant,
int parameterIndex,
Value value)
{
// We don't care about the parameter value.
}
/**
* Returns the value of the specified method parameter.
*/
protected Value getMethodParameterValue(Clazz clazz,
Method method,
int parameterIndex,
String type,
Clazz referencedClass)
{
return valueFactory.createValue(type, referencedClass, true);
}
/**
* Sets the return value of the specified method.
*/
protected void setMethodReturnValue(Clazz clazz,
Method method,
Value value)
{
// We don't care about the return value.
}
/**
* Returns the return value of the specified method.
*/
protected Value getMethodReturnValue(Clazz clazz,
RefConstant refConstant,
String type)
{
// Try to figure out the class of the return type.
returnTypeClass = null;
refConstant.referencedMemberAccept(this);
return valueFactory.createValue(type,
returnTypeClass,
true);
}
/**
* Returns the return value of the specified method.
*/
protected Value getMethodReturnValue(Clazz clazz,
InvokeDynamicConstant invokeDynamicConstant,
String type)
{
// Try to figure out the class of the return type.
Clazz[] referencedClasses = invokeDynamicConstant.referencedClasses;
Clazz returnTypeClass = referencedClasses == null ? null :
referencedClasses[referencedClasses.length - 1];
return valueFactory.createValue(type,
returnTypeClass,
true);
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
returnTypeClass = programField.referencedClass;
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
Clazz[] referencedClasses = programMethod.referencedClasses;
if (referencedClasses != null)
{
returnTypeClass = referencedClasses[referencedClasses.length - 1];
}
}
public void visitLibraryField(LibraryClass programClass, LibraryField programField)
{
returnTypeClass = programField.referencedClass;
}
public void visitLibraryMethod(LibraryClass programClass, LibraryMethod programMethod)
{
Clazz[] referencedClasses = programMethod.referencedClasses;
if (referencedClasses != null)
{
returnTypeClass = referencedClasses[referencedClasses.length - 1];
}
}
// public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
// {
// }
}
proguard4.8/src/proguard/evaluation/TracedStack.java 0000644 0001750 0001750 00000017127 11736333523 021413 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.evaluation;
import proguard.evaluation.value.Value;
/**
* This Stack saves additional information with stack elements, to keep track
* of their origins and destinations.
*
* The stack stores a given producer Value along with each Value it stores.
* It then generalizes a given collected Value with the producer Value
* of each Value it loads. The producer Value and the initial collected Value
* can be set; the generalized collected Value can be retrieved.
*
* @author Eric Lafortune
*/
public class TracedStack extends Stack
{
private Value producerValue;
private Stack producerStack;
/**
* Creates a new TracedStack with a given maximum size.
*/
public TracedStack(int maxSize)
{
super(maxSize);
producerStack = new Stack(maxSize);
}
/**
* Creates a new TracedStack that is a copy of the given TracedStack.
*/
public TracedStack(TracedStack tracedStack)
{
super(tracedStack);
producerStack = new Stack(tracedStack.producerStack);
}
/**
* Sets the Value that will be stored along with all push and pop
* instructions.
*/
public void setProducerValue(Value producerValue)
{
this.producerValue = producerValue;
}
/**
* Gets the specified producer Value from the stack, without disturbing it.
* @param index the index of the stack element, counting from the bottom
* of the stack.
* @return the producer value at the specified position.
*/
public Value getBottomProducerValue(int index)
{
return producerStack.getBottom(index);
}
/**
* Sets the specified producer Value on the stack, without disturbing it.
* @param index the index of the stack element, counting from the bottom
* of the stack.
* @param value the producer value to set.
*/
public void setBottomProducerValue(int index, Value value)
{
producerStack.setBottom(index, value);
}
/**
* Gets the specified producer Value from the stack, without disturbing it.
* @param index the index of the stack element, counting from the top
* of the stack.
* @return the producer value at the specified position.
*/
public Value getTopProducerValue(int index)
{
return producerStack.getTop(index);
}
/**
* Sets the specified producer Value on the stack, without disturbing it.
* @param index the index of the stack element, counting from the top
* of the stack.
* @param value the producer value to set.
*/
public void setTopProducerValue(int index, Value value)
{
producerStack.setTop(index, value);
}
// Implementations for Stack.
public void reset(int size)
{
super.reset(size);
producerStack.reset(size);
}
public void copy(TracedStack other)
{
super.copy(other);
producerStack.copy(other.producerStack);
}
public boolean generalize(TracedStack other)
{
return
super.generalize(other) |
producerStack.generalize(other.producerStack);
}
public void clear()
{
super.clear();
producerStack.clear();
}
public void removeTop(int index)
{
super.removeTop(index);
producerStack.removeTop(index);
}
public void push(Value value)
{
super.push(value);
producerPush();
// Account for the extra space required by Category 2 values.
if (value.isCategory2())
{
producerPush();
}
}
public Value pop()
{
Value value = super.pop();
producerPop();
// Account for the extra space required by Category 2 values.
if (value.isCategory2())
{
producerPop();
}
return value;
}
public void pop1()
{
super.pop1();
producerPop();
}
public void pop2()
{
super.pop2();
producerPop();
producerPop();
}
public void dup()
{
super.dup();
producerPop();
producerPush();
producerPush();
}
public void dup_x1()
{
super.dup_x1();
producerPop();
producerPop();
producerPush();
producerPush();
producerPush();
}
public void dup_x2()
{
super.dup_x2();
producerPop();
producerPop();
producerPop();
producerPush();
producerPush();
producerPush();
producerPush();
}
public void dup2()
{
super.dup2();
producerPop();
producerPop();
producerPush();
producerPush();
producerPush();
producerPush();
}
public void dup2_x1()
{
super.dup2_x1();
producerPop();
producerPop();
producerPop();
producerPush();
producerPush();
producerPush();
producerPush();
producerPush();
}
public void dup2_x2()
{
super.dup2_x2();
producerPop();
producerPop();
producerPop();
producerPop();
producerPush();
producerPush();
producerPush();
producerPush();
producerPush();
producerPush();
}
public void swap()
{
super.swap();
producerPop();
producerPop();
producerPush();
producerPush();
}
// Implementations for Object.
public boolean equals(Object object)
{
if (object == null ||
this.getClass() != object.getClass())
{
return false;
}
TracedStack other = (TracedStack)object;
return super.equals(object) &&
this.producerStack.equals(other.producerStack);
}
public int hashCode()
{
return super.hashCode() ^
producerStack.hashCode();
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
for (int index = 0; index < this.size(); index++)
{
Value value = this.values[index];
Value producerValue = producerStack.getBottom(index);
buffer = buffer.append('[')
.append(producerValue == null ? "empty:" : producerValue.toString())
.append(value == null ? "empty" : value.toString())
.append(']');
}
return buffer.toString();
}
// Small utility methods.
private void producerPush()
{
producerStack.push(producerValue);
}
private void producerPop()
{
producerStack.pop();
}
}
proguard4.8/src/proguard/ArgumentWordReader.java 0000644 0001750 0001750 00000005375 11736333523 020617 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import java.io.*;
/**
* A WordReader
that returns words from an argument list.
* Single arguments are split into individual words if necessary.
*
* @author Eric Lafortune
*/
public class ArgumentWordReader extends WordReader
{
private final String[] arguments;
private int index = 0;
// /**
// * Creates a new ArgumentWordReader for the given arguments.
// */
// public ArgumentWordReader(String[] arguments)
// {
// this(arguments, null);
// }
//
//
/**
* Creates a new ArgumentWordReader for the given arguments, with the
* given base directory.
*/
public ArgumentWordReader(String[] arguments, File baseDir)
{
super(baseDir);
this.arguments = arguments;
}
// Implementations for WordReader.
protected String nextLine() throws IOException
{
return index < arguments.length ?
arguments[index++] :
null;
}
protected String lineLocationDescription()
{
return "argument number " + index;
}
/**
* Test application that prints out the individual words of
* the argument list.
*/
public static void main(String[] args) {
try
{
WordReader reader = new ArgumentWordReader(args, null);
try
{
while (true)
{
String word = reader.nextWord(false);
if (word == null)
System.exit(-1);
System.err.println("["+word+"]");
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
reader.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
proguard4.8/src/proguard/classfile/ 0000775 0001750 0001750 00000000000 11760503005 016137 5 ustar eric eric proguard4.8/src/proguard/classfile/LibraryMethod.java 0000644 0001750 0001750 00000004622 11736333523 021562 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.visitor.*;
/**
* Representation of a method from a class-file.
*
* @author Eric Lafortune
*/
public class LibraryMethod extends LibraryMember implements Method
{
/**
* An extra field pointing to the Clazz objects referenced in the
* descriptor string. This field is filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz[] referencedClasses;
/**
* Creates an uninitialized LibraryMethod.
*/
public LibraryMethod()
{
}
/**
* Creates an initialized LibraryMethod.
*/
public LibraryMethod(int u2accessFlags,
String name,
String descriptor)
{
super(u2accessFlags, name, descriptor);
}
// Implementations for LibraryMember.
public void accept(LibraryClass libraryClass, MemberVisitor memberVisitor)
{
memberVisitor.visitLibraryMethod(libraryClass, this);
}
// Implementations for Member.
public void referencedClassesAccept(ClassVisitor classVisitor)
{
if (referencedClasses != null)
{
for (int index = 0; index < referencedClasses.length; index++)
{
if (referencedClasses[index] != null)
{
referencedClasses[index].accept(classVisitor);
}
}
}
}
}
proguard4.8/src/proguard/classfile/package.html 0000644 0001750 0001750 00000001230 11736333523 020423 0 ustar eric eric
A class file is represented by the {@link proguard.classfile.ClassFile
ClassFile}
interface. This interface currently has two alternative
representations:
{@link ProgramClassFile ProgramClassFile}
:
a complete representation that can be read, modified, and written back.
{@link LibraryClassFile LibraryClassFile}
:
an incomplete representation that can be only be read. It is however
more compact than ProgramClassFile
, and sufficient for
analyzing class files from library jars.
Not every instruction currently has its own class. Only groups of instructions that refer to the constant pool get their own representations.
While the package is sufficient for the current needs of the ProGuard application, it may very well be reorganised and extended in the future. proguard4.8/src/proguard/classfile/instruction/InstructionFactory.java 0000644 0001750 0001750 00000030370 11736333523 025246 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction; /** * This class provides methods to create and reuse Instruction objects. * * @author Eric Lafortune */ public class InstructionFactory { /** * Creates a new Instruction from the data in the byte array, starting * at the given index. */ public static Instruction create(byte[] code, int offset) { Instruction instruction; int index = offset; byte opcode = code[index++]; boolean wide = false; if (opcode == InstructionConstants.OP_WIDE) { opcode = code[index++]; wide = true; } switch (opcode) { // Simple instructions. case InstructionConstants.OP_NOP: case InstructionConstants.OP_ACONST_NULL: case InstructionConstants.OP_ICONST_M1: case InstructionConstants.OP_ICONST_0: case InstructionConstants.OP_ICONST_1: case InstructionConstants.OP_ICONST_2: case InstructionConstants.OP_ICONST_3: case InstructionConstants.OP_ICONST_4: case InstructionConstants.OP_ICONST_5: case InstructionConstants.OP_LCONST_0: case InstructionConstants.OP_LCONST_1: case InstructionConstants.OP_FCONST_0: case InstructionConstants.OP_FCONST_1: case InstructionConstants.OP_FCONST_2: case InstructionConstants.OP_DCONST_0: case InstructionConstants.OP_DCONST_1: case InstructionConstants.OP_BIPUSH: case InstructionConstants.OP_SIPUSH: case InstructionConstants.OP_IALOAD: case InstructionConstants.OP_LALOAD: case InstructionConstants.OP_FALOAD: case InstructionConstants.OP_DALOAD: case InstructionConstants.OP_AALOAD: case InstructionConstants.OP_BALOAD: case InstructionConstants.OP_CALOAD: case InstructionConstants.OP_SALOAD: case InstructionConstants.OP_IASTORE: case InstructionConstants.OP_LASTORE: case InstructionConstants.OP_FASTORE: case InstructionConstants.OP_DASTORE: case InstructionConstants.OP_AASTORE: case InstructionConstants.OP_BASTORE: case InstructionConstants.OP_CASTORE: case InstructionConstants.OP_SASTORE: case InstructionConstants.OP_POP: case InstructionConstants.OP_POP2: case InstructionConstants.OP_DUP: case InstructionConstants.OP_DUP_X1: case InstructionConstants.OP_DUP_X2: case InstructionConstants.OP_DUP2: case InstructionConstants.OP_DUP2_X1: case InstructionConstants.OP_DUP2_X2: case InstructionConstants.OP_SWAP: case InstructionConstants.OP_IADD: case InstructionConstants.OP_LADD: case InstructionConstants.OP_FADD: case InstructionConstants.OP_DADD: case InstructionConstants.OP_ISUB: case InstructionConstants.OP_LSUB: case InstructionConstants.OP_FSUB: case InstructionConstants.OP_DSUB: case InstructionConstants.OP_IMUL: case InstructionConstants.OP_LMUL: case InstructionConstants.OP_FMUL: case InstructionConstants.OP_DMUL: case InstructionConstants.OP_IDIV: case InstructionConstants.OP_LDIV: case InstructionConstants.OP_FDIV: case InstructionConstants.OP_DDIV: case InstructionConstants.OP_IREM: case InstructionConstants.OP_LREM: case InstructionConstants.OP_FREM: case InstructionConstants.OP_DREM: case InstructionConstants.OP_INEG: case InstructionConstants.OP_LNEG: case InstructionConstants.OP_FNEG: case InstructionConstants.OP_DNEG: case InstructionConstants.OP_ISHL: case InstructionConstants.OP_LSHL: case InstructionConstants.OP_ISHR: case InstructionConstants.OP_LSHR: case InstructionConstants.OP_IUSHR: case InstructionConstants.OP_LUSHR: case InstructionConstants.OP_IAND: case InstructionConstants.OP_LAND: case InstructionConstants.OP_IOR: case InstructionConstants.OP_LOR: case InstructionConstants.OP_IXOR: case InstructionConstants.OP_LXOR: case InstructionConstants.OP_I2L: case InstructionConstants.OP_I2F: case InstructionConstants.OP_I2D: case InstructionConstants.OP_L2I: case InstructionConstants.OP_L2F: case InstructionConstants.OP_L2D: case InstructionConstants.OP_F2I: case InstructionConstants.OP_F2L: case InstructionConstants.OP_F2D: case InstructionConstants.OP_D2I: case InstructionConstants.OP_D2L: case InstructionConstants.OP_D2F: case InstructionConstants.OP_I2B: case InstructionConstants.OP_I2C: case InstructionConstants.OP_I2S: case InstructionConstants.OP_LCMP: case InstructionConstants.OP_FCMPL: case InstructionConstants.OP_FCMPG: case InstructionConstants.OP_DCMPL: case InstructionConstants.OP_DCMPG: case InstructionConstants.OP_IRETURN: case InstructionConstants.OP_LRETURN: case InstructionConstants.OP_FRETURN: case InstructionConstants.OP_DRETURN: case InstructionConstants.OP_ARETURN: case InstructionConstants.OP_RETURN: case InstructionConstants.OP_NEWARRAY: case InstructionConstants.OP_ARRAYLENGTH: case InstructionConstants.OP_ATHROW: case InstructionConstants.OP_MONITORENTER: case InstructionConstants.OP_MONITOREXIT: instruction = new SimpleInstruction(); break; // Instructions with a contant pool index. case InstructionConstants.OP_LDC: case InstructionConstants.OP_LDC_W: case InstructionConstants.OP_LDC2_W: case InstructionConstants.OP_GETSTATIC: case InstructionConstants.OP_PUTSTATIC: case InstructionConstants.OP_GETFIELD: case InstructionConstants.OP_PUTFIELD: case InstructionConstants.OP_INVOKEVIRTUAL: case InstructionConstants.OP_INVOKESPECIAL: case InstructionConstants.OP_INVOKESTATIC: case InstructionConstants.OP_INVOKEINTERFACE: case InstructionConstants.OP_INVOKEDYNAMIC: case InstructionConstants.OP_NEW: case InstructionConstants.OP_ANEWARRAY: case InstructionConstants.OP_CHECKCAST: case InstructionConstants.OP_INSTANCEOF: case InstructionConstants.OP_MULTIANEWARRAY: instruction = new ConstantInstruction(); break; // Instructions with a local variable index. case InstructionConstants.OP_ILOAD: case InstructionConstants.OP_LLOAD: case InstructionConstants.OP_FLOAD: case InstructionConstants.OP_DLOAD: case InstructionConstants.OP_ALOAD: case InstructionConstants.OP_ILOAD_0: case InstructionConstants.OP_ILOAD_1: case InstructionConstants.OP_ILOAD_2: case InstructionConstants.OP_ILOAD_3: case InstructionConstants.OP_LLOAD_0: case InstructionConstants.OP_LLOAD_1: case InstructionConstants.OP_LLOAD_2: case InstructionConstants.OP_LLOAD_3: case InstructionConstants.OP_FLOAD_0: case InstructionConstants.OP_FLOAD_1: case InstructionConstants.OP_FLOAD_2: case InstructionConstants.OP_FLOAD_3: case InstructionConstants.OP_DLOAD_0: case InstructionConstants.OP_DLOAD_1: case InstructionConstants.OP_DLOAD_2: case InstructionConstants.OP_DLOAD_3: case InstructionConstants.OP_ALOAD_0: case InstructionConstants.OP_ALOAD_1: case InstructionConstants.OP_ALOAD_2: case InstructionConstants.OP_ALOAD_3: case InstructionConstants.OP_ISTORE: case InstructionConstants.OP_LSTORE: case InstructionConstants.OP_FSTORE: case InstructionConstants.OP_DSTORE: case InstructionConstants.OP_ASTORE: case InstructionConstants.OP_ISTORE_0: case InstructionConstants.OP_ISTORE_1: case InstructionConstants.OP_ISTORE_2: case InstructionConstants.OP_ISTORE_3: case InstructionConstants.OP_LSTORE_0: case InstructionConstants.OP_LSTORE_1: case InstructionConstants.OP_LSTORE_2: case InstructionConstants.OP_LSTORE_3: case InstructionConstants.OP_FSTORE_0: case InstructionConstants.OP_FSTORE_1: case InstructionConstants.OP_FSTORE_2: case InstructionConstants.OP_FSTORE_3: case InstructionConstants.OP_DSTORE_0: case InstructionConstants.OP_DSTORE_1: case InstructionConstants.OP_DSTORE_2: case InstructionConstants.OP_DSTORE_3: case InstructionConstants.OP_ASTORE_0: case InstructionConstants.OP_ASTORE_1: case InstructionConstants.OP_ASTORE_2: case InstructionConstants.OP_ASTORE_3: case InstructionConstants.OP_IINC: case InstructionConstants.OP_RET: instruction = new VariableInstruction(wide); break; // Instructions with a branch offset operand. case InstructionConstants.OP_IFEQ: case InstructionConstants.OP_IFNE: case InstructionConstants.OP_IFLT: case InstructionConstants.OP_IFGE: case InstructionConstants.OP_IFGT: case InstructionConstants.OP_IFLE: case InstructionConstants.OP_IFICMPEQ: case InstructionConstants.OP_IFICMPNE: case InstructionConstants.OP_IFICMPLT: case InstructionConstants.OP_IFICMPGE: case InstructionConstants.OP_IFICMPGT: case InstructionConstants.OP_IFICMPLE: case InstructionConstants.OP_IFACMPEQ: case InstructionConstants.OP_IFACMPNE: case InstructionConstants.OP_GOTO: case InstructionConstants.OP_JSR: case InstructionConstants.OP_IFNULL: case InstructionConstants.OP_IFNONNULL: case InstructionConstants.OP_GOTO_W: case InstructionConstants.OP_JSR_W: instruction = new BranchInstruction(); break; // The tableswitch instruction. case InstructionConstants.OP_TABLESWITCH: instruction = new TableSwitchInstruction(); break; // The lookupswitch instruction. case InstructionConstants.OP_LOOKUPSWITCH: instruction = new LookUpSwitchInstruction(); break; default: throw new IllegalArgumentException("Unknown instruction opcode ["+opcode+"] at offset "+offset); } instruction.opcode = opcode; instruction.readInfo(code, index); return instruction; } } proguard4.8/src/proguard/classfile/instruction/Instruction.java 0000644 0001750 0001750 00000053733 11736333523 023726 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction; import proguard.classfile.*; import proguard.classfile.attribute.CodeAttribute; import proguard.classfile.instruction.visitor.InstructionVisitor; /** * Base class for representing instructions. * * @author Eric Lafortune */ public abstract class Instruction { // An array for marking Category 2 instructions. private static final boolean[] IS_CATEGORY2 = new boolean[] { false, // nop false, // aconst_null false, // iconst_m1 false, // iconst_0 false, // iconst_1 false, // iconst_2 false, // iconst_3 false, // iconst_4 false, // iconst_5 true, // lconst_0 true, // lconst_1 false, // fconst_0 false, // fconst_1 false, // fconst_2 true, // dconst_0 true, // dconst_1 false, // bipush false, // sipush false, // ldc false, // ldc_w true, // ldc2_w false, // iload true, // lload false, // fload true, // dload false, // aload false, // iload_0 false, // iload_1 false, // iload_2 false, // iload_3 true, // lload_0 true, // lload_1 true, // lload_2 true, // lload_3 false, // fload_0 false, // fload_1 false, // fload_2 false, // fload_3 true, // dload_0 true, // dload_1 true, // dload_2 true, // dload_3 false, // aload_0 false, // aload_1 false, // aload_2 false, // aload_3 false, // iaload true, // laload false, // faload true, // daload false, // aaload false, // baload false, // caload false, // saload false, // istore true, // lstore false, // fstore true, // dstore false, // astore false, // istore_0 false, // istore_1 false, // istore_2 false, // istore_3 true, // lstore_0 true, // lstore_1 true, // lstore_2 true, // lstore_3 false, // fstore_0 false, // fstore_1 false, // fstore_2 false, // fstore_3 true, // dstore_0 true, // dstore_1 true, // dstore_2 true, // dstore_3 false, // astore_0 false, // astore_1 false, // astore_2 false, // astore_3 false, // iastore true, // lastore false, // fastore true, // dastore false, // aastore false, // bastore false, // castore false, // sastore false, // pop true, // pop2 false, // dup false, // dup_x1 false, // dup_x2 true, // dup2 true, // dup2_x1 true, // dup2_x2 false, // swap false, // iadd true, // ladd false, // fadd true, // dadd false, // isub true, // lsub false, // fsub true, // dsub false, // imul true, // lmul false, // fmul true, // dmul false, // idiv true, // ldiv false, // fdiv true, // ddiv false, // irem true, // lrem false, // frem true, // drem false, // ineg true, // lneg false, // fneg true, // dneg false, // ishl true, // lshl false, // ishr true, // lshr false, // iushr true, // lushr false, // iand true, // land false, // ior true, // lor false, // ixor true, // lxor false, // iinc false, // i2l false, // i2f false, // i2d true, // l2i true, // l2f true, // l2d false, // f2i false, // f2l false, // f2d true, // d2i true, // d2l true, // d2f false, // i2b false, // i2c false, // i2s true, // lcmp false, // fcmpl false, // fcmpg true, // dcmpl true, // dcmpg false, // ifeq false, // ifne false, // iflt false, // ifge false, // ifgt false, // ifle false, // ificmpeq false, // ificmpne false, // ificmplt false, // ificmpge false, // ificmpgt false, // ificmple false, // ifacmpeq false, // ifacmpne false, // goto false, // jsr false, // ret false, // tableswitch false, // lookupswitch false, // ireturn true, // lreturn false, // freturn true, // dreturn false, // areturn false, // return false, // getstatic false, // putstatic false, // getfield false, // putfield false, // invokevirtual false, // invokespecial false, // invokestatic false, // invokeinterface false, // invokedynamic false, // new false, // newarray false, // anewarray false, // arraylength false, // athrow false, // checkcast false, // instanceof false, // monitorenter false, // monitorexit false, // wide false, // multianewarray false, // ifnull false, // ifnonnull false, // goto_w false, // jsr_w }; // An array containing the fixed number of entries popped from the stack, // for all instructions. private static final int[] STACK_POP_COUNTS = new int[] { 0, // nop 0, // aconst_null 0, // iconst_m1 0, // iconst_0 0, // iconst_1 0, // iconst_2 0, // iconst_3 0, // iconst_4 0, // iconst_5 0, // lconst_0 0, // lconst_1 0, // fconst_0 0, // fconst_1 0, // fconst_2 0, // dconst_0 0, // dconst_1 0, // bipush 0, // sipush 0, // ldc 0, // ldc_w 0, // ldc2_w 0, // iload 0, // lload 0, // fload 0, // dload 0, // aload 0, // iload_0 0, // iload_1 0, // iload_2 0, // iload_3 0, // lload_0 0, // lload_1 0, // lload_2 0, // lload_3 0, // fload_0 0, // fload_1 0, // fload_2 0, // fload_3 0, // dload_0 0, // dload_1 0, // dload_2 0, // dload_3 0, // aload_0 0, // aload_1 0, // aload_2 0, // aload_3 2, // iaload 2, // laload 2, // faload 2, // daload 2, // aaload 2, // baload 2, // caload 2, // saload 1, // istore 2, // lstore 1, // fstore 2, // dstore 1, // astore 1, // istore_0 1, // istore_1 1, // istore_2 1, // istore_3 2, // lstore_0 2, // lstore_1 2, // lstore_2 2, // lstore_3 1, // fstore_0 1, // fstore_1 1, // fstore_2 1, // fstore_3 2, // dstore_0 2, // dstore_1 2, // dstore_2 2, // dstore_3 1, // astore_0 1, // astore_1 1, // astore_2 1, // astore_3 3, // iastore 4, // lastore 3, // fastore 4, // dastore 3, // aastore 3, // bastore 3, // castore 3, // sastore 1, // pop 2, // pop2 1, // dup 2, // dup_x1 3, // dup_x2 2, // dup2 3, // dup2_x1 4, // dup2_x2 2, // swap 2, // iadd 4, // ladd 2, // fadd 4, // dadd 2, // isub 4, // lsub 2, // fsub 4, // dsub 2, // imul 4, // lmul 2, // fmul 4, // dmul 2, // idiv 4, // ldiv 2, // fdiv 4, // ddiv 2, // irem 4, // lrem 2, // frem 4, // drem 1, // ineg 2, // lneg 1, // fneg 2, // dneg 2, // ishl 3, // lshl 2, // ishr 3, // lshr 2, // iushr 3, // lushr 2, // iand 4, // land 2, // ior 4, // lor 2, // ixor 4, // lxor 0, // iinc 1, // i2l 1, // i2f 1, // i2d 2, // l2i 2, // l2f 2, // l2d 1, // f2i 1, // f2l 1, // f2d 2, // d2i 2, // d2l 2, // d2f 1, // i2b 1, // i2c 1, // i2s 4, // lcmp 2, // fcmpl 2, // fcmpg 4, // dcmpl 4, // dcmpg 1, // ifeq 1, // ifne 1, // iflt 1, // ifge 1, // ifgt 1, // ifle 2, // ificmpeq 2, // ificmpne 2, // ificmplt 2, // ificmpge 2, // ificmpgt 2, // ificmple 2, // ifacmpeq 2, // ifacmpne 0, // goto 0, // jsr 0, // ret 1, // tableswitch 1, // lookupswitch 1, // ireturn 2, // lreturn 1, // freturn 2, // dreturn 1, // areturn 0, // return 0, // getstatic 0, // putstatic 1, // getfield 1, // putfield 1, // invokevirtual 1, // invokespecial 0, // invokestatic 1, // invokeinterface 0, // invokedynamic 0, // new 1, // newarray 1, // anewarray 1, // arraylength 1, // athrow 1, // checkcast 1, // instanceof 1, // monitorenter 1, // monitorexit 0, // wide 0, // multianewarray 1, // ifnull 1, // ifnonnull 0, // goto_w 0, // jsr_w }; // An array containing the fixed number of entries pushed onto the stack, // for all instructions. private static final int[] STACK_PUSH_COUNTS = new int[] { 0, // nop 1, // aconst_null 1, // iconst_m1 1, // iconst_0 1, // iconst_1 1, // iconst_2 1, // iconst_3 1, // iconst_4 1, // iconst_5 2, // lconst_0 2, // lconst_1 1, // fconst_0 1, // fconst_1 1, // fconst_2 2, // dconst_0 2, // dconst_1 1, // bipush 1, // sipush 1, // ldc 1, // ldc_w 2, // ldc2_w 1, // iload 2, // lload 1, // fload 2, // dload 1, // aload 1, // iload_0 1, // iload_1 1, // iload_2 1, // iload_3 2, // lload_0 2, // lload_1 2, // lload_2 2, // lload_3 1, // fload_0 1, // fload_1 1, // fload_2 1, // fload_3 2, // dload_0 2, // dload_1 2, // dload_2 2, // dload_3 1, // aload_0 1, // aload_1 1, // aload_2 1, // aload_3 1, // iaload 2, // laload 1, // faload 2, // daload 1, // aaload 1, // baload 1, // caload 1, // saload 0, // istore 0, // lstore 0, // fstore 0, // dstore 0, // astore 0, // istore_0 0, // istore_1 0, // istore_2 0, // istore_3 0, // lstore_0 0, // lstore_1 0, // lstore_2 0, // lstore_3 0, // fstore_0 0, // fstore_1 0, // fstore_2 0, // fstore_3 0, // dstore_0 0, // dstore_1 0, // dstore_2 0, // dstore_3 0, // astore_0 0, // astore_1 0, // astore_2 0, // astore_3 0, // iastore 0, // lastore 0, // fastore 0, // dastore 0, // aastore 0, // bastore 0, // castore 0, // sastore 0, // pop 0, // pop2 2, // dup 3, // dup_x1 4, // dup_x2 4, // dup2 5, // dup2_x1 6, // dup2_x2 2, // swap 1, // iadd 2, // ladd 1, // fadd 2, // dadd 1, // isub 2, // lsub 1, // fsub 2, // dsub 1, // imul 2, // lmul 1, // fmul 2, // dmul 1, // idiv 2, // ldiv 1, // fdiv 2, // ddiv 1, // irem 2, // lrem 1, // frem 2, // drem 1, // ineg 2, // lneg 1, // fneg 2, // dneg 1, // ishl 2, // lshl 1, // ishr 2, // lshr 1, // iushr 2, // lushr 1, // iand 2, // land 1, // ior 2, // lor 1, // ixor 2, // lxor 0, // iinc 2, // i2l 1, // i2f 2, // i2d 1, // l2i 1, // l2f 2, // l2d 1, // f2i 2, // f2l 2, // f2d 1, // d2i 2, // d2l 1, // d2f 1, // i2b 1, // i2c 1, // i2s 1, // lcmp 1, // fcmpl 1, // fcmpg 1, // dcmpl 1, // dcmpg 0, // ifeq 0, // ifne 0, // iflt 0, // ifge 0, // ifgt 0, // ifle 0, // ificmpeq 0, // ificmpne 0, // ificmplt 0, // ificmpge 0, // ificmpgt 0, // ificmple 0, // ifacmpeq 0, // ifacmpne 0, // goto 1, // jsr 0, // ret 0, // tableswitch 0, // lookupswitch 0, // ireturn 0, // lreturn 0, // freturn 0, // dreturn 0, // areturn 0, // return 0, // getstatic 0, // putstatic 0, // getfield 0, // putfield 0, // invokevirtual 0, // invokespecial 0, // invokestatic 0, // invokeinterface 0, // invokedynamic 1, // new 1, // newarray 1, // anewarray 1, // arraylength 0, // athrow 1, // checkcast 1, // instanceof 0, // monitorenter 0, // monitorexit 0, // wide 1, // multianewarray 0, // ifnull 0, // ifnonnull 0, // goto_w 1, // jsr_w }; public byte opcode; /** * Returns the canonical opcode of this instruction, i.e. typically the * opcode whose extension has been removed. */ public byte canonicalOpcode() { return opcode; } /** * Shrinks this instruction to its shortest possible form. * @return this instruction. */ public abstract Instruction shrink(); /** * Writes the Instruction at the given offset in the given code attribute. */ public final void write(CodeAttribute codeAttribute, int offset) { write(codeAttribute.code, offset); } /** * Writes the Instruction at the given offset in the given code array. */ public void write(byte[] code, int offset) { // Write the wide opcode, if necessary. if (isWide()) { code[offset++] = InstructionConstants.OP_WIDE; } // Write the opcode. code[offset++] = opcode; // Write any additional arguments. writeInfo(code, offset); } /** * Returns whether the instruction is wide, i.e. preceded by a wide opcode. * With the current specifications, only variable instructions can be wide. */ protected boolean isWide() { return false; } /** * Reads the data following the instruction opcode. */ protected abstract void readInfo(byte[] code, int offset); /** * Writes data following the instruction opcode. */ protected abstract void writeInfo(byte[] code, int offset); /** * Returns the length in bytes of the instruction. */ public abstract int length(int offset); /** * Accepts the given visitor. */ public abstract void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor); /** * Returns a description of the instruction, at the given offset. */ public String toString(int offset) { return "["+offset+"] "+ this.toString(); } /** * Returns the name of the instruction. */ public String getName() { return InstructionConstants.NAMES[opcode & 0xff]; } /** * Returns whether the instruction is a Category 2 instruction. This means * that it operates on long or double arguments. */ public boolean isCategory2() { return IS_CATEGORY2[opcode & 0xff]; } /** * Returns the number of entries popped from the stack during the execution * of the instruction. */ public int stackPopCount(Clazz clazz) { return STACK_POP_COUNTS[opcode & 0xff]; } /** * Returns the number of entries pushed onto the stack during the execution * of the instruction. */ public int stackPushCount(Clazz clazz) { return STACK_PUSH_COUNTS[opcode & 0xff]; } // Small utility methods. protected static int readByte(byte[] code, int offset) { return code[offset] & 0xff; } protected static int readShort(byte[] code, int offset) { return ((code[offset++] & 0xff) << 8) | ( code[offset ] & 0xff ); } protected static int readInt(byte[] code, int offset) { return ( code[offset++] << 24) | ((code[offset++] & 0xff) << 16) | ((code[offset++] & 0xff) << 8) | ( code[offset ] & 0xff ); } protected static int readValue(byte[] code, int offset, int valueSize) { switch (valueSize) { case 0: return 0; case 1: return readByte( code, offset); case 2: return readShort(code, offset); case 4: return readInt( code, offset); default: throw new IllegalArgumentException("Unsupported value size ["+valueSize+"]"); } } protected static int readSignedByte(byte[] code, int offset) { return code[offset]; } protected static int readSignedShort(byte[] code, int offset) { return (code[offset++] << 8) | (code[offset ] & 0xff); } protected static int readSignedValue(byte[] code, int offset, int valueSize) { switch (valueSize) { case 0: return 0; case 1: return readSignedByte( code, offset); case 2: return readSignedShort(code, offset); case 4: return readInt( code, offset); default: throw new IllegalArgumentException("Unsupported value size ["+valueSize+"]"); } } protected static void writeByte(byte[] code, int offset, int value) { if (value > 0xff) { throw new IllegalArgumentException("Unsigned byte value larger than 0xff ["+value+"]"); } code[offset] = (byte)value; } protected static void writeShort(byte[] code, int offset, int value) { if (value > 0xffff) { throw new IllegalArgumentException("Unsigned short value larger than 0xffff ["+value+"]"); } code[offset++] = (byte)(value >> 8); code[offset ] = (byte)(value ); } protected static void writeInt(byte[] code, int offset, int value) { code[offset++] = (byte)(value >> 24); code[offset++] = (byte)(value >> 16); code[offset++] = (byte)(value >> 8); code[offset ] = (byte)(value ); } protected static void writeValue(byte[] code, int offset, int value, int valueSize) { switch (valueSize) { case 0: break; case 1: writeByte( code, offset, value); break; case 2: writeShort(code, offset, value); break; case 4: writeInt( code, offset, value); break; default: throw new IllegalArgumentException("Unsupported value size ["+valueSize+"]"); } } protected static void writeSignedByte(byte[] code, int offset, int value) { if (value << 24 >> 24 != value) { throw new IllegalArgumentException("Signed byte value out of range ["+value+"]"); } code[offset] = (byte)value; } protected static void writeSignedShort(byte[] code, int offset, int value) { if (value << 16 >> 16 != value) { throw new IllegalArgumentException("Signed short value out of range ["+value+"]"); } code[offset++] = (byte)(value >> 8); code[offset ] = (byte)(value ); } protected static void writeSignedValue(byte[] code, int offset, int value, int valueSize) { switch (valueSize) { case 0: break; case 1: writeSignedByte( code, offset, value); break; case 2: writeSignedShort(code, offset, value); break; case 4: writeInt( code, offset, value); break; default: throw new IllegalArgumentException("Unsupported value size ["+valueSize+"]"); } } } proguard4.8/src/proguard/classfile/instruction/TableSwitchInstruction.java 0000644 0001750 0001750 00000010521 11736333523 026044 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction; import proguard.classfile.*; import proguard.classfile.attribute.CodeAttribute; import proguard.classfile.instruction.visitor.InstructionVisitor; /** * This Instruction represents a simple instruction without variable arguments * or constant pool references. * * @author Eric Lafortune */ public class TableSwitchInstruction extends SwitchInstruction { public int lowCase; public int highCase; /** * Creates an uninitialized TableSwitchInstruction. */ public TableSwitchInstruction() {} /** * Creates a new TableSwitchInstruction with the given arguments. */ public TableSwitchInstruction(byte opcode, int defaultOffset, int lowCase, int highCase, int[] jumpOffsets) { this.opcode = opcode; this.defaultOffset = defaultOffset; this.lowCase = lowCase; this.highCase = highCase; this.jumpOffsets = jumpOffsets; } /** * Copies the given instruction into this instruction. * @param tableSwitchInstruction the instruction to be copied. * @return this instruction. */ public TableSwitchInstruction copy(TableSwitchInstruction tableSwitchInstruction) { this.opcode = tableSwitchInstruction.opcode; this.defaultOffset = tableSwitchInstruction.defaultOffset; this.lowCase = tableSwitchInstruction.lowCase; this.highCase = tableSwitchInstruction.highCase; this.jumpOffsets = tableSwitchInstruction.jumpOffsets; return this; } // Implementations for Instruction. public Instruction shrink() { // There aren't any ways to shrink this instruction. return this; } protected void readInfo(byte[] code, int offset) { // Skip up to three padding bytes. offset += -offset & 3; // Read the three 32-bit arguments. defaultOffset = readInt(code, offset); offset += 4; lowCase = readInt(code, offset); offset += 4; highCase = readInt(code, offset); offset += 4; // Read the jump offsets. jumpOffsets = new int[highCase - lowCase + 1]; for (int index = 0; index < jumpOffsets.length; index++) { jumpOffsets[index] = readInt(code, offset); offset += 4; } } protected void writeInfo(byte[] code, int offset) { // Write up to three padding bytes. while ((offset & 3) != 0) { writeByte(code, offset++, 0); } // Write the three 32-bit arguments. writeInt(code, offset, defaultOffset); offset += 4; writeInt(code, offset, lowCase); offset += 4; writeInt(code, offset, highCase); offset += 4; // Write the jump offsets. int length = highCase - lowCase + 1; for (int index = 0; index < length; index++) { writeInt(code, offset, jumpOffsets[index]); offset += 4; } } public int length(int offset) { return 1 + (-(offset+1) & 3) + 12 + (highCase - lowCase + 1) * 4; } public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor) { instructionVisitor.visitTableSwitchInstruction(clazz, method, codeAttribute, offset, this); } } proguard4.8/src/proguard/classfile/instruction/SwitchInstruction.java 0000644 0001750 0001750 00000004652 11736333523 025104 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction; /** * This Instruction represents a simple instruction without variable arguments * or constant pool references. * * @author Eric Lafortune */ public abstract class SwitchInstruction extends Instruction { public int defaultOffset; public int[] jumpOffsets; /** * Creates an uninitialized SwitchInstruction. */ public SwitchInstruction() {} /** * Creates a new SwitchInstruction with the given arguments. */ public SwitchInstruction(byte opcode, int defaultOffset, int[] jumpOffsets) { this.opcode = opcode; this.defaultOffset = defaultOffset; this.jumpOffsets = jumpOffsets; } /** * Copies the given instruction into this instruction. * @param switchInstruction the instruction to be copied. * @return this instruction. */ public SwitchInstruction copy(SwitchInstruction switchInstruction) { this.opcode = switchInstruction.opcode; this.defaultOffset = switchInstruction.defaultOffset; this.jumpOffsets = switchInstruction.jumpOffsets; return this; } // Implementations for Instruction. public String toString(int offset) { return "["+offset+"] "+toString()+" (target="+(offset+defaultOffset)+")"; } // Implementations for Object. public String toString() { return getName()+" ("+jumpOffsets.length+" offsets, default="+defaultOffset+")"; } } proguard4.8/src/proguard/classfile/instruction/LookUpSwitchInstruction.java 0000644 0001750 0001750 00000010310 11736333523 026222 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction; import proguard.classfile.*; import proguard.classfile.attribute.CodeAttribute; import proguard.classfile.instruction.visitor.InstructionVisitor; /** * This Instruction represents a simple instruction without variable arguments * or constant pool references. * * @author Eric Lafortune */ public class LookUpSwitchInstruction extends SwitchInstruction { public int[] cases; /** * Creates an uninitialized LookUpSwitchInstruction. */ public LookUpSwitchInstruction() {} /** * Creates a new LookUpSwitchInstruction with the given arguments. */ public LookUpSwitchInstruction(byte opcode, int defaultOffset, int[] cases, int[] jumpOffsets) { this.opcode = opcode; this.defaultOffset = defaultOffset; this.cases = cases; this.jumpOffsets = jumpOffsets; } /** * Copies the given instruction into this instruction. * @param lookUpSwitchInstruction the instruction to be copied. * @return this instruction. */ public LookUpSwitchInstruction copy(LookUpSwitchInstruction lookUpSwitchInstruction) { this.opcode = lookUpSwitchInstruction.opcode; this.defaultOffset = lookUpSwitchInstruction.defaultOffset; this.cases = lookUpSwitchInstruction.cases; this.jumpOffsets = lookUpSwitchInstruction.jumpOffsets; return this; } // Implementations for Instruction. public Instruction shrink() { // There aren't any ways to shrink this instruction. return this; } protected void readInfo(byte[] code, int offset) { // Skip up to three padding bytes. offset += -offset & 3; // Read the two 32-bit arguments. defaultOffset = readInt(code, offset); offset += 4; int jumpOffsetCount = readInt(code, offset); offset += 4; // Read the matches-offset pairs. cases = new int[jumpOffsetCount]; jumpOffsets = new int[jumpOffsetCount]; for (int index = 0; index < jumpOffsetCount; index++) { cases[index] = readInt(code, offset); offset += 4; jumpOffsets[index] = readInt(code, offset); offset += 4; } } protected void writeInfo(byte[] code, int offset) { // Write up to three padding bytes. while ((offset & 3) != 0) { writeByte(code, offset++, 0); } // Write the two 32-bit arguments. writeInt(code, offset, defaultOffset); offset += 4; writeInt(code, offset, cases.length); offset += 4; // Write the matches-offset pairs. for (int index = 0; index < cases.length; index++) { writeInt(code, offset, cases[index]); offset += 4; writeInt(code, offset, jumpOffsets[index]); offset += 4; } } public int length(int offset) { return 1 + (-(offset+1) & 3) + 8 + cases.length * 8; } public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor) { instructionVisitor.visitLookUpSwitchInstruction(clazz, method, codeAttribute, offset, this); } } proguard4.8/src/proguard/classfile/instruction/visitor/ 0000775 0001750 0001750 00000000000 11760503005 022217 5 ustar eric eric proguard4.8/src/proguard/classfile/instruction/visitor/package.html 0000644 0001750 0001750 00000000100 11736333523 024476 0 ustar eric eric
This package contains visitors for instructions. proguard4.8/src/proguard/classfile/instruction/visitor/InstructionCounter.java 0000644 0001750 0001750 00000003557 11736333523 026764 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction.visitor; import proguard.classfile.*; import proguard.classfile.attribute.CodeAttribute; import proguard.classfile.instruction.Instruction; import proguard.classfile.util.SimplifiedVisitor; /** * This InstructionVisitor counts the number of instructions that has been visited. * * @author Eric Lafortune */ public class InstructionCounter extends SimplifiedVisitor implements InstructionVisitor { private int count; /** * Returns the number of instructions that has been visited so far. */ public int getCount() { return count; } // Implementations for InstructionVisitor. public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) { count++; } } proguard4.8/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java 0000644 0001750 0001750 00000011477 11736333523 030017 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction.visitor; import proguard.classfile.*; import proguard.classfile.attribute.CodeAttribute; import proguard.classfile.instruction.*; /** * This InstructionVisitor delegates all visits to each InstructionVisitor * in a given list. * * @author Eric Lafortune */ public class MultiInstructionVisitor implements InstructionVisitor { private static final int ARRAY_SIZE_INCREMENT = 5; private InstructionVisitor[] instructionVisitors; private int instructionVisitorCount; public MultiInstructionVisitor() { } public MultiInstructionVisitor(InstructionVisitor[] instructionVisitors) { this.instructionVisitors = instructionVisitors; this.instructionVisitorCount = instructionVisitors.length; } public void addInstructionVisitor(InstructionVisitor instructionVisitor) { ensureArraySize(); instructionVisitors[instructionVisitorCount++] = instructionVisitor; } private void ensureArraySize() { if (instructionVisitors == null) { instructionVisitors = new InstructionVisitor[ARRAY_SIZE_INCREMENT]; } else if (instructionVisitors.length == instructionVisitorCount) { InstructionVisitor[] newInstructionVisitors = new InstructionVisitor[instructionVisitorCount + ARRAY_SIZE_INCREMENT]; System.arraycopy(instructionVisitors, 0, newInstructionVisitors, 0, instructionVisitorCount); instructionVisitors = newInstructionVisitors; } } // Implementations for InstructionVisitor. public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction) { for (int index = 0; index < instructionVisitorCount; index++) { instructionVisitors[index].visitSimpleInstruction(clazz, method, codeAttribute, offset, simpleInstruction); } } public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { for (int index = 0; index < instructionVisitorCount; index++) { instructionVisitors[index].visitVariableInstruction(clazz, method, codeAttribute, offset, variableInstruction); } } public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) { for (int index = 0; index < instructionVisitorCount; index++) { instructionVisitors[index].visitConstantInstruction(clazz, method, codeAttribute, offset, constantInstruction); } } public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) { for (int index = 0; index < instructionVisitorCount; index++) { instructionVisitors[index].visitBranchInstruction(clazz, method, codeAttribute, offset, branchInstruction); } } public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction) { for (int index = 0; index < instructionVisitorCount; index++) { instructionVisitors[index].visitTableSwitchInstruction(clazz, method, codeAttribute, offset, tableSwitchInstruction); } } public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) { for (int index = 0; index < instructionVisitorCount; index++) { instructionVisitors[index].visitLookUpSwitchInstruction(clazz, method, codeAttribute, offset, lookUpSwitchInstruction); } } } proguard4.8/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java 0000644 0001750 0001750 00000003547 11736333523 027434 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction.visitor; import proguard.classfile.*; import proguard.classfile.attribute.*; import proguard.classfile.attribute.visitor.AttributeVisitor; import proguard.classfile.util.SimplifiedVisitor; /** * This AttributeVisitor lets a given InstructionVisitor visit all Instruction * objects of the CodeAttribute objects it visits. * * @author Eric Lafortune */ public class AllInstructionVisitor extends SimplifiedVisitor implements AttributeVisitor { private final InstructionVisitor instructionVisitor; public AllInstructionVisitor(InstructionVisitor instructionVisitor) { this.instructionVisitor = instructionVisitor; } // Implementations for AttributeVisitor. public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { codeAttribute.instructionsAccept(clazz, method, instructionVisitor); } } proguard4.8/src/proguard/classfile/instruction/visitor/InstructionVisitor.java 0000644 0001750 0001750 00000004235 11736333523 026776 0 ustar eric eric /* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu) * * This program is 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.instruction.visitor; import proguard.classfile.*; import proguard.classfile.attribute.CodeAttribute; import proguard.classfile.instruction.*; /** * This interface specifies the methods for a visitor of *Instruction
objects.
*
* @author Eric Lafortune
*/
public interface InstructionVisitor
{
public void visitSimpleInstruction( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction);
public void visitVariableInstruction( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction);
public void visitConstantInstruction( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction);
public void visitBranchInstruction( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction);
public void visitTableSwitchInstruction( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction);
public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction);
}
proguard4.8/src/proguard/classfile/instruction/BranchInstruction.java 0000644 0001750 0001750 00000012047 11736333523 025035 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.instruction;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.instruction.visitor.InstructionVisitor;
/**
* This interface describes an instruction that branches to a given offset in
* the code.
*
* @author Eric Lafortune
*/
public class BranchInstruction extends Instruction
{
public int branchOffset;
/**
* Creates an uninitialized BranchInstruction.
*/
public BranchInstruction() {}
public BranchInstruction(byte opcode, int branchOffset)
{
this.opcode = opcode;
this.branchOffset = branchOffset;
}
/**
* Copies the given instruction into this instruction.
* @param branchInstruction the instruction to be copied.
* @return this instruction.
*/
public BranchInstruction copy(BranchInstruction branchInstruction)
{
this.opcode = branchInstruction.opcode;
this.branchOffset = branchInstruction.branchOffset;
return this;
}
// Implementations for Instruction.
public byte canonicalOpcode()
{
// Remove the _w extension, if any.
switch (opcode)
{
case InstructionConstants.OP_GOTO_W: return InstructionConstants.OP_GOTO;
case InstructionConstants.OP_JSR_W: return InstructionConstants.OP_JSR;
default: return opcode;
}
}
public Instruction shrink()
{
// Do we need an ordinary branch or a wide branch?
if (requiredBranchOffsetSize() == 2)
{
// Can we replace the wide branch by an ordinary branch?
if (opcode == InstructionConstants.OP_GOTO_W)
{
opcode = InstructionConstants.OP_GOTO;
}
else if (opcode == InstructionConstants.OP_JSR_W)
{
opcode = InstructionConstants.OP_JSR;
}
}
else
{
// Should we replace the ordinary branch by a wide branch?
if (opcode == InstructionConstants.OP_GOTO)
{
opcode = InstructionConstants.OP_GOTO_W;
}
else if (opcode == InstructionConstants.OP_JSR)
{
opcode = InstructionConstants.OP_JSR_W;
}
else
{
throw new IllegalArgumentException("Branch instruction can't be widened ("+this.toString()+")");
}
}
return this;
}
protected void readInfo(byte[] code, int offset)
{
branchOffset = readSignedValue(code, offset, branchOffsetSize());
}
protected void writeInfo(byte[] code, int offset)
{
if (requiredBranchOffsetSize() > branchOffsetSize())
{
throw new IllegalArgumentException("Instruction has invalid branch offset size ("+this.toString(offset)+")");
}
writeSignedValue(code, offset, branchOffset, branchOffsetSize());
}
public int length(int offset)
{
return 1 + branchOffsetSize();
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor)
{
instructionVisitor.visitBranchInstruction(clazz, method, codeAttribute, offset, this);
}
public String toString(int offset)
{
return "["+offset+"] "+toString()+" (target="+(offset+branchOffset)+")";
}
// Implementations for Object.
public String toString()
{
return getName()+" "+(branchOffset >= 0 ? "+" : "")+branchOffset;
}
// Small utility methods.
/**
* Returns the branch offset size for this instruction.
*/
private int branchOffsetSize()
{
return opcode == InstructionConstants.OP_GOTO_W ||
opcode == InstructionConstants.OP_JSR_W ? 4 :
2;
}
/**
* Computes the required branch offset size for this instruction's branch
* offset.
*/
private int requiredBranchOffsetSize()
{
return branchOffset << 16 >> 16 == branchOffset ? 2 :
4;
}
}
proguard4.8/src/proguard/classfile/instruction/InstructionConstants.java 0000644 0001750 0001750 00000037543 11736333523 025624 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.instruction;
/**
* Representation of an instruction.
*
* @author Eric Lafortune
*/
public interface InstructionConstants
{
public static final byte OP_NOP = 0;
public static final byte OP_ACONST_NULL = 1;
public static final byte OP_ICONST_M1 = 2;
public static final byte OP_ICONST_0 = 3;
public static final byte OP_ICONST_1 = 4;
public static final byte OP_ICONST_2 = 5;
public static final byte OP_ICONST_3 = 6;
public static final byte OP_ICONST_4 = 7;
public static final byte OP_ICONST_5 = 8;
public static final byte OP_LCONST_0 = 9;
public static final byte OP_LCONST_1 = 10;
public static final byte OP_FCONST_0 = 11;
public static final byte OP_FCONST_1 = 12;
public static final byte OP_FCONST_2 = 13;
public static final byte OP_DCONST_0 = 14;
public static final byte OP_DCONST_1 = 15;
public static final byte OP_BIPUSH = 16;
public static final byte OP_SIPUSH = 17;
public static final byte OP_LDC = 18;
public static final byte OP_LDC_W = 19;
public static final byte OP_LDC2_W = 20;
public static final byte OP_ILOAD = 21;
public static final byte OP_LLOAD = 22;
public static final byte OP_FLOAD = 23;
public static final byte OP_DLOAD = 24;
public static final byte OP_ALOAD = 25;
public static final byte OP_ILOAD_0 = 26;
public static final byte OP_ILOAD_1 = 27;
public static final byte OP_ILOAD_2 = 28;
public static final byte OP_ILOAD_3 = 29;
public static final byte OP_LLOAD_0 = 30;
public static final byte OP_LLOAD_1 = 31;
public static final byte OP_LLOAD_2 = 32;
public static final byte OP_LLOAD_3 = 33;
public static final byte OP_FLOAD_0 = 34;
public static final byte OP_FLOAD_1 = 35;
public static final byte OP_FLOAD_2 = 36;
public static final byte OP_FLOAD_3 = 37;
public static final byte OP_DLOAD_0 = 38;
public static final byte OP_DLOAD_1 = 39;
public static final byte OP_DLOAD_2 = 40;
public static final byte OP_DLOAD_3 = 41;
public static final byte OP_ALOAD_0 = 42;
public static final byte OP_ALOAD_1 = 43;
public static final byte OP_ALOAD_2 = 44;
public static final byte OP_ALOAD_3 = 45;
public static final byte OP_IALOAD = 46;
public static final byte OP_LALOAD = 47;
public static final byte OP_FALOAD = 48;
public static final byte OP_DALOAD = 49;
public static final byte OP_AALOAD = 50;
public static final byte OP_BALOAD = 51;
public static final byte OP_CALOAD = 52;
public static final byte OP_SALOAD = 53;
public static final byte OP_ISTORE = 54;
public static final byte OP_LSTORE = 55;
public static final byte OP_FSTORE = 56;
public static final byte OP_DSTORE = 57;
public static final byte OP_ASTORE = 58;
public static final byte OP_ISTORE_0 = 59;
public static final byte OP_ISTORE_1 = 60;
public static final byte OP_ISTORE_2 = 61;
public static final byte OP_ISTORE_3 = 62;
public static final byte OP_LSTORE_0 = 63;
public static final byte OP_LSTORE_1 = 64;
public static final byte OP_LSTORE_2 = 65;
public static final byte OP_LSTORE_3 = 66;
public static final byte OP_FSTORE_0 = 67;
public static final byte OP_FSTORE_1 = 68;
public static final byte OP_FSTORE_2 = 69;
public static final byte OP_FSTORE_3 = 70;
public static final byte OP_DSTORE_0 = 71;
public static final byte OP_DSTORE_1 = 72;
public static final byte OP_DSTORE_2 = 73;
public static final byte OP_DSTORE_3 = 74;
public static final byte OP_ASTORE_0 = 75;
public static final byte OP_ASTORE_1 = 76;
public static final byte OP_ASTORE_2 = 77;
public static final byte OP_ASTORE_3 = 78;
public static final byte OP_IASTORE = 79;
public static final byte OP_LASTORE = 80;
public static final byte OP_FASTORE = 81;
public static final byte OP_DASTORE = 82;
public static final byte OP_AASTORE = 83;
public static final byte OP_BASTORE = 84;
public static final byte OP_CASTORE = 85;
public static final byte OP_SASTORE = 86;
public static final byte OP_POP = 87;
public static final byte OP_POP2 = 88;
public static final byte OP_DUP = 89;
public static final byte OP_DUP_X1 = 90;
public static final byte OP_DUP_X2 = 91;
public static final byte OP_DUP2 = 92;
public static final byte OP_DUP2_X1 = 93;
public static final byte OP_DUP2_X2 = 94;
public static final byte OP_SWAP = 95;
public static final byte OP_IADD = 96;
public static final byte OP_LADD = 97;
public static final byte OP_FADD = 98;
public static final byte OP_DADD = 99;
public static final byte OP_ISUB = 100;
public static final byte OP_LSUB = 101;
public static final byte OP_FSUB = 102;
public static final byte OP_DSUB = 103;
public static final byte OP_IMUL = 104;
public static final byte OP_LMUL = 105;
public static final byte OP_FMUL = 106;
public static final byte OP_DMUL = 107;
public static final byte OP_IDIV = 108;
public static final byte OP_LDIV = 109;
public static final byte OP_FDIV = 110;
public static final byte OP_DDIV = 111;
public static final byte OP_IREM = 112;
public static final byte OP_LREM = 113;
public static final byte OP_FREM = 114;
public static final byte OP_DREM = 115;
public static final byte OP_INEG = 116;
public static final byte OP_LNEG = 117;
public static final byte OP_FNEG = 118;
public static final byte OP_DNEG = 119;
public static final byte OP_ISHL = 120;
public static final byte OP_LSHL = 121;
public static final byte OP_ISHR = 122;
public static final byte OP_LSHR = 123;
public static final byte OP_IUSHR = 124;
public static final byte OP_LUSHR = 125;
public static final byte OP_IAND = 126;
public static final byte OP_LAND = 127;
public static final byte OP_IOR = -128;
public static final byte OP_LOR = -127;
public static final byte OP_IXOR = -126;
public static final byte OP_LXOR = -125;
public static final byte OP_IINC = -124;
public static final byte OP_I2L = -123;
public static final byte OP_I2F = -122;
public static final byte OP_I2D = -121;
public static final byte OP_L2I = -120;
public static final byte OP_L2F = -119;
public static final byte OP_L2D = -118;
public static final byte OP_F2I = -117;
public static final byte OP_F2L = -116;
public static final byte OP_F2D = -115;
public static final byte OP_D2I = -114;
public static final byte OP_D2L = -113;
public static final byte OP_D2F = -112;
public static final byte OP_I2B = -111;
public static final byte OP_I2C = -110;
public static final byte OP_I2S = -109;
public static final byte OP_LCMP = -108;
public static final byte OP_FCMPL = -107;
public static final byte OP_FCMPG = -106;
public static final byte OP_DCMPL = -105;
public static final byte OP_DCMPG = -104;
public static final byte OP_IFEQ = -103;
public static final byte OP_IFNE = -102;
public static final byte OP_IFLT = -101;
public static final byte OP_IFGE = -100;
public static final byte OP_IFGT = -99;
public static final byte OP_IFLE = -98;
public static final byte OP_IFICMPEQ = -97;
public static final byte OP_IFICMPNE = -96;
public static final byte OP_IFICMPLT = -95;
public static final byte OP_IFICMPGE = -94;
public static final byte OP_IFICMPGT = -93;
public static final byte OP_IFICMPLE = -92;
public static final byte OP_IFACMPEQ = -91;
public static final byte OP_IFACMPNE = -90;
public static final byte OP_GOTO = -89;
public static final byte OP_JSR = -88;
public static final byte OP_RET = -87;
public static final byte OP_TABLESWITCH = -86;
public static final byte OP_LOOKUPSWITCH = -85;
public static final byte OP_IRETURN = -84;
public static final byte OP_LRETURN = -83;
public static final byte OP_FRETURN = -82;
public static final byte OP_DRETURN = -81;
public static final byte OP_ARETURN = -80;
public static final byte OP_RETURN = -79;
public static final byte OP_GETSTATIC = -78;
public static final byte OP_PUTSTATIC = -77;
public static final byte OP_GETFIELD = -76;
public static final byte OP_PUTFIELD = -75;
public static final byte OP_INVOKEVIRTUAL = -74;
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_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 =
{
"nop",
"aconst_null",
"iconst_m1",
"iconst_0",
"iconst_1",
"iconst_2",
"iconst_3",
"iconst_4",
"iconst_5",
"lconst_0",
"lconst_1",
"fconst_0",
"fconst_1",
"fconst_2",
"dconst_0",
"dconst_1",
"bipush",
"sipush",
"ldc",
"ldc_w",
"ldc2_w",
"iload",
"lload",
"fload",
"dload",
"aload",
"iload_0",
"iload_1",
"iload_2",
"iload_3",
"lload_0",
"lload_1",
"lload_2",
"lload_3",
"fload_0",
"fload_1",
"fload_2",
"fload_3",
"dload_0",
"dload_1",
"dload_2",
"dload_3",
"aload_0",
"aload_1",
"aload_2",
"aload_3",
"iaload",
"laload",
"faload",
"daload",
"aaload",
"baload",
"caload",
"saload",
"istore",
"lstore",
"fstore",
"dstore",
"astore",
"istore_0",
"istore_1",
"istore_2",
"istore_3",
"lstore_0",
"lstore_1",
"lstore_2",
"lstore_3",
"fstore_0",
"fstore_1",
"fstore_2",
"fstore_3",
"dstore_0",
"dstore_1",
"dstore_2",
"dstore_3",
"astore_0",
"astore_1",
"astore_2",
"astore_3",
"iastore",
"lastore",
"fastore",
"dastore",
"aastore",
"bastore",
"castore",
"sastore",
"pop",
"pop2",
"dup",
"dup_x1",
"dup_x2",
"dup2",
"dup2_x1",
"dup2_x2",
"swap",
"iadd",
"ladd",
"fadd",
"dadd",
"isub",
"lsub",
"fsub",
"dsub",
"imul",
"lmul",
"fmul",
"dmul",
"idiv",
"ldiv",
"fdiv",
"ddiv",
"irem",
"lrem",
"frem",
"drem",
"ineg",
"lneg",
"fneg",
"dneg",
"ishl",
"lshl",
"ishr",
"lshr",
"iushr",
"lushr",
"iand",
"land",
"ior",
"lor",
"ixor",
"lxor",
"iinc",
"i2l",
"i2f",
"i2d",
"l2i",
"l2f",
"l2d",
"f2i",
"f2l",
"f2d",
"d2i",
"d2l",
"d2f",
"i2b",
"i2c",
"i2s",
"lcmp",
"fcmpl",
"fcmpg",
"dcmpl",
"dcmpg",
"ifeq",
"ifne",
"iflt",
"ifge",
"ifgt",
"ifle",
"ificmpeq",
"ificmpne",
"ificmplt",
"ificmpge",
"ificmpgt",
"ificmple",
"ifacmpeq",
"ifacmpne",
"goto",
"jsr",
"ret",
"tableswitch",
"lookupswitch",
"ireturn",
"lreturn",
"freturn",
"dreturn",
"areturn",
"return",
"getstatic",
"putstatic",
"getfield",
"putfield",
"invokevirtual",
"invokespecial",
"invokestatic",
"invokeinterface",
"invokedynamic",
"new",
"newarray",
"anewarray",
"arraylength",
"athrow",
"checkcast",
"instanceof",
"monitorenter",
"monitorexit",
"wide",
"multianewarray",
"ifnull",
"ifnonnull",
"goto_w",
"jsr_w",
};
public static final byte ARRAY_T_BOOLEAN = 4;
public static final byte ARRAY_T_CHAR = 5;
public static final byte ARRAY_T_FLOAT = 6;
public static final byte ARRAY_T_DOUBLE = 7;
public static final byte ARRAY_T_BYTE = 8;
public static final byte ARRAY_T_SHORT = 9;
public static final byte ARRAY_T_INT = 10;
public static final byte ARRAY_T_LONG = 11;
}
proguard4.8/src/proguard/classfile/instruction/InstructionUtil.java 0000644 0001750 0001750 00000006405 11736333523 024556 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.instruction;
import proguard.classfile.ClassConstants;
/**
* Utility methods for converting between representations of names and
* descriptions.
*
* @author Eric Lafortune
*/
public class InstructionUtil
{
/**
* Returns the internal type corresponding to the given 'newarray' type.
* @param arrayType InstructionConstants.ARRAY_T_BOOLEAN
,
* InstructionConstants.ARRAY_T_BYTE
,
* InstructionConstants.ARRAY_T_CHAR
,
* InstructionConstants.ARRAY_T_SHORT
,
* InstructionConstants.ARRAY_T_INT
,
* InstructionConstants.ARRAY_T_LONG
,
* InstructionConstants.ARRAY_T_FLOAT
, or
* InstructionConstants.ARRAY_T_DOUBLE
.
* @return ClassConstants.INTERNAL_TYPE_BOOLEAN
,
* ClassConstants.INTERNAL_TYPE_BYTE
,
* ClassConstants.INTERNAL_TYPE_CHAR
,
* ClassConstants.INTERNAL_TYPE_SHORT
,
* ClassConstants.INTERNAL_TYPE_INT
,
* ClassConstants.INTERNAL_TYPE_LONG
,
* ClassConstants.INTERNAL_TYPE_FLOAT
, or
* ClassConstants.INTERNAL_TYPE_DOUBLE
.
*/
public static char internalTypeFromArrayType(byte arrayType)
{
switch (arrayType)
{
case InstructionConstants.ARRAY_T_BOOLEAN: return ClassConstants.INTERNAL_TYPE_BOOLEAN;
case InstructionConstants.ARRAY_T_CHAR: return ClassConstants.INTERNAL_TYPE_CHAR;
case InstructionConstants.ARRAY_T_FLOAT: return ClassConstants.INTERNAL_TYPE_FLOAT;
case InstructionConstants.ARRAY_T_DOUBLE: return ClassConstants.INTERNAL_TYPE_DOUBLE;
case InstructionConstants.ARRAY_T_BYTE: return ClassConstants.INTERNAL_TYPE_BYTE;
case InstructionConstants.ARRAY_T_SHORT: return ClassConstants.INTERNAL_TYPE_SHORT;
case InstructionConstants.ARRAY_T_INT: return ClassConstants.INTERNAL_TYPE_INT;
case InstructionConstants.ARRAY_T_LONG: return ClassConstants.INTERNAL_TYPE_LONG;
default: throw new IllegalArgumentException("Unknown array type ["+arrayType+"]");
}
}
}
proguard4.8/src/proguard/classfile/instruction/VariableInstruction.java 0000644 0001750 0001750 00000032376 11736333523 025374 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.instruction;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.instruction.visitor.InstructionVisitor;
/**
* This Instruction represents an instruction that refers to a variable on the
* local variable stack.
*
* @author Eric Lafortune
*/
public class VariableInstruction extends Instruction
{
public boolean wide;
public int variableIndex;
public int constant;
/**
* Creates an uninitialized VariableInstruction.
*/
public VariableInstruction() {}
public VariableInstruction(boolean wide)
{
this.wide = wide;
}
public VariableInstruction(byte opcode)
{
this(opcode, embeddedVariable(opcode), 0);
}
public VariableInstruction(byte opcode,
int variableIndex)
{
this(opcode, variableIndex, 0);
}
public VariableInstruction(byte opcode,
int variableIndex,
int constant)
{
this.opcode = opcode;
this.variableIndex = variableIndex;
this.constant = constant;
this.wide = requiredVariableIndexSize() > 1 ||
requiredConstantSize() > 1;
}
/**
* Copies the given instruction into this instruction.
* @param variableInstruction the instruction to be copied.
* @return this instruction.
*/
public VariableInstruction copy(VariableInstruction variableInstruction)
{
this.opcode = variableInstruction.opcode;
this.variableIndex = variableInstruction.variableIndex;
this.constant = variableInstruction.constant;
this.wide = variableInstruction.wide;
return this;
}
/**
* Return the embedded variable of the given opcode, or 0 if the opcode
* doesn't have one.
*/
private static int embeddedVariable(byte opcode)
{
switch (opcode)
{
case InstructionConstants.OP_ILOAD_1:
case InstructionConstants.OP_LLOAD_1:
case InstructionConstants.OP_FLOAD_1:
case InstructionConstants.OP_DLOAD_1:
case InstructionConstants.OP_ALOAD_1:
case InstructionConstants.OP_ISTORE_1:
case InstructionConstants.OP_LSTORE_1:
case InstructionConstants.OP_FSTORE_1:
case InstructionConstants.OP_DSTORE_1:
case InstructionConstants.OP_ASTORE_1: return 1;
case InstructionConstants.OP_ILOAD_2:
case InstructionConstants.OP_LLOAD_2:
case InstructionConstants.OP_FLOAD_2:
case InstructionConstants.OP_DLOAD_2:
case InstructionConstants.OP_ALOAD_2:
case InstructionConstants.OP_ISTORE_2:
case InstructionConstants.OP_LSTORE_2:
case InstructionConstants.OP_FSTORE_2:
case InstructionConstants.OP_DSTORE_2:
case InstructionConstants.OP_ASTORE_2: return 2;
case InstructionConstants.OP_ILOAD_3:
case InstructionConstants.OP_LLOAD_3:
case InstructionConstants.OP_FLOAD_3:
case InstructionConstants.OP_DLOAD_3:
case InstructionConstants.OP_ALOAD_3:
case InstructionConstants.OP_ISTORE_3:
case InstructionConstants.OP_LSTORE_3:
case InstructionConstants.OP_FSTORE_3:
case InstructionConstants.OP_DSTORE_3:
case InstructionConstants.OP_ASTORE_3: return 3;
default: return 0;
}
}
/**
* Returns whether this instruction stores the value of a variable.
* The value is false for the ret instruction, but true for the iinc
* instruction.
*/
public boolean isStore()
{
// A store instruction can be recognized as follows. Note that this
// excludes the ret instruction, which has a negative opcode.
return opcode >= InstructionConstants.OP_ISTORE ||
opcode == InstructionConstants.OP_IINC;
}
/**
* Returns whether this instruction loads the value of a variable.
* The value is true for the ret instruction and for the iinc
* instruction.
*/
public boolean isLoad()
{
// A load instruction can be recognized as follows. Note that this
// includes the ret instruction, which has a negative opcode.
return opcode < InstructionConstants.OP_ISTORE;
}
// Implementations for Instruction.
public byte canonicalOpcode()
{
// Remove the _0, _1, _2, _3 extension, if any.
switch (opcode)
{
case InstructionConstants.OP_ILOAD_0:
case InstructionConstants.OP_ILOAD_1:
case InstructionConstants.OP_ILOAD_2:
case InstructionConstants.OP_ILOAD_3: return InstructionConstants.OP_ILOAD;
case InstructionConstants.OP_LLOAD_0:
case InstructionConstants.OP_LLOAD_1:
case InstructionConstants.OP_LLOAD_2:
case InstructionConstants.OP_LLOAD_3: return InstructionConstants.OP_LLOAD;
case InstructionConstants.OP_FLOAD_0:
case InstructionConstants.OP_FLOAD_1:
case InstructionConstants.OP_FLOAD_2:
case InstructionConstants.OP_FLOAD_3: return InstructionConstants.OP_FLOAD;
case InstructionConstants.OP_DLOAD_0:
case InstructionConstants.OP_DLOAD_1:
case InstructionConstants.OP_DLOAD_2:
case InstructionConstants.OP_DLOAD_3: return InstructionConstants.OP_DLOAD;
case InstructionConstants.OP_ALOAD_0:
case InstructionConstants.OP_ALOAD_1:
case InstructionConstants.OP_ALOAD_2:
case InstructionConstants.OP_ALOAD_3: return InstructionConstants.OP_ALOAD;
case InstructionConstants.OP_ISTORE_0:
case InstructionConstants.OP_ISTORE_1:
case InstructionConstants.OP_ISTORE_2:
case InstructionConstants.OP_ISTORE_3: return InstructionConstants.OP_ISTORE;
case InstructionConstants.OP_LSTORE_0:
case InstructionConstants.OP_LSTORE_1:
case InstructionConstants.OP_LSTORE_2:
case InstructionConstants.OP_LSTORE_3: return InstructionConstants.OP_LSTORE;
case InstructionConstants.OP_FSTORE_0:
case InstructionConstants.OP_FSTORE_1:
case InstructionConstants.OP_FSTORE_2:
case InstructionConstants.OP_FSTORE_3: return InstructionConstants.OP_FSTORE;
case InstructionConstants.OP_DSTORE_0:
case InstructionConstants.OP_DSTORE_1:
case InstructionConstants.OP_DSTORE_2:
case InstructionConstants.OP_DSTORE_3: return InstructionConstants.OP_DSTORE;
case InstructionConstants.OP_ASTORE_0:
case InstructionConstants.OP_ASTORE_1:
case InstructionConstants.OP_ASTORE_2:
case InstructionConstants.OP_ASTORE_3: return InstructionConstants.OP_ASTORE;
default: return opcode;
}
}
public Instruction shrink()
{
opcode = canonicalOpcode();
// Is this instruction pointing to a variable with index from 0 to 3?
if (variableIndex <= 3)
{
switch (opcode)
{
case InstructionConstants.OP_ILOAD: opcode = (byte)(InstructionConstants.OP_ILOAD_0 + variableIndex); break;
case InstructionConstants.OP_LLOAD: opcode = (byte)(InstructionConstants.OP_LLOAD_0 + variableIndex); break;
case InstructionConstants.OP_FLOAD: opcode = (byte)(InstructionConstants.OP_FLOAD_0 + variableIndex); break;
case InstructionConstants.OP_DLOAD: opcode = (byte)(InstructionConstants.OP_DLOAD_0 + variableIndex); break;
case InstructionConstants.OP_ALOAD: opcode = (byte)(InstructionConstants.OP_ALOAD_0 + variableIndex); break;
case InstructionConstants.OP_ISTORE: opcode = (byte)(InstructionConstants.OP_ISTORE_0 + variableIndex); break;
case InstructionConstants.OP_LSTORE: opcode = (byte)(InstructionConstants.OP_LSTORE_0 + variableIndex); break;
case InstructionConstants.OP_FSTORE: opcode = (byte)(InstructionConstants.OP_FSTORE_0 + variableIndex); break;
case InstructionConstants.OP_DSTORE: opcode = (byte)(InstructionConstants.OP_DSTORE_0 + variableIndex); break;
case InstructionConstants.OP_ASTORE: opcode = (byte)(InstructionConstants.OP_ASTORE_0 + variableIndex); break;
}
}
// Only make the instruction wide if necessary.
wide = requiredVariableIndexSize() > 1 ||
requiredConstantSize() > 1;
return this;
}
protected boolean isWide()
{
return wide;
}
protected void readInfo(byte[] code, int offset)
{
int variableIndexSize = variableIndexSize();
int constantSize = constantSize();
// Also initialize embedded variable indexes.
if (variableIndexSize == 0)
{
// An embedded variable index can be decoded as follows.
variableIndex = opcode < InstructionConstants.OP_ISTORE_0 ?
(opcode - InstructionConstants.OP_ILOAD_0 ) & 3 :
(opcode - InstructionConstants.OP_ISTORE_0) & 3;
}
else
{
variableIndex = readValue(code, offset, variableIndexSize); offset += variableIndexSize;
}
constant = readSignedValue(code, offset, constantSize);
}
protected void writeInfo(byte[] code, int offset)
{
int variableIndexSize = variableIndexSize();
int constantSize = constantSize();
if (requiredVariableIndexSize() > variableIndexSize)
{
throw new IllegalArgumentException("Instruction has invalid variable index size ("+this.toString(offset)+")");
}
if (requiredConstantSize() > constantSize)
{
throw new IllegalArgumentException("Instruction has invalid constant size ("+this.toString(offset)+")");
}
writeValue(code, offset, variableIndex, variableIndexSize); offset += variableIndexSize;
writeSignedValue(code, offset, constant, constantSize);
}
public int length(int offset)
{
return (wide ? 2 : 1) + variableIndexSize() + constantSize();
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor)
{
instructionVisitor.visitVariableInstruction(clazz, method, codeAttribute, offset, this);
}
// Implementations for Object.
public String toString()
{
return getName() +
(wide ? "_w" : "") +
" v"+variableIndex +
(constantSize() > 0 ? ", "+constant : "");
}
// Small utility methods.
/**
* Returns the variable index size for this instruction.
*/
private int variableIndexSize()
{
return (opcode >= InstructionConstants.OP_ILOAD_0 &&
opcode <= InstructionConstants.OP_ALOAD_3) ||
(opcode >= InstructionConstants.OP_ISTORE_0 &&
opcode <= InstructionConstants.OP_ASTORE_3) ? 0 :
wide ? 2 :
1;
}
/**
* Computes the required variable index size for this instruction's variable
* index.
*/
private int requiredVariableIndexSize()
{
return (variableIndex & 0x3) == variableIndex ? 0 :
(variableIndex & 0xff) == variableIndex ? 1 :
(variableIndex & 0xffff) == variableIndex ? 2 :
4;
}
/**
* Returns the constant size for this instruction.
*/
private int constantSize()
{
return opcode != InstructionConstants.OP_IINC ? 0 :
wide ? 2 :
1;
}
/**
* Computes the required constant size for this instruction's constant.
*/
private int requiredConstantSize()
{
return opcode != InstructionConstants.OP_IINC ? 0 :
constant << 24 >> 24 == constant ? 1 :
constant << 16 >> 16 == constant ? 2 :
4;
}
}
proguard4.8/src/proguard/classfile/instruction/SimpleInstruction.java 0000644 0001750 0001750 00000017500 11736333523 025070 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.instruction;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.instruction.visitor.InstructionVisitor;
/**
* This Instruction represents a simple instruction without variable arguments
* or constant pool references.
*
* @author Eric Lafortune
*/
public class SimpleInstruction extends Instruction
{
public int constant;
/**
* Creates an uninitialized SimpleInstruction.
*/
public SimpleInstruction() {}
/**
* Creates a new SimpleInstruction with the given opcode.
*/
public SimpleInstruction(byte opcode)
{
this(opcode, embeddedConstant(opcode));
}
/**
* Creates a new SimpleInstruction with the given opcode and constant.
*/
public SimpleInstruction(byte opcode, int constant)
{
this.opcode = opcode;
this.constant = constant;
}
/**
* Copies the given instruction into this instruction.
* @param simpleInstruction the instruction to be copied.
* @return this instruction.
*/
public SimpleInstruction copy(SimpleInstruction simpleInstruction)
{
this.opcode = simpleInstruction.opcode;
this.constant = simpleInstruction.constant;
return this;
}
/**
* Return the embedded constant of the given opcode, or 0 if the opcode
* doesn't have one.
*/
private static int embeddedConstant(byte opcode)
{
switch (opcode)
{
case InstructionConstants.OP_ICONST_M1: return -1;
case InstructionConstants.OP_ICONST_1:
case InstructionConstants.OP_LCONST_1:
case InstructionConstants.OP_FCONST_1:
case InstructionConstants.OP_DCONST_1: return 1;
case InstructionConstants.OP_ICONST_2:
case InstructionConstants.OP_FCONST_2: return 2;
case InstructionConstants.OP_ICONST_3: return 3;
case InstructionConstants.OP_ICONST_4: return 4;
case InstructionConstants.OP_ICONST_5: return 5;
default: return 0;
}
}
// Implementations for Instruction.
public byte canonicalOpcode()
{
// Replace any _1, _2, _3,... extension by _0.
switch (opcode)
{
case InstructionConstants.OP_ICONST_M1:
case InstructionConstants.OP_ICONST_0:
case InstructionConstants.OP_ICONST_1:
case InstructionConstants.OP_ICONST_2:
case InstructionConstants.OP_ICONST_3:
case InstructionConstants.OP_ICONST_4:
case InstructionConstants.OP_ICONST_5:
case InstructionConstants.OP_BIPUSH:
case InstructionConstants.OP_SIPUSH: return InstructionConstants.OP_ICONST_0;
case InstructionConstants.OP_LCONST_0:
case InstructionConstants.OP_LCONST_1: return InstructionConstants.OP_LCONST_0;
case InstructionConstants.OP_FCONST_0:
case InstructionConstants.OP_FCONST_1:
case InstructionConstants.OP_FCONST_2: return InstructionConstants.OP_FCONST_0;
case InstructionConstants.OP_DCONST_0:
case InstructionConstants.OP_DCONST_1: return InstructionConstants.OP_DCONST_0;
default: return opcode;
}
}
public Instruction shrink()
{
// Reconstruct the opcode of the shortest instruction, if there are
// any alternatives.
switch (opcode)
{
case InstructionConstants.OP_ICONST_M1:
case InstructionConstants.OP_ICONST_0:
case InstructionConstants.OP_ICONST_1:
case InstructionConstants.OP_ICONST_2:
case InstructionConstants.OP_ICONST_3:
case InstructionConstants.OP_ICONST_4:
case InstructionConstants.OP_ICONST_5:
case InstructionConstants.OP_BIPUSH:
case InstructionConstants.OP_SIPUSH:
switch (requiredConstantSize())
{
case 0:
opcode = (byte)(InstructionConstants.OP_ICONST_0 + constant);
break;
case 1:
opcode = InstructionConstants.OP_BIPUSH;
break;
case 2:
opcode = InstructionConstants.OP_SIPUSH;
break;
}
break;
case InstructionConstants.OP_LCONST_0:
case InstructionConstants.OP_LCONST_1:
opcode = (byte)(InstructionConstants.OP_LCONST_0 + constant);
break;
case InstructionConstants.OP_FCONST_0:
case InstructionConstants.OP_FCONST_1:
case InstructionConstants.OP_FCONST_2:
opcode = (byte)(InstructionConstants.OP_FCONST_0 + constant);
break;
case InstructionConstants.OP_DCONST_0:
case InstructionConstants.OP_DCONST_1:
opcode = (byte)(InstructionConstants.OP_DCONST_0 + constant);
break;
}
return this;
}
protected void readInfo(byte[] code, int offset)
{
int constantSize = constantSize();
// Also initialize embedded constants that are different from 0.
constant = constantSize == 0 ?
embeddedConstant(opcode) :
readSignedValue(code, offset, constantSize);
}
protected void writeInfo(byte[] code, int offset)
{
int constantSize = constantSize();
if (requiredConstantSize() > constantSize)
{
throw new IllegalArgumentException("Instruction has invalid constant size ("+this.toString(offset)+")");
}
writeSignedValue(code, offset, constant, constantSize);
}
public int length(int offset)
{
return 1 + constantSize();
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor)
{
instructionVisitor.visitSimpleInstruction(clazz, method, codeAttribute, offset, this);
}
// Implementations for Object.
public String toString()
{
return getName() +
(constantSize() > 0 ? " "+constant : "");
}
// Small utility methods.
/**
* Returns the constant size for this instruction.
*/
private int constantSize()
{
return opcode == InstructionConstants.OP_BIPUSH ||
opcode == InstructionConstants.OP_NEWARRAY ? 1 :
opcode == InstructionConstants.OP_SIPUSH ? 2 :
0;
}
/**
* Computes the required constant size for this instruction.
*/
private int requiredConstantSize()
{
return constant >= -1 && constant <= 5 ? 0 :
constant << 24 >> 24 == constant ? 1 :
constant << 16 >> 16 == constant ? 2 :
4;
}
}
proguard4.8/src/proguard/classfile/instruction/ConstantInstruction.java 0000644 0001750 0001750 00000023741 11752431530 025427 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.instruction;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.ClassUtil;
/**
* This Instruction represents an instruction that refers to an entry in the
* constant pool.
*
* @author Eric Lafortune
*/
public class ConstantInstruction extends Instruction
implements ConstantVisitor
{
public int constantIndex;
public int constant;
// Fields acting as return parameters for the ConstantVisitor methods.
private int parameterStackDelta;
private int typeStackDelta;
/**
* Creates an uninitialized ConstantInstruction.
*/
public ConstantInstruction() {}
/**
* Creates a new ConstantInstruction with the given opcode and constant pool
* index.
*/
public ConstantInstruction(byte opcode, int constantIndex)
{
this(opcode, constantIndex, 0);
}
/**
* Creates a new ConstantInstruction with the given opcode, constant pool
* index, and constant.
*/
public ConstantInstruction(byte opcode, int constantIndex, int constant)
{
this.opcode = opcode;
this.constantIndex = constantIndex;
this.constant = constant;
}
/**
* Copies the given instruction into this instruction.
* @param constantInstruction the instruction to be copied.
* @return this instruction.
*/
public ConstantInstruction copy(ConstantInstruction constantInstruction)
{
this.opcode = constantInstruction.opcode;
this.constantIndex = constantInstruction.constantIndex;
this.constant = constantInstruction.constant;
return this;
}
// Implementations for Instruction.
public byte canonicalOpcode()
{
// Remove the _w extension, if any.
return
opcode == InstructionConstants.OP_LDC_W ? InstructionConstants.OP_LDC :
opcode;
}
public Instruction shrink()
{
// Do we need a short index or a long index?
if (requiredConstantIndexSize() == 1)
{
// Can we replace the long instruction by a short instruction?
if (opcode == InstructionConstants.OP_LDC_W)
{
opcode = InstructionConstants.OP_LDC;
}
}
else
{
// Should we replace the short instruction by a long instruction?
if (opcode == InstructionConstants.OP_LDC)
{
opcode = InstructionConstants.OP_LDC_W;
}
}
return this;
}
protected void readInfo(byte[] code, int offset)
{
int constantIndexSize = constantIndexSize();
int constantSize = constantSize();
constantIndex = readValue(code, offset, constantIndexSize); offset += constantIndexSize;
constant = readValue(code, offset, constantSize);
}
protected void writeInfo(byte[] code, int offset)
{
int constantIndexSize = constantIndexSize();
int constantSize = constantSize();
if (requiredConstantIndexSize() > constantIndexSize)
{
throw new IllegalArgumentException("Instruction has invalid constant index size ("+this.toString(offset)+")");
}
writeValue(code, offset, constantIndex, constantIndexSize); offset += constantIndexSize;
writeValue(code, offset, constant, constantSize);
}
public int length(int offset)
{
return 1 + constantIndexSize() + constantSize();
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor)
{
instructionVisitor.visitConstantInstruction(clazz, method, codeAttribute, offset, this);
}
public int stackPopCount(Clazz clazz)
{
int stackPopCount = super.stackPopCount(clazz);
// Some special cases.
switch (opcode)
{
case InstructionConstants.OP_MULTIANEWARRAY:
// For each dimension, an integer size is popped from the stack.
stackPopCount += constant;
break;
case InstructionConstants.OP_PUTSTATIC:
case InstructionConstants.OP_PUTFIELD:
// The field value is be popped from the stack.
clazz.constantPoolEntryAccept(constantIndex, this);
stackPopCount += typeStackDelta;
break;
case InstructionConstants.OP_INVOKEVIRTUAL:
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
case InstructionConstants.OP_INVOKEDYNAMIC:
// Some parameters may be popped from the stack.
clazz.constantPoolEntryAccept(constantIndex, this);
stackPopCount += parameterStackDelta;
break;
}
return stackPopCount;
}
public int stackPushCount(Clazz clazz)
{
int stackPushCount = super.stackPushCount(clazz);
// Some special cases.
switch (opcode)
{
case InstructionConstants.OP_GETSTATIC:
case InstructionConstants.OP_GETFIELD:
case InstructionConstants.OP_INVOKEVIRTUAL:
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;
break;
}
return stackPushCount;
}
// Implementations for ConstantVisitor.
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) {}
public void visitLongConstant(Clazz clazz, LongConstant longConstant) {}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) {}
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 visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) {}
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
String type = fieldrefConstant.getType(clazz);
typeStackDelta = ClassUtil.internalTypeSize(ClassUtil.internalMethodReturnType(type));
}
public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
{
clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this);
}
public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
{
clazz.constantPoolEntryAccept(interfaceMethodrefConstant.u2nameAndTypeIndex, this);
}
public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
{
clazz.constantPoolEntryAccept(methodrefConstant.u2nameAndTypeIndex, this);
}
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
String type = nameAndTypeConstant.getType(clazz);
parameterStackDelta = ClassUtil.internalMethodParameterSize(type);
typeStackDelta = ClassUtil.internalTypeSize(ClassUtil.internalMethodReturnType(type));
}
// Implementations for Object.
public String toString()
{
return getName()+" #"+constantIndex+(constantSize() == 0 ? "" : ", "+constant);
}
// Small utility methods.
/**
* Returns the constant pool index size for this instruction.
*/
private int constantIndexSize()
{
return opcode == InstructionConstants.OP_LDC ? 1 :
2;
}
/**
* Returns the constant size for this instruction.
*/
private int constantSize()
{
return opcode == InstructionConstants.OP_MULTIANEWARRAY ? 1 :
opcode == InstructionConstants.OP_INVOKEDYNAMIC ||
opcode == InstructionConstants.OP_INVOKEINTERFACE ? 2 :
0;
}
/**
* Computes the required constant pool index size for this instruction's
* constant pool index.
*/
private int requiredConstantIndexSize()
{
return (constantIndex & 0xff) == constantIndex ? 1 :
(constantIndex & 0xffff) == constantIndex ? 2 :
4;
}
}
proguard4.8/src/proguard/classfile/ProgramField.java 0000644 0001750 0001750 00000005503 11736333523 021367 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.visitor.*;
/**
* Representation of a field from a program class.
*
* @author Eric Lafortune
*/
public class ProgramField extends ProgramMember implements Field
{
/**
* An extra field pointing to the Clazz object referenced in the
* descriptor string. This field is filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz referencedClass;
/**
* Creates an uninitialized ProgramField.
*/
public ProgramField()
{
}
/**
* Creates an initialized ProgramField.
*/
public ProgramField(int u2accessFlags,
int u2nameIndex,
int u2descriptorIndex,
int u2attributesCount,
Attribute[] attributes,
Clazz referencedClass)
{
super(u2accessFlags, u2nameIndex, u2descriptorIndex, u2attributesCount, attributes);
this.referencedClass = referencedClass;
}
// Implementations for ProgramMember.
public void accept(ProgramClass programClass, MemberVisitor memberVisitor)
{
memberVisitor.visitProgramField(programClass, this);
}
public void attributesAccept(ProgramClass programClass, AttributeVisitor attributeVisitor)
{
for (int index = 0; index < u2attributesCount; index++)
{
attributes[index].accept(programClass, this, attributeVisitor);
}
}
// Implementations for Member.
public void referencedClassesAccept(ClassVisitor classVisitor)
{
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
}
proguard4.8/src/proguard/classfile/attribute/ 0000775 0001750 0001750 00000000000 11760503005 020142 5 ustar eric eric proguard4.8/src/proguard/classfile/attribute/package.html 0000644 0001750 0001750 00000000135 11736333523 022431 0 ustar eric eric
This package contains classes to represent the attributes inside class files.
proguard4.8/src/proguard/classfile/attribute/ConstantValueAttribute.java 0000644 0001750 0001750 00000003500 11736333523 025464 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.AttributeVisitor;
/**
* This Attribute represents a constant value attribute.
*
* @author Eric Lafortune
*/
public class ConstantValueAttribute extends Attribute
{
public int u2constantValueIndex;
/**
* Creates an uninitialized ConstantValueAttribute.
*/
public ConstantValueAttribute()
{
}
/**
* Creates an initialized ConstantValueAttribute.
*/
public ConstantValueAttribute(int u2attributeNameIndex,
int u2constantValueIndex)
{
super(u2attributeNameIndex);
this.u2constantValueIndex = u2constantValueIndex;
}
// Implementations for Attribute.
public void accept(Clazz clazz, Field field, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitConstantValueAttribute(clazz, field, this);
}
}
proguard4.8/src/proguard/classfile/attribute/SyntheticAttribute.java 0000644 0001750 0001750 00000003676 11736333523 024666 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.AttributeVisitor;
/**
* This Attribute represents a synthetic attribute.
*
* @author Eric Lafortune
*/
public class SyntheticAttribute extends Attribute
{
/**
* Creates an uninitialized SyntheticAttribute.
*/
public SyntheticAttribute()
{
}
/**
* Creates an initialized SyntheticAttribute.
*/
public SyntheticAttribute(int u2attributeNameIndex)
{
super(u2attributeNameIndex);
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitSyntheticAttribute(clazz, this);
}
public void accept(Clazz clazz, Field field, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitSyntheticAttribute(clazz, field, this);
}
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitSyntheticAttribute(clazz, method, this);
}
}
proguard4.8/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java 0000755 0001750 0001750 00000006363 11736333523 026214 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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]);
}
}
proguard4.8/src/proguard/classfile/attribute/DeprecatedAttribute.java 0000644 0001750 0001750 00000003707 11736333523 024747 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.AttributeVisitor;
/**
* This Attribute represents a deprecated attribute.
*
* @author Eric Lafortune
*/
public class DeprecatedAttribute extends Attribute
{
/**
* Creates an uninitialized DeprecatedAttribute.
*/
public DeprecatedAttribute()
{
}
/**
* Creates an initialized DeprecatedAttribute.
*/
public DeprecatedAttribute(int u2attributeNameIndex)
{
super(u2attributeNameIndex);
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitDeprecatedAttribute(clazz, this);
}
public void accept(Clazz clazz, Field field, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitDeprecatedAttribute(clazz, field, this);
}
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitDeprecatedAttribute(clazz, method, this);
}
}
proguard4.8/src/proguard/classfile/attribute/UnknownAttribute.java 0000644 0001750 0001750 00000004665 11736333523 024352 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.AttributeVisitor;
/**
* This Attribute represents an unknown attribute.
*
* @author Eric Lafortune
*/
public class UnknownAttribute extends Attribute
{
public final int u4attributeLength;
public byte[] info;
/**
* Creates an uninitialized UnknownAttribute with the given length.
*/
public UnknownAttribute(int attributeLength)
{
u4attributeLength = attributeLength;
}
/**
* Creates an initialized UnknownAttribute.
*/
public UnknownAttribute(int u2attributeNameIndex,
int u4attributeLength,
byte[] info)
{
super(u2attributeNameIndex);
this.u4attributeLength = u4attributeLength;
this.info = info;
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitUnknownAttribute(clazz, this);
}
public void accept(Clazz clazz, Field field, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitUnknownAttribute(clazz, this);
}
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitUnknownAttribute(clazz, this);
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitUnknownAttribute(clazz, this);
}
}
proguard4.8/src/proguard/classfile/attribute/InnerClassesAttribute.java 0000644 0001750 0001750 00000004622 11736333523 025275 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.Clazz;
import proguard.classfile.attribute.visitor.*;
/**
* This Attribute represents an inner classes attribute.
*
* @author Eric Lafortune
*/
public class InnerClassesAttribute extends Attribute
{
public int u2classesCount;
public InnerClassesInfo[] classes;
/**
* Creates an uninitialized InnerClassesAttribute.
*/
public InnerClassesAttribute()
{
}
/**
* Creates an initialized InnerClassesAttribute.
*/
public InnerClassesAttribute(int u2attributeNameIndex,
int u2classesCount,
InnerClassesInfo[] classes)
{
super(u2attributeNameIndex);
this.u2classesCount = u2classesCount;
this.classes = classes;
}
//
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitInnerClassesAttribute(clazz, this);
}
/**
* Applies the given visitor to all inner classes.
*/
public void innerClassEntriesAccept(Clazz clazz, InnerClassesInfoVisitor innerClassesInfoVisitor)
{
for (int index = 0; index < u2classesCount; index++)
{
// We don't need double dispatching here, since there is only one
// type of InnerClassesInfo.
innerClassesInfoVisitor.visitInnerClassesInfo(clazz, classes[index]);
}
}
}
proguard4.8/src/proguard/classfile/attribute/Attribute.java 0000644 0001750 0001750 00000010135 11736333523 022757 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.AttributeVisitor;
/**
* This abstract class represents an attribute that is attached to a class,
* a class member, or a code attribute. Specific types of attributes are
* subclassed from it.
*
* @author Eric Lafortune
* @noinspection AbstractClassWithoutAbstractMethods
*/
public abstract class Attribute implements VisitorAccepter
{
public int u2attributeNameIndex;
//public int u4attributeLength;
//public byte info[];
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Create an uninitialized Attribute.
*/
protected Attribute()
{
}
/**
* Create an initialized Attribute.
*/
protected Attribute(int u2attributeNameIndex)
{
this.u2attributeNameIndex = u2attributeNameIndex;
}
/**
* Returns the String name of the attribute.
*/
public String getAttributeName(Clazz clazz)
{
return clazz.getString(u2attributeNameIndex);
}
// Methods to be implemented by extensions, if applicable.
/**
* Accepts the given visitor.
*/
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
/**
* Accepts the given visitor in the context of the given field.
*/
public void accept(Clazz clazz, Field field, AttributeVisitor attributeVisitor)
{
// Delegate the default invocation if the field is null anyway.
if (field == null)
{
accept(clazz, attributeVisitor);
}
else
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
}
/**
* Accepts the given visitor in the context of the given method.
*/
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
// Delegate the default invocation if the method is null anyway.
if (method == null)
{
accept(clazz, (Field)null, attributeVisitor);
}
else
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
}
/**
* Accepts the given visitor in the context of the given code attribute.
*/
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor)
{
// Delegate the default invocation if the code attribute is null anyway.
if (codeAttribute == null)
{
accept(clazz, method, attributeVisitor);
}
else
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
}
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
}
proguard4.8/src/proguard/classfile/attribute/LocalVariableTableAttribute.java 0000644 0001750 0001750 00000005300 11736333523 026346 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This Attribute represents a local variable table attribute.
*
* @author Eric Lafortune
*/
public class LocalVariableTableAttribute extends Attribute
{
public int u2localVariableTableLength;
public LocalVariableInfo[] localVariableTable;
/**
* Creates an uninitialized LocalVariableTableAttribute.
*/
public LocalVariableTableAttribute()
{
}
/**
* Creates an initialized LocalVariableTableAttribute.
*/
public LocalVariableTableAttribute(int u2attributeNameIndex,
int u2localVariableTableLength,
LocalVariableInfo[] localVariableTable)
{
super(u2attributeNameIndex);
this.u2localVariableTableLength = u2localVariableTableLength;
this.localVariableTable = localVariableTable;
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitLocalVariableTableAttribute(clazz, method, codeAttribute, this);
}
/**
* Applies the given visitor to all local variables.
*/
public void localVariablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfoVisitor localVariableInfoVisitor)
{
for (int index = 0; index < u2localVariableTableLength; index++)
{
// We don't need double dispatching here, since there is only one
// type of LocalVariableInfo.
localVariableInfoVisitor.visitLocalVariableInfo(clazz, method, codeAttribute, localVariableTable[index]);
}
}
}
proguard4.8/src/proguard/classfile/attribute/BootstrapMethodInfo.java 0000755 0001750 0001750 00000005051 11736333523 024752 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
}
}
proguard4.8/src/proguard/classfile/attribute/LocalVariableInfo.java 0000664 0001750 0001750 00000006542 11736333523 024341 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.Clazz;
import proguard.classfile.visitor.ClassVisitor;
/**
* Representation of an Local Variable table entry.
*
* @author Eric Lafortune
*/
public class LocalVariableInfo implements Comparable
{
public int u2startPC;
public int u2length;
public int u2nameIndex;
public int u2descriptorIndex;
public int u2index;
/**
* An extra field pointing to the referenced Clazz object.
* This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
.
*/
public Clazz referencedClass;
/**
* Creates an uninitialized LocalVariableInfo.
*/
public LocalVariableInfo()
{
}
/**
* Creates an initialized LocalVariableInfo.
*/
public LocalVariableInfo(int u2startPC,
int u2length,
int u2nameIndex,
int u2descriptorIndex,
int u2index)
{
this.u2startPC = u2startPC;
this.u2length = u2length;
this.u2nameIndex = u2nameIndex;
this.u2descriptorIndex = u2descriptorIndex;
this.u2index = u2index;
}
/**
* Lets the referenced class accept the given visitor.
*/
public void referencedClassAccept(ClassVisitor classVisitor)
{
if (referencedClass != null)
{
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.u2index < other.u2index ? -1 : this.u2index > other.u2index ? 1 :
this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 :
this.u2descriptorIndex < other.u2descriptorIndex ? -1 : this.u2descriptorIndex > other.u2descriptorIndex ? 1 :
this.u2nameIndex < other.u2nameIndex ? -1 : this.u2nameIndex > other.u2nameIndex ? 1 :
0;
}
}
proguard4.8/src/proguard/classfile/attribute/InnerClassesInfo.java 0000644 0001750 0001750 00000006071 11736333523 024225 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 an Inner Classes table entry.
*
* @author Eric Lafortune
*/
public class InnerClassesInfo implements VisitorAccepter
{
public int u2innerClassIndex;
public int u2outerClassIndex;
public int u2innerNameIndex;
public int u2innerClassAccessFlags;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Returns the inner class index.
*/
protected int getInnerClassIndex()
{
return u2innerClassIndex;
}
/**
* Returns the name index.
*/
protected int getInnerNameIndex()
{
return u2innerNameIndex;
}
/**
* Sets the name index.
*/
protected void setInnerNameIndex(int index)
{
u2innerNameIndex = index;
}
/**
* Applies the given constant pool visitor to the class constant of the
* inner class, if any.
*/
public void innerClassConstantAccept(Clazz clazz, ConstantVisitor constantVisitor)
{
if (u2innerClassIndex != 0)
{
clazz.constantPoolEntryAccept(u2innerClassIndex, constantVisitor);
}
}
/**
* Applies the given constant pool visitor to the class constant of the
* outer class, if any.
*/
public void outerClassConstantAccept(Clazz clazz, ConstantVisitor constantVisitor)
{
if (u2outerClassIndex != 0)
{
clazz.constantPoolEntryAccept(u2outerClassIndex, constantVisitor);
}
}
/**
* Applies the given constant pool visitor to the Utf8 constant of the
* inner name, if any.
*/
public void innerNameConstantAccept(Clazz clazz, ConstantVisitor constantVisitor)
{
if (u2innerNameIndex != 0)
{
clazz.constantPoolEntryAccept(u2innerNameIndex, constantVisitor);
}
}
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
}
proguard4.8/src/proguard/classfile/attribute/visitor/ 0000775 0001750 0001750 00000000000 11760503005 021641 5 ustar eric eric proguard4.8/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java 0000644 0001750 0001750 00000002675 11736333523 026761 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This interface specifies the methods for a visitor of
* LineNumberInfo
objects. Note that there is only a single
* implementation of LineNumberInfo
, such that this interface
* is not strictly necessary as a visitor.
*
* @author Eric Lafortune
*/
public interface LineNumberInfoVisitor
{
public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo);
}
proguard4.8/src/proguard/classfile/attribute/visitor/package.html 0000644 0001750 0001750 00000000123 11736333523 024125 0 ustar eric eric
This package contains visitors for attributes and their components.
proguard4.8/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java 0000644 0001750 0001750 00000003564 11736333523 027741 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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);
}
} proguard4.8/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java 0000644 0001750 0001750 00000002717 11736333523 027416 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This interface specifies the methods for a visitor of
* LocalVariableInfo
objects. Note that there is only a single
* implementation of LocalVariableInfo
, such that this interface
* is not strictly necessary as a visitor.
*
* @author Eric Lafortune
*/
public interface LocalVariableInfoVisitor
{
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo);
}
proguard4.8/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java 0000644 0001750 0001750 00000031644 11736333523 027061 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This AttributeVisitor delegates all visits to each AttributeVisitor
* in a given list.
*
* @author Eric Lafortune
*/
public class MultiAttributeVisitor implements AttributeVisitor
{
private AttributeVisitor[] attributeVisitors;
public MultiAttributeVisitor()
{
}
public MultiAttributeVisitor(AttributeVisitor[] attributeVisitors)
{
this.attributeVisitors = attributeVisitors;
}
public void addAttributeVisitor(AttributeVisitor attributeVisitor)
{
incrementArraySize();
attributeVisitors[attributeVisitors.length - 1] = attributeVisitor;
}
private void incrementArraySize()
{
if (attributeVisitors == null)
{
attributeVisitors = new AttributeVisitor[1];
}
else
{
AttributeVisitor[] newAttributeVisitors =
new AttributeVisitor[attributeVisitors.length + 1];
System.arraycopy(attributeVisitors, 0,
newAttributeVisitors, 0,
attributeVisitors.length);
attributeVisitors = newAttributeVisitors;
}
}
// Implementations for AttributeVisitor.
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitUnknownAttribute(clazz, unknownAttribute);
}
}
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++)
{
attributeVisitors[index].visitSourceFileAttribute(clazz, sourceFileAttribute);
}
}
public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitSourceDirAttribute(clazz, sourceDirAttribute);
}
}
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitInnerClassesAttribute(clazz, innerClassesAttribute);
}
}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitEnclosingMethodAttribute(clazz, enclosingMethodAttribute);
}
}
public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitDeprecatedAttribute(clazz, deprecatedAttribute);
}
}
public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitSyntheticAttribute(clazz, syntheticAttribute);
}
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute syntheticAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitSignatureAttribute(clazz, syntheticAttribute);
}
}
public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitDeprecatedAttribute(clazz, field, deprecatedAttribute);
}
}
public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitSyntheticAttribute(clazz, field, syntheticAttribute);
}
}
public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute syntheticAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitSignatureAttribute(clazz, field, syntheticAttribute);
}
}
public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitDeprecatedAttribute(clazz, method, deprecatedAttribute);
}
}
public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitSyntheticAttribute(clazz, method, syntheticAttribute);
}
}
public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute syntheticAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitSignatureAttribute(clazz, method, syntheticAttribute);
}
}
public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitConstantValueAttribute(clazz, field, constantValueAttribute);
}
}
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitExceptionsAttribute(clazz, method, exceptionsAttribute);
}
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitCodeAttribute(clazz, method, codeAttribute);
}
}
public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitStackMapAttribute(clazz, method, codeAttribute, stackMapAttribute);
}
}
public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitStackMapTableAttribute(clazz, method, codeAttribute, stackMapTableAttribute);
}
}
public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitLineNumberTableAttribute(clazz, method, codeAttribute, lineNumberTableAttribute);
}
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitLocalVariableTableAttribute(clazz, method, codeAttribute, localVariableTableAttribute);
}
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitLocalVariableTypeTableAttribute(clazz, method, codeAttribute, localVariableTypeTableAttribute);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitRuntimeVisibleAnnotationsAttribute(clazz, runtimeVisibleAnnotationsAttribute);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitRuntimeInvisibleAnnotationsAttribute(clazz, runtimeInvisibleAnnotationsAttribute);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitRuntimeVisibleAnnotationsAttribute(clazz, field, runtimeVisibleAnnotationsAttribute);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitRuntimeInvisibleAnnotationsAttribute(clazz, field, runtimeInvisibleAnnotationsAttribute);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitRuntimeVisibleAnnotationsAttribute(clazz, method, runtimeVisibleAnnotationsAttribute);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitRuntimeInvisibleAnnotationsAttribute(clazz, method, runtimeInvisibleAnnotationsAttribute);
}
}
public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitRuntimeVisibleParameterAnnotationsAttribute(clazz, method, runtimeVisibleParameterAnnotationsAttribute);
}
}
public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitRuntimeInvisibleParameterAnnotationsAttribute(clazz, method, runtimeInvisibleParameterAnnotationsAttribute);
}
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
{
attributeVisitors[index].visitAnnotationDefaultAttribute(clazz, method, annotationDefaultAttribute);
}
}
}
proguard4.8/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java 0000755 0001750 0001750 00000002724 11736333523 030035 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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
* BootstrapMethodInfo
objects. Note that there is only a single
* implementation of BootstrapMethodInfo
, such that this interface
* is not strictly necessary as a visitor.
*
* @author Eric Lafortune
*/
public interface BootstrapMethodInfoVisitor
{
public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo);
}
proguard4.8/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java 0000644 0001750 0001750 00000002747 11736333523 030263 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This interface specifies the methods for a visitor of
* LocalVariableTypeInfo
objects. Note that there is only a single
* implementation of LocalVariableTypeInfo
, such that this interface
* is not strictly necessary as a visitor.
*
* @author Eric Lafortune
*/
public interface LocalVariableTypeInfoVisitor
{
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo);
}
proguard4.8/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java 0000644 0001750 0001750 00000027356 11736333523 027342 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.obfuscate.AttributeShrinker;
/**
* This AttributeVisitor delegates its visits to one of two other
* AttributeVisitor instances, depending on whether the visited attribute
* is strictly required or not.
*
* @see AttributeShrinker
*
* @author Eric Lafortune
*/
public class RequiredAttributeFilter
implements AttributeVisitor
{
private final AttributeVisitor requiredAttributeVisitor;
private final AttributeVisitor optionalAttributeVisitor;
/**
* Creates a new RequiredAttributeFilter for visiting required attributes.
* @param requiredAttributeVisitor the visitor that will visit required
* attributes.
*/
public RequiredAttributeFilter(AttributeVisitor requiredAttributeVisitor)
{
this(requiredAttributeVisitor, null);
}
/**
* Creates a new RequiredAttributeFilter for visiting required and
* optional attributes.
* @param requiredAttributeVisitor the visitor that will visit required
* attributes.
* @param optionalAttributeVisitor the visitor that will visit optional
* attributes.
*/
public RequiredAttributeFilter(AttributeVisitor requiredAttributeVisitor,
AttributeVisitor optionalAttributeVisitor)
{
this.requiredAttributeVisitor = requiredAttributeVisitor;
this.optionalAttributeVisitor = optionalAttributeVisitor;
}
// Implementations for AttributeVisitor.
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
if (optionalAttributeVisitor != null)
{
unknownAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
{
if (requiredAttributeVisitor != null)
{
bootstrapMethodsAttribute.accept(clazz, requiredAttributeVisitor);
}
}
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
if (optionalAttributeVisitor != null)
{
sourceFileAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
{
if (optionalAttributeVisitor != null)
{
sourceDirAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
if (optionalAttributeVisitor != null)
{
innerClassesAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
if (optionalAttributeVisitor != null)
{
enclosingMethodAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
{
if (optionalAttributeVisitor != null)
{
deprecatedAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
{
if (optionalAttributeVisitor != null)
{
deprecatedAttribute.accept(clazz, field, optionalAttributeVisitor);
}
}
public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
{
if (optionalAttributeVisitor != null)
{
deprecatedAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
{
if (optionalAttributeVisitor != null)
{
syntheticAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
{
if (optionalAttributeVisitor != null)
{
syntheticAttribute.accept(clazz, field, optionalAttributeVisitor);
}
}
public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
{
if (optionalAttributeVisitor != null)
{
syntheticAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
if (optionalAttributeVisitor != null)
{
signatureAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute)
{
if (optionalAttributeVisitor != null)
{
signatureAttribute.accept(clazz, field, optionalAttributeVisitor);
}
}
public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute)
{
if (optionalAttributeVisitor != null)
{
signatureAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
{
if (requiredAttributeVisitor != null)
{
constantValueAttribute.accept(clazz, field, requiredAttributeVisitor);
}
}
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
if (optionalAttributeVisitor != null)
{
exceptionsAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
if (requiredAttributeVisitor != null)
{
codeAttribute.accept(clazz, method, requiredAttributeVisitor);
}
}
public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
{
if (optionalAttributeVisitor != null)
{
stackMapAttribute.accept(clazz, method, codeAttribute, optionalAttributeVisitor);
}
}
public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
{
if (requiredAttributeVisitor != null)
{
stackMapTableAttribute.accept(clazz, method, codeAttribute, requiredAttributeVisitor);
}
}
public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
{
if (optionalAttributeVisitor != null)
{
lineNumberTableAttribute.accept(clazz, method, codeAttribute, optionalAttributeVisitor);
}
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
if (optionalAttributeVisitor != null)
{
localVariableTableAttribute.accept(clazz, method, codeAttribute, optionalAttributeVisitor);
}
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
if (optionalAttributeVisitor != null)
{
localVariableTypeTableAttribute.accept(clazz, method, codeAttribute, optionalAttributeVisitor);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
if (optionalAttributeVisitor != null)
{
runtimeVisibleAnnotationsAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
if (optionalAttributeVisitor != null)
{
runtimeVisibleAnnotationsAttribute.accept(clazz, field, optionalAttributeVisitor);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
if (optionalAttributeVisitor != null)
{
runtimeVisibleAnnotationsAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
if (optionalAttributeVisitor != null)
{
runtimeInvisibleAnnotationsAttribute.accept(clazz, optionalAttributeVisitor);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
if (optionalAttributeVisitor != null)
{
runtimeInvisibleAnnotationsAttribute.accept(clazz, field, optionalAttributeVisitor);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
if (optionalAttributeVisitor != null)
{
runtimeInvisibleAnnotationsAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
{
if (optionalAttributeVisitor != null)
{
runtimeVisibleParameterAnnotationsAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
{
if (optionalAttributeVisitor != null)
{
runtimeInvisibleParameterAnnotationsAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
if (optionalAttributeVisitor != null)
{
annotationDefaultAttribute.accept(clazz, method, optionalAttributeVisitor);
}
}
}
proguard4.8/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java 0000664 0001750 0001750 00000031242 11740563614 026432 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
import java.util.List;
/**
* This AttributeVisitor delegates its visits another AttributeVisitor, but
* only when the visited attribute has a name that that matches a given regular
* expression.
*
* @author Eric Lafortune
*/
public class AttributeNameFilter
implements AttributeVisitor
{
private final StringMatcher regularExpressionMatcher;
private final AttributeVisitor attributeVisitor;
/**
* Creates a new AttributeNameFilter.
* @param regularExpression the regular expression against which attribute
* names will be matched.
* @param attributeVisitor the AttributeVisitor
to which
* visits will be delegated.
*/
public AttributeNameFilter(String regularExpression,
AttributeVisitor attributeVisitor)
{
this(new ListParser(new NameParser()).parse(regularExpression),
attributeVisitor);
}
/**
* Creates a new AttributeNameFilter.
* @param regularExpression the regular expression against which attribute
* names will be matched.
* @param attributeVisitor the AttributeVisitor
to which
* visits will be delegated.
*/
public AttributeNameFilter(List regularExpression,
AttributeVisitor attributeVisitor)
{
this(new ListParser(new NameParser()).parse(regularExpression),
attributeVisitor);
}
/**
* Creates a new AttributeNameFilter.
* @param regularExpressionMatcher the string matcher against which
* attribute names will be matched.
* @param attributeVisitor the AttributeVisitor
to
* which visits will be delegated.
*/
public AttributeNameFilter(StringMatcher regularExpressionMatcher,
AttributeVisitor attributeVisitor)
{
this.regularExpressionMatcher = regularExpressionMatcher;
this.attributeVisitor = attributeVisitor;
}
// Implementations for AttributeVisitor.
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
if (accepted(clazz, unknownAttribute))
{
unknownAttribute.accept(clazz, 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))
{
sourceFileAttribute.accept(clazz, attributeVisitor);
}
}
public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
{
if (accepted(clazz, sourceDirAttribute))
{
sourceDirAttribute.accept(clazz, attributeVisitor);
}
}
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
if (accepted(clazz, innerClassesAttribute))
{
innerClassesAttribute.accept(clazz, attributeVisitor);
}
}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
if (accepted(clazz, enclosingMethodAttribute))
{
enclosingMethodAttribute.accept(clazz, attributeVisitor);
}
}
public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
{
if (accepted(clazz, deprecatedAttribute))
{
deprecatedAttribute.accept(clazz, attributeVisitor);
}
}
public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
{
if (accepted(clazz, deprecatedAttribute))
{
deprecatedAttribute.accept(clazz, field, attributeVisitor);
}
}
public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
{
if (accepted(clazz, deprecatedAttribute))
{
deprecatedAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
{
if (accepted(clazz, syntheticAttribute))
{
syntheticAttribute.accept(clazz, attributeVisitor);
}
}
public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
{
if (accepted(clazz, syntheticAttribute))
{
syntheticAttribute.accept(clazz, field, attributeVisitor);
}
}
public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
{
if (accepted(clazz, syntheticAttribute))
{
syntheticAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
if (accepted(clazz, signatureAttribute))
{
signatureAttribute.accept(clazz, attributeVisitor);
}
}
public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute)
{
if (accepted(clazz, signatureAttribute))
{
signatureAttribute.accept(clazz, field, attributeVisitor);
}
}
public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute)
{
if (accepted(clazz, signatureAttribute))
{
signatureAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
{
if (accepted(clazz, constantValueAttribute))
{
constantValueAttribute.accept(clazz, field, attributeVisitor);
}
}
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
if (accepted(clazz, exceptionsAttribute))
{
exceptionsAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
if (accepted(clazz, codeAttribute))
{
codeAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
{
if (accepted(clazz, stackMapAttribute))
{
stackMapAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
}
}
public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
{
if (accepted(clazz, stackMapTableAttribute))
{
stackMapTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
}
}
public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
{
if (accepted(clazz, lineNumberTableAttribute))
{
lineNumberTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
}
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
if (accepted(clazz, localVariableTableAttribute))
{
localVariableTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
}
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
if (accepted(clazz, localVariableTypeTableAttribute))
{
localVariableTypeTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
if (accepted(clazz, runtimeVisibleAnnotationsAttribute))
{
runtimeVisibleAnnotationsAttribute.accept(clazz, attributeVisitor);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
if (accepted(clazz, runtimeVisibleAnnotationsAttribute))
{
runtimeVisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor);
}
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
if (accepted(clazz, runtimeVisibleAnnotationsAttribute))
{
runtimeVisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
if (accepted(clazz, runtimeInvisibleAnnotationsAttribute))
{
runtimeInvisibleAnnotationsAttribute.accept(clazz, attributeVisitor);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
if (accepted(clazz, runtimeInvisibleAnnotationsAttribute))
{
runtimeInvisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor);
}
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
if (accepted(clazz, runtimeInvisibleAnnotationsAttribute))
{
runtimeInvisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
{
if (accepted(clazz, runtimeVisibleParameterAnnotationsAttribute))
{
runtimeVisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
{
if (accepted(clazz, runtimeInvisibleParameterAnnotationsAttribute))
{
runtimeInvisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor);
}
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
if (accepted(clazz, annotationDefaultAttribute))
{
annotationDefaultAttribute.accept(clazz, method, attributeVisitor);
}
}
// Small utility methods.
private boolean accepted(Clazz clazz, Attribute attribute)
{
return regularExpressionMatcher.matches(attribute.getAttributeName(clazz));
}
}
proguard4.8/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java 0000644 0001750 0001750 00000002660 11736333523 027304 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.Clazz;
import proguard.classfile.attribute.InnerClassesInfo;
/**
* This interface specifies the methods for a visitor of
* InnerClassesInfo
objects. Note that there is only a single
* implementation of InnerClassesInfo
, such that this interface
* is not strictly necessary as a visitor.
*
* @author Eric Lafortune
*/
public interface InnerClassesInfoVisitor
{
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo);
}
proguard4.8/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java 0000664 0001750 0001750 00000007341 11736333523 026476 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.visitor.*;
/**
* This ClassVisitor, MemberVisitor, and AttributeVisitor lets a given
* AttributeVisitor visit all Attribute objects of the program classes,
* program class members, or code attributes, respectively, that it visits.
*
* @author Eric Lafortune
*/
public class AllAttributeVisitor
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
AttributeVisitor
{
private final boolean deep;
private final AttributeVisitor attributeVisitor;
/**
* Creates a new shallow AllAttributeVisitor.
* @param attributeVisitor the AttributeVisitor to which visits will be
* delegated.
*/
public AllAttributeVisitor(AttributeVisitor attributeVisitor)
{
this(false, attributeVisitor);
}
/**
* Creates a new optionally deep AllAttributeVisitor.
* @param deep specifies whether the attributes contained
* further down the class structure should be
* visited too.
* @param attributeVisitor the AttributeVisitor to which visits will be
* delegated.
*/
public AllAttributeVisitor(boolean deep,
AttributeVisitor attributeVisitor)
{
this.deep = deep;
this.attributeVisitor = attributeVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.attributesAccept(attributeVisitor);
// Visit the attributes further down the class structure, if required.
if (deep)
{
programClass.fieldsAccept(this);
programClass.methodsAccept(this);
programClass.attributesAccept(this);
}
}
public void visitLibraryClass(LibraryClass libraryClass) {}
// Implementations for MemberVisitor.
public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
programMember.attributesAccept(programClass, attributeVisitor);
// Visit the attributes further down the member structure, if required.
if (deep)
{
programMember.attributesAccept(programClass, this);
}
}
public void visitLibraryMember(LibraryClass programClass, LibraryMember programMember) {}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
codeAttribute.attributesAccept(clazz, method, attributeVisitor);
}
}
proguard4.8/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java 0000644 0001750 0001750 00000023757 11736333523 027334 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 AttributeVisitor
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);
}
}
proguard4.8/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java 0000644 0001750 0001750 00000003653 11736333523 030465 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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);
}
}
proguard4.8/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java 0000644 0001750 0001750 00000002666 11736333523 026657 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This interface specifies the methods for a visitor of
* ExceptionInfo
objects. Note that there is only a single
* implementation of ExceptionInfo
, such that this interface
* is not strictly necessary as a visitor.
*
* @author Eric Lafortune
*/
public interface ExceptionInfoVisitor
{
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo);
}
proguard4.8/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java 0000644 0001750 0001750 00000003470 11736333523 027302 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 ExceptionInfoVisitor visit all exceptions
* objects of the CodeAttribute objects it visits.
*
* @author Eric Lafortune
*/
public class AllExceptionInfoVisitor
extends SimplifiedVisitor
implements AttributeVisitor
{
private final ExceptionInfoVisitor exceptionInfoVisitor;
public AllExceptionInfoVisitor(ExceptionInfoVisitor exceptionInfoVisitor)
{
this.exceptionInfoVisitor = exceptionInfoVisitor;
}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
codeAttribute.exceptionsAccept(clazz, method, exceptionInfoVisitor);
}
}
proguard4.8/src/proguard/classfile/attribute/visitor/AttributeVisitor.java 0000644 0001750 0001750 00000014147 11736333523 026045 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This interface specifies the methods for a visitor of Attribute
* objects.
*
* @author Eric Lafortune
*/
public interface AttributeVisitor
{
// Attributes that are attached to classes.
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.
public void visitDeprecatedAttribute( Clazz clazz, DeprecatedAttribute deprecatedAttribute);
public void visitDeprecatedAttribute( Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute);
public void visitDeprecatedAttribute( Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute);
public void visitSyntheticAttribute( Clazz clazz, SyntheticAttribute syntheticAttribute);
public void visitSyntheticAttribute( Clazz clazz, Field field, SyntheticAttribute syntheticAttribute);
public void visitSyntheticAttribute( Clazz clazz, Method method, SyntheticAttribute syntheticAttribute);
public void visitSignatureAttribute( Clazz clazz, SignatureAttribute signatureAttribute);
public void visitSignatureAttribute( Clazz clazz, Field field, SignatureAttribute signatureAttribute);
public void visitSignatureAttribute( Clazz clazz, Method method, SignatureAttribute signatureAttribute);
// Attributes that are attached to fields.
public void visitConstantValueAttribute( Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute);
// Attributes that are attached to methods.
public void visitExceptionsAttribute( Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute);
public void visitCodeAttribute( Clazz clazz, Method method, CodeAttribute codeAttribute);
// Attributes that are attached to code attributes.
public void visitStackMapAttribute( Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute);
public void visitStackMapTableAttribute( Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute);
public void visitLineNumberTableAttribute( Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute);
public void visitLocalVariableTableAttribute( Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute);
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute);
// Annotation attributes.
public void visitRuntimeVisibleAnnotationsAttribute( Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute);
public void visitRuntimeVisibleAnnotationsAttribute( Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute);
public void visitRuntimeVisibleAnnotationsAttribute( Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute);
public void visitRuntimeInvisibleAnnotationsAttribute( Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute);
public void visitRuntimeInvisibleAnnotationsAttribute( Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute);
public void visitRuntimeInvisibleAnnotationsAttribute( Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute);
public void visitRuntimeVisibleParameterAnnotationsAttribute( Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute);
public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute);
public void visitAnnotationDefaultAttribute( Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute);
}
proguard4.8/src/proguard/classfile/attribute/visitor/StackSizeComputer.java 0000644 0001750 0001750 00000032202 11736333523 026131 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor.ClassPrinter;
import proguard.classfile.attribute.*;
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.
*
* @author Eric Lafortune
*/
public class StackSizeComputer
extends SimplifiedVisitor
implements AttributeVisitor,
InstructionVisitor,
ExceptionInfoVisitor
{
//*
private static final boolean DEBUG = false;
/*/
private static boolean DEBUG = true;
//*/
private boolean[] evaluated = new boolean[ClassConstants.TYPICAL_CODE_LENGTH];
private int[] stackSizes = new int[ClassConstants.TYPICAL_CODE_LENGTH];
private boolean exitInstructionBlock;
private int stackSize;
private int maxStackSize;
/**
* Returns whether the instruction at the given offset is reachable in the
* most recently visited code attribute.
*/
public boolean isReachable(int instructionOffset)
{
return evaluated[instructionOffset];
}
/**
* Returns the stack size at the given instruction offset of the most
* recently visited code attribute.
*/
public int getStackSize(int instructionOffset)
{
if (!evaluated[instructionOffset])
{
throw new IllegalArgumentException("Unknown stack size at unreachable instruction offset ["+instructionOffset+"]");
}
return stackSizes[instructionOffset];
}
/**
* Returns the maximum stack size of the most recently visited code attribute.
*/
public int getMaxStackSize()
{
return maxStackSize;
}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
// DEBUG =
// clazz.getName().equals("abc/Def") &&
// method.getName(clazz).equals("abc");
// TODO: Remove this when the code has stabilized.
// Catch any unexpected exceptions from the actual visiting method.
try
{
// Process the code.
visitCodeAttribute0(clazz, method, codeAttribute);
}
catch (RuntimeException ex)
{
System.err.println("Unexpected error while computing stack sizes:");
System.err.println(" Class = ["+clazz.getName()+"]");
System.err.println(" Method = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");
System.err.println(" Exception = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");
if (DEBUG)
{
method.accept(clazz, new ClassPrinter());
}
throw ex;
}
}
public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
if (DEBUG)
{
System.out.println("StackSizeComputer: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
}
// Try to reuse the previous array.
int codeLength = codeAttribute.u4codeLength;
if (evaluated.length < codeLength)
{
evaluated = new boolean[codeLength];
stackSizes = new int[codeLength];
}
else
{
Arrays.fill(evaluated, 0, codeLength, false);
}
// The initial stack is always empty.
stackSize = 0;
maxStackSize = 0;
// Evaluate the instruction block starting at the entry point of the method.
evaluateInstructionBlock(clazz, method, codeAttribute, 0);
// Evaluate the exception handlers.
codeAttribute.exceptionsAccept(clazz, method, this);
}
// Implementations for InstructionVisitor.
public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
{
byte opcode = simpleInstruction.opcode;
// Some simple instructions exit from the current instruction block.
exitInstructionBlock =
opcode == InstructionConstants.OP_IRETURN ||
opcode == InstructionConstants.OP_LRETURN ||
opcode == InstructionConstants.OP_FRETURN ||
opcode == InstructionConstants.OP_DRETURN ||
opcode == InstructionConstants.OP_ARETURN ||
opcode == InstructionConstants.OP_RETURN ||
opcode == InstructionConstants.OP_ATHROW;
}
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
// Constant pool instructions never end the current instruction block.
exitInstructionBlock = false;
}
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
{
byte opcode = variableInstruction.opcode;
// The ret instruction end the current instruction block.
exitInstructionBlock =
opcode == InstructionConstants.OP_RET;
}
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
{
byte opcode = branchInstruction.opcode;
// Evaluate the target instruction blocks.
evaluateInstructionBlock(clazz,
method,
codeAttribute,
offset +
branchInstruction.branchOffset);
// Evaluate the instructions after a subroutine branch.
if (opcode == InstructionConstants.OP_JSR ||
opcode == InstructionConstants.OP_JSR_W)
{
// We assume subroutine calls (jsr and jsr_w instructions) don't
// change the stack, other than popping the return value.
stackSize -= 1;
evaluateInstructionBlock(clazz,
method,
codeAttribute,
offset + branchInstruction.length(offset));
}
// Some branch instructions always end the current instruction block.
exitInstructionBlock =
opcode == InstructionConstants.OP_GOTO ||
opcode == InstructionConstants.OP_GOTO_W ||
opcode == InstructionConstants.OP_JSR ||
opcode == InstructionConstants.OP_JSR_W;
}
public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction)
{
// Evaluate the target instruction blocks.
// Loop over all jump offsets.
int[] jumpOffsets = switchInstruction.jumpOffsets;
for (int index = 0; index < jumpOffsets.length; index++)
{
// Evaluate the jump instruction block.
evaluateInstructionBlock(clazz,
method,
codeAttribute,
offset + jumpOffsets[index]);
}
// Also evaluate the default instruction block.
evaluateInstructionBlock(clazz,
method,
codeAttribute,
offset + switchInstruction.defaultOffset);
// The switch instruction always ends the current instruction block.
exitInstructionBlock = true;
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
if (DEBUG)
{
System.out.println("Exception:");
}
// The stack size when entering the exception handler is always 1.
stackSize = 1;
// Evaluate the instruction block starting at the entry point of the
// exception handler.
evaluateInstructionBlock(clazz,
method,
codeAttribute,
exceptionInfo.u2handlerPC);
}
// Small utility methods.
/**
* Evaluates a block of instructions that hasn't been handled before,
* starting at the given offset and ending at a branch instruction, a return
* instruction, or a throw instruction. Branch instructions are handled
* recursively.
*/
private void evaluateInstructionBlock(Clazz clazz,
Method method,
CodeAttribute codeAttribute,
int instructionOffset)
{
if (DEBUG)
{
if (evaluated[instructionOffset])
{
System.out.println("-- (instruction block at "+instructionOffset+" already evaluated)");
}
else
{
System.out.println("-- instruction block:");
}
}
// Remember the initial stack size.
int initialStackSize = stackSize;
// Remember the maximum stack size.
if (maxStackSize < stackSize)
{
maxStackSize = stackSize;
}
// Evaluate any instructions that haven't been evaluated before.
while (!evaluated[instructionOffset])
{
// Mark the instruction as evaluated.
evaluated[instructionOffset] = true;
Instruction instruction = InstructionFactory.create(codeAttribute.code,
instructionOffset);
if (DEBUG)
{
int stackPushCount = instruction.stackPushCount(clazz);
int stackPopCount = instruction.stackPopCount(clazz);
System.out.println("["+instructionOffset+"]: "+
stackSize+" - "+
stackPopCount+" + "+
stackPushCount+" = "+
(stackSize+stackPushCount-stackPopCount)+": "+
instruction.toString(instructionOffset));
}
// Compute the instruction's effect on the stack size.
stackSize -= instruction.stackPopCount(clazz);
if (stackSize < 0)
{
throw new IllegalArgumentException("Stack size becomes negative after instruction "+
instruction.toString(instructionOffset)+" in ["+
clazz.getName()+"."+
method.getName(clazz)+
method.getDescriptor(clazz)+"]");
}
stackSizes[instructionOffset] =
stackSize += instruction.stackPushCount(clazz);
// Remember the maximum stack size.
if (maxStackSize < stackSize)
{
maxStackSize = stackSize;
}
// Remember the next instruction offset.
int nextInstructionOffset = instructionOffset +
instruction.length(instructionOffset);
// Visit the instruction, in order to handle branches.
instruction.accept(clazz, method, codeAttribute, instructionOffset, this);
// Stop evaluating after a branch.
if (exitInstructionBlock)
{
break;
}
// Continue with the next instruction.
instructionOffset = nextInstructionOffset;
if (DEBUG)
{
if (evaluated[instructionOffset])
{
System.out.println("-- (instruction at "+instructionOffset+" already evaluated)");
}
}
}
// Restore the stack size for possible subsequent instruction blocks.
this.stackSize = initialStackSize;
}
}
proguard4.8/src/proguard/classfile/attribute/LineNumberTableAttribute.java 0000644 0001750 0001750 00000006162 11736333523 025715 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This Attribute represents a line number table attribute.
*
* @author Eric Lafortune
*/
public class LineNumberTableAttribute extends Attribute
{
public int u2lineNumberTableLength;
public LineNumberInfo[] lineNumberTable;
/**
* Creates an uninitialized LineNumberTableAttribute.
*/
public LineNumberTableAttribute()
{
}
/**
* Creates an initialized LineNumberTableAttribute.
*/
public LineNumberTableAttribute(int u2attributeNameIndex,
int u2lineNumberTableLength,
LineNumberInfo[] lineNumberTable)
{
super(u2attributeNameIndex);
this.u2lineNumberTableLength = u2lineNumberTableLength;
this.lineNumberTable = lineNumberTable;
}
/**
* Returns the line number corresponding to the given byte code program
* counter.
*/
public int getLineNumber(int pc)
{
for (int index = u2lineNumberTableLength-1 ; index >= 0 ; index--)
{
LineNumberInfo info = lineNumberTable[index];
if (pc >= info.u2startPC)
{
return info.u2lineNumber;
}
}
return u2lineNumberTableLength > 0 ?
lineNumberTable[0].u2lineNumber :
0;
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitLineNumberTableAttribute(clazz, method, codeAttribute, this);
}
/**
* Applies the given visitor to all line numbers.
*/
public void lineNumbersAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfoVisitor lineNumberInfoVisitor)
{
for (int index = 0; index < u2lineNumberTableLength; index++)
{
// We don't need double dispatching here, since there is only one
// type of LineNumberInfo.
lineNumberInfoVisitor.visitLineNumberInfo(clazz, method, codeAttribute, lineNumberTable[index]);
}
}
}
proguard4.8/src/proguard/classfile/attribute/ExceptionInfo.java 0000644 0001750 0001750 00000005150 11736333523 023567 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.VisitorAccepter;
/**
* Representation of an Exception table entry.
*
* @author Eric Lafortune
*/
public class ExceptionInfo implements VisitorAccepter
{
public int u2startPC;
public int u2endPC;
public int u2handlerPC;
public int u2catchType;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Creates an uninitialized ExceptionInfo.
*/
public ExceptionInfo()
{
this(0, 0, 0, 0);
}
/**
* Creates an ExceptionInfo with the given properties.
*/
public ExceptionInfo(int u2startPC,
int u2endPC,
int u2handlerPC,
int u2catchType)
{
this.u2startPC = u2startPC;
this.u2endPC = u2endPC;
this.u2handlerPC = u2handlerPC;
this.u2catchType = u2catchType;
}
/**
* Returns whether the exception's try block contains the instruction at the
* given offset.
*/
public boolean isApplicable(int instructionOffset)
{
return instructionOffset >= u2startPC &&
instructionOffset < u2endPC;
}
/**
* Returns whether the exception's try block overlaps with the specified
* block of instructions.
*/
public boolean isApplicable(int startOffset, int endOffset)
{
return u2startPC < endOffset &&
u2endPC > startOffset;
}
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
}
proguard4.8/src/proguard/classfile/attribute/SourceDirAttribute.java 0000644 0001750 0001750 00000003402 11736333523 024576 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.Clazz;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents a source directory attribute.
*
* @author Eric Lafortune
*/
public class SourceDirAttribute extends Attribute
{
public int u2sourceDirIndex;
/**
* Creates an uninitialized SourceDirAttribute.
*/
public SourceDirAttribute()
{
}
/**
* Creates an initialized SourceDirAttribute.
*/
public SourceDirAttribute(int u2attributeNameIndex,
int u2sourceDirIndex)
{
super(u2attributeNameIndex);
this.u2sourceDirIndex = u2sourceDirIndex;
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitSourceDirAttribute(clazz, this);
}
}
proguard4.8/src/proguard/classfile/attribute/ExceptionsAttribute.java 0000644 0001750 0001750 00000004740 11736333523 025026 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.AttributeVisitor;
import proguard.classfile.constant.visitor.ConstantVisitor;
/**
* This Attribute represents an exceptions attribute.
*
* @author Eric Lafortune
*/
public class ExceptionsAttribute extends Attribute
{
public int u2exceptionIndexTableLength;
public int[] u2exceptionIndexTable;
/**
* Creates an uninitialized ExceptionsAttribute.
*/
public ExceptionsAttribute()
{
}
/**
* Creates an initialized ExceptionsAttribute.
*/
public ExceptionsAttribute(int u2attributeNameIndex,
int u2exceptionIndexTableLength,
int[] u2exceptionIndexTable)
{
super(u2attributeNameIndex);
this.u2exceptionIndexTableLength = u2exceptionIndexTableLength;
this.u2exceptionIndexTable = u2exceptionIndexTable;
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitExceptionsAttribute(clazz, method, this);
}
/**
* Applies the given constant pool visitor to all exception class pool info
* entries.
*/
public void exceptionEntriesAccept(Clazz clazz, ConstantVisitor constantVisitor)
{
for (int index = 0; index < u2exceptionIndexTableLength; index++)
{
clazz.constantPoolEntryAccept(u2exceptionIndexTable[index],
constantVisitor);
}
}
}
proguard4.8/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java 0000644 0001750 0001750 00000005472 11736333523 027222 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.*;
/**
* This Attribute represents a local variable table type attribute.
*
* @author Eric Lafortune
*/
public class LocalVariableTypeTableAttribute extends Attribute
{
public int u2localVariableTypeTableLength;
public LocalVariableTypeInfo[] localVariableTypeTable;
/**
* Creates an uninitialized LocalVariableTypeTableAttribute.
*/
public LocalVariableTypeTableAttribute()
{
}
/**
* Creates an initialized LocalVariableTypeTableAttribute.
*/
public LocalVariableTypeTableAttribute(int u2attributeNameIndex,
int u2localVariableTypeTableLength,
LocalVariableTypeInfo[] localVariableTypeTable)
{
super(u2attributeNameIndex);
this.u2localVariableTypeTableLength = u2localVariableTypeTableLength;
this.localVariableTypeTable = localVariableTypeTable;
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitLocalVariableTypeTableAttribute(clazz, method, codeAttribute, this);
}
/**
* Applies the given visitor to all local variable types.
*/
public void localVariablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfoVisitor localVariableTypeInfoVisitor)
{
for (int index = 0; index < u2localVariableTypeTableLength; index++)
{
// We don't need double dispatching here, since there is only one
// type of LocalVariableTypeInfo.
localVariableTypeInfoVisitor.visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeTable[index]);
}
}
}
proguard4.8/src/proguard/classfile/attribute/LocalVariableTypeInfo.java 0000644 0001750 0001750 00000007277 11736333523 025207 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.Clazz;
import proguard.classfile.visitor.ClassVisitor;
/**
* Representation of an Local Variable table entry.
*
* @author Eric Lafortune
*/
public class LocalVariableTypeInfo implements Comparable
{
public int u2startPC;
public int u2length;
public int u2nameIndex;
public int u2signatureIndex;
public int u2index;
/**
* An extra field pointing to the Clazz objects referenced in the
* type string. This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz[] referencedClasses;
/**
* Creates an uninitialized LocalVariableTypeInfo.
*/
public LocalVariableTypeInfo()
{
}
/**
* Creates an initialized LocalVariableTypeInfo.
*/
public LocalVariableTypeInfo(int u2startPC,
int u2length,
int u2nameIndex,
int u2signatureIndex,
int u2index)
{
this.u2startPC = u2startPC;
this.u2length = u2length;
this.u2nameIndex = u2nameIndex;
this.u2signatureIndex = u2signatureIndex;
this.u2index = u2index;
}
/**
* Applies the given visitor to all referenced classes.
*/
public void referencedClassesAccept(ClassVisitor classVisitor)
{
if (referencedClasses != null)
{
for (int index = 0; index < referencedClasses.length; index++)
{
Clazz referencedClass = referencedClasses[index];
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
}
}
// 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;
}
}
proguard4.8/src/proguard/classfile/attribute/EnclosingMethodAttribute.java 0000644 0001750 0001750 00000007036 11736333523 025770 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.AttributeVisitor;
import proguard.classfile.visitor.*;
/**
* This Attribute represents an enclosing method attribute.
*
* @author Eric Lafortune
*/
public class EnclosingMethodAttribute extends Attribute
{
public int u2classIndex;
public int u2nameAndTypeIndex;
/**
* An extra field pointing to the referenced Clazz object.
* This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
.
*/
public Clazz referencedClass;
/**
* An extra field optionally pointing to the referenced Method object.
* This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
.
*/
public Method referencedMethod;
/**
* Creates an uninitialized EnclosingMethodAttribute.
*/
public EnclosingMethodAttribute()
{
}
/**
* Creates an initialized EnclosingMethodAttribute.
*/
public EnclosingMethodAttribute(int u2attributeNameIndex,
int u2classIndex,
int u2nameAndTypeIndex)
{
super(u2attributeNameIndex);
this.u2classIndex = u2classIndex;
this.u2nameAndTypeIndex = u2nameAndTypeIndex;
}
/**
* Returns the class name.
*/
public String getClassName(Clazz clazz)
{
return clazz.getClassName(u2classIndex);
}
/**
* Returns the method/field name.
*/
public String getName(Clazz clazz)
{
return clazz.getName(u2nameAndTypeIndex);
}
/**
* Returns the type.
*/
public String getType(Clazz clazz)
{
return clazz.getType(u2nameAndTypeIndex);
}
/**
* Lets the referenced class accept the given visitor.
*/
public void referencedClassAccept(ClassVisitor classVisitor)
{
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
/**
* Lets the referenced class member accept the given visitor.
*/
public void referencedMethodAccept(MemberVisitor memberVisitor)
{
if (referencedMethod != null)
{
referencedMethod.accept(referencedClass,
memberVisitor);
}
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitEnclosingMethodAttribute(clazz, this);
}
}
proguard4.8/src/proguard/classfile/attribute/SourceFileAttribute.java 0000644 0001750 0001750 00000003410 11736333523 024736 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.Clazz;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents a source file attribute.
*
* @author Eric Lafortune
*/
public class SourceFileAttribute extends Attribute
{
public int u2sourceFileIndex;
/**
* Creates an uninitialized SourceFileAttribute.
*/
public SourceFileAttribute()
{
}
/**
* Creates an initialized SourceFileAttribute.
*/
public SourceFileAttribute(int u2attributeNameIndex,
int u2sourceFileIndex)
{
super(u2attributeNameIndex);
this.u2sourceFileIndex = u2sourceFileIndex;
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitSourceFileAttribute(clazz, this);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/ 0000775 0001750 0001750 00000000000 11760503005 022314 5 ustar eric eric proguard4.8/src/proguard/classfile/attribute/annotation/package.html 0000644 0001750 0001750 00000000150 11736333523 024600 0 ustar eric eric
This package contains classes to represent the annotation attributes inside
class files.
proguard4.8/src/proguard/classfile/attribute/annotation/ElementValue.java 0000644 0001750 0001750 00000006641 11736333523 025563 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
import proguard.classfile.visitor.MemberVisitor;
/**
* This abstract class represents an element value that is attached to an
* annotation or an annotation default. Specific types of element values are
* subclassed from it.
*
* @author Eric Lafortune
*/
public abstract class ElementValue implements VisitorAccepter
{
/**
* An extra field for the optional element name. It is used in element value
* pairs of annotations. Otherwise, it is 0.
*/
public int u2elementNameIndex;
/**
* An extra field pointing to the referenced Clazz
* object, if applicable. This field is typically filled out by the
* {@link proguard.classfile.util.ClassReferenceInitializer}
.
*/
public Clazz referencedClass;
/**
* An extra field pointing to the referenced Method
* object, if applicable. This field is typically filled out by the
* {@link proguard.classfile.util.ClassReferenceInitializer}
.
*/
public Method referencedMethod;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Creates an uninitialized ElementValue.
*/
protected ElementValue()
{
}
/**
* Creates an initialized ElementValue.
*/
protected ElementValue(int u2elementNameIndex)
{
this.u2elementNameIndex = u2elementNameIndex;
}
/**
* Returns the element name.
*/
public String getMethodName(Clazz clazz)
{
return clazz.getString(u2elementNameIndex);
}
// Abstract methods to be implemented by extensions.
/**
* Returns the tag of this element value.
*/
public abstract int getTag();
/**
* Accepts the given visitor.
*/
public abstract void accept(Clazz clazz, Annotation annotation, ElementValueVisitor elementValueVisitor);
/**
* Applies the given visitor to the referenced method.
*/
public void referencedMethodAccept(MemberVisitor memberVisitor)
{
if (referencedMethod != null)
{
referencedMethod.accept(referencedClass, memberVisitor);
}
}
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/ArrayElementValue.java 0000644 0001750 0001750 00000004721 11736333523 026557 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
/**
* This ElementValue represents an array element value.
*
* @author Eric Lafortune
*/
public class ArrayElementValue extends ElementValue
{
public int u2elementValuesCount;
public ElementValue[] elementValues;
/**
* Creates an uninitialized ArrayElementValue.
*/
public ArrayElementValue()
{
}
/**
* Creates an initialized ArrayElementValue.
*/
public ArrayElementValue(int u2elementNameIndex,
int u2elementValuesCount,
ElementValue[] elementValues)
{
super(u2elementNameIndex);
this.u2elementValuesCount = u2elementValuesCount;
this.elementValues = elementValues;
}
// Implementations for ElementValue.
public int getTag()
{
return ClassConstants.ELEMENT_VALUE_ARRAY;
}
public void accept(Clazz clazz, Annotation annotation, ElementValueVisitor elementValueVisitor)
{
elementValueVisitor.visitArrayElementValue(clazz, annotation, this);
}
/**
* Applies the given visitor to all nested element values.
*/
public void elementValuesAccept(Clazz clazz, Annotation annotation, ElementValueVisitor elementValueVisitor)
{
for (int index = 0; index < u2elementValuesCount; index++)
{
elementValues[index].accept(clazz, annotation, elementValueVisitor);
}
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/ConstantElementValue.java 0000644 0001750 0001750 00000004076 11736333523 027275 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.Clazz;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
/**
* This ElementValue represents a constant element value.
*
* @author Eric Lafortune
*/
public class ConstantElementValue extends ElementValue
{
public final int u1tag;
public int u2constantValueIndex;
/**
* Creates an uninitialized ConstantElementValue.
*/
public ConstantElementValue(int u1tag)
{
this.u1tag = u1tag;
}
/**
* Creates an initialized ConstantElementValue.
*/
public ConstantElementValue(int u1tag,
int u2elementNameIndex,
int u2constantValueIndex)
{
super(u2elementNameIndex);
this.u1tag = u1tag;
this.u2constantValueIndex = u2constantValueIndex;
}
// Implementations for ElementValue.
public int getTag()
{
return u1tag;
}
public void accept(Clazz clazz, Annotation annotation, ElementValueVisitor elementValueVisitor)
{
elementValueVisitor.visitConstantElementValue(clazz, annotation, this);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/ClassElementValue.java 0000644 0001750 0001750 00000005437 11736333523 026553 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
import proguard.classfile.visitor.ClassVisitor;
/**
* This ElementValue represents a class element value.
*
* @author Eric Lafortune
*/
public class ClassElementValue extends ElementValue
{
public int u2classInfoIndex;
/**
* An extra field pointing to the Clazz objects referenced in the
* type name string. This field is filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz[] referencedClasses;
/**
* Creates an uninitialized ClassElementValue.
*/
public ClassElementValue()
{
}
/**
* Creates an initialized ClassElementValue.
*/
public ClassElementValue(int u2elementNameIndex,
int u2classInfoIndex)
{
super(u2elementNameIndex);
this.u2classInfoIndex = u2classInfoIndex;
}
/**
* Applies the given visitor to all referenced classes.
*/
public void referencedClassesAccept(ClassVisitor classVisitor)
{
if (referencedClasses != null)
{
for (int index = 0; index < referencedClasses.length; index++)
{
Clazz referencedClass = referencedClasses[index];
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
}
}
// Implementations for ElementValue.
public int getTag()
{
return ClassConstants.ELEMENT_VALUE_CLASS;
}
public void accept(Clazz clazz, Annotation annotation, ElementValueVisitor elementValueVisitor)
{
elementValueVisitor.visitClassElementValue(clazz, annotation, this);
}
}
././@LongLink 0000000 0000000 0000000 00000000153 00000000000 011564 L ustar root root proguard4.8/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java proguard4.8/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribut0000644 0001750 0001750 00000004374 11736333523 033344 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents a runtime invisible parameter annotations attribute.
*
* @author Eric Lafortune
*/
public class RuntimeInvisibleParameterAnnotationsAttribute extends ParameterAnnotationsAttribute
{
/**
* Creates an uninitialized RuntimeInvisibleParameterAnnotationsAttribute.
*/
public RuntimeInvisibleParameterAnnotationsAttribute()
{
}
/**
* Creates an initialized RuntimeInvisibleParameterAnnotationsAttribute.
*/
public RuntimeInvisibleParameterAnnotationsAttribute(int u2attributeNameIndex,
int u2parametersCount,
int[] u2parameterAnnotationsCount,
Annotation[][] parameterAnnotations)
{
super(u2attributeNameIndex,
u2parametersCount,
u2parameterAnnotationsCount,
parameterAnnotations);
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitRuntimeInvisibleParameterAnnotationsAttribute(clazz, method, this);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java 0000644 0001750 0001750 00000004451 11736333523 032235 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents a runtime visible annotations attribute.
*
* @author Eric Lafortune
*/
public class RuntimeVisibleAnnotationsAttribute extends AnnotationsAttribute
{
/**
* Creates an uninitialized RuntimeVisibleAnnotationsAttribute.
*/
public RuntimeVisibleAnnotationsAttribute()
{
}
/**
* Creates an initialized RuntimeVisibleAnnotationsAttribute.
*/
public RuntimeVisibleAnnotationsAttribute(int u2attributeNameIndex,
int u2annotationsCount,
Annotation[] annotations)
{
super(u2attributeNameIndex, u2annotationsCount, annotations);
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, this);
}
public void accept(Clazz clazz, Field field, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, field, this);
}
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, method, this);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/visitor/ 0000775 0001750 0001750 00000000000 11760503005 024013 5 ustar eric eric proguard4.8/src/proguard/classfile/attribute/annotation/visitor/package.html 0000644 0001750 0001750 00000000136 11736333523 026303 0 ustar eric eric
This package contains visitors for annotation attributes and their components.
proguard4.8/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java 0000644 0001750 0001750 00000003362 11736333523 030363 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.Annotation;
/**
* This interface specifies the methods for a visitor of
* Annotation
objects. Note that there is only a single
* implementation of Annotation
, such that this interface
* is not strictly necessary as a visitor.
*
* @author Eric Lafortune
*/
public interface AnnotationVisitor
{
public void visitAnnotation(Clazz clazz, Annotation annotation);
public void visitAnnotation(Clazz clazz, Field field, Annotation annotation);
public void visitAnnotation(Clazz clazz, Method method, Annotation annotation);
public void visitAnnotation(Clazz clazz, Method method, int parameterIndex, Annotation annotation);
}
proguard4.8/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java 0000644 0001750 0001750 00000006525 11736333523 030643 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation.visitor;
import proguard.classfile.Clazz;
import proguard.classfile.attribute.annotation.*;
/**
* This interface specifies the methods for a visitor of ElementValue
* objects.
*
* @author Eric Lafortune
*/
public interface ElementValueVisitor
{
public void visitConstantElementValue( Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue);
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue);
public void visitClassElementValue( Clazz clazz, Annotation annotation, ClassElementValue classElementValue);
public void visitAnnotationElementValue( Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue);
public void visitArrayElementValue( Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue);
// public void visitConstantElementValue( Clazz clazz, Field field, Annotation annotation, ConstantElementValue constantElementValue);
// public void visitEnumConstantElementValue(Clazz clazz, Field field, Annotation annotation, EnumConstantElementValue enumConstantElementValue);
// public void visitClassElementValue( Clazz clazz, Field field, Annotation annotation, ClassElementValue classElementValue);
// public void visitAnnotationElementValue( Clazz clazz, Field field, Annotation annotation, AnnotationElementValue annotationElementValue);
// public void visitArrayElementValue( Clazz clazz, Field field, Annotation annotation, ArrayElementValue arrayElementValue);
//
// public void visitConstantElementValue( Clazz clazz, Method method, Annotation annotation, ConstantElementValue constantElementValue);
// public void visitEnumConstantElementValue(Clazz clazz, Method method, Annotation annotation, EnumConstantElementValue enumConstantElementValue);
// public void visitClassElementValue( Clazz clazz, Method method, Annotation annotation, ClassElementValue classElementValue);
// public void visitAnnotationElementValue( Clazz clazz, Method method, Annotation annotation, AnnotationElementValue annotationElementValue);
// public void visitArrayElementValue( Clazz clazz, Method method, Annotation annotation, ArrayElementValue arrayElementValue);
}
proguard4.8/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java 0000644 0001750 0001750 00000007336 11736333523 031021 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This AttributeVisitor lets a given AnnotationVisitor visit all Annotation
* objects of the attributes it visits.
*
* @author Eric Lafortune
*/
public class AllAnnotationVisitor
extends SimplifiedVisitor
implements AttributeVisitor
{
private final AnnotationVisitor annotationVisitor;
public AllAnnotationVisitor(AnnotationVisitor annotationVisitor)
{
this.annotationVisitor = annotationVisitor;
}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
// Visit the annotations.
runtimeVisibleAnnotationsAttribute.annotationsAccept(clazz, annotationVisitor);
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
// Visit the annotations.
runtimeVisibleAnnotationsAttribute.annotationsAccept(clazz, field, annotationVisitor);
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
// Visit the annotations.
runtimeVisibleAnnotationsAttribute.annotationsAccept(clazz, method, annotationVisitor);
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
// Visit the annotations.
runtimeInvisibleAnnotationsAttribute.annotationsAccept(clazz, annotationVisitor);
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
// Visit the annotations.
runtimeInvisibleAnnotationsAttribute.annotationsAccept(clazz, field, annotationVisitor);
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
// Visit the annotations.
runtimeInvisibleAnnotationsAttribute.annotationsAccept(clazz, method, annotationVisitor);
}
public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
{
// Visit the annotations.
parameterAnnotationsAttribute.annotationsAccept(clazz, method, annotationVisitor);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java 0000644 0001750 0001750 00000006464 11736333523 031021 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.Annotation;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.util.*;
/**
* This AnnotationVisitor
delegates its visits to another given
* AnnotationVisitor
, but only when the visited annotation has
* a type that matches a given regular expression.
*
* @author Eric Lafortune
*/
public class AnnotationTypeFilter
extends SimplifiedVisitor
implements AnnotationVisitor
{
private final StringMatcher regularExpressionMatcher;
private final AnnotationVisitor annotationVisitor;
/**
* Creates a new ClassNameFilter.
* @param regularExpression the regular expression against which annotation
* type names will be matched.
* @param annotationVisitor the annotationVisitor
to which
* visits will be delegated.
*/
public AnnotationTypeFilter(String regularExpression,
AnnotationVisitor annotationVisitor)
{
this.regularExpressionMatcher = new ListParser(new ClassNameParser()).parse(regularExpression);
this.annotationVisitor = annotationVisitor;
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
if (accepted(annotation.getType(clazz)))
{
annotationVisitor.visitAnnotation(clazz, annotation);
}
}
public void visitAnnotation(Clazz clazz, Field field, Annotation annotation)
{
if (accepted(annotation.getType(clazz)))
{
annotationVisitor.visitAnnotation(clazz, field, annotation);
}
}
public void visitAnnotation(Clazz clazz, Method method, Annotation annotation)
{
if (accepted(annotation.getType(clazz)))
{
annotationVisitor.visitAnnotation(clazz, method, annotation);
}
}
public void visitAnnotation(Clazz clazz, Method method, int parameterIndex, Annotation annotation)
{
if (accepted(annotation.getType(clazz)))
{
annotationVisitor.visitAnnotation(clazz, method, parameterIndex, annotation);
}
}
// Small utility methods.
private boolean accepted(String name)
{
return regularExpressionMatcher.matches(name);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java 0000644 0001750 0001750 00000003740 11736333523 032016 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.Annotation;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.MemberVisitor;
/**
* This AnnotationVisitor delegates all visits to a given MemberVisitor.
* The latter visits the class member of each visited class member annotation
* or method parameter annotation, although never twice in a row.
*
* @author Eric Lafortune
*/
public class AnnotationToMemberVisitor
extends SimplifiedVisitor
implements AnnotationVisitor
{
private final MemberVisitor memberVisitor;
private Member lastVisitedMember;
public AnnotationToMemberVisitor(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Member member, Annotation annotation)
{
if (!member.equals(lastVisitedMember))
{
member.accept(clazz, memberVisitor);
lastVisitedMember = member;
}
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java 0000644 0001750 0001750 00000003603 11736333523 031152 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation.visitor;
import proguard.classfile.Clazz;
import proguard.classfile.attribute.annotation.Annotation;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.ClassVisitor;
/**
* This AnnotationVisitor delegates all visits to a given ClassVisitor.
* The latter visits the class of each visited annotation, although
* never twice in a row.
*
* @author Eric Lafortune
*/
public class AnnotatedClassVisitor
extends SimplifiedVisitor
implements AnnotationVisitor
{
private final ClassVisitor classVisitor;
private Clazz lastVisitedClass;
public AnnotatedClassVisitor(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
if (!clazz.equals(lastVisitedClass))
{
clazz.accept(classVisitor);
lastVisitedClass = clazz;
}
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java 0000644 0001750 0001750 00000004473 11736333523 032570 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents a runtime invisible annotations attribute.
*
* @author Eric Lafortune
*/
public class RuntimeInvisibleAnnotationsAttribute extends AnnotationsAttribute
{
/**
* Creates an uninitialized RuntimeInvisibleAnnotationsAttribute.
*/
public RuntimeInvisibleAnnotationsAttribute()
{
}
/**
* Creates an initialized RuntimeInvisibleAnnotationsAttribute.
*/
public RuntimeInvisibleAnnotationsAttribute(int u2attributeNameIndex,
int u2annotationsCount,
Annotation[] annotations)
{
super(u2attributeNameIndex, u2annotationsCount, annotations);
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, this);
}
public void accept(Clazz clazz, Field field, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, field, this);
}
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, method, this);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java 0000644 0001750 0001750 00000006273 11736333523 027357 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.attribute.annotation.visitor.AnnotationVisitor;
/**
* This Attribute represents an annotations attribute.
*
* @author Eric Lafortune
*/
public abstract class AnnotationsAttribute extends Attribute
{
public int u2annotationsCount;
public Annotation[] annotations;
/**
* Creates an uninitialized AnnotationsAttribute.
*/
protected AnnotationsAttribute()
{
}
/**
* Creates an initialized AnnotationsAttribute.
*/
protected AnnotationsAttribute(int u2attributeNameIndex,
int u2annotationsCount,
Annotation[] annotations)
{
super(u2attributeNameIndex);
this.u2annotationsCount = u2annotationsCount;
this.annotations = annotations;
}
/**
* Applies the given visitor to all class annotations.
*/
public void annotationsAccept(Clazz clazz, AnnotationVisitor annotationVisitor)
{
for (int index = 0; index < u2annotationsCount; index++)
{
// We don't need double dispatching here, since there is only one
// type of Annotation.
annotationVisitor.visitAnnotation(clazz, annotations[index]);
}
}
/**
* Applies the given visitor to all field annotations.
*/
public void annotationsAccept(Clazz clazz, Field field, AnnotationVisitor annotationVisitor)
{
for (int index = 0; index < u2annotationsCount; index++)
{
// We don't need double dispatching here, since there is only one
// type of Annotation.
annotationVisitor.visitAnnotation(clazz, field, annotations[index]);
}
}
/**
* Applies the given visitor to all method annotations.
*/
public void annotationsAccept(Clazz clazz, Method method, AnnotationVisitor annotationVisitor)
{
for (int index = 0; index < u2annotationsCount; index++)
{
// We don't need double dispatching here, since there is only one
// type of Annotation.
annotationVisitor.visitAnnotation(clazz, method, annotations[index]);
}
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java 0000644 0001750 0001750 00000006022 11736333523 030113 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
import proguard.classfile.visitor.ClassVisitor;
/**
* This ElementValue represents an enumeration constant element value.
*
* @author Eric Lafortune
*/
public class EnumConstantElementValue extends ElementValue
{
public int u2typeNameIndex;
public int u2constantNameIndex;
/**
* An extra field pointing to the Clazz objects referenced in the
* type name string. This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz[] referencedClasses;
/**
* Creates an uninitialized EnumConstantElementValue.
*/
public EnumConstantElementValue()
{
}
/**
* Creates an initialized EnumConstantElementValue.
*/
public EnumConstantElementValue(int u2elementNameIndex,
int u2typeNameIndex,
int u2constantNameIndex)
{
super(u2elementNameIndex);
this.u2typeNameIndex = u2typeNameIndex;
this.u2constantNameIndex = u2constantNameIndex;
}
/**
* Applies the given visitor to all referenced classes.
*/
public void referencedClassesAccept(ClassVisitor classVisitor)
{
if (referencedClasses != null)
{
for (int index = 0; index < referencedClasses.length; index++)
{
Clazz referencedClass = referencedClasses[index];
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
}
}
// Implementations for ElementValue.
public int getTag()
{
return ClassConstants.ELEMENT_VALUE_ENUM_CONSTANT;
}
public void accept(Clazz clazz, Annotation annotation, ElementValueVisitor elementValueVisitor)
{
elementValueVisitor.visitEnumConstantElementValue(clazz, annotation, this);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java 0000644 0001750 0001750 00000006032 11736333523 031211 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.attribute.annotation.visitor.AnnotationVisitor;
/**
* This Attribute represents a runtime parameter annotations attribute.
*
* @author Eric Lafortune
*/
public abstract class ParameterAnnotationsAttribute extends Attribute
{
public int u2parametersCount;
public int[] u2parameterAnnotationsCount;
public Annotation[][] parameterAnnotations;
/**
* Creates an uninitialized ParameterAnnotationsAttribute.
*/
protected ParameterAnnotationsAttribute()
{
}
/**
* Creates an initialized ParameterAnnotationsAttribute.
*/
protected ParameterAnnotationsAttribute(int u2attributeNameIndex,
int u2parametersCount,
int[] u2parameterAnnotationsCount,
Annotation[][] parameterAnnotations)
{
super(u2attributeNameIndex);
this.u2parametersCount = u2parametersCount;
this.u2parameterAnnotationsCount = u2parameterAnnotationsCount;
this.parameterAnnotations = parameterAnnotations;
}
/**
* Applies the given visitor to all annotations.
*/
public void annotationsAccept(Clazz clazz, Method method, AnnotationVisitor annotationVisitor)
{
// Loop over all parameters.
for (int parameterIndex = 0; parameterIndex < u2parametersCount; parameterIndex++)
{
int annotationsCount = u2parameterAnnotationsCount[parameterIndex];
Annotation[] annotations = parameterAnnotations[parameterIndex];
// Loop over all parameter annotations.
for (int index = 0; index < annotationsCount; index++)
{
// We don't need double dispatching here, since there is only one
// type of Annotation.
annotationVisitor.visitAnnotation(clazz, method, parameterIndex, annotations[index]);
}
}
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java 0000644 0001750 0001750 00000004326 11736333523 030476 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents an annotation default attribute.
*
* @author Eric Lafortune
*/
public class AnnotationDefaultAttribute extends Attribute
{
public ElementValue defaultValue;
/**
* Creates an uninitialized AnnotationDefaultAttribute.
*/
public AnnotationDefaultAttribute()
{
}
/**
* Creates an initialized AnnotationDefaultAttribute.
*/
public AnnotationDefaultAttribute(int u2attributeNameIndex,
ElementValue defaultValue)
{
super(u2attributeNameIndex);
this.defaultValue = defaultValue;
}
/**
* Applies the given visitor to the default element value.
*/
public void defaultValueAccept(Clazz clazz, ElementValueVisitor elementValueVisitor)
{
defaultValue.accept(clazz, null, elementValueVisitor);
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitAnnotationDefaultAttribute(clazz, method, this);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/Annotation.java 0000644 0001750 0001750 00000007616 11736333523 025312 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
import proguard.classfile.visitor.ClassVisitor;
/**
* Representation of an annotation.
*
* @author Eric Lafortune
*/
public class Annotation implements VisitorAccepter
{
public int u2typeIndex;
public int u2elementValuesCount;
public ElementValue[] elementValues;
/**
* An extra field pointing to the Clazz objects referenced in the
* type string. This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz[] referencedClasses;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Creates an uninitialized Annotation.
*/
public Annotation()
{
}
/**
* Creates an initialized Annotation.
*/
public Annotation(int u2typeIndex,
int u2elementValuesCount,
ElementValue[] elementValues)
{
this.u2typeIndex = u2typeIndex;
this.u2elementValuesCount = u2elementValuesCount;
this.elementValues = elementValues;
}
/**
* Returns the type.
*/
public String getType(Clazz clazz)
{
return clazz.getString(u2typeIndex);
}
/**
* Applies the given visitor to the first referenced class. This is the
* main annotation class.
*/
public void referencedClassAccept(ClassVisitor classVisitor)
{
if (referencedClasses != null)
{
Clazz referencedClass = referencedClasses[0];
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
}
/**
* Applies the given visitor to all referenced classes.
*/
public void referencedClassesAccept(ClassVisitor classVisitor)
{
if (referencedClasses != null)
{
for (int index = 0; index < referencedClasses.length; index++)
{
Clazz referencedClass = referencedClasses[index];
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
}
}
/**
* Applies the given visitor to all element value pairs.
*/
public void elementValuesAccept(Clazz clazz, ElementValueVisitor elementValueVisitor)
{
for (int index = 0; index < u2elementValuesCount; index++)
{
elementValues[index].accept(clazz, this, elementValueVisitor);
}
}
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
}
././@LongLink 0000000 0000000 0000000 00000000151 00000000000 011562 L ustar root root proguard4.8/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java proguard4.8/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.0000644 0001750 0001750 00000004350 11736333523 033232 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents a runtime visible parameter annotations attribute.
*
* @author Eric Lafortune
*/
public class RuntimeVisibleParameterAnnotationsAttribute extends ParameterAnnotationsAttribute
{
/**
* Creates an uninitialized RuntimeVisibleParameterAnnotationsAttribute.
*/
public RuntimeVisibleParameterAnnotationsAttribute()
{
}
/**
* Creates an initialized RuntimeVisibleParameterAnnotationsAttribute.
*/
public RuntimeVisibleParameterAnnotationsAttribute(int u2attributeNameIndex,
int u2parametersCount,
int[] u2parameterAnnotationsCount,
Annotation[][] parameterAnnotations)
{
super(u2attributeNameIndex,
u2parametersCount,
u2parameterAnnotationsCount,
parameterAnnotations);
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitRuntimeVisibleParameterAnnotationsAttribute(clazz, method, this);
}
}
proguard4.8/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java 0000644 0001750 0001750 00000004247 11736333523 027616 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.annotation;
import proguard.classfile.*;
import proguard.classfile.attribute.annotation.visitor.*;
/**
* This ElementValue represents an annotation element value.
*
* @author Eric Lafortune
*/
public class AnnotationElementValue extends ElementValue
{
public Annotation annotationValue;
/**
* Creates an uninitialized AnnotationElementValue.
*/
public AnnotationElementValue()
{
}
/**
* Creates an initialized AnnotationElementValue.
*/
public AnnotationElementValue(int u2elementNameIndex,
Annotation annotationValue)
{
super(u2elementNameIndex);
this.annotationValue = annotationValue;
}
/**
* Applies the given visitor to the annotation.
*/
public void annotationAccept(Clazz clazz, AnnotationVisitor annotationVisitor)
{
annotationVisitor.visitAnnotation(clazz, annotationValue);
}
// Implementations for ElementValue.
public int getTag()
{
return ClassConstants.ELEMENT_VALUE_ANNOTATION;
}
public void accept(Clazz clazz, Annotation annotation, ElementValueVisitor elementValueVisitor)
{
elementValueVisitor.visitAnnotationElementValue(clazz, annotation, this);
}
}
proguard4.8/src/proguard/classfile/attribute/SignatureAttribute.java 0000644 0001750 0001750 00000005714 11736333523 024650 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.AttributeVisitor;
import proguard.classfile.visitor.ClassVisitor;
/**
* This Attribute represents a signature attribute.
*
* @author Eric Lafortune
*/
public class SignatureAttribute extends Attribute
{
public int u2signatureIndex;
/**
* An extra field pointing to the Clazz objects referenced in the
* signature string. This field is filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz[] referencedClasses;
/**
* Creates an uninitialized SignatureAttribute.
*/
public SignatureAttribute()
{
}
/**
* Creates an initialized SignatureAttribute.
*/
public SignatureAttribute(int u2attributeNameIndex,
int u2signatureIndex)
{
super(u2attributeNameIndex);
this.u2signatureIndex = u2signatureIndex;
}
/**
* Lets the Clazz objects referenced in the signature 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);
}
}
}
}
// Implementations for Attribute.
public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitSignatureAttribute(clazz, this);
}
public void accept(Clazz clazz, Field field, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitSignatureAttribute(clazz, field, this);
}
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitSignatureAttribute(clazz, method, this);
}
}
proguard4.8/src/proguard/classfile/attribute/LineNumberInfo.java 0000644 0001750 0001750 00000002631 11736333523 023672 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
/**
* Representation of an Line Number table entry.
*
* @author Eric Lafortune
*/
public class LineNumberInfo
{
public int u2startPC;
public int u2lineNumber;
/**
* Creates an uninitialized LineNumberInfo.
*/
public LineNumberInfo()
{
}
/**
* Creates an initialized LineNumberInfo.
*/
public LineNumberInfo(int u2startPC, int u2lineNumber)
{
this.u2startPC = u2startPC;
this.u2lineNumber = u2lineNumber;
}
}
proguard4.8/src/proguard/classfile/attribute/CodeAttribute.java 0000644 0001750 0001750 00000015262 11736333523 023560 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
/**
* This Attribute represents a code attribute.
*
* @author Eric Lafortune
*/
public class CodeAttribute extends Attribute
{
public int u2maxStack;
public int u2maxLocals;
public int u4codeLength;
public byte[] code;
public int u2exceptionTableLength;
public ExceptionInfo[] exceptionTable;
public int u2attributesCount;
public Attribute[] attributes;
/**
* Creates an uninitialized CodeAttribute.
*/
public CodeAttribute()
{
}
/**
* Creates an initialized CodeAttribute.
*/
public CodeAttribute(int u2attributeNameIndex,
int u2maxStack,
int u2maxLocals,
int u4codeLength,
byte[] code,
int u2exceptionTableLength,
ExceptionInfo[] exceptionTable,
int u2attributesCount,
Attribute[] attributes)
{
super(u2attributeNameIndex);
this.u2maxStack = u2maxStack;
this.u2maxLocals = u2maxLocals;
this.u4codeLength = u4codeLength;
this.code = code;
this.u2exceptionTableLength = u2exceptionTableLength;
this.exceptionTable = exceptionTable;
this.u2attributesCount = u2attributesCount;
this.attributes = attributes;
}
/**
* Returns the (first) attribute with the given name.
*/
public Attribute getAttribute(Clazz clazz, String name)
{
for (int index = 0; index < u2attributesCount; index++)
{
Attribute attribute = attributes[index];
if (attribute.getAttributeName(clazz).equals(name))
{
return attribute;
}
}
return null;
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitCodeAttribute(clazz, method, this);
}
/**
* Applies the given instruction visitor to all instructions.
*/
public void instructionsAccept(Clazz clazz, Method method, InstructionVisitor instructionVisitor)
{
instructionsAccept(clazz, method, 0, u4codeLength, instructionVisitor);
}
/**
* Applies the given instruction visitor to the instruction at the specified
* offset.
*/
public void instructionAccept(Clazz clazz, Method method, int offset, InstructionVisitor instructionVisitor)
{
Instruction instruction = InstructionFactory.create(code, offset);
instruction.accept(clazz, method, this, offset, instructionVisitor);
}
/**
* Applies the given instruction visitor to all instructions in the
* specified range of offsets.
*/
public void instructionsAccept(Clazz clazz, Method method, int startOffset, int endOffset, InstructionVisitor instructionVisitor)
{
int offset = startOffset;
while (offset < endOffset)
{
// Note that the instruction is only volatile.
Instruction instruction = InstructionFactory.create(code, offset);
int instructionLength = instruction.length(offset);
instruction.accept(clazz, method, this, offset, instructionVisitor);
offset += instructionLength;
}
}
/**
* Applies the given exception visitor to all exceptions.
*/
public void exceptionsAccept(Clazz clazz, Method method, ExceptionInfoVisitor exceptionInfoVisitor)
{
for (int index = 0; index < u2exceptionTableLength; index++)
{
// We don't need double dispatching here, since there is only one
// type of ExceptionInfo.
exceptionInfoVisitor.visitExceptionInfo(clazz, method, this, exceptionTable[index]);
}
}
/**
* Applies the given exception visitor to all exceptions that are applicable
* to the instruction at the specified offset.
*/
public void exceptionsAccept(Clazz clazz, Method method, int offset, ExceptionInfoVisitor exceptionInfoVisitor)
{
for (int index = 0; index < u2exceptionTableLength; index++)
{
ExceptionInfo exceptionInfo = exceptionTable[index];
if (exceptionInfo.isApplicable(offset))
{
exceptionInfoVisitor.visitExceptionInfo(clazz, method, this, exceptionInfo);
}
}
}
/**
* Applies the given exception visitor to all exceptions that are applicable
* to any of the instructions in the specified range of offsets.
*/
public void exceptionsAccept(Clazz clazz, Method method, int startOffset, int endOffset, ExceptionInfoVisitor exceptionInfoVisitor)
{
for (int index = 0; index < u2exceptionTableLength; index++)
{
ExceptionInfo exceptionInfo = exceptionTable[index];
if (exceptionInfo.isApplicable(startOffset, endOffset))
{
exceptionInfoVisitor.visitExceptionInfo(clazz, method, this, exceptionInfo);
}
}
}
/**
* Applies the given attribute visitor to all attributes.
*/
public void attributesAccept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
{
for (int index = 0; index < u2attributesCount; index++)
{
attributes[index].accept(clazz, method, this, attributeVisitor);
}
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/ 0000775 0001750 0001750 00000000000 11760503005 023333 5 ustar eric eric proguard4.8/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java 0000644 0001750 0001750 00000006207 11736333523 031026 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
/**
* This class provides methods to create and reuse IntegerType objects.
*
* @author Eric Lafortune
*/
public class VerificationTypeFactory
{
// Shared copies of Type objects, to avoid creating a lot of objects.
static final IntegerType INTEGER_TYPE = new IntegerType();
static final LongType LONG_TYPE = new LongType();
static final FloatType FLOAT_TYPE = new FloatType();
static final DoubleType DOUBLE_TYPE = new DoubleType();
static final TopType TOP_TYPE = new TopType();
static final NullType NULL_TYPE = new NullType();
static final UninitializedThisType UNINITIALIZED_THIS_TYPE = new UninitializedThisType();
/**
* Creates a new IntegerType.
*/
public static IntegerType createIntegerType()
{
return INTEGER_TYPE;
}
/**
* Creates a new LongType.
*/
public static LongType createLongType()
{
return LONG_TYPE;
}
/**
* Creates a new FloatType.
*/
public static FloatType createFloatType()
{
return FLOAT_TYPE;
}
/**
* Creates a new DoubleType.
*/
public static DoubleType createDoubleType()
{
return DOUBLE_TYPE;
}
/**
* Creates a new TopType.
*/
public static TopType createTopType()
{
return TOP_TYPE;
}
/**
* Creates a new NullType.
*/
public static NullType createNullType()
{
return NULL_TYPE;
}
/**
* Creates a new UninitializedThisType.
*/
public static UninitializedThisType createUninitializedThisType()
{
return UNINITIALIZED_THIS_TYPE;
}
/**
* Creates a new UninitializedType for an instance that was created at
* the given offset.
*/
public static UninitializedType createUninitializedType(int newInstructionOffset)
{
return new UninitializedType(newInstructionOffset);
}
/**
* Creates a new ObjectType of the given type.
*/
public static ObjectType createObjectType(int classIndex)
{
return new ObjectType(classIndex);
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/TopType.java 0000644 0001750 0001750 00000004460 11736333523 025615 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents a Top type.
*
* @author Eric Lafortune
*/
public class TopType extends VerificationType
{
// Implementations for VerificationType.
public int getTag()
{
return TOP_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitTopType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackTopType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesTopType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public String toString()
{
return "T";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/SameZeroFrame.java 0000644 0001750 0001750 00000004200 11736333523 026701 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.StackMapFrameVisitor;
/**
* This StackMapFrame represents a "same frame" or a "same frame extended".
*
* @author Eric Lafortune
* @noinspection PointlessArithmeticExpression
*/
public class SameZeroFrame extends StackMapFrame
{
/**
* Creates an uninitialized SameZeroFrame.
*/
public SameZeroFrame()
{
}
/**
* Creates a SameZeroFrame with the given tag.
*/
public SameZeroFrame(int tag)
{
u2offsetDelta = tag - SAME_ZERO_FRAME;
}
// Implementations for StackMapFrame.
public int getTag()
{
return u2offsetDelta < 64 ?
SAME_ZERO_FRAME + u2offsetDelta :
SAME_ZERO_FRAME_EXTENDED;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrameVisitor stackMapFrameVisitor)
{
stackMapFrameVisitor.visitSameZeroFrame(clazz, method, codeAttribute, offset, this);
}
// Implementations for Object.
public String toString()
{
return super.toString()+"Var: ..., Stack: (empty)";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java 0000644 0001750 0001750 00000010721 11736333523 026723 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.*;
/**
* This StackMapFrame represents an "append frame".
*
* @author Eric Lafortune
*/
public class MoreZeroFrame extends StackMapFrame
{
public int additionalVariablesCount;
public VerificationType[] additionalVariables;
/**
* Creates an uninitialized MoreZeroFrame.
*/
public MoreZeroFrame()
{
}
/**
* Creates a MoreZeroFrame with the given tag.
*/
public MoreZeroFrame(int tag)
{
additionalVariablesCount = tag + 1 - MORE_ZERO_FRAME;
}
/**
* Creates a MoreZeroFrame with the given additional variables.
*/
public MoreZeroFrame(VerificationType[] additionalVariables)
{
this(additionalVariables.length, additionalVariables);
}
/**
* Creates a MoreZeroFrame with the given additional variables.
*/
public MoreZeroFrame(int additionalVariablesCount,
VerificationType[] additionalVariables)
{
this.additionalVariablesCount = additionalVariablesCount;
this.additionalVariables = additionalVariables;
}
/**
* Applies the given verification type visitor to all variables.
*/
public void additionalVariablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationTypeVisitor verificationTypeVisitor)
{
for (int index = 0; index < additionalVariablesCount; index++)
{
additionalVariables[index].accept(clazz, method, codeAttribute, offset, verificationTypeVisitor);
}
}
// Implementations for StackMapFrame.
public int getTag()
{
return MORE_ZERO_FRAME + additionalVariablesCount - 1;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrameVisitor stackMapFrameVisitor)
{
stackMapFrameVisitor.visitMoreZeroFrame(clazz, method, codeAttribute, offset, this);
}
// Implementations for Object.
public boolean equals(Object object)
{
if (!super.equals(object))
{
return false;
}
MoreZeroFrame other = (MoreZeroFrame)object;
if (this.u2offsetDelta != other.u2offsetDelta ||
this.additionalVariablesCount != other.additionalVariablesCount)
{
return false;
}
for (int index = 0; index < additionalVariablesCount; index++)
{
VerificationType thisType = this.additionalVariables[index];
VerificationType otherType = other.additionalVariables[index];
if (!thisType.equals(otherType))
{
return false;
}
}
return true;
}
public int hashCode()
{
int hashCode = super.hashCode();
for (int index = 0; index < additionalVariablesCount; index++)
{
hashCode ^= additionalVariables[index].hashCode();
}
return hashCode;
}
public String toString()
{
StringBuffer buffer = new StringBuffer(super.toString()).append("Var: ...");
for (int index = 0; index < additionalVariablesCount; index++)
{
buffer = buffer.append('[')
.append(additionalVariables[index].toString())
.append(']');
}
buffer.append(", Stack: (empty)");
return buffer.toString();
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/IntegerType.java 0000644 0001750 0001750 00000004510 11736333523 026444 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents a Integer type.
*
* @author Eric Lafortune
*/
public class IntegerType extends VerificationType
{
// Implementations for VerificationType.
public int getTag()
{
return INTEGER_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitIntegerType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackIntegerType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesIntegerType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public String toString()
{
return "i";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/SameOneFrame.java 0000644 0001750 0001750 00000006073 11736333523 026515 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.*;
/**
* This StackMapFrame represents a "same locals 1 stack item frame" or a
* "same locals 1 stack item frame extended".
*
* @author Eric Lafortune
*/
public class SameOneFrame extends StackMapFrame
{
public VerificationType stackItem;
/**
* Creates an uninitialized SameOneFrame.
*/
public SameOneFrame()
{
}
/**
* Creates a SameOneFrame with the given tag.
*/
public SameOneFrame(int tag)
{
u2offsetDelta = tag - SAME_ONE_FRAME;
}
/**
* Creates a SameOneFrame with the given stack verification type.
*/
public SameOneFrame(VerificationType stackItem)
{
this.stackItem = stackItem;
}
/**
* Applies the given verification type visitor to the stack item.
*/
public void stackItemAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationTypeVisitor verificationTypeVisitor)
{
stackItem.accept(clazz, method, codeAttribute, offset, verificationTypeVisitor);
}
// Implementations for StackMapFrame.
public int getTag()
{
return u2offsetDelta < 64 ?
SAME_ONE_FRAME + u2offsetDelta :
SAME_ONE_FRAME_EXTENDED;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrameVisitor stackMapFrameVisitor)
{
stackMapFrameVisitor.visitSameOneFrame(clazz, method, codeAttribute, offset, this);
}
// Implementations for Object.
public boolean equals(Object object)
{
if (!super.equals(object))
{
return false;
}
SameOneFrame other = (SameOneFrame)object;
return this.u2offsetDelta == other.u2offsetDelta &&
this.stackItem.equals(other.stackItem);
}
public int hashCode()
{
return super.hashCode() ^ stackItem.hashCode();
}
public String toString()
{
return super.toString()+"Var: ..., Stack: ["+stackItem.toString()+"]";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/ObjectType.java 0000644 0001750 0001750 00000005743 11736333523 026266 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents an Object type.
*
* @author Eric Lafortune
*/
public class ObjectType extends VerificationType
{
public int u2classIndex;
/**
* Creates an uninitialized ObjectType.
*/
public ObjectType()
{
}
/**
* Creates an ObjectType that points to the given class constant.
*/
public ObjectType(int u2classIndex)
{
this.u2classIndex = u2classIndex;
}
// Implementations for VerificationType.
public int getTag()
{
return OBJECT_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitObjectType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackObjectType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesObjectType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public boolean equals(Object object)
{
if (!super.equals(object))
{
return false;
}
ObjectType other = (ObjectType)object;
return this.u2classIndex == other.u2classIndex;
}
public int hashCode()
{
return super.hashCode() ^
u2classIndex;
}
public String toString()
{
return "a:" + u2classIndex;
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/StackMapAttribute.java 0000644 0001750 0001750 00000005600 11736333523 027575 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.preverification.visitor.StackMapFrameVisitor;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents an exceptions attribute.
*
* @author Eric Lafortune
*/
public class StackMapAttribute extends Attribute
{
public int u2stackMapFramesCount;
public FullFrame[] stackMapFrames;
/**
* Creates an uninitialized ExceptionsAttribute.
*/
public StackMapAttribute()
{
}
/**
* Creates a StackMapTableAttribute with the given stack map frames.
*/
public StackMapAttribute(FullFrame[] stackMapFrames)
{
this(stackMapFrames.length, stackMapFrames);
}
/**
* Creates a StackMapTableAttribute with the given stack map frames.
*/
public StackMapAttribute(int stackMapFramesCount,
FullFrame[] stackMapFrames)
{
this.u2stackMapFramesCount = stackMapFramesCount;
this.stackMapFrames = stackMapFrames;
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitStackMapAttribute(clazz, method, codeAttribute, this);
}
/**
* Applies the given stack map frame visitor to all stack map frames.
*/
public void stackMapFramesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapFrameVisitor stackMapFrameVisitor)
{
for (int index = 0; index < u2stackMapFramesCount; index++)
{
FullFrame stackMapFrame = stackMapFrames[index];
// We don't need double dispatching here, since there is only one
// type of StackMapFrame.
stackMapFrameVisitor.visitFullFrame(clazz, method, codeAttribute, stackMapFrame.getOffsetDelta(), stackMapFrame);
}
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/LongType.java 0000644 0001750 0001750 00000004466 11736333523 025760 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents a Long type.
*
* @author Eric Lafortune
*/
public class LongType extends VerificationType
{
// Implementations for VerificationType.
public int getTag()
{
return LONG_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitLongType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackLongType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesLongType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public String toString()
{
return "l";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/NullType.java 0000644 0001750 0001750 00000004466 11736333523 025773 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents a Null type.
*
* @author Eric Lafortune
*/
public class NullType extends VerificationType
{
// Implementations for VerificationType.
public int getTag()
{
return NULL_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitNullType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackNullType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesNullType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public String toString()
{
return "n";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/visitor/ 0000775 0001750 0001750 00000000000 11760503005 025032 5 ustar eric eric proguard4.8/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java 0000644 0001750 0001750 00000003622 11736333523 031745 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.*;
/**
* This interface specifies the methods for a visitor of
* StackMapFrame
objects.
*
* @author Eric Lafortune
*/
public interface StackMapFrameVisitor
{
public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame);
public void visitSameOneFrame( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame);
public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame);
public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame);
public void visitFullFrame( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame);
}
proguard4.8/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java 0000644 0001750 0001750 00000013056 11736333523 032555 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.*;
/**
* This interface specifies the methods for a visitor of
* VerificationType
objects. There a methods for stack entries
* and methods for variable entries.
*
* @author Eric Lafortune
*/
public interface VerificationTypeVisitor
{
public void visitIntegerType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, IntegerType integerType);
public void visitFloatType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FloatType floatType);
public void visitLongType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LongType longType);
public void visitDoubleType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, DoubleType doubleType);
public void visitTopType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TopType topType);
public void visitObjectType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType);
public void visitNullType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, NullType nullType);
public void visitUninitializedType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType);
public void visitUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedThisType uninitializedThisType);
public void visitStackIntegerType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, IntegerType integerType);
public void visitStackFloatType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, FloatType floatType);
public void visitStackLongType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, LongType longType);
public void visitStackDoubleType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, DoubleType doubleType);
public void visitStackTopType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, TopType topType);
public void visitStackObjectType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, ObjectType objectType);
public void visitStackNullType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, NullType nullType);
public void visitStackUninitializedType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, UninitializedType uninitializedType);
public void visitStackUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, UninitializedThisType uninitializedThisType);
public void visitVariablesIntegerType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, IntegerType integerType);
public void visitVariablesFloatType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, FloatType floatType);
public void visitVariablesLongType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, LongType longType);
public void visitVariablesDoubleType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, DoubleType doubleType);
public void visitVariablesTopType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, TopType topType);
public void visitVariablesObjectType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, ObjectType objectType);
public void visitVariablesNullType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, NullType nullType);
public void visitVariablesUninitializedType( Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, UninitializedType uninitializedType);
public void visitVariablesUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, UninitializedThisType uninitializedThisType);
}
proguard4.8/src/proguard/classfile/attribute/preverification/LessZeroFrame.java 0000644 0001750 0001750 00000005324 11736333523 026732 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.StackMapFrameVisitor;
/**
* This StackMapFrame represents an "chop frame".
*
* @author Eric Lafortune
*/
public class LessZeroFrame extends StackMapFrame
{
public int choppedVariablesCount;
/**
* Creates an uninitialized LessZeroFrame.
*/
public LessZeroFrame()
{
}
/**
* Creates a LessZeroFrame with the given tag.
*/
public LessZeroFrame(int tag)
{
choppedVariablesCount = LESS_ZERO_FRAME + 3 - tag;
}
/**
* Creates a LessZeroFrame with the given number of chopped variables.
*/
public LessZeroFrame(byte choppedVariablesCount)
{
this.choppedVariablesCount = (int)choppedVariablesCount;
}
// Implementations for StackMapFrame.
public int getTag()
{
return LESS_ZERO_FRAME + 3 - choppedVariablesCount;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrameVisitor stackMapFrameVisitor)
{
stackMapFrameVisitor.visitLessZeroFrame(clazz, method, codeAttribute, offset, this);
}
// Implementations for Object.
public boolean equals(Object object)
{
if (!super.equals(object))
{
return false;
}
LessZeroFrame other = (LessZeroFrame)object;
return this.u2offsetDelta == other.u2offsetDelta &&
this.choppedVariablesCount != other.choppedVariablesCount;
}
public int hashCode()
{
return super.hashCode() ^ choppedVariablesCount;
}
public String toString()
{
return super.toString()+"Var: (chopped "+choppedVariablesCount+"), Stack: (empty)";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/FloatType.java 0000644 0001750 0001750 00000004474 11736333523 026125 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents a Float type.
*
* @author Eric Lafortune
*/
public class FloatType extends VerificationType
{
// Implementations for VerificationType.
public int getTag()
{
return FLOAT_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitFloatType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackFloatType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesFloatType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public String toString()
{
return "f";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/DoubleType.java 0000644 0001750 0001750 00000004502 11736333523 026262 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents a Double type.
*
* @author Eric Lafortune
*/
public class DoubleType extends VerificationType
{
// Implementations for VerificationType.
public int getTag()
{
return DOUBLE_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitDoubleType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackDoubleType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesDoubleType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public String toString()
{
return "d";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/UninitializedThisType.java 0000644 0001750 0001750 00000004612 11736333523 030512 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents a UninitializedThis type.
*
* @author Eric Lafortune
*/
public class UninitializedThisType extends VerificationType
{
// Implementations for VerificationType.
public int getTag()
{
return UNINITIALIZED_THIS_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitUninitializedThisType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackUninitializedThisType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesUninitializedThisType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public String toString()
{
return "u:this";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/StackMapFrame.java 0000644 0001750 0001750 00000006201 11736333523 026662 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.StackMapFrameVisitor;
/**
* This abstract class represents a stack map frame. Specific types
* of entries are subclassed from it.
*
* @author Eric Lafortune
*/
public abstract class StackMapFrame implements VisitorAccepter
{
public static final int SAME_ZERO_FRAME = 0;
public static final int SAME_ONE_FRAME = 64;
public static final int SAME_ONE_FRAME_EXTENDED = 247;
public static final int LESS_ZERO_FRAME = 248;
public static final int SAME_ZERO_FRAME_EXTENDED = 251;
public static final int MORE_ZERO_FRAME = 252;
public static final int FULL_FRAME = 255;
public int u2offsetDelta;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Returns the bytecode offset delta relative to the previous stack map
* frame.
*/
public int getOffsetDelta()
{
return u2offsetDelta;
}
// Abstract methods to be implemented by extensions.
/**
* Returns the stack map frame tag that specifies the entry type.
*/
public abstract int getTag();
/**
* Accepts the given visitor.
*/
public abstract void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrameVisitor stackMapFrameVisitor);
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
// Implementations for Object.
public boolean equals(Object object)
{
if (object == null ||
this.getClass() != object.getClass())
{
return false;
}
StackMapFrame other = (StackMapFrame)object;
return this.u2offsetDelta == other.u2offsetDelta;
}
public int hashCode()
{
return getClass().hashCode() ^
u2offsetDelta;
}
public String toString()
{
return "[" + u2offsetDelta + "] ";
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java 0000644 0001750 0001750 00000006002 11736333523 030542 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.preverification.visitor.StackMapFrameVisitor;
import proguard.classfile.attribute.visitor.AttributeVisitor;
/**
* This Attribute represents a stack map table attribute.
*
* @author Eric Lafortune
*/
public class StackMapTableAttribute extends Attribute
{
public int u2stackMapFramesCount;
public StackMapFrame[] stackMapFrames;
/**
* Creates an uninitialized StackMapTableAttribute.
*/
public StackMapTableAttribute()
{
}
/**
* Creates a StackMapTableAttribute with the given stack map frames.
*/
public StackMapTableAttribute(StackMapFrame[] stackMapFrames)
{
this(stackMapFrames.length, stackMapFrames);
}
/**
* Creates a StackMapTableAttribute with the given stack map frames.
*/
public StackMapTableAttribute(int stackMapFramesCount,
StackMapFrame[] stackMapFrames)
{
this.u2stackMapFramesCount = stackMapFramesCount;
this.stackMapFrames = stackMapFrames;
}
// Implementations for Attribute.
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor)
{
attributeVisitor.visitStackMapTableAttribute(clazz, method, codeAttribute, this);
}
/**
* Applies the given stack map frame visitor to all stack map frames.
*/
public void stackMapFramesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapFrameVisitor stackMapFrameVisitor)
{
int offset = 0;
for (int index = 0; index < u2stackMapFramesCount; index++)
{
StackMapFrame stackMapFrame = stackMapFrames[index];
// Note that the byte code offset is computed differently for the
// first stack map frame.
offset += stackMapFrame.getOffsetDelta() + (index == 0 ? 0 : 1);
stackMapFrame.accept(clazz, method, codeAttribute, offset, stackMapFrameVisitor);
}
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/VerificationType.java 0000644 0001750 0001750 00000006572 11736333523 027503 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This abstract class represents a verification type of a local variable or
* a stack element. Specific verification types are subclassed from it.
*
* @author Eric Lafortune
*/
public abstract class VerificationType implements VisitorAccepter
{
public static final int TOP_TYPE = 0;
public static final int INTEGER_TYPE = 1;
public static final int FLOAT_TYPE = 2;
public static final int DOUBLE_TYPE = 3;
public static final int LONG_TYPE = 4;
public static final int NULL_TYPE = 5;
public static final int UNINITIALIZED_THIS_TYPE = 6;
public static final int OBJECT_TYPE = 7;
public static final int UNINITIALIZED_TYPE = 8;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Returns the tag of the verification type.
*/
public abstract int getTag();
/**
* Accepts the given visitor in the context of a method's code, either on
* a stack or as a variable.
*/
public abstract void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor);
/**
* Accepts the given visitor in the context of a stack in a method's code .
*/
public abstract void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor);
/**
* Accepts the given visitor in the context of a variable in a method's code.
*/
public abstract void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor);
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
// Implementations for Object.
public boolean equals(Object object)
{
return object != null &&
this.getClass() == object.getClass();
}
public int hashCode()
{
return this.getClass().hashCode();
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/UninitializedType.java 0000644 0001750 0001750 00000006205 11736333523 027662 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.VerificationTypeVisitor;
/**
* This VerificationType represents a Uninitialized type.
*
* @author Eric Lafortune
*/
public class UninitializedType extends VerificationType
{
public int u2newInstructionOffset;
/**
* Creates an uninitialized UninitializedType.
*/
public UninitializedType()
{
}
/**
* Creates an UninitializedType pointing to the given 'new' instruction.
*/
public UninitializedType(int u2newInstructionOffset)
{
this.u2newInstructionOffset = u2newInstructionOffset;
}
// Implementations for VerificationType.
public int getTag()
{
return UNINITIALIZED_TYPE;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitUninitializedType(clazz, method, codeAttribute, instructionOffset, this);
}
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int stackIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitStackUninitializedType(clazz, method, codeAttribute, instructionOffset, stackIndex, this);
}
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset, int variableIndex, VerificationTypeVisitor verificationTypeVisitor)
{
verificationTypeVisitor.visitVariablesUninitializedType(clazz, method, codeAttribute, instructionOffset, variableIndex, this);
}
// Implementations for Object.
public boolean equals(Object object)
{
if (!super.equals(object))
{
return false;
}
UninitializedType other = (UninitializedType)object;
return this.u2newInstructionOffset == other.u2newInstructionOffset;
}
public int hashCode()
{
return super.hashCode() ^
u2newInstructionOffset;
}
public String toString()
{
return "u:" + u2newInstructionOffset;
}
}
proguard4.8/src/proguard/classfile/attribute/preverification/FullFrame.java 0000644 0001750 0001750 00000013147 11736333523 026070 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.preverification;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.attribute.preverification.visitor.*;
/**
* This StackMapFrame represents a "full frame".
*
* @author Eric Lafortune
*/
public class FullFrame extends StackMapFrame
{
public int variablesCount;
public VerificationType[] variables;
public int stackCount;
public VerificationType[] stack;
/**
* Creates an uninitialized FullFrame.
*/
public FullFrame()
{
}
/**
* Creates a FullFrame with the given variables and stack.
*/
public FullFrame(int offsetDelta,
VerificationType[] variables,
VerificationType[] stack)
{
this(offsetDelta,
variables.length,
variables,
stack.length,
stack);
}
/**
* Creates a FullFrame with the given variables and stack.
*/
public FullFrame(int offsetDelta,
int variablesCount,
VerificationType[] variables,
int stackCount,
VerificationType[] stack)
{
this.u2offsetDelta = offsetDelta;
this.variablesCount = variablesCount;
this.variables = variables;
this.stackCount = stackCount;
this.stack = stack;
}
/**
* Applies the given verification type visitor to all variables.
*/
public void variablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationTypeVisitor verificationTypeVisitor)
{
for (int index = 0; index < variablesCount; index++)
{
variables[index].variablesAccept(clazz, method, codeAttribute, offset, index, verificationTypeVisitor);
}
}
/**
* Applies the given verification type visitor to all stack.
*/
public void stackAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationTypeVisitor verificationTypeVisitor)
{
for (int index = 0; index < stackCount; index++)
{
stack[index].stackAccept(clazz, method, codeAttribute, offset, index, verificationTypeVisitor);
}
}
// Implementations for StackMapFrame.
public int getTag()
{
return FULL_FRAME;
}
public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrameVisitor stackMapFrameVisitor)
{
stackMapFrameVisitor.visitFullFrame(clazz, method, codeAttribute, offset, this);
}
// Implementations for Object.
public boolean equals(Object object)
{
if (!super.equals(object))
{
return false;
}
FullFrame other = (FullFrame)object;
if (this.u2offsetDelta != other.u2offsetDelta ||
this.variablesCount != other.variablesCount ||
this.stackCount != other.stackCount)
{
return false;
}
for (int index = 0; index < variablesCount; index++)
{
VerificationType thisType = this.variables[index];
VerificationType otherType = other.variables[index];
if (!thisType.equals(otherType))
{
return false;
}
}
for (int index = 0; index < stackCount; index++)
{
VerificationType thisType = this.stack[index];
VerificationType otherType = other.stack[index];
if (!thisType.equals(otherType))
{
return false;
}
}
return true;
}
public int hashCode()
{
int hashCode = super.hashCode();
for (int index = 0; index < variablesCount; index++)
{
hashCode ^= variables[index].hashCode();
}
for (int index = 0; index < stackCount; index++)
{
hashCode ^= stack[index].hashCode();
}
return hashCode;
}
public String toString()
{
StringBuffer buffer = new StringBuffer(super.toString()).append("Var: ");
for (int index = 0; index < variablesCount; index++)
{
buffer = buffer.append('[')
.append(variables[index].toString())
.append(']');
}
buffer.append(", Stack: ");
for (int index = 0; index < stackCount; index++)
{
buffer = buffer.append('[')
.append(stack[index].toString())
.append(']');
}
return buffer.toString();
}
}
proguard4.8/src/proguard/classfile/ClassPool.java 0000664 0001750 0001750 00000010020 11740556650 020706 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.util.ClassUtil;
import proguard.classfile.visitor.*;
import java.util.*;
/**
* 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
{
// 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();
/**
* Clears the class pool.
*/
public void clear()
{
classes.clear();
}
/**
* Adds the given Clazz to the class pool.
*/
public void addClass(Clazz clazz)
{
classes.put(clazz.getName(), clazz);
}
/**
* Removes the given Clazz from the class pool.
*/
public void removeClass(Clazz clazz)
{
removeClass(clazz.getName());
}
/**
* Removes the specified Clazz from the class pool.
*/
public void removeClass(String className)
{
classes.remove(className);
}
/**
* Returns a Clazz from the class pool based on its name. Returns
* null
if the class with the given name is not in the class
* pool.
*/
public Clazz getClass(String className)
{
return (Clazz)classes.get(className);
}
/**
* Returns an Iterator of all class names in the class pool.
*/
public Iterator classNames()
{
return classes.keySet().iterator();
}
/**
* Returns the number of classes in the class pool.
*/
public int size()
{
return classes.size();
}
/**
* Applies the given ClassPoolVisitor to the class pool.
*/
public void accept(ClassPoolVisitor classPoolVisitor)
{
classPoolVisitor.visitClassPool(this);
}
/**
* Applies the given ClassVisitor to all classes in the class pool,
* in random order.
*/
public void classesAccept(ClassVisitor classVisitor)
{
Iterator iterator = classes.values().iterator();
while (iterator.hasNext())
{
Clazz clazz = (Clazz)iterator.next();
clazz.accept(classVisitor);
}
}
/**
* Applies the given ClassVisitor to all classes in the class pool,
* in sorted order.
*/
public void classesAcceptAlphabetically(ClassVisitor classVisitor)
{
// 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();
clazz.accept(classVisitor);
}
}
/**
* Applies the given ClassVisitor to the class with the given name,
* if it is present in the class pool.
*/
public void classAccept(String className, ClassVisitor classVisitor)
{
Clazz clazz = getClass(className);
if (clazz != null)
{
clazz.accept(classVisitor);
}
}
}
proguard4.8/src/proguard/classfile/Clazz.java 0000644 0001750 0001750 00000020474 11736333523 020103 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.visitor.*;
/**
* This interface provides access to the representation of a Java class.
*
* @author Eric Lafortune
*/
public interface Clazz extends VisitorAccepter
{
/**
* Returns the access flags of this class.
* @see ClassConstants
*/
public int getAccessFlags();
/**
* Returns the full internal name of this class.
*/
public String getName();
/**
* Returns the full internal name of the super class of this class, or
* null if this class represents java.lang.Object.
*/
public String getSuperName();
/**
* Returns the number of interfaces that this class implements.
*/
public int getInterfaceCount();
/**
* Returns the full internal name of the interface at the given index of
* this class.
*/
public String getInterfaceName(int index);
/**
* Returns the tag value of the Constant at the specified index.
*/
public int getTag(int constantIndex);
/**
* Returns the String value of the Utf8Constant at the specified index.
*/
public String getString(int constantIndex);
/**
* Returns the String value of the StringConstant at the specified index.
*/
public String getStringString(int constantIndex);
/**
* Returns the class name of ClassConstant at the specified index.
*/
public String getClassName(int constantIndex);
/**
* Returns the name of the NameAndTypeConstant at the specified index.
*/
public String getName(int constantIndex);
/**
* Returns the type of the NameAndTypeConstant at the specified index.
*/
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.
/**
* Notifies this Clazz that it is being subclassed by another class.
*/
public void addSubClass(Clazz clazz);
/**
* Returns the super class of this class.
*/
public Clazz getSuperClass();
/**
* Returns the interface at the given index.
*/
public Clazz getInterface(int index);
/**
* Returns whether this class extends the given class.
* A class is always considered to extend itself.
* Interfaces are considered to only extend the root Object class.
*/
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.
/**
* Returns the field with the given name and descriptor.
*/
Field findField(String name, String descriptor);
/**
* Returns the method with the given name and descriptor.
*/
Method findMethod(String name, String descriptor);
// Methods for accepting various types of visitors.
/**
* Accepts the given class visitor.
*/
public void accept(ClassVisitor classVisitor);
/**
* Accepts the given class visitor in the class hierarchy.
* @param visitThisClass specifies whether to visit this class.
* @param visitSuperClass specifies whether to visit the super classes.
* @param visitInterfaces specifies whether to visit the interfaces.
* @param visitSubclasses specifies whether to visit the subclasses.
* @param classVisitor the ClassVisitor
that will
* visit the class hierarchy.
*/
public void hierarchyAccept(boolean visitThisClass,
boolean visitSuperClass,
boolean visitInterfaces,
boolean visitSubclasses,
ClassVisitor classVisitor);
/**
* Lets the given class visitor visit all known subclasses.
* @param classVisitor the ClassVisitor
that will visit the
* subclasses.
*/
public void subclassesAccept(ClassVisitor classVisitor);
/**
* Lets the given constant pool entry visitor visit all constant pool entries
* of this class.
*/
public void constantPoolEntriesAccept(ConstantVisitor constantVisitor);
/**
* Lets the given constant pool entry visitor visit the constant pool entry
* at the specified index.
*/
public void constantPoolEntryAccept(int index, ConstantVisitor constantVisitor);
/**
* Lets the given constant pool entry visitor visit the class constant pool
* entry of this class.
*/
public void thisClassConstantAccept(ConstantVisitor constantVisitor);
/**
* Lets the given constant pool entry visitor visit the class constant pool
* entry of the super class of this class, if there is one.
*/
public void superClassConstantAccept(ConstantVisitor constantVisitor);
/**
* Lets the given constant pool entry visitor visit the class constant pool
* entries for all interfaces of this class.
*/
public void interfaceConstantsAccept(ConstantVisitor constantVisitor);
/**
* Lets the given member info visitor visit all fields of this class.
*/
public void fieldsAccept(MemberVisitor memberVisitor);
/**
* Lets the given member info visitor visit the specified field.
*/
public void fieldAccept(String name, String descriptor, MemberVisitor memberVisitor);
/**
* Lets the given member info visitor visit all methods of this class.
*/
public void methodsAccept(MemberVisitor memberVisitor);
/**
* Lets the given member info visitor visit the specified method.
*/
public void methodAccept(String name, String descriptor, MemberVisitor memberVisitor);
/**
* Returns whether the given method may possibly have implementing or
* overriding methods down the class hierarchy. This can only be true
* if the class is not final, and the method is not private, static, or
* final, or a constructor.
* @param method the method that may have implementations.
* @return whether it may have implementations.
*/
public boolean mayHaveImplementations(Method method);
/**
* 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);
}
proguard4.8/src/proguard/classfile/LibraryClass.java 0000644 0001750 0001750 00000035703 11736333523 021413 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
/**
* This Clazz is a compact representation of the essential data in a Java class.
*
* @author Eric Lafortune
*/
public class LibraryClass implements Clazz
{
public int u2accessFlags;
public String thisClassName;
public String superClassName;
public String[] interfaceNames;
public LibraryField[] fields;
public LibraryMethod[] methods;
/**
* An extra field pointing to the superclass of this class.
* This field is filled out by the {@link ClassSuperHierarchyInitializer}.
*/
public Clazz superClass;
/**
* An extra field pointing to the interfaces of this class.
* This field is filled out by the {@link ClassSuperHierarchyInitializer}.
*/
public Clazz[] interfaceClasses;
/**
* An extra field pointing to the subclasses of this class.
* This field is filled out by the {@link ClassSubHierarchyInitializer}.
*/
public Clazz[] subClasses;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Creates an empty LibraryClass.
*/
public LibraryClass() {}
/**
* Returns whether this library class is visible to the outside world.
*/
boolean isVisible()
{
return (u2accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0;
}
// Implementations for Clazz.
public int getAccessFlags()
{
return u2accessFlags;
}
public String getName()
{
return thisClassName;
}
public String getSuperName()
{
// This may be java/lang/Object, in which case there is no super.
return superClassName;
}
public int getInterfaceCount()
{
return interfaceClasses.length;
}
public String getInterfaceName(int index)
{
return interfaceNames[index];
}
public int getTag(int constantIndex)
{
throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
}
public String getString(int constantIndex)
{
throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
}
public String getStringString(int constantIndex)
{
throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
}
public String getClassName(int constantIndex)
{
throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
}
public String getName(int constantIndex)
{
throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
}
public String getType(int constantIndex)
{
throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
}
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)
{
subClasses = new Clazz[1];
}
else
{
// Copy the old elements into new larger array.
Clazz[] temp = new Clazz[subClasses.length+1];
System.arraycopy(subClasses, 0, temp, 0, subClasses.length);
subClasses = temp;
}
subClasses[subClasses.length-1] = clazz;
}
public Clazz getSuperClass()
{
return superClass;
}
public Clazz getInterface(int index)
{
return interfaceClasses[index];
}
public boolean extends_(Clazz clazz)
{
if (this.equals(clazz))
{
return true;
}
return superClass != null &&
superClass.extends_(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))
{
return true;
}
if (superClass != null &&
superClass.extendsOrImplements(clazz))
{
return true;
}
if (interfaceClasses != null)
{
for (int index = 0; index < interfaceClasses.length; index++)
{
Clazz interfaceClass = interfaceClasses[index];
if (interfaceClass != null &&
interfaceClass.extendsOrImplements(clazz))
{
return true;
}
}
}
return false;
}
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++)
{
Field field = fields[index];
if (field != null &&
(name == null || field.getName(this).equals(name)) &&
(descriptor == null || field.getDescriptor(this).equals(descriptor)))
{
return field;
}
}
return null;
}
public Method findMethod(String name, String descriptor)
{
for (int index = 0; index < methods.length; index++)
{
Method method = methods[index];
if (method != null &&
(name == null || method.getName(this).equals(name)) &&
(descriptor == null || method.getDescriptor(this).equals(descriptor)))
{
return method;
}
}
return null;
}
public void accept(ClassVisitor classVisitor)
{
classVisitor.visitLibraryClass(this);
}
public void hierarchyAccept(boolean visitThisClass,
boolean visitSuperClass,
boolean visitInterfaces,
boolean visitSubclasses,
ClassVisitor classVisitor)
{
// First visit the current classfile.
if (visitThisClass)
{
accept(classVisitor);
}
// Then visit its superclass, recursively.
if (visitSuperClass)
{
if (superClass != null)
{
superClass.hierarchyAccept(true,
true,
visitInterfaces,
false,
classVisitor);
}
}
// Then visit its interfaces, recursively.
if (visitInterfaces)
{
// Visit the interfaces of the superclasses, if we haven't done so yet.
if (!visitSuperClass)
{
if (superClass != null)
{
superClass.hierarchyAccept(false,
false,
true,
false,
classVisitor);
}
}
// Visit the interfaces.
if (interfaceClasses != null)
{
for (int index = 0; index < interfaceClasses.length; index++)
{
Clazz interfaceClass = interfaceClasses[index];
if (interfaceClass != null)
{
interfaceClass.hierarchyAccept(true,
false,
true,
false,
classVisitor);
}
}
}
}
// Then visit its subclasses, recursively.
if (visitSubclasses)
{
if (subClasses != null)
{
for (int index = 0; index < subClasses.length; index++)
{
subClasses[index].hierarchyAccept(true,
false,
false,
true,
classVisitor);
}
}
}
}
/**
* Lets the given class visitor visit the superclass, if it is known.
* @param classVisitor the ClassVisitor
that will visit the
* superclass.
*/
public void superClassAccept(ClassVisitor classVisitor)
{
if (superClass != null)
{
superClass.accept(classVisitor);
}
}
/**
* Lets the given class visitor visit all known direct interfaces.
* @param classVisitor the ClassVisitor
that will visit the
* interfaces.
*/
public void interfacesAccept(ClassVisitor classVisitor)
{
if (interfaceClasses != null)
{
for (int index = 0; index < interfaceClasses.length; index++)
{
Clazz interfaceClass = interfaceClasses[index];
if (interfaceClass != null)
{
interfaceClass.accept(classVisitor);
}
}
}
}
public void subclassesAccept(ClassVisitor classVisitor)
{
if (subClasses != null)
{
for (int index = 0; index < subClasses.length; index++)
{
subClasses[index].accept(classVisitor);
}
}
}
public void constantPoolEntriesAccept(ConstantVisitor constantVisitor)
{
// This class doesn't keep references to its constant pool entries.
}
public void constantPoolEntryAccept(int index, ConstantVisitor constantVisitor)
{
// This class doesn't keep references to its constant pool entries.
}
public void thisClassConstantAccept(ConstantVisitor constantVisitor)
{
// This class doesn't keep references to its constant pool entries.
}
public void superClassConstantAccept(ConstantVisitor constantVisitor)
{
// This class doesn't keep references to its constant pool entries.
}
public void interfaceConstantsAccept(ConstantVisitor constantVisitor)
{
// This class doesn't keep references to its constant pool entries.
}
public void fieldsAccept(MemberVisitor memberVisitor)
{
for (int index = 0; index < fields.length; index++)
{
Field field = fields[index];
if (field != null)
{
field.accept(this, memberVisitor);
}
}
}
public void fieldAccept(String name, String descriptor, MemberVisitor memberVisitor)
{
Field field = findField(name, descriptor);
if (field != null)
{
field.accept(this, memberVisitor);
}
}
public void methodsAccept(MemberVisitor memberVisitor)
{
for (int index = 0; index < methods.length; index++)
{
Method method = methods[index];
if (method != null)
{
method.accept(this, memberVisitor);
}
}
}
public void methodAccept(String name, String descriptor, MemberVisitor memberVisitor)
{
Method method = findMethod(name, descriptor);
if (method != null)
{
method.accept(this, memberVisitor);
}
}
public boolean mayHaveImplementations(Method method)
{
return
(u2accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0 &&
(method == null ||
((method.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_STATIC |
ClassConstants.INTERNAL_ACC_FINAL)) == 0 &&
!method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)));
}
public void attributesAccept(AttributeVisitor attributeVisitor)
{
throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store attributes");
}
public void attributeAccept(String name, AttributeVisitor attributeVisitor)
{
throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store attributes");
}
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
// Implementations for Object.
public String toString()
{
return "LibraryClass("+getName()+")";
}
}
proguard4.8/src/proguard/classfile/io/ 0000775 0001750 0001750 00000000000 11760503005 016546 5 ustar eric eric proguard4.8/src/proguard/classfile/io/ProgramClassReader.java 0000664 0001750 0001750 00000116146 11736333523 023153 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
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.util.*;
import proguard.classfile.visitor.*;
import java.io.DataInput;
/**
* This ClassVisitor fills out the ProgramClass objects that it visits with data
* from the given DataInput object.
*
* @author Eric Lafortune
*/
public class ProgramClassReader
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
ConstantVisitor,
AttributeVisitor,
BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
LineNumberInfoVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
ElementValueVisitor
{
private final RuntimeDataInput dataInput;
/**
* Creates a new ProgramClassReader for reading from the given DataInput.
*/
public ProgramClassReader(DataInput dataInput)
{
this.dataInput = new RuntimeDataInput(dataInput);
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Read and check the magic number.
programClass.u4magic = dataInput.readInt();
ClassUtil.checkMagicNumber(programClass.u4magic);
// Read and check the version numbers.
int u2minorVersion = dataInput.readUnsignedShort();
int u2majorVersion = dataInput.readUnsignedShort();
programClass.u4version = ClassUtil.internalClassVersion(u2majorVersion,
u2minorVersion);
ClassUtil.checkVersionNumbers(programClass.u4version);
// Read the constant pool. Note that the first entry is not used.
programClass.u2constantPoolCount = dataInput.readUnsignedShort();
programClass.constantPool = new Constant[programClass.u2constantPoolCount];
for (int index = 1; index < programClass.u2constantPoolCount; index++)
{
Constant constant = createConstant();
constant.accept(programClass, this);
programClass.constantPool[index] = constant;
// Long constants and double constants take up two entries in the
// constant pool.
int tag = constant.getTag();
if (tag == ClassConstants.CONSTANT_Long ||
tag == ClassConstants.CONSTANT_Double)
{
programClass.constantPool[++index] = null;
}
}
// Read the general class information.
programClass.u2accessFlags = dataInput.readUnsignedShort();
programClass.u2thisClass = dataInput.readUnsignedShort();
programClass.u2superClass = dataInput.readUnsignedShort();
// Read the interfaces.
programClass.u2interfacesCount = dataInput.readUnsignedShort();
programClass.u2interfaces = new int[programClass.u2interfacesCount];
for (int index = 0; index < programClass.u2interfacesCount; index++)
{
programClass.u2interfaces[index] = dataInput.readUnsignedShort();
}
// Read the fields.
programClass.u2fieldsCount = dataInput.readUnsignedShort();
programClass.fields = new ProgramField[programClass.u2fieldsCount];
for (int index = 0; index < programClass.u2fieldsCount; index++)
{
ProgramField programField = new ProgramField();
this.visitProgramField(programClass, programField);
programClass.fields[index] = programField;
}
// Read the methods.
programClass.u2methodsCount = dataInput.readUnsignedShort();
programClass.methods = new ProgramMethod[programClass.u2methodsCount];
for (int index = 0; index < programClass.u2methodsCount; index++)
{
ProgramMethod programMethod = new ProgramMethod();
this.visitProgramMethod(programClass, programMethod);
programClass.methods[index] = programMethod;
}
// Read the class attributes.
programClass.u2attributesCount = dataInput.readUnsignedShort();
programClass.attributes = new Attribute[programClass.u2attributesCount];
for (int index = 0; index < programClass.u2attributesCount; index++)
{
Attribute attribute = createAttribute(programClass);
attribute.accept(programClass, this);
programClass.attributes[index] = attribute;
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
// Read the general field information.
programField.u2accessFlags = dataInput.readUnsignedShort();
programField.u2nameIndex = dataInput.readUnsignedShort();
programField.u2descriptorIndex = dataInput.readUnsignedShort();
// Read the field attributes.
programField.u2attributesCount = dataInput.readUnsignedShort();
programField.attributes = new Attribute[programField.u2attributesCount];
for (int index = 0; index < programField.u2attributesCount; index++)
{
Attribute attribute = createAttribute(programClass);
attribute.accept(programClass, programField, this);
programField.attributes[index] = attribute;
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
// Read the general method information.
programMethod.u2accessFlags = dataInput.readUnsignedShort();
programMethod.u2nameIndex = dataInput.readUnsignedShort();
programMethod.u2descriptorIndex = dataInput.readUnsignedShort();
// Read the method attributes.
programMethod.u2attributesCount = dataInput.readUnsignedShort();
programMethod.attributes = new Attribute[programMethod.u2attributesCount];
for (int index = 0; index < programMethod.u2attributesCount; index++)
{
Attribute attribute = createAttribute(programClass);
attribute.accept(programClass, programMethod, this);
programMethod.attributes[index] = attribute;
}
}
public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
{
}
// Implementations for ConstantVisitor.
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
integerConstant.u4value = dataInput.readInt();
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
longConstant.u8value = dataInput.readLong();
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
floatConstant.f4value = dataInput.readFloat();
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
doubleConstant.f8value = dataInput.readDouble();
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
stringConstant.u2stringIndex = dataInput.readUnsignedShort();
}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
int u2length = dataInput.readUnsignedShort();
// Read the UTF-8 bytes.
byte[] bytes = new byte[u2length];
dataInput.readFully(bytes);
utf8Constant.setBytes(bytes);
}
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();
refConstant.u2nameAndTypeIndex = dataInput.readUnsignedShort();
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
classConstant.u2nameIndex = dataInput.readUnsignedShort();
}
public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
{
methodTypeConstant.u2descriptorIndex = dataInput.readUnsignedShort();
}
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
nameAndTypeConstant.u2nameIndex = dataInput.readUnsignedShort();
nameAndTypeConstant.u2descriptorIndex = dataInput.readUnsignedShort();
}
// Implementations for AttributeVisitor.
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
// Read the unknown information.
byte[] info = new byte[unknownAttribute.u4attributeLength];
dataInput.readFully(info);
unknownAttribute.info = info;
}
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();
}
public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
{
sourceDirAttribute.u2sourceDirIndex = dataInput.readUnsignedShort();
}
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
// Read the inner classes.
innerClassesAttribute.u2classesCount = dataInput.readUnsignedShort();
innerClassesAttribute.classes = new InnerClassesInfo[innerClassesAttribute.u2classesCount];
for (int index = 0; index < innerClassesAttribute.u2classesCount; index++)
{
InnerClassesInfo innerClassesInfo = new InnerClassesInfo();
visitInnerClassesInfo(clazz, innerClassesInfo);
innerClassesAttribute.classes[index] = innerClassesInfo;
}
}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
enclosingMethodAttribute.u2classIndex = dataInput.readUnsignedShort();
enclosingMethodAttribute.u2nameAndTypeIndex = dataInput.readUnsignedShort();
}
public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
{
// This attribute does not contain any additional information.
}
public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
{
// This attribute does not contain any additional information.
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
signatureAttribute.u2signatureIndex = dataInput.readUnsignedShort();
}
public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
{
constantValueAttribute.u2constantValueIndex = dataInput.readUnsignedShort();
}
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
// Read the exceptions.
exceptionsAttribute.u2exceptionIndexTableLength = dataInput.readUnsignedShort();
exceptionsAttribute.u2exceptionIndexTable = new int[exceptionsAttribute.u2exceptionIndexTableLength];
for (int index = 0; index < exceptionsAttribute.u2exceptionIndexTableLength; index++)
{
exceptionsAttribute.u2exceptionIndexTable[index] = dataInput.readUnsignedShort();
}
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
// Read the stack size and local variable frame size.
codeAttribute.u2maxStack = dataInput.readUnsignedShort();
codeAttribute.u2maxLocals = dataInput.readUnsignedShort();
// Read the byte code.
codeAttribute.u4codeLength = dataInput.readInt();
byte[] code = new byte[codeAttribute.u4codeLength];
dataInput.readFully(code);
codeAttribute.code = code;
// Read the exceptions.
codeAttribute.u2exceptionTableLength = dataInput.readUnsignedShort();
codeAttribute.exceptionTable = new ExceptionInfo[codeAttribute.u2exceptionTableLength];
for (int index = 0; index < codeAttribute.u2exceptionTableLength; index++)
{
ExceptionInfo exceptionInfo = new ExceptionInfo();
visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
codeAttribute.exceptionTable[index] = exceptionInfo;
}
// Read the code attributes.
codeAttribute.u2attributesCount = dataInput.readUnsignedShort();
codeAttribute.attributes = new Attribute[codeAttribute.u2attributesCount];
for (int index = 0; index < codeAttribute.u2attributesCount; index++)
{
Attribute attribute = createAttribute(clazz);
attribute.accept(clazz, method, codeAttribute, this);
codeAttribute.attributes[index] = attribute;
}
}
public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
{
// Read the stack map frames (only full frames, without tag).
stackMapAttribute.u2stackMapFramesCount = dataInput.readUnsignedShort();
stackMapAttribute.stackMapFrames = new FullFrame[stackMapAttribute.u2stackMapFramesCount];
for (int index = 0; index < stackMapAttribute.u2stackMapFramesCount; index++)
{
FullFrame stackMapFrame = new FullFrame();
visitFullFrame(clazz, method, codeAttribute, index, stackMapFrame);
stackMapAttribute.stackMapFrames[index] = stackMapFrame;
}
}
public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
{
// Read the stack map frames.
stackMapTableAttribute.u2stackMapFramesCount = dataInput.readUnsignedShort();
stackMapTableAttribute.stackMapFrames = new StackMapFrame[stackMapTableAttribute.u2stackMapFramesCount];
for (int index = 0; index < stackMapTableAttribute.u2stackMapFramesCount; index++)
{
StackMapFrame stackMapFrame = createStackMapFrame();
stackMapFrame.accept(clazz, method, codeAttribute, 0, this);
stackMapTableAttribute.stackMapFrames[index] = stackMapFrame;
}
}
public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
{
// Read the line numbers.
lineNumberTableAttribute.u2lineNumberTableLength = dataInput.readUnsignedShort();
lineNumberTableAttribute.lineNumberTable = new LineNumberInfo[lineNumberTableAttribute.u2lineNumberTableLength];
for (int index = 0; index < lineNumberTableAttribute.u2lineNumberTableLength; index++)
{
LineNumberInfo lineNumberInfo = new LineNumberInfo();
visitLineNumberInfo(clazz, method, codeAttribute, lineNumberInfo);
lineNumberTableAttribute.lineNumberTable[index] = lineNumberInfo;
}
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
// Read the local variables.
localVariableTableAttribute.u2localVariableTableLength = dataInput.readUnsignedShort();
localVariableTableAttribute.localVariableTable = new LocalVariableInfo[localVariableTableAttribute.u2localVariableTableLength];
for (int index = 0; index < localVariableTableAttribute.u2localVariableTableLength; index++)
{
LocalVariableInfo localVariableInfo = new LocalVariableInfo();
visitLocalVariableInfo(clazz, method, codeAttribute, localVariableInfo);
localVariableTableAttribute.localVariableTable[index] = localVariableInfo;
}
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
// Read the local variable types.
localVariableTypeTableAttribute.u2localVariableTypeTableLength = dataInput.readUnsignedShort();
localVariableTypeTableAttribute.localVariableTypeTable = new LocalVariableTypeInfo[localVariableTypeTableAttribute.u2localVariableTypeTableLength];
for (int index = 0; index < localVariableTypeTableAttribute.u2localVariableTypeTableLength; index++)
{
LocalVariableTypeInfo localVariableTypeInfo = new LocalVariableTypeInfo();
visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeInfo);
localVariableTypeTableAttribute.localVariableTypeTable[index] = localVariableTypeInfo;
}
}
public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
{
// Read the annotations.
annotationsAttribute.u2annotationsCount = dataInput.readUnsignedShort();
annotationsAttribute.annotations = new Annotation[annotationsAttribute.u2annotationsCount];
for (int index = 0; index < annotationsAttribute.u2annotationsCount; index++)
{
Annotation annotation = new Annotation();
visitAnnotation(clazz, annotation);
annotationsAttribute.annotations[index] = annotation;
}
}
public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
{
// Read the parameter annotations.
parameterAnnotationsAttribute.u2parametersCount = dataInput.readUnsignedByte();
// The java compilers of JDK 1.5, JDK 1.6, and Eclipse all count the
// number of parameters of constructors of non-static inner classes
// incorrectly. Fix it right here.
int parameterStart = 0;
if (method.getName(clazz).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))
{
int realParametersCount = ClassUtil.internalMethodParameterCount(method.getDescriptor(clazz));
parameterStart = realParametersCount - parameterAnnotationsAttribute.u2parametersCount;
parameterAnnotationsAttribute.u2parametersCount = realParametersCount;
}
parameterAnnotationsAttribute.u2parameterAnnotationsCount = new int[parameterAnnotationsAttribute.u2parametersCount];
parameterAnnotationsAttribute.parameterAnnotations = new Annotation[parameterAnnotationsAttribute.u2parametersCount][];
for (int parameterIndex = parameterStart; parameterIndex < parameterAnnotationsAttribute.u2parametersCount; parameterIndex++)
{
// Read the parameter annotations of the given parameter.
int u2annotationsCount = dataInput.readUnsignedShort();
Annotation[] annotations = new Annotation[u2annotationsCount];
for (int index = 0; index < u2annotationsCount; index++)
{
Annotation annotation = new Annotation();
visitAnnotation(clazz, annotation);
annotations[index] = annotation;
}
parameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex] = u2annotationsCount;
parameterAnnotationsAttribute.parameterAnnotations[parameterIndex] = annotations;
}
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
// Read the default element value.
ElementValue elementValue = createElementValue();
elementValue.accept(clazz, null, this);
annotationDefaultAttribute.defaultValue = elementValue;
}
// 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)
{
innerClassesInfo.u2innerClassIndex = dataInput.readUnsignedShort();
innerClassesInfo.u2outerClassIndex = dataInput.readUnsignedShort();
innerClassesInfo.u2innerNameIndex = dataInput.readUnsignedShort();
innerClassesInfo.u2innerClassAccessFlags = dataInput.readUnsignedShort();
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
exceptionInfo.u2startPC = dataInput.readUnsignedShort();
exceptionInfo.u2endPC = dataInput.readUnsignedShort();
exceptionInfo.u2handlerPC = dataInput.readUnsignedShort();
exceptionInfo.u2catchType = dataInput.readUnsignedShort();
}
// Implementations for StackMapFrameVisitor.
public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame)
{
if (sameZeroFrame.getTag() == StackMapFrame.SAME_ZERO_FRAME_EXTENDED)
{
sameZeroFrame.u2offsetDelta = dataInput.readUnsignedShort();
}
}
public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
{
if (sameOneFrame.getTag() == StackMapFrame.SAME_ONE_FRAME_EXTENDED)
{
sameOneFrame.u2offsetDelta = dataInput.readUnsignedShort();
}
// Read the verification type of the stack entry.
VerificationType verificationType = createVerificationType();
verificationType.accept(clazz, method, codeAttribute, offset, this);
sameOneFrame.stackItem = verificationType;
}
public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame)
{
lessZeroFrame.u2offsetDelta = dataInput.readUnsignedShort();
}
public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
{
moreZeroFrame.u2offsetDelta = dataInput.readUnsignedShort();
// Read the verification types of the additional local variables.
moreZeroFrame.additionalVariables = new VerificationType[moreZeroFrame.additionalVariablesCount];
for (int index = 0; index < moreZeroFrame.additionalVariablesCount; index++)
{
VerificationType verificationType = createVerificationType();
verificationType.accept(clazz, method, codeAttribute, offset, this);
moreZeroFrame.additionalVariables[index] = verificationType;
}
}
public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
{
fullFrame.u2offsetDelta = dataInput.readUnsignedShort();
// Read the verification types of the local variables.
fullFrame.variablesCount = dataInput.readUnsignedShort();
fullFrame.variables = new VerificationType[fullFrame.variablesCount];
for (int index = 0; index < fullFrame.variablesCount; index++)
{
VerificationType verificationType = createVerificationType();
verificationType.variablesAccept(clazz, method, codeAttribute, offset, index, this);
fullFrame.variables[index] = verificationType;
}
// Read the verification types of the stack entries.
fullFrame.stackCount = dataInput.readUnsignedShort();
fullFrame.stack = new VerificationType[fullFrame.stackCount];
for (int index = 0; index < fullFrame.stackCount; index++)
{
VerificationType verificationType = createVerificationType();
verificationType.stackAccept(clazz, method, codeAttribute, offset, index, this);
fullFrame.stack[index] = verificationType;
}
}
// Implementations for VerificationTypeVisitor.
public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType)
{
// Most verification types don't contain any additional information.
}
public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
{
objectType.u2classIndex = dataInput.readUnsignedShort();
}
public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType)
{
uninitializedType.u2newInstructionOffset = dataInput.readUnsignedShort();
}
// Implementations for LineNumberInfoVisitor.
public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo)
{
lineNumberInfo.u2startPC = dataInput.readUnsignedShort();
lineNumberInfo.u2lineNumber = dataInput.readUnsignedShort();
}
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
localVariableInfo.u2startPC = dataInput.readUnsignedShort();
localVariableInfo.u2length = dataInput.readUnsignedShort();
localVariableInfo.u2nameIndex = dataInput.readUnsignedShort();
localVariableInfo.u2descriptorIndex = dataInput.readUnsignedShort();
localVariableInfo.u2index = dataInput.readUnsignedShort();
}
// Implementations for LocalVariableTypeInfoVisitor.
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
localVariableTypeInfo.u2startPC = dataInput.readUnsignedShort();
localVariableTypeInfo.u2length = dataInput.readUnsignedShort();
localVariableTypeInfo.u2nameIndex = dataInput.readUnsignedShort();
localVariableTypeInfo.u2signatureIndex = dataInput.readUnsignedShort();
localVariableTypeInfo.u2index = dataInput.readUnsignedShort();
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
// Read the annotation type.
annotation.u2typeIndex = dataInput.readUnsignedShort();
// Read the element value pairs.
annotation.u2elementValuesCount = dataInput.readUnsignedShort();
annotation.elementValues = new ElementValue[annotation.u2elementValuesCount];
for (int index = 0; index < annotation.u2elementValuesCount; index++)
{
int u2elementNameIndex = dataInput.readUnsignedShort();
ElementValue elementValue = createElementValue();
elementValue.u2elementNameIndex = u2elementNameIndex;
elementValue.accept(clazz, annotation, this);
annotation.elementValues[index] = elementValue;
}
}
// Implementations for ElementValueVisitor.
public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
{
constantElementValue.u2constantValueIndex = dataInput.readUnsignedShort();
}
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
{
enumConstantElementValue.u2typeNameIndex = dataInput.readUnsignedShort();
enumConstantElementValue.u2constantNameIndex = dataInput.readUnsignedShort();
}
public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
{
classElementValue.u2classInfoIndex = dataInput.readUnsignedShort();
}
public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
{
// Read the annotation.
Annotation annotationValue = new Annotation();
visitAnnotation(clazz, annotationValue);
annotationElementValue.annotationValue = annotationValue;
}
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
// Read the element values.
arrayElementValue.u2elementValuesCount = dataInput.readUnsignedShort();
arrayElementValue.elementValues = new ElementValue[arrayElementValue.u2elementValuesCount];
for (int index = 0; index < arrayElementValue.u2elementValuesCount; index++)
{
ElementValue elementValue = createElementValue();
elementValue.accept(clazz, annotation, this);
arrayElementValue.elementValues[index] = elementValue;
}
}
// Small utility methods.
private Constant createConstant()
{
int u1tag = dataInput.readUnsignedByte();
switch (u1tag)
{
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");
}
}
private Attribute createAttribute(Clazz clazz)
{
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():
attributeName.equals(ClassConstants.ATTR_EnclosingMethod) ? (Attribute)new EnclosingMethodAttribute():
attributeName.equals(ClassConstants.ATTR_Deprecated) ? (Attribute)new DeprecatedAttribute():
attributeName.equals(ClassConstants.ATTR_Synthetic) ? (Attribute)new SyntheticAttribute():
attributeName.equals(ClassConstants.ATTR_Signature) ? (Attribute)new SignatureAttribute():
attributeName.equals(ClassConstants.ATTR_ConstantValue) ? (Attribute)new ConstantValueAttribute():
attributeName.equals(ClassConstants.ATTR_Exceptions) ? (Attribute)new ExceptionsAttribute():
attributeName.equals(ClassConstants.ATTR_Code) ? (Attribute)new CodeAttribute():
attributeName.equals(ClassConstants.ATTR_StackMap) ? (Attribute)new StackMapAttribute():
attributeName.equals(ClassConstants.ATTR_StackMapTable) ? (Attribute)new StackMapTableAttribute():
attributeName.equals(ClassConstants.ATTR_LineNumberTable) ? (Attribute)new LineNumberTableAttribute():
attributeName.equals(ClassConstants.ATTR_LocalVariableTable) ? (Attribute)new LocalVariableTableAttribute():
attributeName.equals(ClassConstants.ATTR_LocalVariableTypeTable) ? (Attribute)new LocalVariableTypeTableAttribute():
attributeName.equals(ClassConstants.ATTR_RuntimeVisibleAnnotations) ? (Attribute)new RuntimeVisibleAnnotationsAttribute():
attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleAnnotations) ? (Attribute)new RuntimeInvisibleAnnotationsAttribute():
attributeName.equals(ClassConstants.ATTR_RuntimeVisibleParameterAnnotations) ? (Attribute)new RuntimeVisibleParameterAnnotationsAttribute():
attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleParameterAnnotations) ? (Attribute)new RuntimeInvisibleParameterAnnotationsAttribute():
attributeName.equals(ClassConstants.ATTR_AnnotationDefault) ? (Attribute)new AnnotationDefaultAttribute():
(Attribute)new UnknownAttribute(u4attributeLength);
attribute.u2attributeNameIndex = u2attributeNameIndex;
return attribute;
}
private StackMapFrame createStackMapFrame()
{
int u1tag = dataInput.readUnsignedByte();
return
u1tag < StackMapFrame.SAME_ONE_FRAME ? (StackMapFrame)new SameZeroFrame(u1tag) :
u1tag < StackMapFrame.SAME_ONE_FRAME_EXTENDED ? (StackMapFrame)new SameOneFrame(u1tag) :
u1tag < StackMapFrame.LESS_ZERO_FRAME ? (StackMapFrame)new SameOneFrame(u1tag) :
u1tag < StackMapFrame.SAME_ZERO_FRAME_EXTENDED ? (StackMapFrame)new LessZeroFrame(u1tag) :
u1tag < StackMapFrame.MORE_ZERO_FRAME ? (StackMapFrame)new SameZeroFrame(u1tag) :
u1tag < StackMapFrame.FULL_FRAME ? (StackMapFrame)new MoreZeroFrame(u1tag) :
(StackMapFrame)new FullFrame();
}
private VerificationType createVerificationType()
{
int u1tag = dataInput.readUnsignedByte();
switch (u1tag)
{
case VerificationType.INTEGER_TYPE: return new IntegerType();
case VerificationType.FLOAT_TYPE: return new FloatType();
case VerificationType.LONG_TYPE: return new LongType();
case VerificationType.DOUBLE_TYPE: return new DoubleType();
case VerificationType.TOP_TYPE: return new TopType();
case VerificationType.OBJECT_TYPE: return new ObjectType();
case VerificationType.NULL_TYPE: return new NullType();
case VerificationType.UNINITIALIZED_TYPE: return new UninitializedType();
case VerificationType.UNINITIALIZED_THIS_TYPE: return new UninitializedThisType();
default: throw new RuntimeException("Unknown verification type ["+u1tag+"] in stack map frame");
}
}
private ElementValue createElementValue()
{
int u1tag = dataInput.readUnsignedByte();
switch (u1tag)
{
case ClassConstants.INTERNAL_TYPE_BOOLEAN:
case ClassConstants.INTERNAL_TYPE_BYTE:
case ClassConstants.INTERNAL_TYPE_CHAR:
case ClassConstants.INTERNAL_TYPE_SHORT:
case ClassConstants.INTERNAL_TYPE_INT:
case ClassConstants.INTERNAL_TYPE_FLOAT:
case ClassConstants.INTERNAL_TYPE_LONG:
case ClassConstants.INTERNAL_TYPE_DOUBLE:
case ClassConstants.ELEMENT_VALUE_STRING_CONSTANT: return new ConstantElementValue(u1tag);
case ClassConstants.ELEMENT_VALUE_ENUM_CONSTANT: return new EnumConstantElementValue();
case ClassConstants.ELEMENT_VALUE_CLASS: return new ClassElementValue();
case ClassConstants.ELEMENT_VALUE_ANNOTATION: return new AnnotationElementValue();
case ClassConstants.ELEMENT_VALUE_ARRAY: return new ArrayElementValue();
default: throw new IllegalArgumentException("Unknown element value tag ["+u1tag+"]");
}
}
}
proguard4.8/src/proguard/classfile/io/package.html 0000644 0001750 0001750 00000000122 11736333523 021031 0 ustar eric eric
This package contains classes for reading and writing class files.
proguard4.8/src/proguard/classfile/io/LibraryClassReader.java 0000644 0001750 0001750 00000030624 11736333523 023142 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
import java.io.DataInput;
/**
* This ClassVisitor fills out the LibraryClass objects that it visits with data
* from the given DataInput object.
*
* @author Eric Lafortune
*/
public class LibraryClassReader
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
ConstantVisitor
{
private static final LibraryField[] EMPTY_LIBRARY_FIELDS = new LibraryField[0];
private static final LibraryMethod[] EMPTY_LIBRARY_METHODS = new LibraryMethod[0];
private final RuntimeDataInput dataInput;
private final boolean skipNonPublicClasses;
private final boolean skipNonPublicClassMembers;
// A global array that acts as a parameter for the visitor methods.
private Constant[] constantPool;
/**
* Creates a new ProgramClassReader for reading from the given DataInput.
*/
public LibraryClassReader(DataInput dataInput,
boolean skipNonPublicClasses,
boolean skipNonPublicClassMembers)
{
this.dataInput = new RuntimeDataInput(dataInput);
this.skipNonPublicClasses = skipNonPublicClasses;
this.skipNonPublicClassMembers = skipNonPublicClassMembers;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass libraryClass)
{
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Read and check the magic number.
int u4magic = dataInput.readInt();
ClassUtil.checkMagicNumber(u4magic);
// Read and check the version numbers.
int u2minorVersion = dataInput.readUnsignedShort();
int u2majorVersion = dataInput.readUnsignedShort();
int u4version = ClassUtil.internalClassVersion(u2majorVersion,
u2minorVersion);
ClassUtil.checkVersionNumbers(u4version);
// Read the constant pool. Note that the first entry is not used.
int u2constantPoolCount = dataInput.readUnsignedShort();
// Create the constant pool array.
constantPool = new Constant[u2constantPoolCount];
for (int index = 1; index < u2constantPoolCount; index++)
{
Constant constant = createConstant();
constant.accept(libraryClass, this);
int tag = constant.getTag();
if (tag == ClassConstants.CONSTANT_Class ||
tag == ClassConstants.CONSTANT_Utf8)
{
constantPool[index] = constant;
}
// Long constants and double constants take up two entries in the
// constant pool.
if (tag == ClassConstants.CONSTANT_Long ||
tag == ClassConstants.CONSTANT_Double)
{
index++;
}
}
// Read the general class information.
libraryClass.u2accessFlags = dataInput.readUnsignedShort();
// We may stop parsing this library class if it's not public anyway.
// E.g. only about 60% of all rt.jar classes need to be parsed.
if (skipNonPublicClasses &&
AccessUtil.accessLevel(libraryClass.getAccessFlags()) < AccessUtil.PUBLIC)
{
return;
}
// Read the class and super class indices.
int u2thisClass = dataInput.readUnsignedShort();
int u2superClass = dataInput.readUnsignedShort();
// Store their actual names.
libraryClass.thisClassName = getClassName(u2thisClass);
libraryClass.superClassName = (u2superClass == 0) ? null :
getClassName(u2superClass);
// Read the interfaces
int u2interfacesCount = dataInput.readUnsignedShort();
libraryClass.interfaceNames = new String[u2interfacesCount];
for (int index = 0; index < u2interfacesCount; index++)
{
// Store the actual interface name.
int u2interface = dataInput.readUnsignedShort();
libraryClass.interfaceNames[index] = getClassName(u2interface);
}
// Read the fields.
int u2fieldsCount = dataInput.readUnsignedShort();
// Create the fields array.
LibraryField[] reusableFields = new LibraryField[u2fieldsCount];
int visibleFieldsCount = 0;
for (int index = 0; index < u2fieldsCount; index++)
{
LibraryField field = new LibraryField();
this.visitLibraryMember(libraryClass, field);
// Only store fields that are visible.
if (AccessUtil.accessLevel(field.getAccessFlags()) >=
(skipNonPublicClassMembers ? AccessUtil.PROTECTED :
AccessUtil.PACKAGE_VISIBLE))
{
reusableFields[visibleFieldsCount++] = field;
}
}
// Copy the visible fields (if any) into a fields array of the right size.
if (visibleFieldsCount == 0)
{
libraryClass.fields = EMPTY_LIBRARY_FIELDS;
}
else
{
libraryClass.fields = new LibraryField[visibleFieldsCount];
System.arraycopy(reusableFields, 0, libraryClass.fields, 0, visibleFieldsCount);
}
// Read the methods.
int u2methodsCount = dataInput.readUnsignedShort();
// Create the methods array.
LibraryMethod[] reusableMethods = new LibraryMethod[u2methodsCount];
int visibleMethodsCount = 0;
for (int index = 0; index < u2methodsCount; index++)
{
LibraryMethod method = new LibraryMethod();
this.visitLibraryMember(libraryClass, method);
// Only store methods that are visible.
if (AccessUtil.accessLevel(method.getAccessFlags()) >=
(skipNonPublicClassMembers ? AccessUtil.PROTECTED :
AccessUtil.PACKAGE_VISIBLE))
{
reusableMethods[visibleMethodsCount++] = method;
}
}
// Copy the visible methods (if any) into a methods array of the right size.
if (visibleMethodsCount == 0)
{
libraryClass.methods = EMPTY_LIBRARY_METHODS;
}
else
{
libraryClass.methods = new LibraryMethod[visibleMethodsCount];
System.arraycopy(reusableMethods, 0, libraryClass.methods, 0, visibleMethodsCount);
}
// Skip the class attributes.
skipAttributes();
}
// Implementations for MemberVisitor.
public void visitProgramMember(ProgramClass libraryClass, ProgramMember libraryMember)
{
}
public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
{
// Read the general field information.
libraryMember.u2accessFlags = dataInput.readUnsignedShort();
libraryMember.name = getString(dataInput.readUnsignedShort());
libraryMember.descriptor = getString(dataInput.readUnsignedShort());
// Skip the field attributes.
skipAttributes();
}
// Implementations for ConstantVisitor.
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
dataInput.skipBytes(4);
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
dataInput.skipBytes(8);
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
dataInput.skipBytes(4);
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
dataInput.skipBytes(8);
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
dataInput.skipBytes(2);
}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
int u2length = dataInput.readUnsignedShort();
// Read the UTF-8 bytes.
byte[] bytes = new byte[u2length];
dataInput.readFully(bytes);
utf8Constant.setBytes(bytes);
}
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);
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
classConstant.u2nameIndex = dataInput.readUnsignedShort();
}
public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
{
dataInput.skipBytes(2);
}
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
dataInput.skipBytes(4);
}
// Small utility methods.
/**
* Returns the class name of the ClassConstant at the specified index in the
* reusable constant pool.
*/
private String getClassName(int constantIndex)
{
ClassConstant classEntry = (ClassConstant)constantPool[constantIndex];
return getString(classEntry.u2nameIndex);
}
/**
* Returns the string of the Utf8Constant at the specified index in the
* reusable constant pool.
*/
private String getString(int constantIndex)
{
return ((Utf8Constant)constantPool[constantIndex]).getString();
}
private Constant createConstant()
{
int u1tag = dataInput.readUnsignedByte();
switch (u1tag)
{
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");
}
}
private void skipAttributes()
{
int u2attributesCount = dataInput.readUnsignedShort();
for (int index = 0; index < u2attributesCount; index++)
{
skipAttribute();
}
}
private void skipAttribute()
{
dataInput.skipBytes(2);
int u4attributeLength = dataInput.readInt();
dataInput.skipBytes(u4attributeLength);
}
}
proguard4.8/src/proguard/classfile/io/ProgramClassWriter.java 0000644 0001750 0001750 00000064477 11736333523 023234 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
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.util.*;
import proguard.classfile.visitor.*;
import java.io.*;
/**
* This ClassVisitor writes out the ProgramClass objects that it visits to the
* given DataOutput object.
*
* @author Eric Lafortune
*/
public class ProgramClassWriter
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
ConstantVisitor,
AttributeVisitor
{
private RuntimeDataOutput dataOutput;
private final ConstantBodyWriter constantBodyWriter = new ConstantBodyWriter();
private final AttributeBodyWriter attributeBodyWriter = new AttributeBodyWriter();
private final StackMapFrameBodyWriter stackMapFrameBodyWriter = new StackMapFrameBodyWriter();
private final VerificationTypeBodyWriter verificationTypeBodyWriter = new VerificationTypeBodyWriter();
private final ElementValueBodyWriter elementValueBodyWriter = new ElementValueBodyWriter();
/**
* Creates a new ProgramClassWriter for writing to the given DataOutput.
*/
public ProgramClassWriter(DataOutput dataOutput)
{
this.dataOutput = new RuntimeDataOutput(dataOutput);
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Write the magic number.
dataOutput.writeInt(programClass.u4magic);
// Write the version numbers.
dataOutput.writeShort(ClassUtil.internalMinorClassVersion(programClass.u4version));
dataOutput.writeShort(ClassUtil.internalMajorClassVersion(programClass.u4version));
// Write the constant pool.
dataOutput.writeShort(programClass.u2constantPoolCount);
programClass.constantPoolEntriesAccept(this);
// Write the general class information.
dataOutput.writeShort(programClass.u2accessFlags);
dataOutput.writeShort(programClass.u2thisClass);
dataOutput.writeShort(programClass.u2superClass);
// Write the interfaces.
dataOutput.writeShort(programClass.u2interfacesCount);
for (int index = 0; index < programClass.u2interfacesCount; index++)
{
dataOutput.writeShort(programClass.u2interfaces[index]);
}
// Write the fields.
dataOutput.writeShort(programClass.u2fieldsCount);
programClass.fieldsAccept(this);
// Write the methods.
dataOutput.writeShort(programClass.u2methodsCount);
programClass.methodsAccept(this);
// Write the class attributes.
dataOutput.writeShort(programClass.u2attributesCount);
programClass.attributesAccept(this);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
// Write the general field information.
dataOutput.writeShort(programField.u2accessFlags);
dataOutput.writeShort(programField.u2nameIndex);
dataOutput.writeShort(programField.u2descriptorIndex);
// Write the field attributes.
dataOutput.writeShort(programField.u2attributesCount);
programField.attributesAccept(programClass, this);
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
// Write the general method information.
dataOutput.writeShort(programMethod.u2accessFlags);
dataOutput.writeShort(programMethod.u2nameIndex);
dataOutput.writeShort(programMethod.u2descriptorIndex);
// Write the method attributes.
dataOutput.writeShort(programMethod.u2attributesCount);
programMethod.attributesAccept(programClass, this);
}
public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
{
}
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant)
{
// Write the tag.
dataOutput.writeByte(constant.getTag());
// Write the actual body.
constant.accept(clazz, constantBodyWriter);
}
private class ConstantBodyWriter
extends SimplifiedVisitor
implements ConstantVisitor
{
// Implementations for ConstantVisitor.
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
dataOutput.writeInt(integerConstant.u4value);
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
dataOutput.writeLong(longConstant.u8value);
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
dataOutput.writeFloat(floatConstant.f4value);
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
dataOutput.writeDouble(doubleConstant.f8value);
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
dataOutput.writeShort(stringConstant.u2stringIndex);
}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
byte[] bytes = utf8Constant.getBytes();
dataOutput.writeShort(bytes.length);
dataOutput.write(bytes);
}
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);
dataOutput.writeShort(refConstant.u2nameAndTypeIndex);
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
dataOutput.writeShort(classConstant.u2nameIndex);
}
public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
{
dataOutput.writeShort(methodTypeConstant.u2descriptorIndex);
}
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
dataOutput.writeShort(nameAndTypeConstant.u2nameIndex);
dataOutput.writeShort(nameAndTypeConstant.u2descriptorIndex);
}
}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute)
{
// Write the attribute name index.
dataOutput.writeShort(attribute.u2attributeNameIndex);
// We'll write the attribute body into an array first, so we can
// automatically figure out its length.
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// Temporarily replace the current data output.
RuntimeDataOutput oldDataOutput = dataOutput;
dataOutput = new RuntimeDataOutput(new DataOutputStream(byteArrayOutputStream));
// Write the attribute body into the array. Note that the
// accept method with two dummy null arguments never throws
// an UnsupportedOperationException.
attribute.accept(clazz, null, null, attributeBodyWriter);
// Restore the original data output.
dataOutput = oldDataOutput;
// Write the attribute length and body.
byte[] info = byteArrayOutputStream.toByteArray();
dataOutput.writeInt(info.length);
dataOutput.write(info);
}
private class AttributeBodyWriter
extends SimplifiedVisitor
implements AttributeVisitor,
BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
LineNumberInfoVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
ElementValueVisitor
{
// Implementations for AttributeVisitor.
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
// Write the unknown information.
dataOutput.write(unknownAttribute.info);
}
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);
}
public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
{
dataOutput.writeShort(sourceDirAttribute.u2sourceDirIndex);
}
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
// Write the inner classes.
dataOutput.writeShort(innerClassesAttribute.u2classesCount);
innerClassesAttribute.innerClassEntriesAccept(clazz, this);
}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
dataOutput.writeShort(enclosingMethodAttribute.u2classIndex);
dataOutput.writeShort(enclosingMethodAttribute.u2nameAndTypeIndex);
}
public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
{
// This attribute does not contain any additional information.
}
public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
{
// This attribute does not contain any additional information.
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
dataOutput.writeShort(signatureAttribute.u2signatureIndex);
}
public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
{
dataOutput.writeShort(constantValueAttribute.u2constantValueIndex);
}
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
// Write the exceptions.
dataOutput.writeShort(exceptionsAttribute.u2exceptionIndexTableLength);
for (int index = 0; index < exceptionsAttribute.u2exceptionIndexTableLength; index++)
{
dataOutput.writeShort(exceptionsAttribute.u2exceptionIndexTable[index]);
}
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
// Write the stack size and local variable frame size.
dataOutput.writeShort(codeAttribute.u2maxStack);
dataOutput.writeShort(codeAttribute.u2maxLocals);
// Write the byte code.
dataOutput.writeInt(codeAttribute.u4codeLength);
dataOutput.write(codeAttribute.code, 0, codeAttribute.u4codeLength);
// Write the exceptions.
dataOutput.writeShort(codeAttribute.u2exceptionTableLength);
codeAttribute.exceptionsAccept(clazz, method, this);
// Write the code attributes.
dataOutput.writeShort(codeAttribute.u2attributesCount);
codeAttribute.attributesAccept(clazz, method, ProgramClassWriter.this);
}
public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
{
// Write the stack map frames (only full frames, without tag).
dataOutput.writeShort(stackMapAttribute.u2stackMapFramesCount);
stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, stackMapFrameBodyWriter);
}
public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
{
// Write the stack map frames.
dataOutput.writeShort(stackMapTableAttribute.u2stackMapFramesCount);
stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
}
public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
{
// Write the line numbers.
dataOutput.writeShort(lineNumberTableAttribute.u2lineNumberTableLength);
lineNumberTableAttribute.lineNumbersAccept(clazz, method, codeAttribute, this);
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
// Write the local variables.
dataOutput.writeShort(localVariableTableAttribute.u2localVariableTableLength);
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
// Write the local variable types.
dataOutput.writeShort(localVariableTypeTableAttribute.u2localVariableTypeTableLength);
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
{
// Write the annotations.
dataOutput.writeShort(annotationsAttribute.u2annotationsCount);
annotationsAttribute.annotationsAccept(clazz, this);
}
public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
{
// Write the parameter annotations.
dataOutput.writeByte(parameterAnnotationsAttribute.u2parametersCount);
for (int parameterIndex = 0; parameterIndex < parameterAnnotationsAttribute.u2parametersCount; parameterIndex++)
{
// Write the parameter annotations of the given parameter.
int u2annotationsCount = parameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex];
Annotation[] annotations = parameterAnnotationsAttribute.parameterAnnotations[parameterIndex];
dataOutput.writeShort(u2annotationsCount);
for (int index = 0; index < u2annotationsCount; index++)
{
visitAnnotation(clazz, annotations[index]);
}
}
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
// Write the default element value.
annotationDefaultAttribute.defaultValue.accept(clazz, null, this);
}
// 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)
{
dataOutput.writeShort(innerClassesInfo.u2innerClassIndex);
dataOutput.writeShort(innerClassesInfo.u2outerClassIndex);
dataOutput.writeShort(innerClassesInfo.u2innerNameIndex);
dataOutput.writeShort(innerClassesInfo.u2innerClassAccessFlags);
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
dataOutput.writeShort(exceptionInfo.u2startPC);
dataOutput.writeShort(exceptionInfo.u2endPC);
dataOutput.writeShort(exceptionInfo.u2handlerPC);
dataOutput.writeShort(exceptionInfo.u2catchType);
}
// Implementations for StackMapFrameVisitor.
public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame)
{
// Write the stack map frame tag.
dataOutput.writeByte(stackMapFrame.getTag());
// Write the actual body.
stackMapFrame.accept(clazz, method, codeAttribute, offset, stackMapFrameBodyWriter);
}
// Implementations for LineNumberInfoVisitor.
public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo)
{
dataOutput.writeShort(lineNumberInfo.u2startPC);
dataOutput.writeShort(lineNumberInfo.u2lineNumber);
}
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
dataOutput.writeShort(localVariableInfo.u2startPC);
dataOutput.writeShort(localVariableInfo.u2length);
dataOutput.writeShort(localVariableInfo.u2nameIndex);
dataOutput.writeShort(localVariableInfo.u2descriptorIndex);
dataOutput.writeShort(localVariableInfo.u2index);
}
// Implementations for LocalVariableTypeInfoVisitor.
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
dataOutput.writeShort(localVariableTypeInfo.u2startPC);
dataOutput.writeShort(localVariableTypeInfo.u2length);
dataOutput.writeShort(localVariableTypeInfo.u2nameIndex);
dataOutput.writeShort(localVariableTypeInfo.u2signatureIndex);
dataOutput.writeShort(localVariableTypeInfo.u2index);
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
// Write the annotation type.
dataOutput.writeShort(annotation.u2typeIndex);
// Write the element value pairs.
dataOutput.writeShort(annotation.u2elementValuesCount);
annotation.elementValuesAccept(clazz, this);
}
// Implementations for ElementValueVisitor.
public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
{
// Write the element name index, if applicable.
int u2elementNameIndex = elementValue.u2elementNameIndex;
if (u2elementNameIndex != 0)
{
dataOutput.writeShort(u2elementNameIndex);
}
// Write the tag.
dataOutput.writeByte(elementValue.getTag());
// Write the actual body.
elementValue.accept(clazz, annotation, elementValueBodyWriter);
}
}
private class StackMapFrameBodyWriter
extends SimplifiedVisitor
implements StackMapFrameVisitor,
VerificationTypeVisitor
{
public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame)
{
if (sameZeroFrame.getTag() == StackMapFrame.SAME_ZERO_FRAME_EXTENDED)
{
dataOutput.writeShort(sameZeroFrame.u2offsetDelta);
}
}
public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
{
if (sameOneFrame.getTag() == StackMapFrame.SAME_ONE_FRAME_EXTENDED)
{
dataOutput.writeShort(sameOneFrame.u2offsetDelta);
}
// Write the verification type of the stack entry.
sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
}
public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame)
{
dataOutput.writeShort(lessZeroFrame.u2offsetDelta);
}
public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
{
dataOutput.writeShort(moreZeroFrame.u2offsetDelta);
// Write the verification types of the additional local variables.
moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
}
public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
{
dataOutput.writeShort(fullFrame.u2offsetDelta);
// Write the verification types of the local variables.
dataOutput.writeShort(fullFrame.variablesCount);
fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);
// Write the verification types of the stack entries.
dataOutput.writeShort(fullFrame.stackCount);
fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);
}
// Implementations for VerificationTypeVisitor.
public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType)
{
// Write the verification type tag.
dataOutput.writeByte(verificationType.getTag());
// Write the actual body.
verificationType.accept(clazz, method, codeAttribute, offset, verificationTypeBodyWriter);
}
}
private class VerificationTypeBodyWriter
extends SimplifiedVisitor
implements VerificationTypeVisitor
{
// Implementations for VerificationTypeVisitor.
public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType)
{
// Most verification types don't contain any additional information.
}
public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
{
dataOutput.writeShort(objectType.u2classIndex);
}
public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType)
{
dataOutput.writeShort(uninitializedType.u2newInstructionOffset);
}
}
private class ElementValueBodyWriter
extends SimplifiedVisitor
implements ElementValueVisitor
{
// Implementations for ElementValueVisitor.
public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
{
dataOutput.writeShort(constantElementValue.u2constantValueIndex);
}
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
{
dataOutput.writeShort(enumConstantElementValue.u2typeNameIndex);
dataOutput.writeShort(enumConstantElementValue.u2constantNameIndex);
}
public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
{
dataOutput.writeShort(classElementValue.u2classInfoIndex);
}
public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
{
// Write the annotation.
attributeBodyWriter.visitAnnotation(clazz, annotationElementValue.annotationValue);
}
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
// Write the element values.
dataOutput.writeShort(arrayElementValue.u2elementValuesCount);
arrayElementValue.elementValuesAccept(clazz, annotation, attributeBodyWriter);
}
}
}
proguard4.8/src/proguard/classfile/io/RuntimeDataOutput.java 0000644 0001750 0001750 00000010656 11736333523 023066 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This class delegates its method calls to the corresponding DataOutput methods,
* converting its IOExceptions to RuntimeExceptions.
*
* @author Eric Lafortune
*/
final class RuntimeDataOutput
{
private final DataOutput dataOutput;
public RuntimeDataOutput(DataOutput dataOutput)
{
this.dataOutput = dataOutput;
}
// Methods delegating to DataOutput.
public void write(byte[] b)
{
try
{
dataOutput.write(b);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void write(byte[] b, int off, int len)
{
try
{
dataOutput.write(b, off, len);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void write(int b)
{
try
{
dataOutput.write(b);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeBoolean(boolean v)
{
try
{
dataOutput.writeBoolean(v);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeByte(int v)
{
try
{
dataOutput.writeByte(v);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeBytes(String s)
{
try
{
dataOutput.writeBytes(s);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeChar(int v)
{
try
{
dataOutput.writeChar(v);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeChars(String s)
{
try
{
dataOutput.writeChars(s);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeDouble(double v)
{
try
{
dataOutput.writeDouble(v);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeFloat(float v)
{
try
{
dataOutput.writeFloat(v);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeInt(int v)
{
try
{
dataOutput.writeInt(v);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeLong(long v)
{
try
{
dataOutput.writeLong(v);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeShort(int v)
{
try
{
dataOutput.writeShort(v);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void writeUTF(String str)
{
try
{
dataOutput.writeUTF(str);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
}
proguard4.8/src/proguard/classfile/io/RuntimeDataInput.java 0000644 0001750 0001750 00000011210 11736333523 022650 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This class delegates its method calls to the corresponding DataInput methods,
* converting its IOExceptions to RuntimeExceptions.
*
* @author Eric Lafortune
*/
final class RuntimeDataInput
{
private final DataInput dataInput;
public RuntimeDataInput(DataInput dataInput)
{
this.dataInput = dataInput;
}
// Methods delegating to DataInput.
public boolean readBoolean()
{
try
{
return dataInput.readBoolean();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public byte readByte()
{
try
{
return dataInput.readByte();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public char readChar()
{
try
{
return dataInput.readChar();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public double readDouble()
{
try
{
return dataInput.readDouble();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public float readFloat()
{
try
{
return dataInput.readFloat();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void readFully(byte[] b)
{
try
{
dataInput.readFully(b);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public void readFully(byte[] b, int off, int len)
{
try
{
dataInput.readFully(b, off, len);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public int readInt()
{
try
{
return dataInput.readInt();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public String readLine()
{
try
{
return dataInput.readLine();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public long readLong()
{
try
{
return dataInput.readLong();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public short readShort()
{
try
{
return dataInput.readShort();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public int readUnsignedByte()
{
try
{
return dataInput.readUnsignedByte();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public int readUnsignedShort()
{
try
{
return dataInput.readUnsignedShort();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public String readUTF()
{
try
{
return dataInput.readUTF();
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
public int skipBytes(int n)
{
try
{
return dataInput.skipBytes(n);
}
catch (IOException ex)
{
throw new RuntimeException(ex.getMessage());
}
}
}
proguard4.8/src/proguard/classfile/ClassConstants.java 0000664 0001750 0001750 00000057040 11736333523 021763 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
/**
* Constants used in representing a Java class (*.class).
*
* @author Eric Lafortune
*/
public interface ClassConstants
{
public static final String CLASS_FILE_EXTENSION = ".class";
public static final int MAGIC = 0xCAFEBABE;
public static final int INTERNAL_CLASS_VERSION_1_0_MAJOR = 45;
public static final int INTERNAL_CLASS_VERSION_1_0_MINOR = 3;
public static final int INTERNAL_CLASS_VERSION_1_2_MAJOR = 46;
public static final int INTERNAL_CLASS_VERSION_1_2_MINOR = 0;
public static final int INTERNAL_CLASS_VERSION_1_3_MAJOR = 47;
public static final int INTERNAL_CLASS_VERSION_1_3_MINOR = 0;
public static final int INTERNAL_CLASS_VERSION_1_4_MAJOR = 48;
public static final int INTERNAL_CLASS_VERSION_1_4_MINOR = 0;
public static final int INTERNAL_CLASS_VERSION_1_5_MAJOR = 49;
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;
public static final int INTERNAL_CLASS_VERSION_1_3 = (INTERNAL_CLASS_VERSION_1_3_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_3_MINOR;
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";
public static final String EXTERNAL_CLASS_VERSION_1_2 = "1.2";
public static final String EXTERNAL_CLASS_VERSION_1_3 = "1.3";
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;
public static final int INTERNAL_ACC_PROTECTED = 0x0004;
public static final int INTERNAL_ACC_STATIC = 0x0008;
public static final int INTERNAL_ACC_FINAL = 0x0010;
public static final int INTERNAL_ACC_SUPER = 0x0020;
public static final int INTERNAL_ACC_SYNCHRONIZED = 0x0020;
public static final int INTERNAL_ACC_VOLATILE = 0x0040;
public static final int INTERNAL_ACC_TRANSIENT = 0x0080;
public static final int INTERNAL_ACC_BRIDGE = 0x0040;
public static final int INTERNAL_ACC_VARARGS = 0x0080;
public static final int INTERNAL_ACC_NATIVE = 0x0100;
public static final int INTERNAL_ACC_INTERFACE = 0x0200;
public static final int INTERNAL_ACC_ABSTRACT = 0x0400;
public static final int INTERNAL_ACC_STRICT = 0x0800;
public static final int INTERNAL_ACC_SYNTHETIC = 0x1000;
public static final int INTERNAL_ACC_ANNOTATTION = 0x2000;
public static final int INTERNAL_ACC_ENUM = 0x4000;
public static final int VALID_INTERNAL_ACC_CLASS = INTERNAL_ACC_PUBLIC |
INTERNAL_ACC_FINAL |
INTERNAL_ACC_SUPER |
INTERNAL_ACC_INTERFACE |
INTERNAL_ACC_ABSTRACT |
INTERNAL_ACC_SYNTHETIC |
INTERNAL_ACC_ANNOTATTION |
INTERNAL_ACC_ENUM;
public static final int VALID_INTERNAL_ACC_FIELD = INTERNAL_ACC_PUBLIC |
INTERNAL_ACC_PRIVATE |
INTERNAL_ACC_PROTECTED |
INTERNAL_ACC_STATIC |
INTERNAL_ACC_FINAL |
INTERNAL_ACC_VOLATILE |
INTERNAL_ACC_TRANSIENT |
INTERNAL_ACC_SYNTHETIC |
INTERNAL_ACC_ENUM;
public static final int VALID_INTERNAL_ACC_METHOD = INTERNAL_ACC_PUBLIC |
INTERNAL_ACC_PRIVATE |
INTERNAL_ACC_PROTECTED |
INTERNAL_ACC_STATIC |
INTERNAL_ACC_FINAL |
INTERNAL_ACC_SYNCHRONIZED |
INTERNAL_ACC_BRIDGE |
INTERNAL_ACC_VARARGS |
INTERNAL_ACC_NATIVE |
INTERNAL_ACC_ABSTRACT |
INTERNAL_ACC_STRICT |
INTERNAL_ACC_SYNTHETIC;
public static final String EXTERNAL_ACC_PUBLIC = "public";
public static final String EXTERNAL_ACC_PRIVATE = "private";
public static final String EXTERNAL_ACC_PROTECTED = "protected";
public static final String EXTERNAL_ACC_STATIC = "static";
public static final String EXTERNAL_ACC_FINAL = "final";
public static final String EXTERNAL_ACC_SUPER = "super";
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";
public static final int CONSTANT_Utf8 = 1;
public static final int CONSTANT_Integer = 3;
public static final int CONSTANT_Float = 4;
public static final int CONSTANT_Long = 5;
public static final int CONSTANT_Double = 6;
public static final int CONSTANT_Class = 7;
public static final int CONSTANT_String = 8;
public static final int CONSTANT_Fieldref = 9;
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";
public static final String ATTR_EnclosingMethod = "EnclosingMethod";
public static final String ATTR_Deprecated = "Deprecated";
public static final String ATTR_Synthetic = "Synthetic";
public static final String ATTR_Signature = "Signature";
public static final String ATTR_ConstantValue = "ConstantValue";
public static final String ATTR_Exceptions = "Exceptions";
public static final String ATTR_Code = "Code";
public static final String ATTR_StackMap = "StackMap";
public static final String ATTR_StackMapTable = "StackMapTable";
public static final String ATTR_LineNumberTable = "LineNumberTable";
public static final String ATTR_LocalVariableTable = "LocalVariableTable";
public static final String ATTR_LocalVariableTypeTable = "LocalVariableTypeTable";
public static final String ATTR_RuntimeVisibleAnnotations = "RuntimeVisibleAnnotations";
public static final String ATTR_RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
public static final String ATTR_RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
public static final String ATTR_RuntimeInvisibleParameterAnnotations = "RuntimeInvisibleParameterAnnotations";
public static final String ATTR_AnnotationDefault = "AnnotationDefault";
public static final int ELEMENT_VALUE_STRING_CONSTANT = 's';
public static final int ELEMENT_VALUE_ENUM_CONSTANT = 'e';
public static final int ELEMENT_VALUE_CLASS = 'c';
public static final int ELEMENT_VALUE_ANNOTATION = '@';
public static final int ELEMENT_VALUE_ARRAY = '[';
public static final char EXTERNAL_PACKAGE_SEPARATOR = '.';
public static final char EXTERNAL_INNER_CLASS_SEPARATOR = '.';
public static final char INTERNAL_PACKAGE_SEPARATOR = '/';
public static final char INTERNAL_INNER_CLASS_SEPARATOR = '$';
public static final char SPECIAL_CLASS_CHARACTER = '-';
public static final char SPECIAL_MEMBER_SEPARATOR = '$';
public static final char EXTERNAL_METHOD_ARGUMENTS_OPEN = '(';
public static final char EXTERNAL_METHOD_ARGUMENTS_CLOSE = ')';
public static final char EXTERNAL_METHOD_ARGUMENTS_SEPARATOR = ',';
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_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 = "Comparable
wrapper of Constant
* objects. It can store an index, in order to identify the constant pool
* entry after it has been sorted. The comparison is primarily based on the
* types of the constant pool entries, and secondarily on the contents of
* the constant pool entries.
*
* @author Eric Lafortune
*/
class ComparableConstant
extends SimplifiedVisitor
implements Comparable, ConstantVisitor
{
private static final int[] PRIORITIES = new int[19];
static
{
PRIORITIES[ClassConstants.CONSTANT_Integer] = 0; // Possibly byte index (ldc).
PRIORITIES[ClassConstants.CONSTANT_Float] = 1;
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; // 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;
private final int thisIndex;
private final Constant thisConstant;
private Constant otherConstant;
private int result;
public ComparableConstant(Clazz clazz, int index, Constant constant)
{
this.clazz = clazz;
this.thisIndex = index;
this.thisConstant = constant;
}
public int getIndex()
{
return thisIndex;
}
public Constant getConstant()
{
return thisConstant;
}
// Implementations for Comparable.
public int compareTo(Object other)
{
ComparableConstant otherComparableConstant = (ComparableConstant)other;
otherConstant = otherComparableConstant.thisConstant;
// Compare based on the original indices, if the actual constant pool
// entries are the same.
if (thisConstant == otherConstant)
{
int otherIndex = otherComparableConstant.thisIndex;
return thisIndex < otherIndex ? -1 :
thisIndex == otherIndex ? 0 :
1;
}
// Compare based on the tags, if they are different.
int thisTag = thisConstant.getTag();
int otherTag = otherConstant.getTag();
if (thisTag != otherTag)
{
return PRIORITIES[thisTag] < PRIORITIES[otherTag] ? -1 : 1;
}
// Otherwise compare based on the contents of the Constant objects.
thisConstant.accept(clazz, this);
return result;
}
// Implementations for ConstantVisitor.
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
int value = integerConstant.getValue();
int otherValue = ((IntegerConstant)otherConstant).getValue();
result = value < otherValue ? -1 :
value == otherValue ? 0 :
1;
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
long value = longConstant.getValue();
long otherValue = ((LongConstant)otherConstant).getValue();
result = value < otherValue ? -1 :
value == otherValue ? 0 :
1;
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
result = Float.compare(floatConstant.getValue(),
((FloatConstant)otherConstant).getValue());
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
result = Double.compare(doubleConstant.getValue(),
((DoubleConstant)otherConstant).getValue());
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
result = stringConstant.getString(clazz).compareTo(((StringConstant)otherConstant).getString(clazz));
}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
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;
result = (refConstant.getClassName(clazz) + ' ' +
refConstant.getName(clazz) + ' ' +
refConstant.getType(clazz))
.compareTo
(otherRefConstant.getClassName(clazz) + ' ' +
otherRefConstant.getName(clazz) + ' ' +
otherRefConstant.getType(clazz));
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
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;
result = (nameAndTypeConstant.getName(clazz) + ' ' +
nameAndTypeConstant.getType(clazz))
.compareTo
(otherNameAndTypeConstant.getName(clazz) + ' ' +
otherNameAndTypeConstant.getType(clazz));
}
// Implementations for Object.
public boolean equals(Object other)
{
return other != null &&
this.getClass().equals(other.getClass()) &&
this.getConstant().getClass().equals(((ComparableConstant)other).getConstant().getClass()) &&
this.compareTo(other) == 0;
}
public int hashCode()
{
return this.getClass().hashCode();
}
}
proguard4.8/src/proguard/classfile/editor/ConstantPoolShrinker.java 0000644 0001750 0001750 00000046553 11736333524 024446 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
}
}
proguard4.8/src/proguard/classfile/LibraryMember.java 0000644 0001750 0001750 00000005274 11736333524 021556 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.visitor.MemberVisitor;
/**
* Representation of a field or method from a library class.
*
* @author Eric Lafortune
*/
public abstract class LibraryMember implements Member
{
private static final int ACC_VISIBLE = ClassConstants.INTERNAL_ACC_PUBLIC |
ClassConstants.INTERNAL_ACC_PROTECTED;
public int u2accessFlags;
public String name;
public String descriptor;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Creates an uninitialized LibraryMember.
*/
protected LibraryMember()
{
}
/**
* Creates an initialized LibraryMember.
*/
protected LibraryMember(int u2accessFlags,
String name,
String descriptor)
{
this.u2accessFlags = u2accessFlags;
this.name = name;
this.descriptor = descriptor;
}
/**
* Accepts the given member info visitor.
*/
public abstract void accept(LibraryClass libraryClass,
MemberVisitor memberVisitor);
// Implementations for Member.
public int getAccessFlags()
{
return u2accessFlags;
}
public String getName(Clazz clazz)
{
return name;
}
public String getDescriptor(Clazz clazz)
{
return descriptor;
}
public void accept(Clazz clazz, MemberVisitor memberVisitor)
{
accept((LibraryClass)clazz, memberVisitor);
}
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
}
proguard4.8/src/proguard/classfile/util/ 0000775 0001750 0001750 00000000000 11760503005 017114 5 ustar eric eric proguard4.8/src/proguard/classfile/util/package.html 0000644 0001750 0001750 00000000121 11736333524 021377 0 ustar eric eric
This package contains utility classes for processing class files.
proguard4.8/src/proguard/classfile/util/MemberFinder.java 0000644 0001750 0001750 00000013473 11736333524 022336 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.visitor.*;
/**
* This class provides methods to find class members in a given class or in its
* hierarchy.
*
* @author Eric Lafortune
*/
public class MemberFinder
extends SimplifiedVisitor
implements MemberVisitor
{
private static class MemberFoundException extends RuntimeException {}
private static final MemberFoundException MEMBER_FOUND = new MemberFoundException();
private Clazz clazz;
private Member member;
/**
* Finds the field with the given name and descriptor in the given
* class or its hierarchy.
*/
public Field findField(Clazz referencingClass,
Clazz clazz,
String name,
String descriptor)
{
return (Field)findMember(referencingClass, clazz, name, descriptor, true);
}
/**
* Finds the method with the given name and descriptor in the given
* class or its hierarchy.
*/
public Method findMethod(Clazz referencingClass,
Clazz clazz,
String name,
String descriptor)
{
return (Method)findMember(referencingClass, clazz, name, descriptor, false);
}
/**
* Finds the class member with the given name and descriptor in the given
* class or its hierarchy.
*/
public Member findMember(Clazz referencingClass,
Clazz clazz,
String name,
String descriptor,
boolean isField)
{
// Organize a search in the hierarchy of superclasses and interfaces.
// The class member may be in a different class, if the code was
// compiled with "-target 1.2" or higher (the default in JDK 1.4).
try
{
this.clazz = null;
this.member = null;
clazz.hierarchyAccept(true, true, true, false, isField ?
(ClassVisitor)new NamedFieldVisitor(name, descriptor,
new MemberClassAccessFilter(referencingClass, this)) :
(ClassVisitor)new NamedMethodVisitor(name, descriptor,
new MemberClassAccessFilter(referencingClass, this)));
}
catch (MemberFoundException ex)
{
// We've found the member we were looking for.
}
return member;
}
/**
* Returns the corresponding class of the most recently found class
* member.
*/
public Clazz correspondingClass()
{
return clazz;
}
/**
* Returns whether the given method is overridden anywhere down the class
* hierarchy.
*/
public boolean isOverriden(Clazz clazz,
Method method)
{
String name = method.getName(clazz);
String descriptor = method.getDescriptor(clazz);
// Go looking for the method down the class hierarchy.
try
{
this.clazz = null;
this.member = null;
clazz.hierarchyAccept(false, false, false, true,
new NamedMethodVisitor(name, descriptor,
new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, this)));
}
catch (MemberFoundException ex)
{
// We've found an overriding method.
return true;
}
return false;
}
/**
* Returns whether the given field is shadowed anywhere down the class
* hierarchy.
*/
public boolean isShadowed(Clazz clazz,
Field field)
{
String name = field.getName(clazz);
String descriptor = field.getDescriptor(clazz);
// Go looking for the field down the class hierarchy.
try
{
this.clazz = null;
this.member = null;
clazz.hierarchyAccept(false, false, false, true,
new NamedFieldVisitor(name, descriptor,
new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, this)));
}
catch (MemberFoundException ex)
{
// We've found a shadowing field.
return true;
}
return false;
}
// // Implementations for ClassVisitor.
//
// private void visitAnyClass(Clazz clazz)
// {
// if (member == null)
// {
// member = isField ?
// (Member)clazz.findField(name, descriptor) :
// (Member)clazz.findMethod(name, descriptor);
//
// if (member != null)
// {
// this.clazz = clazz;
// }
// }
// }
// Implementations for MemberVisitor.
public void visitAnyMember(Clazz clazz, Member member)
{
this.clazz = clazz;
this.member = member;
throw MEMBER_FOUND;
}
}
proguard4.8/src/proguard/classfile/util/InstructionSequenceMatcher.java 0000644 0001750 0001750 00000063450 11736333524 025315 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.constant.*;
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
* instruction sequence can be wildcards that are matched.
*
* @author Eric Lafortune
*/
public class InstructionSequenceMatcher
extends SimplifiedVisitor
implements InstructionVisitor,
ConstantVisitor
{
/*
public static boolean DEBUG = true;
public static boolean DEBUG_MORE = true;
/*/
private static final boolean DEBUG = false;
private static final boolean DEBUG_MORE = false;
//*/
public static final int X = 0x40000000;
public static final int Y = 0x40000001;
public static final int Z = 0x40000002;
public static final int A = 0x40000003;
public static final int B = 0x40000004;
public static final int C = 0x40000005;
public static final int D = 0x40000006;
private final Constant[] patternConstants;
private final Instruction[] patternInstructions;
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;
private boolean matchingConstant;
/**
* Creates a new InstructionSequenceMatcher.
* @param patternConstants any constants referenced by the pattern
* instruction.
* @param patternInstructions the pattern instruction sequence.
*/
public InstructionSequenceMatcher(Constant[] patternConstants,
Instruction[] patternInstructions)
{
this.patternConstants = patternConstants;
this.patternInstructions = patternInstructions;
matchedInstructionOffsets = new int[patternInstructions.length];
matchedConstantFlags = new long[(patternConstants.length + 63) / 64];
matchedConstantIndices = new int[patternConstants.length];
}
/**
* Starts matching from the first instruction again next time.
*/
public void reset()
{
patternInstructionIndex = 0;
matchedArgumentFlags = 0;
Arrays.fill(matchedConstantFlags, 0L);
previousConstantFlags = constantFlags;
constantFlags = 0;
}
/**
* Returns whether the complete pattern sequence has been matched.
*/
public boolean isMatching()
{
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;
return argumentIndex < 0 ?
argument :
matchedArguments[argumentIndex];
}
/**
* Returns the values of the specified matched arguments (wildcard or not).
*/
public int[] matchedArguments(int[] arguments)
{
int[] matchedArguments = new int[arguments.length];
for (int index = 0; index < arguments.length; index++)
{
matchedArguments[index] = matchedArgument(arguments[index]);
}
return matchedArguments;
}
/**
* Returns the index of the specified matched constant (wildcard or not).
*/
public int matchedConstantIndex(int constantIndex)
{
int argumentIndex = constantIndex - X;
return argumentIndex < 0 ?
matchedConstantIndices[constantIndex] :
matchedArguments[argumentIndex];
}
/**
* Returns the value of the specified matched branch offset (wildcard or
* not).
*/
public int matchedBranchOffset(int offset, int branchOffset)
{
int argumentIndex = branchOffset - X;
return argumentIndex < 0 ?
branchOffset :
matchedArguments[argumentIndex] - offset;
}
/**
* 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];
for (int index = 0; index < jumpOffsets.length; index++)
{
matchedJumpOffsets[index] = matchedBranchOffset(offset,
jumpOffsets[index]);
}
return matchedJumpOffsets;
}
// Implementations for InstructionVisitor.
public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
{
Instruction patternInstruction = patternInstructions[patternInstructionIndex];
// Check if the instruction matches the next instruction in the sequence.
boolean condition =
matchingOpcodes(simpleInstruction, patternInstruction) &&
matchingArguments(simpleInstruction.constant,
((SimpleInstruction)patternInstruction).constant);
// Check if the instruction sequence is matching now.
checkMatch(condition,
clazz,
method,
codeAttribute,
offset,
simpleInstruction);
}
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
{
Instruction patternInstruction = patternInstructions[patternInstructionIndex];
// Check if the instruction matches the next instruction in the sequence.
boolean condition =
matchingOpcodes(variableInstruction, patternInstruction) &&
matchingArguments(variableInstruction.variableIndex,
((VariableInstruction)patternInstruction).variableIndex) &&
matchingArguments(variableInstruction.constant,
((VariableInstruction)patternInstruction).constant);
// Check if the instruction sequence is matching now.
checkMatch(condition,
clazz,
method,
codeAttribute,
offset,
variableInstruction);
}
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
Instruction patternInstruction = patternInstructions[patternInstructionIndex];
// Check if the instruction matches the next instruction in the sequence.
boolean condition =
matchingOpcodes(constantInstruction, patternInstruction) &&
matchingConstantIndices(clazz,
constantInstruction.constantIndex,
((ConstantInstruction)patternInstruction).constantIndex) &&
matchingArguments(constantInstruction.constant,
((ConstantInstruction)patternInstruction).constant);
// Check if the instruction sequence is matching now.
checkMatch(condition,
clazz,
method,
codeAttribute,
offset,
constantInstruction);
}
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
{
Instruction patternInstruction = patternInstructions[patternInstructionIndex];
// Check if the instruction matches the next instruction in the from
// sequence.
boolean condition =
matchingOpcodes(branchInstruction, patternInstruction) &&
matchingBranchOffsets(offset,
branchInstruction.branchOffset,
((BranchInstruction)patternInstruction).branchOffset);
// Check if the instruction sequence is matching now.
checkMatch(condition,
clazz,
method,
codeAttribute,
offset,
branchInstruction);
}
public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)
{
Instruction patternInstruction = patternInstructions[patternInstructionIndex];
// Check if the instruction matches the next instruction in the sequence.
boolean condition =
matchingOpcodes(tableSwitchInstruction, patternInstruction) &&
matchingBranchOffsets(offset,
tableSwitchInstruction.defaultOffset,
((TableSwitchInstruction)patternInstruction).defaultOffset) &&
matchingArguments(tableSwitchInstruction.lowCase,
((TableSwitchInstruction)patternInstruction).lowCase) &&
matchingArguments(tableSwitchInstruction.highCase,
((TableSwitchInstruction)patternInstruction).highCase) &&
matchingJumpOffsets(offset,
tableSwitchInstruction.jumpOffsets,
((TableSwitchInstruction)patternInstruction).jumpOffsets);
// Check if the instruction sequence is matching now.
checkMatch(condition,
clazz,
method,
codeAttribute,
offset,
tableSwitchInstruction);
}
public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
{
Instruction patternInstruction = patternInstructions[patternInstructionIndex];
// Check if the instruction matches the next instruction in the sequence.
boolean condition =
matchingOpcodes(lookUpSwitchInstruction, patternInstruction) &&
matchingBranchOffsets(offset,
lookUpSwitchInstruction.defaultOffset,
((LookUpSwitchInstruction)patternInstruction).defaultOffset) &&
matchingArguments(lookUpSwitchInstruction.cases,
((LookUpSwitchInstruction)patternInstruction).cases) &&
matchingJumpOffsets(offset,
lookUpSwitchInstruction.jumpOffsets,
((LookUpSwitchInstruction)patternInstruction).jumpOffsets);
// Check if the instruction sequence is matching now.
checkMatch(condition,
clazz,
method,
codeAttribute,
offset,
lookUpSwitchInstruction);
}
// Implementations for ConstantVisitor.
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
IntegerConstant integerPatternConstant = (IntegerConstant)patternConstant;
// Compare the integer values.
matchingConstant = integerConstant.getValue() ==
integerPatternConstant.getValue();
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
LongConstant longPatternConstant = (LongConstant)patternConstant;
// Compare the long values.
matchingConstant = longConstant.getValue() ==
longPatternConstant.getValue();
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
FloatConstant floatPatternConstant = (FloatConstant)patternConstant;
// Compare the float values.
matchingConstant = floatConstant.getValue() ==
floatPatternConstant.getValue();
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
DoubleConstant doublePatternConstant = (DoubleConstant)patternConstant;
// Compare the double values.
matchingConstant = doubleConstant.getValue() ==
doublePatternConstant.getValue();
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
StringConstant stringPatternConstant = (StringConstant)patternConstant;
// Check the UTF-8 constant.
matchingConstant =
matchingConstantIndices(clazz,
stringConstant.u2stringIndex,
stringPatternConstant.u2stringIndex);
}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
Utf8Constant utf8PatternConstant = (Utf8Constant)patternConstant;
// Compare the actual strings.
matchingConstant = utf8Constant.getString().equals(
utf8PatternConstant.getString());
}
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;
// Check the class and the name and type.
matchingConstant =
matchingConstantIndices(clazz,
refConstant.getClassIndex(),
refPatternConstant.getClassIndex()) &&
matchingConstantIndices(clazz,
refConstant.getNameAndTypeIndex(),
refPatternConstant.getNameAndTypeIndex());
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
ClassConstant classPatternConstant = (ClassConstant)patternConstant;
// Check the class name.
matchingConstant =
matchingConstantIndices(clazz,
classConstant.u2nameIndex,
classPatternConstant.u2nameIndex);
}
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;
// Check the name and the descriptor.
matchingConstant =
matchingConstantIndices(clazz,
nameAndTypeConstant.u2nameIndex,
typePatternConstant.u2nameIndex) &&
matchingConstantIndices(clazz,
nameAndTypeConstant.u2descriptorIndex,
typePatternConstant.u2descriptorIndex);
}
// Small utility methods.
private boolean matchingOpcodes(Instruction instruction1,
Instruction instruction2)
{
// Check the opcode.
return instruction1.opcode == instruction2.opcode ||
instruction1.canonicalOpcode() == instruction2.opcode;
}
private boolean matchingArguments(int argument1,
int argument2)
{
int argumentIndex = argument2 - X;
if (argumentIndex < 0)
{
// Check the literal argument.
return argument1 == argument2;
}
else if (!isMatchingArgumentIndex(argumentIndex))
{
// Store the wildcard argument.
setMatchingArgument(argumentIndex, argument1);
return true;
}
else
{
// Check the previously stored wildcard argument.
return matchedArguments[argumentIndex] == argument1;
}
}
/**
* 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)
{
if (arguments1.length != arguments2.length)
{
return false;
}
for (int index = 0; index < arguments1.length; index++)
{
if (!matchingArguments(arguments1[index], arguments2[index]))
{
return false;
}
}
return true;
}
private boolean matchingConstantIndices(Clazz clazz,
int constantIndex1,
int constantIndex2)
{
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 (!isMatchingConstantIndex(constantIndex2))
{
// Check the actual constant.
matchingConstant = false;
patternConstant = patternConstants[constantIndex2];
if (clazz.getTag(constantIndex1) == patternConstant.getTag())
{
clazz.constantPoolEntryAccept(constantIndex1, this);
if (matchingConstant)
{
// Store the constant index.
setMatchingConstant(constantIndex2, constantIndex1);
}
}
return matchingConstant;
}
else
{
// Check a previously stored constant index.
return matchedConstantIndices[constantIndex2] == constantIndex1;
}
}
/**
* 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)
{
int argumentIndex = branchOffset2 - X;
if (argumentIndex < 0)
{
// Check the literal argument.
return branchOffset1 == branchOffset2;
}
else if (!isMatchingArgumentIndex(argumentIndex))
{
// Store a wildcard argument.
setMatchingArgument(argumentIndex, offset + branchOffset1);
return true;
}
else
{
// Check the previously stored wildcard argument.
return matchedArguments[argumentIndex] == offset + branchOffset1;
}
}
private boolean matchingJumpOffsets(int offset,
int[] jumpOffsets1,
int[] jumpOffsets2)
{
if (jumpOffsets1.length != jumpOffsets2.length)
{
return false;
}
for (int index = 0; index < jumpOffsets1.length; index++)
{
if (!matchingBranchOffsets(offset,
jumpOffsets1[index],
jumpOffsets2[index]))
{
return false;
}
}
return true;
}
private void checkMatch(boolean condition,
Clazz clazz,
Method method,
CodeAttribute codeAttribute,
int offset,
Instruction instruction)
{
if (DEBUG_MORE)
{
System.out.println("InstructionSequenceMatcher: ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"]: "+patternInstructions[patternInstructionIndex].toString(patternInstructionIndex)+(condition?"\t== ":"\t ")+instruction.toString(offset));
}
// Did the instruction match?
if (condition)
{
// Remember the offset of the matching instruction.
matchedInstructionOffsets[patternInstructionIndex] = offset;
// Try to match the next instruction next time.
patternInstructionIndex++;
// Did we match all instructions in the sequence?
matching = patternInstructionIndex == patternInstructions.length;
if (matching)
{
if (DEBUG)
{
System.out.println("InstructionSequenceMatcher: ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"]");
for (int index = 0; index < patternInstructionIndex; index++)
{
System.out.println(" "+InstructionFactory.create(codeAttribute.code, matchedInstructionOffsets[index]).toString(matchedInstructionOffsets[index]));
}
}
// Start matching from the first instruction again next time.
reset();
}
}
else
{
// The instruction didn't match.
matching = false;
// Is this a failed second instruction?
boolean retry = patternInstructionIndex == 1;
// Start matching from the first instruction next time.
reset();
// Retry a failed second instruction as a first instruction.
if (retry)
{
instruction.accept(clazz, method, codeAttribute, offset, this);
}
}
}
}
proguard4.8/src/proguard/classfile/util/AccessUtil.java 0000644 0001750 0001750 00000007537 11736333524 022042 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.ClassConstants;
/**
* Utility methods for working with access flags. For convenience, this class
* defines access levels, in ascending order: PRIVATE
,
* PACKAGE_VISIBLE
, PROTECTED
, and PUBLIC
.
*
* @author Eric Lafortune
*/
public class AccessUtil
{
public static final int PRIVATE = 0;
public static final int PACKAGE_VISIBLE = 1;
public static final int PROTECTED = 2;
public static final int PUBLIC = 3;
// The mask of access flags.
private static final int ACCESS_MASK =
ClassConstants.INTERNAL_ACC_PUBLIC |
ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_PROTECTED;
/**
* Returns the corresponding access level of the given access flags.
* @param accessFlags the internal access flags.
* @return the corresponding access level: PRIVATE
,
* PACKAGE_VISIBLE
, PROTECTED
, or
* PUBLIC
.
*/
public static int accessLevel(int accessFlags)
{
switch (accessFlags & ACCESS_MASK)
{
case ClassConstants.INTERNAL_ACC_PRIVATE: return PRIVATE;
default: return PACKAGE_VISIBLE;
case ClassConstants.INTERNAL_ACC_PROTECTED: return PROTECTED;
case ClassConstants.INTERNAL_ACC_PUBLIC: return PUBLIC;
}
}
/**
* Returns the corresponding access flags of the given access level.
* @param accessLevel the access level: PRIVATE
,
* PACKAGE_VISIBLE
, PROTECTED
,
* or PUBLIC
.
* @return the corresponding internal access flags, the internal access
* flags as a logical bit mask of INTERNAL_ACC_PRIVATE
,
* INTERNAL_ACC_PROTECTED
, and
* INTERNAL_ACC_PUBLIC
.
*/
public static int accessFlags(int accessLevel)
{
switch (accessLevel)
{
case PRIVATE: return ClassConstants.INTERNAL_ACC_PRIVATE;
default: return 0;
case PROTECTED: return ClassConstants.INTERNAL_ACC_PROTECTED;
case PUBLIC: return ClassConstants.INTERNAL_ACC_PUBLIC;
}
}
/**
* Replaces the access part of the given access flags.
* @param accessFlags the internal access flags.
* @param accessFlags the new internal access flags.
*/
public static int replaceAccessFlags(int accessFlags, int newAccessFlags)
{
// A private class member should not be explicitly final.
if (newAccessFlags == ClassConstants.INTERNAL_ACC_PRIVATE)
{
accessFlags &= ~ClassConstants.INTERNAL_ACC_FINAL;
}
return (accessFlags & ~ACCESS_MASK) |
(newAccessFlags & ACCESS_MASK);
}
}
proguard4.8/src/proguard/classfile/util/ClassReferenceInitializer.java 0000644 0001750 0001750 00000051535 11736333524 025070 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.annotation.visitor.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.visitor.*;
/**
* This ClassVisitor initializes the references of all classes that
* it visits.
* * All class constant pool entries get direct references to the corresponding * classes. These references make it more convenient to travel up and across * the class hierarchy. *
* All field and method reference constant pool entries get direct references * to the corresponding classes, fields, and methods. *
* All name and type constant pool entries get a list of direct references to * the classes listed in the type. *
* This visitor optionally prints warnings if some items can't be found. *
* The class hierarchy must be initialized before using this visitor.
*
* @author Eric Lafortune
*/
public class ClassReferenceInitializer
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
ConstantVisitor,
AttributeVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
ElementValueVisitor
{
private final ClassPool programClassPool;
private final ClassPool libraryClassPool;
private final WarningPrinter missingClassWarningPrinter;
private final WarningPrinter missingMemberWarningPrinter;
private final WarningPrinter dependencyWarningPrinter;
private final MemberFinder memberFinder = new MemberFinder();
/**
* Creates a new ClassReferenceInitializer that initializes the references
* of all visited class files, optionally printing warnings if some classes
* or class members can't be found or if they are in the program class pool.
*/
public ClassReferenceInitializer(ClassPool programClassPool,
ClassPool libraryClassPool,
WarningPrinter missingClassWarningPrinter,
WarningPrinter missingMemberWarningPrinter,
WarningPrinter dependencyWarningPrinter)
{
this.programClassPool = programClassPool;
this.libraryClassPool = libraryClassPool;
this.missingClassWarningPrinter = missingClassWarningPrinter;
this.missingMemberWarningPrinter = missingMemberWarningPrinter;
this.dependencyWarningPrinter = dependencyWarningPrinter;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Initialize the constant pool entries.
programClass.constantPoolEntriesAccept(this);
// Initialize all fields and methods.
programClass.fieldsAccept(this);
programClass.methodsAccept(this);
// Initialize the attributes.
programClass.attributesAccept(this);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Initialize all fields and methods.
libraryClass.fieldsAccept(this);
libraryClass.methodsAccept(this);
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
programField.referencedClass =
findReferencedClass(programClass.getName(),
programField.getDescriptor(programClass));
// Initialize the attributes.
programField.attributesAccept(programClass, this);
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
programMethod.referencedClasses =
findReferencedClasses(programClass.getName(),
programMethod.getDescriptor(programClass));
// Initialize the attributes.
programMethod.attributesAccept(programClass, this);
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
libraryField.referencedClass =
findReferencedClass(libraryClass.getName(),
libraryField.getDescriptor(libraryClass));
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
libraryMethod.referencedClasses =
findReferencedClasses(libraryClass.getName(),
libraryMethod.getDescriptor(libraryClass));
}
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant) {}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
// Fill out the String class.
stringConstant.javaLangStringClass =
findClass(clazz.getName(), ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING);
}
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)
{
String name = refConstant.getName(clazz);
String type = refConstant.getType(clazz);
boolean isFieldRef = refConstant.getTag() == ClassConstants.CONSTANT_Fieldref;
// See if we can find the referenced class member somewhere in the
// hierarchy.
refConstant.referencedMember = memberFinder.findMember(clazz,
referencedClass,
name,
type,
isFieldRef);
refConstant.referencedClass = memberFinder.correspondingClass();
if (refConstant.referencedMember == null)
{
// We haven't found the class member anywhere in the hierarchy.
missingMemberWarningPrinter.print(clazz.getName(),
className,
"Warning: " +
ClassUtil.externalClassName(clazz.getName()) +
": can't find referenced " +
(isFieldRef ?
"field '" + ClassUtil.externalFullFieldDescription(0, name, type) :
"method '" + ClassUtil.externalFullMethodDescription(className, 0, name, type)) +
"' in class " +
ClassUtil.externalClassName(className));
}
}
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
String className = clazz.getName();
// Fill out the referenced class.
classConstant.referencedClass =
findClass(className, ClassUtil.internalClassNameFromClassType(classConstant.getName(clazz)));
// Fill out the Class class.
classConstant.javaLangClassClass =
findClass(className, ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS);
}
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) {}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
String className = clazz.getName();
String enclosingClassName = enclosingMethodAttribute.getClassName(clazz);
// See if we can find the referenced class.
enclosingMethodAttribute.referencedClass =
findClass(className, enclosingClassName);
if (enclosingMethodAttribute.referencedClass != null)
{
// 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.
enclosingMethodAttribute.referencedMethod =
enclosingMethodAttribute.referencedClass.findMethod(name, type);
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));
}
}
}
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
// Initialize the nested attributes.
codeAttribute.attributesAccept(clazz, method, this);
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
// Initialize the local variables.
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
// Initialize the local variable types.
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
signatureAttribute.referencedClasses =
findReferencedClasses(clazz.getName(),
clazz.getString(signatureAttribute.u2signatureIndex));
}
public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
{
// Initialize the annotations.
annotationsAttribute.annotationsAccept(clazz, this);
}
public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
{
// Initialize the annotations.
parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
// Initialize the annotation.
annotationDefaultAttribute.defaultValueAccept(clazz, this);
}
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
localVariableInfo.referencedClass =
findReferencedClass(clazz.getName(),
clazz.getString(localVariableInfo.u2descriptorIndex));
}
// Implementations for LocalVariableTypeInfoVisitor.
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
localVariableTypeInfo.referencedClasses =
findReferencedClasses(clazz.getName(),
clazz.getString(localVariableTypeInfo.u2signatureIndex));
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
annotation.referencedClasses =
findReferencedClasses(clazz.getName(),
clazz.getString(annotation.u2typeIndex));
// Initialize the element values.
annotation.elementValuesAccept(clazz, this);
}
// Implementations for ElementValueVisitor.
public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
{
initializeElementValue(clazz, annotation, constantElementValue);
}
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
{
initializeElementValue(clazz, annotation, enumConstantElementValue);
enumConstantElementValue.referencedClasses =
findReferencedClasses(clazz.getName(),
clazz.getString(enumConstantElementValue.u2typeNameIndex));
}
public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
{
initializeElementValue(clazz, annotation, classElementValue);
classElementValue.referencedClasses =
findReferencedClasses(clazz.getName(),
clazz.getString(classElementValue.u2classInfoIndex));
}
public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
{
initializeElementValue(clazz, annotation, annotationElementValue);
// Initialize the annotation.
annotationElementValue.annotationAccept(clazz, this);
}
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
initializeElementValue(clazz, annotation, arrayElementValue);
// Initialize the element values.
arrayElementValue.elementValuesAccept(clazz, annotation, this);
}
/**
* Initializes the referenced method of an element value, if any.
*/
private void initializeElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
{
// See if we have a referenced class.
if (annotation != null &&
annotation.referencedClasses != null &&
elementValue.u2elementNameIndex != 0)
{
// See if we can find the method in the referenced class
// (ignoring the descriptor).
String name = clazz.getString(elementValue.u2elementNameIndex);
Clazz referencedClass = annotation.referencedClasses[0];
elementValue.referencedClass = referencedClass;
elementValue.referencedMethod = referencedClass.findMethod(name, null);
}
}
// Small utility methods.
/**
* Returns the single class referenced by the given descriptor, or
* null
if there isn't any useful reference.
*/
private Clazz findReferencedClass(String referencingClassName,
String descriptor)
{
DescriptorClassEnumeration enumeration =
new DescriptorClassEnumeration(descriptor);
enumeration.nextFluff();
if (enumeration.hasMoreClassNames())
{
return findClass(referencingClassName, enumeration.nextClassName());
}
return null;
}
/**
* Returns an array of classes referenced by the given descriptor, or
* null
if there aren't any useful references.
*/
private Clazz[] findReferencedClasses(String referencingClassName,
String descriptor)
{
DescriptorClassEnumeration enumeration =
new DescriptorClassEnumeration(descriptor);
int classCount = enumeration.classCount();
if (classCount > 0)
{
Clazz[] referencedClasses = new Clazz[classCount];
boolean foundReferencedClasses = false;
for (int index = 0; index < classCount; index++)
{
String fluff = enumeration.nextFluff();
String name = enumeration.nextClassName();
Clazz referencedClass = findClass(referencingClassName, name);
if (referencedClass != null)
{
referencedClasses[index] = referencedClass;
foundReferencedClasses = true;
}
}
if (foundReferencedClasses)
{
return referencedClasses;
}
}
return null;
}
/**
* Returns the class with the given name, either for the program class pool
* or from the library class pool, or null
if it can't be found.
*/
private Clazz findClass(String referencingClassName, String name)
{
// Is it an array type?
if (ClassUtil.isInternalArrayType(name))
{
// 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.
Clazz clazz = programClassPool.getClass(name);
// Otherwise look for the class in the library class pool.
if (clazz == null)
{
clazz = libraryClassPool.getClass(name);
if (clazz == null &&
missingClassWarningPrinter != null)
{
// We didn't find the superclass or interface. Print a warning.
missingClassWarningPrinter.print(referencingClassName,
name,
"Warning: " +
ClassUtil.externalClassName(referencingClassName) +
": can't find referenced class " +
ClassUtil.externalClassName(name));
}
}
else if (dependencyWarningPrinter != null)
{
// The superclass or interface was found in the program class pool.
// Print a warning.
dependencyWarningPrinter.print(referencingClassName,
name,
"Warning: library class " +
ClassUtil.externalClassName(referencingClassName) +
" depends on program class " +
ClassUtil.externalClassName(name));
}
return clazz;
}
}
proguard4.8/src/proguard/classfile/util/ClassUtil.java 0000664 0001750 0001750 00000145632 11740606107 021702 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.ClassConstants;
import java.util.List;
/**
* Utility methods for converting between internal and external representations
* of names and descriptions.
*
* @author Eric Lafortune
*/
public class ClassUtil
{
private static final String EMPTY_STRING = "";
/**
* Checks whether the given class magic number is correct.
* @param magicNumber the magic number.
* @throws UnsupportedOperationException when the magic number is incorrect.
*/
public static void checkMagicNumber(int magicNumber) throws UnsupportedOperationException
{
if (magicNumber != ClassConstants.MAGIC)
{
throw new UnsupportedOperationException("Invalid magic number ["+Integer.toHexString(magicNumber)+"] in class");
}
}
/**
* Returns the combined class version number.
* @param majorVersion the major part of the class version number.
* @param minorVersion the minor part of the class version number.
* @return the combined class version number.
*/
public static int internalClassVersion(int majorVersion, int minorVersion)
{
return (majorVersion << 16) | minorVersion;
}
/**
* Returns the major part of the given class version number.
* @param classVersion the combined class version number.
* @return the major part of the class version number.
*/
public static int internalMajorClassVersion(int classVersion)
{
return classVersion >>> 16;
}
/**
* Returns the internal class version number.
* @param classVersion the external class version number.
* @return the internal class version number.
*/
public static int internalMinorClassVersion(int classVersion)
{
return classVersion & 0xffff;
}
/**
* Returns the internal class version number.
* @param classVersion the external class version number.
* @return the internal class version number.
*/
public static int internalClassVersion(String classVersion)
{
return
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_0) ||
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_1) ? ClassConstants.INTERNAL_CLASS_VERSION_1_0 :
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_2) ? ClassConstants.INTERNAL_CLASS_VERSION_1_2 :
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_3) ? ClassConstants.INTERNAL_CLASS_VERSION_1_3 :
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_4) ? ClassConstants.INTERNAL_CLASS_VERSION_1_4 :
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_5_ALIAS) ||
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;
}
/**
* Returns the minor part of the given class version number.
* @param classVersion the combined class version number.
* @return the minor part of the class version number.
*/
public static String externalClassVersion(int classVersion)
{
switch (classVersion)
{
case ClassConstants.INTERNAL_CLASS_VERSION_1_0: return ClassConstants.EXTERNAL_CLASS_VERSION_1_0;
case ClassConstants.INTERNAL_CLASS_VERSION_1_2: return ClassConstants.EXTERNAL_CLASS_VERSION_1_2;
case ClassConstants.INTERNAL_CLASS_VERSION_1_3: return ClassConstants.EXTERNAL_CLASS_VERSION_1_3;
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;
}
}
/**
* Checks whether the given class version number is supported.
* @param classVersion the combined class version number.
* @throws UnsupportedOperationException when the version is not supported.
*/
public static void checkVersionNumbers(int classVersion) throws UnsupportedOperationException
{
if (classVersion < ClassConstants.INTERNAL_CLASS_VERSION_1_0 ||
classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_7)
{
throw new UnsupportedOperationException("Unsupported class version number ["+
internalMajorClassVersion(classVersion)+"."+
internalMinorClassVersion(classVersion)+"] (maximum "+
ClassConstants.INTERNAL_CLASS_VERSION_1_7_MAJOR+"."+
ClassConstants.INTERNAL_CLASS_VERSION_1_7_MINOR+", Java "+
ClassConstants.EXTERNAL_CLASS_VERSION_1_7+")");
}
}
/**
* Converts an external class name into an internal class name.
* @param externalClassName the external class name,
* e.g. "java.lang.Object
"
* @return the internal class name,
* e.g. "java/lang/Object
".
*/
public static String internalClassName(String externalClassName)
{
return externalClassName.replace(ClassConstants.EXTERNAL_PACKAGE_SEPARATOR,
ClassConstants.INTERNAL_PACKAGE_SEPARATOR);
}
/**
* Converts an internal class description into an external class description.
* @param accessFlags the access flags of the class.
* @param internalClassName the internal class name,
* e.g. "java/lang/Object
".
* @return the external class description,
* e.g. "public java.lang.Object
".
*/
public static String externalFullClassDescription(int accessFlags,
String internalClassName)
{
return externalClassAccessFlags(accessFlags) +
externalClassName(internalClassName);
}
/**
* Converts an internal class name into an external class name.
* @param internalClassName the internal class name,
* e.g. "java/lang/Object
".
* @return the external class name,
* e.g. "java.lang.Object
".
*/
public static String externalClassName(String internalClassName)
{
return //internalClassName.startsWith(ClassConstants.INTERNAL_PACKAGE_JAVA_LANG) &&
//internalClassName.indexOf(ClassConstants.INTERNAL_PACKAGE_SEPARATOR, ClassConstants.INTERNAL_PACKAGE_JAVA_LANG.length() + 1) < 0 ?
//internalClassName.substring(ClassConstants.INTERNAL_PACKAGE_JAVA_LANG.length()) :
internalClassName.replace(ClassConstants.INTERNAL_PACKAGE_SEPARATOR,
ClassConstants.EXTERNAL_PACKAGE_SEPARATOR);
}
/**
* Returns the external base type of an external array type, dropping any
* array brackets.
* @param externalArrayType the external array type,
* e.g. "java.lang.Object[][]
"
* @return the external base type,
* e.g. "java.lang.Object
".
*/
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. "java.lang.Object
"
* @return the external short class name,
* e.g. "Object
".
*/
public static String externalShortClassName(String externalClassName)
{
int index = externalClassName.lastIndexOf(ClassConstants.EXTERNAL_PACKAGE_SEPARATOR);
return externalClassName.substring(index+1);
}
/**
* Returns whether the given internal type is an array type.
* @param internalType the internal type,
* e.g. "[[Ljava/lang/Object;
".
* @return true
if the given type is an array type,
* false
otherwise.
*/
public static boolean isInternalArrayType(String internalType)
{
return internalType.length() > 1 &&
internalType.charAt(0) == ClassConstants.INTERNAL_TYPE_ARRAY;
}
/**
* Returns the number of dimensions of the given internal type.
* @param internalType the internal type,
* e.g. "[[Ljava/lang/Object;
".
* @return the number of dimensions, e.g. 2.
*/
public static int internalArrayTypeDimensionCount(String internalType)
{
int dimensions = 0;
while (internalType.charAt(dimensions) == ClassConstants.INTERNAL_TYPE_ARRAY)
{
dimensions++;
}
return dimensions;
}
/**
* Returns whether the given internal class name is one of the interfaces
* that is implemented by all array types. These class names are
* "java/lang/Object
", "java/lang/Cloneable
", and
* "java/io/Serializable
"
* @param internalClassName the internal class name,
* e.g. "java/lang/Object
".
* @return true
if the given type is an array interface name,
* false
otherwise.
*/
public static boolean isInternalArrayInterfaceName(String internalClassName)
{
return ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT.equals(internalClassName) ||
ClassConstants.INTERNAL_NAME_JAVA_LANG_CLONEABLE.equals(internalClassName) ||
ClassConstants.INTERNAL_NAME_JAVA_IO_SERIALIZABLE.equals(internalClassName);
}
/**
* Returns whether the given internal type is a plain primitive type
* (not void).
* @param internalType the internal type,
* e.g. "I
".
* @return true
if the given type is a class type,
* false
otherwise.
*/
public static boolean isInternalPrimitiveType(char internalType)
{
return internalType == ClassConstants.INTERNAL_TYPE_BOOLEAN ||
internalType == ClassConstants.INTERNAL_TYPE_BYTE ||
internalType == ClassConstants.INTERNAL_TYPE_CHAR ||
internalType == ClassConstants.INTERNAL_TYPE_SHORT ||
internalType == ClassConstants.INTERNAL_TYPE_INT ||
internalType == ClassConstants.INTERNAL_TYPE_FLOAT ||
internalType == ClassConstants.INTERNAL_TYPE_LONG ||
internalType == ClassConstants.INTERNAL_TYPE_DOUBLE;
}
/**
* Returns whether the given internal type is a primitive Category 2 type.
* @param internalType the internal type,
* e.g. "L
".
* @return true
if the given type is a Category 2 type,
* false
otherwise.
*/
public static boolean isInternalCategory2Type(String internalType)
{
return internalType.length() == 1 &&
(internalType.charAt(0) == ClassConstants.INTERNAL_TYPE_LONG ||
internalType.charAt(0) == ClassConstants.INTERNAL_TYPE_DOUBLE);
}
/**
* Returns whether the given internal type is a plain class type
* (including an array type of a plain class type).
* @param internalType the internal type,
* e.g. "Ljava/lang/Object;
".
* @return true
if the given type is a class type,
* false
otherwise.
*/
public static boolean isInternalClassType(String internalType)
{
int length = internalType.length();
return length > 1 &&
// internalType.charAt(0) == ClassConstants.INTERNAL_TYPE_CLASS_START &&
internalType.charAt(length-1) == ClassConstants.INTERNAL_TYPE_CLASS_END;
}
/**
* Returns the internal type of a given class name.
* @param internalClassName the internal class name,
* e.g. "java/lang/Object
".
* @return the internal type,
* e.g. "Ljava/lang/Object;
".
*/
public static String internalTypeFromClassName(String internalClassName)
{
return internalArrayTypeFromClassName(internalClassName, 0);
}
/**
* Returns the internal array type of a given class name with a given number
* of dimensions. If the number of dimensions is 0, the class name itself is
* returned.
* @param internalClassName the internal class name,
* e.g. "java/lang/Object
".
* @param dimensionCount the number of array dimensions.
* @return the internal array type of the array elements,
* e.g. "Ljava/lang/Object;
".
*/
public static String internalArrayTypeFromClassName(String internalClassName,
int dimensionCount)
{
StringBuffer buffer = new StringBuffer(internalClassName.length() + dimensionCount + 2);
for (int dimension = 0; dimension < dimensionCount; dimension++)
{
buffer.append(ClassConstants.INTERNAL_TYPE_ARRAY);
}
return buffer.append(ClassConstants.INTERNAL_TYPE_CLASS_START)
.append(internalClassName)
.append(ClassConstants.INTERNAL_TYPE_CLASS_END)
.toString();
}
/**
* Returns the internal element type of a given internal array type.
* @param internalArrayType the internal array type,
* e.g. "[[Ljava/lang/Object;
" or
* "[I
".
* @return the internal type of the array elements,
* e.g. "Ljava/lang/Object;
" or
* "I
".
*/
public static String internalTypeFromArrayType(String internalArrayType)
{
int index = internalArrayType.lastIndexOf(ClassConstants.INTERNAL_TYPE_ARRAY);
return internalArrayType.substring(index+1);
}
/**
* Returns the internal class name of a given internal class type
* (including an array type). Types involving primitive types are returned
* unchanged.
* @param internalClassType the internal class type,
* e.g. "[Ljava/lang/Object;
",
* "Ljava/lang/Object;
", or
* "java/lang/Object
".
* @return the internal class name,
* e.g. "java/lang/Object
".
*/
public static String internalClassNameFromClassType(String internalClassType)
{
return isInternalClassType(internalClassType) ?
internalClassType.substring(internalClassType.indexOf(ClassConstants.INTERNAL_TYPE_CLASS_START)+1,
internalClassType.length()-1) :
internalClassType;
}
/**
* Returns the internal class name of any given internal descriptor type,
* disregarding array prefixes.
* @param internalClassType the internal class type,
* e.g. "Ljava/lang/Object;
" or
* "[[I
".
* @return the internal class name,
* e.g. "java/lang/Object
" or
* null
.
*/
public static String internalClassNameFromType(String internalClassType)
{
if (!isInternalClassType(internalClassType))
{
return null;
}
// Is it an array type?
if (isInternalArrayType(internalClassType))
{
internalClassType = internalTypeFromArrayType(internalClassType);
}
return internalClassNameFromClassType(internalClassType);
}
/**
* Returns whether the given method name refers to a class initializer or
* an instance initializer.
* @param internalMethodName the internal method name,
* e.g. "<clinit>
".
* @return whether the method name refers to an initializer,
* e.g. true
.
*/
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. "(II)Z
".
* @return the internal return type,
* e.g. "Z
".
*/
public static String internalMethodReturnType(String internalMethodDescriptor)
{
int index = internalMethodDescriptor.indexOf(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE);
return internalMethodDescriptor.substring(index + 1);
}
/**
* Returns the number of parameters of the given internal method descriptor.
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "(ID)Z
".
* @return the number of parameters,
* e.g. 2.
*/
public static int internalMethodParameterCount(String internalMethodDescriptor)
{
InternalTypeEnumeration internalTypeEnumeration =
new InternalTypeEnumeration(internalMethodDescriptor);
int counter = 0;
while (internalTypeEnumeration.hasMoreTypes())
{
internalTypeEnumeration.nextType();
counter++;
}
return counter;
}
/**
* Returns the size taken up on the stack by the parameters of the given
* internal method descriptor. This accounts for long and double parameters
* taking up two entries.
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "(ID)Z
".
* @return the size taken up on the stack,
* e.g. 3.
*/
public static int internalMethodParameterSize(String internalMethodDescriptor)
{
return internalMethodParameterSize(internalMethodDescriptor, true);
}
/**
* Returns the size taken up on the stack by the parameters of the given
* internal method descriptor. This accounts for long and double parameters
* taking up two entries, and a non-static method taking up an additional
* entry.
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "(ID)Z
".
* @param accessFlags the access flags of the method,
* e.g. 0.
* @return the size taken up on the stack,
* e.g. 4.
*/
public static int internalMethodParameterSize(String internalMethodDescriptor,
int accessFlags)
{
return internalMethodParameterSize(internalMethodDescriptor,
(accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0);
}
/**
* Returns the size taken up on the stack by the parameters of the given
* internal method descriptor. This accounts for long and double parameters
* taking up two spaces, and a non-static method taking up an additional
* entry.
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "(ID)Z
".
* @param isStatic specifies whether the method is static,
* e.g. false.
* @return the size taken up on the stack,
* e.g. 4.
*/
public static int internalMethodParameterSize(String internalMethodDescriptor,
boolean isStatic)
{
InternalTypeEnumeration internalTypeEnumeration =
new InternalTypeEnumeration(internalMethodDescriptor);
int size = isStatic ? 0 : 1;
while (internalTypeEnumeration.hasMoreTypes())
{
String internalType = internalTypeEnumeration.nextType();
size += internalTypeSize(internalType);
}
return size;
}
/**
* Returns the size taken up on the stack by the given internal type.
* The size is 1, except for long and double types, for which it is 2,
* and for the void type, for which 0 is returned.
* @param internalType the internal type,
* e.g. "I
".
* @return the size taken up on the stack,
* e.g. 1.
*/
public static int internalTypeSize(String internalType)
{
if (internalType.length() == 1)
{
char internalPrimitiveType = internalType.charAt(0);
if (internalPrimitiveType == ClassConstants.INTERNAL_TYPE_LONG ||
internalPrimitiveType == ClassConstants.INTERNAL_TYPE_DOUBLE)
{
return 2;
}
else if (internalPrimitiveType == ClassConstants.INTERNAL_TYPE_VOID)
{
return 0;
}
}
return 1;
}
/**
* Converts an external type into an internal type.
* @param externalType the external type,
* e.g. "java.lang.Object[][]
" or
* "int[]
".
* @return the internal type,
* e.g. "[[Ljava/lang/Object;
" or
* "[I
".
*/
public static String internalType(String externalType)
{
// Strip the array part, if any.
int dimensionCount = externalArrayTypeDimensionCount(externalType);
if (dimensionCount > 0)
{
externalType = externalType.substring(0, externalType.length() - dimensionCount * ClassConstants.EXTERNAL_TYPE_ARRAY.length());
}
// Analyze the actual type part.
char internalTypeChar =
externalType.equals(ClassConstants.EXTERNAL_TYPE_VOID ) ?
ClassConstants.INTERNAL_TYPE_VOID :
externalType.equals(ClassConstants.EXTERNAL_TYPE_BOOLEAN) ?
ClassConstants.INTERNAL_TYPE_BOOLEAN :
externalType.equals(ClassConstants.EXTERNAL_TYPE_BYTE ) ?
ClassConstants.INTERNAL_TYPE_BYTE :
externalType.equals(ClassConstants.EXTERNAL_TYPE_CHAR ) ?
ClassConstants.INTERNAL_TYPE_CHAR :
externalType.equals(ClassConstants.EXTERNAL_TYPE_SHORT ) ?
ClassConstants.INTERNAL_TYPE_SHORT :
externalType.equals(ClassConstants.EXTERNAL_TYPE_INT ) ?
ClassConstants.INTERNAL_TYPE_INT :
externalType.equals(ClassConstants.EXTERNAL_TYPE_FLOAT ) ?
ClassConstants.INTERNAL_TYPE_FLOAT :
externalType.equals(ClassConstants.EXTERNAL_TYPE_LONG ) ?
ClassConstants.INTERNAL_TYPE_LONG :
externalType.equals(ClassConstants.EXTERNAL_TYPE_DOUBLE ) ?
ClassConstants.INTERNAL_TYPE_DOUBLE :
externalType.equals("%" ) ?
'%' :
(char)0;
String internalType =
internalTypeChar != 0 ? String.valueOf(internalTypeChar) :
ClassConstants.INTERNAL_TYPE_CLASS_START +
internalClassName(externalType) +
ClassConstants.INTERNAL_TYPE_CLASS_END;
// Prepend the array part, if any.
for (int count = 0; count < dimensionCount; count++)
{
internalType = ClassConstants.INTERNAL_TYPE_ARRAY + internalType;
}
return internalType;
}
/**
* Returns the number of dimensions of the given external type.
* @param externalType the external type,
* e.g. "[[Ljava/lang/Object;
".
* @return the number of dimensions, e.g. 2.
*/
public static int externalArrayTypeDimensionCount(String externalType)
{
int dimensions = 0;
int length = ClassConstants.EXTERNAL_TYPE_ARRAY.length();
int offset = externalType.length() - length;
while (externalType.regionMatches(offset,
ClassConstants.EXTERNAL_TYPE_ARRAY,
0,
length))
{
dimensions++;
offset -= length;
}
return dimensions;
}
/**
* Converts an internal type into an external type.
* @param internalType the internal type,
* e.g. "[[Ljava/lang/Object;
" or
* "[I
".
* @return the external type,
* e.g. "java.lang.Object[][]
" or
* "int[]
".
*/
public static String externalType(String internalType)
{
// Strip the array part, if any.
int dimensionCount = internalArrayTypeDimensionCount(internalType);
if (dimensionCount > 0)
{
internalType = internalType.substring(dimensionCount);
}
// Analyze the actual type part.
char internalTypeChar = internalType.charAt(0);
String externalType =
internalTypeChar == ClassConstants.INTERNAL_TYPE_VOID ?
ClassConstants.EXTERNAL_TYPE_VOID :
internalTypeChar == ClassConstants.INTERNAL_TYPE_BOOLEAN ?
ClassConstants.EXTERNAL_TYPE_BOOLEAN :
internalTypeChar == ClassConstants.INTERNAL_TYPE_BYTE ?
ClassConstants.EXTERNAL_TYPE_BYTE :
internalTypeChar == ClassConstants.INTERNAL_TYPE_CHAR ?
ClassConstants.EXTERNAL_TYPE_CHAR :
internalTypeChar == ClassConstants.INTERNAL_TYPE_SHORT ?
ClassConstants.EXTERNAL_TYPE_SHORT :
internalTypeChar == ClassConstants.INTERNAL_TYPE_INT ?
ClassConstants.EXTERNAL_TYPE_INT :
internalTypeChar == ClassConstants.INTERNAL_TYPE_FLOAT ?
ClassConstants.EXTERNAL_TYPE_FLOAT :
internalTypeChar == ClassConstants.INTERNAL_TYPE_LONG ?
ClassConstants.EXTERNAL_TYPE_LONG :
internalTypeChar == ClassConstants.INTERNAL_TYPE_DOUBLE ?
ClassConstants.EXTERNAL_TYPE_DOUBLE :
internalTypeChar == '%' ?
"%" :
internalTypeChar == ClassConstants.INTERNAL_TYPE_CLASS_START ?
externalClassName(internalType.substring(1, internalType.indexOf(ClassConstants.INTERNAL_TYPE_CLASS_END))) :
null;
if (externalType == null)
{
throw new IllegalArgumentException("Unknown type ["+internalType+"]");
}
// Append the array part, if any.
for (int count = 0; count < dimensionCount; count++)
{
externalType += ClassConstants.EXTERNAL_TYPE_ARRAY;
}
return externalType;
}
/**
* Returns whether the given internal descriptor String represents a method
* descriptor.
* @param internalDescriptor the internal descriptor String,
* e.g. "(II)Z
".
* @return true
if the given String is a method descriptor,
* false
otherwise.
*/
public static boolean isInternalMethodDescriptor(String internalDescriptor)
{
return internalDescriptor.charAt(0) == ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN;
}
/**
* Returns whether the given member String represents an external method
* name with arguments.
* @param externalMemberNameAndArguments the external member String,
* e.g. "myField
" or
* e.g. "myMethod(int,int)
".
* @return true
if the given String refers to a method,
* false
otherwise.
*/
public static boolean isExternalMethodNameAndArguments(String externalMemberNameAndArguments)
{
return externalMemberNameAndArguments.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN) > 0;
}
/**
* Returns the name part of the given external method name and arguments.
* @param externalMethodNameAndArguments the external method name and arguments,
* e.g. "myMethod(int,int)
".
* @return the name part of the String, e.g. "myMethod
".
*/
public static String externalMethodName(String externalMethodNameAndArguments)
{
ExternalTypeEnumeration externalTypeEnumeration =
new ExternalTypeEnumeration(externalMethodNameAndArguments);
return externalTypeEnumeration.methodName();
}
/**
* Converts the given external method return type and name and arguments to
* an internal method descriptor.
* @param externalReturnType the external method return type,
* e.g. "boolean
".
* @param externalMethodNameAndArguments the external method name and arguments,
* e.g. "myMethod(int,int)
".
* @return the internal method descriptor,
* e.g. "(II)Z
".
*/
public static String internalMethodDescriptor(String externalReturnType,
String externalMethodNameAndArguments)
{
StringBuffer internalMethodDescriptor = new StringBuffer();
internalMethodDescriptor.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN);
ExternalTypeEnumeration externalTypeEnumeration =
new ExternalTypeEnumeration(externalMethodNameAndArguments);
while (externalTypeEnumeration.hasMoreTypes())
{
internalMethodDescriptor.append(internalType(externalTypeEnumeration.nextType()));
}
internalMethodDescriptor.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE);
internalMethodDescriptor.append(internalType(externalReturnType));
return internalMethodDescriptor.toString();
}
/**
* Converts the given external method return type and List of arguments to
* an internal method descriptor.
* @param externalReturnType the external method return type,
* e.g. "boolean
".
* @param externalArguments the external method arguments,
* e.g. { "int", "int" }
.
* @return the internal method descriptor,
* e.g. "(II)Z
".
*/
public static String internalMethodDescriptor(String externalReturnType,
List externalArguments)
{
StringBuffer internalMethodDescriptor = new StringBuffer();
internalMethodDescriptor.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN);
for (int index = 0; index < externalArguments.size(); index++)
{
internalMethodDescriptor.append(internalType((String)externalArguments.get(index)));
}
internalMethodDescriptor.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE);
internalMethodDescriptor.append(internalType(externalReturnType));
return internalMethodDescriptor.toString();
}
/**
* Converts an internal field description into an external full field description.
* @param accessFlags the access flags of the field.
* @param fieldName the field name,
* e.g. "myField
".
* @param internalFieldDescriptor the internal field descriptor,
* e.g. "Z
".
* @return the external full field description,
* e.g. "public boolean myField
".
*/
public static String externalFullFieldDescription(int accessFlags,
String fieldName,
String internalFieldDescriptor)
{
return externalFieldAccessFlags(accessFlags) +
externalType(internalFieldDescriptor) +
' ' +
fieldName;
}
/**
* Converts an internal method description into an external full method description.
* @param internalClassName the internal name of the class of the method,
* e.g. "mypackage/MyClass
".
* @param accessFlags the access flags of the method.
* @param internalMethodName the internal method name,
* e.g. "myMethod
" or
* "<init>
".
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "(II)Z
".
* @return the external full method description,
* e.g. "public boolean myMethod(int,int)
" or
* "public MyClass(int,int)
".
*/
public static String externalFullMethodDescription(String internalClassName,
int accessFlags,
String internalMethodName,
String internalMethodDescriptor)
{
return externalMethodAccessFlags(accessFlags) +
externalMethodReturnTypeAndName(internalClassName,
internalMethodName,
internalMethodDescriptor) +
ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN +
externalMethodArguments(internalMethodDescriptor) +
ClassConstants.EXTERNAL_METHOD_ARGUMENTS_CLOSE;
}
/**
* Converts internal class access flags into an external access description.
* @param accessFlags the class access flags.
* @return the external class access description,
* e.g. "public final
".
*/
public static String externalClassAccessFlags(int accessFlags)
{
return externalClassAccessFlags(accessFlags, "");
}
/**
* Converts internal class access flags into an external access description.
* @param accessFlags the class access flags.
* @param prefix a prefix that is added to each access modifier.
* @return the external class access description,
* e.g. "public final
".
*/
public static String externalClassAccessFlags(int accessFlags, String prefix)
{
if (accessFlags == 0)
{
return EMPTY_STRING;
}
StringBuffer string = new StringBuffer(50);
if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0)
{
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(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_ANNOTATTION) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ANNOTATION);
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_INTERFACE) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_INTERFACE).append(' ');
}
else if ((accessFlags & ClassConstants.INTERNAL_ACC_ENUM) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ENUM).append(' ');
}
else if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
{
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();
}
/**
* Converts internal field access flags into an external access description.
* @param accessFlags the field access flags.
* @return the external field access description,
* e.g. "public volatile
".
*/
public static String externalFieldAccessFlags(int accessFlags)
{
return externalFieldAccessFlags(accessFlags, "");
}
/**
* Converts internal field access flags into an external access description.
* @param accessFlags the field access flags.
* @param prefix a prefix that is added to each access modifier.
* @return the external field access description,
* e.g. "public volatile
".
*/
public static String externalFieldAccessFlags(int accessFlags, String prefix)
{
if (accessFlags == 0)
{
return EMPTY_STRING;
}
StringBuffer string = new StringBuffer(50);
if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)
{
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(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_VOLATILE) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_VOLATILE).append(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_TRANSIENT) != 0)
{
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();
}
/**
* Converts internal method access flags into an external access description.
* @param accessFlags the method access flags.
* @return the external method access description,
* e.g. "public synchronized
".
*/
public static String externalMethodAccessFlags(int accessFlags)
{
return externalMethodAccessFlags(accessFlags, "");
}
/**
* Converts internal method access flags into an external access description.
* @param accessFlags the method access flags.
* @param prefix a prefix that is added to each access modifier.
* @return the external method access description,
* e.g. "public synchronized ".
*/
public static String externalMethodAccessFlags(int accessFlags, String prefix)
{
if (accessFlags == 0)
{
return EMPTY_STRING;
}
StringBuffer string = new StringBuffer(50);
if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)
{
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(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNCHRONIZED) != 0)
{
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(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ABSTRACT).append(' ');
}
if ((accessFlags & ClassConstants.INTERNAL_ACC_STRICT) != 0)
{
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();
}
/**
* Converts an internal method descriptor into an external method return type.
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "(II)Z
".
* @return the external method return type,
* e.g. "boolean
".
*/
public static String externalMethodReturnType(String internalMethodDescriptor)
{
return externalType(internalMethodReturnType(internalMethodDescriptor));
}
/**
* Converts an internal class name, method name, and method descriptor to
* an external method return type and name.
* @param internalClassName the internal name of the class of the method,
* e.g. "mypackage/MyClass
".
* @param internalMethodName the internal method name,
* e.g. "myMethod
" or
* "<init>
".
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "(II)Z
".
* @return the external method return type and name,
* e.g. "boolean myMethod
" or
* "MyClass
".
*/
private static String externalMethodReturnTypeAndName(String internalClassName,
String internalMethodName,
String internalMethodDescriptor)
{
return internalMethodName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ?
externalShortClassName(externalClassName(internalClassName)) :
(externalMethodReturnType(internalMethodDescriptor) +
' ' +
internalMethodName);
}
/**
* Converts an internal method descriptor into an external method argument
* description.
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "(II)Z
".
* @return the external method argument description,
* e.g. "int,int
".
*/
public static String externalMethodArguments(String internalMethodDescriptor)
{
StringBuffer externalMethodNameAndArguments = new StringBuffer();
InternalTypeEnumeration internalTypeEnumeration =
new InternalTypeEnumeration(internalMethodDescriptor);
while (internalTypeEnumeration.hasMoreTypes())
{
externalMethodNameAndArguments.append(externalType(internalTypeEnumeration.nextType()));
if (internalTypeEnumeration.hasMoreTypes())
{
externalMethodNameAndArguments.append(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_SEPARATOR);
}
}
return externalMethodNameAndArguments.toString();
}
/**
* Returns the internal package name of the given internal class name.
* @param internalClassName the internal class name,
* e.g. "java/lang/Object
".
* @return the internal package name,
* e.g. "java/lang
".
*/
public static String internalPackageName(String internalClassName)
{
String internalPackagePrefix = internalPackagePrefix(internalClassName);
int length = internalPackagePrefix.length();
return length > 0 ?
internalPackagePrefix.substring(0, length - 1) :
"";
}
/**
* Returns the internal package prefix of the given internal class name.
* @param internalClassName the internal class name,
* e.g. "java/lang/Object
".
* @return the internal package prefix,
* e.g. "java/lang/
".
*/
public static String internalPackagePrefix(String internalClassName)
{
return internalClassName.substring(0, internalClassName.lastIndexOf(ClassConstants.INTERNAL_PACKAGE_SEPARATOR,
internalClassName.length() - 2) + 1);
}
/**
* Returns the external package name of the given external class name.
* @param externalClassName the external class name,
* e.g. "java.lang.Object
".
* @return the external package name,
* e.g. "java.lang
".
*/
public static String externalPackageName(String externalClassName)
{
String externalPackagePrefix = externalPackagePrefix(externalClassName);
int length = externalPackagePrefix.length();
return length > 0 ?
externalPackagePrefix.substring(0, length - 1) :
"";
}
/**
* Returns the external package prefix of the given external class name.
* @param externalClassName the external class name,
* e.g. "java.lang.Object
".
* @return the external package prefix,
* e.g. "java.lang.
".
*/
public static String externalPackagePrefix(String externalClassName)
{
return externalClassName.substring(0, externalClassName.lastIndexOf(ClassConstants.EXTERNAL_PACKAGE_SEPARATOR,
externalClassName.length() - 2) + 1);
}
}
proguard4.8/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java 0000644 0001750 0001750 00000132023 11736333524 026527 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
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.visitor.*;
import proguard.util.StringMatcher;
/**
* This InstructionVisitor initializes any constant
* Class.get[Declared]{Field,Method}
references of all instructions
* it visits. More specifically, it fills out the references of string constant
* pool entries that refer to a class member in the program class pool or in the
* library class pool.
*
* It optionally prints notes if on usage of
* (SomeClass)Class.forName(variable).newInstance()
.
*
* The class hierarchy and references must be initialized before using this
* visitor.
*
* @see ClassSuperHierarchyInitializer
* @see ClassReferenceInitializer
*
* @author Eric Lafortune
*/
public class DynamicMemberReferenceInitializer
extends SimplifiedVisitor
implements InstructionVisitor,
ConstantVisitor,
AttributeVisitor,
MemberVisitor
{
/*
private static boolean DEBUG = true;
/*/
private static final boolean DEBUG = false;
//*/
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[]
{
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_METHOD_NAME_CLASS_GET_FIELD),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_FIELD),
};
private final Constant[] GET_DECLARED_FIELD_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_METHOD_NAME_CLASS_GET_DECLARED_FIELD),
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),
new ClassConstant(3, null),
new NameAndTypeConstant(4, 5),
new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_CLASS_GET_METHOD),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_METHOD),
};
private final Constant[] GET_DECLARED_METHOD_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_METHOD_NAME_CLASS_GET_DECLARED_METHOD),
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, 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, 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),
};
// SomeClass.class.get[Declared]Method("someMethod", new Class[] { A.class }).
private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS1 = new Instruction[]
{
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, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
// 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, 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, 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),
};
// 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, 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, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
// get[Declared]Method("someMethod", new Class[] { A.class }).
private final Instruction[] GET_METHOD_INSTRUCTIONS1 = new Instruction[]
{
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, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
// get[Declared]Method("someMethod", new Class[] { A.class, B.class }).
private final Instruction[] GET_METHOD_INSTRUCTIONS2 = new Instruction[]
{
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, 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),
};
// 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;
private final WarningPrinter notePrinter;
private final StringMatcher noteFieldExceptionMatcher;
private final StringMatcher noteMethodExceptionMatcher;
private final InstructionSequenceMatcher constantGetFieldMatcher =
new InstructionSequenceMatcher(GET_FIELD_CONSTANTS,
CONSTANT_GET_FIELD_INSTRUCTIONS);
private final InstructionSequenceMatcher constantGetDeclaredFieldMatcher =
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);
private final InstructionSequenceMatcher constantGetDeclaredMethodMatcher0 =
new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS,
CONSTANT_GET_METHOD_INSTRUCTIONS0);
private final InstructionSequenceMatcher constantGetMethodMatcher1 =
new InstructionSequenceMatcher(GET_METHOD_CONSTANTS,
CONSTANT_GET_METHOD_INSTRUCTIONS1);
private final InstructionSequenceMatcher constantGetDeclaredMethodMatcher1 =
new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS,
CONSTANT_GET_METHOD_INSTRUCTIONS1);
private final InstructionSequenceMatcher constantGetMethodMatcher2 =
new InstructionSequenceMatcher(GET_METHOD_CONSTANTS,
CONSTANT_GET_METHOD_INSTRUCTIONS2);
private final InstructionSequenceMatcher constantGetDeclaredMethodMatcher2 =
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);
private final InstructionSequenceMatcher getDeclaredFieldMatcher =
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);
private final InstructionSequenceMatcher getDeclaredMethodMatcher0 =
new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS,
GET_METHOD_INSTRUCTIONS0);
private final InstructionSequenceMatcher getMethodMatcher1 =
new InstructionSequenceMatcher(GET_METHOD_CONSTANTS,
GET_METHOD_INSTRUCTIONS1);
private final InstructionSequenceMatcher getDeclaredMethodMatcher1 =
new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS,
GET_METHOD_INSTRUCTIONS1);
private final InstructionSequenceMatcher getMethodMatcher2 =
new InstructionSequenceMatcher(GET_METHOD_CONSTANTS,
GET_METHOD_INSTRUCTIONS2);
private final InstructionSequenceMatcher getDeclaredMethodMatcher2 =
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;
/**
* Creates a new DynamicMemberReferenceInitializer.
*/
public DynamicMemberReferenceInitializer(ClassPool programClassPool,
ClassPool libraryClassPool,
WarningPrinter notePrinter,
StringMatcher noteFieldExceptionMatcher,
StringMatcher noteMethodExceptionMatcher)
{
this.programClassPool = programClassPool;
this.libraryClassPool = libraryClassPool;
this.notePrinter = notePrinter;
this.noteFieldExceptionMatcher = noteFieldExceptionMatcher;
this.noteMethodExceptionMatcher = noteMethodExceptionMatcher;
}
// Implementations for InstructionVisitor.
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
{
// Try to match the SomeClass.class.getField("someField") construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetFieldMatcher,
getFieldMatcher, true, false, null, null);
// Try to match the SomeClass.class.getDeclaredField("someField") construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredFieldMatcher,
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, null, null);
// Try to match the SomeClass.class.getDeclaredMethod("someMethod",
// new Class[] {}) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredMethodMatcher0,
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, 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, 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, null, null);
// Try to match the SomeClass.class.getDeclaredMethod("someMethod",
// new Class[] { A.class, B.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredMethodMatcher2,
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);
}
/**
* Tries to match the next instruction and fills out the string constant
* or prints out a note accordingly.
*/
private void matchGetMember(Clazz clazz,
Method method,
CodeAttribute codeAttribute,
int offset,
Instruction instruction,
InstructionSequenceMatcher constantSequenceMatcher,
InstructionSequenceMatcher variableSequenceMatcher,
boolean isField,
boolean isDeclared,
String defaultName,
String defaultDescriptor)
{
if (constantSequenceMatcher != null)
{
// 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())
{
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.
instruction.accept(clazz, method, codeAttribute, offset,
variableSequenceMatcher);
// Did we find a match to print out a note?
if (variableSequenceMatcher.isMatching())
{
// Print out a note about the dynamic invocation.
printDynamicInvocationNote(clazz,
variableSequenceMatcher,
isField,
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.
/**
* Remembers the referenced class.
*/
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 :
classConstant.referencedClass;
}
/**
* Fills out the link to the referenced class member.
*/
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
if (referencedClass != null)
{
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, descriptor) :
(Member)referencedClass.findMethod(name, descriptor) :
(Member)memberFinder.findMember(clazz,
referencedClass,
name,
descriptor,
isField);
if (referencedMember != null)
{
stringConstant.referencedMember = referencedMember;
stringConstant.referencedClass = isDeclared ?
referencedClass :
memberFinder.correspondingClass();
}
}
}
// Small utility methods.
/**
* Prints out a note on the matched dynamic invocation, if necessary.
*/
private void printDynamicInvocationNote(Clazz clazz,
InstructionSequenceMatcher noteSequenceMatcher,
boolean isField,
boolean isDeclared,
String defaultName,
String defaultDescriptor)
{
// Print out a note about the dynamic invocation.
if (notePrinter != null &&
notePrinter.accepts(clazz.getName()))
{
// Is the class member name in the list of exceptions?
StringMatcher noteExceptionMatcher = isField ?
noteFieldExceptionMatcher :
noteMethodExceptionMatcher;
int memberNameIndex = noteSequenceMatcher.matchedConstantIndex(MEMBER_NAME_INDEX);
String memberName = memberNameIndex <= 0 ? defaultName :
clazz.getStringString(memberNameIndex);
if (noteExceptionMatcher == null ||
!noteExceptionMatcher.matches(memberName))
{
// Compose the external member name and partial descriptor.
String externalMemberDescription = memberName;
if (!isField)
{
externalMemberDescription += '(';
for (int count = 0; count < 2; count++)
{
int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(
PARAMETER0_CLASS_INDEX + count);
if (memberArgumentIndex > 0)
{
if (count > 0)
{
externalMemberDescription += ',';
}
String className = clazz.getClassName(memberArgumentIndex);
externalMemberDescription += ClassUtil.isInternalArrayType(className) ?
ClassUtil.externalType(className) :
ClassUtil.externalClassName(className);
}
}
externalMemberDescription += ')';
}
// Print out the actual note.
notePrinter.print(clazz.getName(),
"Note: " +
ClassUtil.externalClassName(clazz.getName()) +
" accesses a " +
(isDeclared ? "declared " : "") +
(isField ? "field" :
memberName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ?
"constructor" : "method") +
" '" +
externalMemberDescription +
"' dynamically");
// Print out notes about potential candidates.
ClassVisitor classVisitor;
if (isField)
{
classVisitor = defaultDescriptor == null ?
new AllFieldVisitor(
new MemberNameFilter(memberName, this)) :
new AllFieldVisitor(
new MemberNameFilter(memberName,
new MemberDescriptorFilter(defaultDescriptor, this)));
}
else
{
// Compose the partial method descriptor.
String methodDescriptor = "(";
for (int count = 0; count < 2; count++)
{
int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(PARAMETER0_CLASS_INDEX + count);
if (memberArgumentIndex > 0)
{
String className = clazz.getClassName(memberArgumentIndex);
methodDescriptor += ClassUtil.isInternalArrayType(className) ?
className :
ClassUtil.internalTypeFromClassName(className);
}
}
methodDescriptor += ")L***;";
classVisitor =
new AllMethodVisitor(
new MemberNameFilter(memberName,
new MemberDescriptorFilter(methodDescriptor, this)));
}
programClassPool.classesAcceptAlphabetically(classVisitor);
libraryClassPool.classesAcceptAlphabetically(classVisitor);
}
}
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (notePrinter.accepts(programClass.getName()))
{
System.out.println(" Maybe this is program field '" +
ClassUtil.externalFullClassDescription(0, programClass.getName()) +
" { " +
ClassUtil.externalFullFieldDescription(0, programField.getName(programClass), programField.getDescriptor(programClass)) +
"; }'");
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (notePrinter.accepts(programClass.getName()))
{
System.out.println(" Maybe this is program method '" +
ClassUtil.externalFullClassDescription(0, programClass.getName()) +
" { " +
ClassUtil.externalFullMethodDescription(programClass.getName(), 0, programMethod.getName(programClass), programMethod.getDescriptor(programClass)) +
"; }'");
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
if (notePrinter.accepts(libraryClass.getName()))
{
System.out.println(" Maybe this is library field '" +
ClassUtil.externalFullClassDescription(0, libraryClass.getName()) +
" { " +
ClassUtil.externalFullFieldDescription(0, libraryField.getName(libraryClass), libraryField.getDescriptor(libraryClass)) +
"; }'");
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (notePrinter.accepts(libraryClass.getName()))
{
System.out.println(" Maybe this is library method '" +
ClassUtil.externalFullClassDescription(0, libraryClass.getName()) +
" { " +
ClassUtil.externalFullMethodDescription(libraryClass.getName(), 0, libraryMethod.getName(libraryClass), libraryMethod.getDescriptor(libraryClass)) +
"; }'");
}
}
} proguard4.8/src/proguard/classfile/util/InternalTypeEnumeration.java 0000644 0001750 0001750 00000012510 11736333524 024613 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.ClassConstants;
/**
* An InternalTypeEnumeration
provides an enumeration of all
* parameter types listed in a given internal method descriptor or signature.
* The signature can also be a class signature. The return type of a method
* descriptor can be retrieved separately.
*
* @author Eric Lafortune
*/
public class InternalTypeEnumeration
{
private String descriptor;
private int firstIndex;
private int lastIndex;
private int index;
/**
* Creates a new InternalTypeEnumeration for the given method descriptor.
*/
public InternalTypeEnumeration(String descriptor)
{
this.descriptor = descriptor;
this.firstIndex = descriptor.indexOf(ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN);
this.lastIndex = descriptor.indexOf(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE);
this.index = firstIndex + 1;
if (lastIndex < 0)
{
lastIndex = descriptor.length();
}
}
/**
* Returns the formal type parameters from the descriptor, assuming it's a
* method descriptor.
*/
public String formalTypeParameters()
{
return descriptor.substring(0, firstIndex);
}
/**
* Returns whether the enumeration can provide more types from the method
* descriptor.
*/
public boolean hasMoreTypes()
{
return index < lastIndex;
}
/**
* Returns the next type from the method descriptor.
*/
public String nextType()
{
int startIndex = index;
skipArray();
char c = descriptor.charAt(index++);
switch (c)
{
case ClassConstants.INTERNAL_TYPE_CLASS_START:
case ClassConstants.INTERNAL_TYPE_GENERIC_VARIABLE_START:
{
skipClass();
break;
}
case ClassConstants.INTERNAL_TYPE_GENERIC_START:
{
skipGeneric();
break;
}
}
return descriptor.substring(startIndex, index);
}
/**
* Returns the return type from the descriptor, assuming it's a method
* descriptor.
*/
public String returnType()
{
return descriptor.substring(lastIndex + 1);
}
// Small utility methods.
private void skipArray()
{
while (descriptor.charAt(index) == ClassConstants.INTERNAL_TYPE_ARRAY)
{
index++;
}
}
private void skipClass()
{
while (true)
{
char c = descriptor.charAt(index++);
switch (c)
{
case ClassConstants.INTERNAL_TYPE_GENERIC_START:
skipGeneric();
break;
case ClassConstants.INTERNAL_TYPE_CLASS_END:
return;
}
}
}
private void skipGeneric()
{
int nestingLevel = 1;
do
{
char c = descriptor.charAt(index++);
switch (c)
{
case ClassConstants.INTERNAL_TYPE_GENERIC_START:
nestingLevel++;
break;
case ClassConstants.INTERNAL_TYPE_GENERIC_END:
nestingLevel--;
break;
}
}
while (nestingLevel > 0);
}
/**
* A main method for testing the type enumeration.
*/
public static void main(String[] args)
{
try
{
for (int index = 0; index < args.length; index++)
{
String descriptor = args[index];
System.out.println("Descriptor ["+descriptor+"]");
InternalTypeEnumeration enumeration = new InternalTypeEnumeration(descriptor);
if (enumeration.firstIndex >= 0)
{
System.out.println(" Formal type parameters ["+enumeration.formalTypeParameters()+"]");
}
while (enumeration.hasMoreTypes())
{
System.out.println(" Type ["+enumeration.nextType()+"]");
}
if (enumeration.lastIndex < descriptor.length())
{
System.out.println(" Return type ["+enumeration.returnType()+"]");
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
proguard4.8/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java 0000644 0001750 0001750 00000014047 11736333524 026124 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.constant.ClassConstant;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.visitor.ClassVisitor;
/**
* This ClassVisitor initializes the superclass hierarchy of all classes that
* it visits.
*
* Visited library classes get direct references to their superclasses and * interfaces, replacing the superclass names and interface names. The direct * references are equivalent to the names, but they are more efficient to work * with. *
* This visitor optionally prints warnings if some superclasses can't be found
* or if they are in the program class pool.
*
* @author Eric Lafortune
*/
public class ClassSuperHierarchyInitializer
extends SimplifiedVisitor
implements ClassVisitor,
ConstantVisitor
{
private final ClassPool programClassPool;
private final ClassPool libraryClassPool;
private final WarningPrinter missingWarningPrinter;
private final WarningPrinter dependencyWarningPrinter;
/**
* Creates a new ClassSuperHierarchyInitializer that initializes the super
* hierarchy of all visited class files, optionally printing warnings if
* some classes can't be found or if they are in the program class pool.
*/
public ClassSuperHierarchyInitializer(ClassPool programClassPool,
ClassPool libraryClassPool,
WarningPrinter missingWarningPrinter,
WarningPrinter dependencyWarningPrinter)
{
this.programClassPool = programClassPool;
this.libraryClassPool = libraryClassPool;
this.missingWarningPrinter = missingWarningPrinter;
this.dependencyWarningPrinter = dependencyWarningPrinter;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Link to the super class.
programClass.superClassConstantAccept(this);
// Link to the interfaces.
programClass.interfaceConstantsAccept(this);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
String className = libraryClass.getName();
// Link to the super class.
String superClassName = libraryClass.superClassName;
if (superClassName != null)
{
// Keep a reference to the superclass.
libraryClass.superClass = findClass(className, superClassName);
}
// Link to the interfaces.
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.
interfaceClasses[index] =
findClass(className, interfaceNames[index]);
}
libraryClass.interfaceClasses = interfaceClasses;
}
}
// Implementations for ConstantVisitor.
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
classConstant.referencedClass =
findClass(clazz.getName(), classConstant.getName(clazz));
}
// Small utility methods.
/**
* Returns the class with the given name, either for the program class pool
* or from the library class pool, or
* It optionally prints notes if on usage of
*
* The class hierarchy must be initialized before using this visitor.
*
* @see ClassSuperHierarchyInitializer
*
* @author Eric Lafortune
*/
public class DynamicClassReferenceInitializer
extends SimplifiedVisitor
implements InstructionVisitor,
ConstantVisitor,
AttributeVisitor
{
public static final int X = InstructionSequenceMatcher.X;
public static final int Y = InstructionSequenceMatcher.Y;
public static final int Z = InstructionSequenceMatcher.Z;
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;
private final Constant[] CLASS_FOR_NAME_CONSTANTS = new Constant[]
{
// 0
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_METHOD_NAME_CLASS_FOR_NAME),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_FOR_NAME),
// 6
new MethodrefConstant(1, 7, null, null),
new NameAndTypeConstant(8, 9),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_INSTANCE),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_INSTANCE),
// 10
new MethodrefConstant(1, 11, null, null),
new NameAndTypeConstant(12, 13),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_CLASS_GET_COMPONENT_TYPE),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_COMPONENT_TYPE),
};
// Class.forName("SomeClass").
private final Instruction[] CONSTANT_CLASS_FOR_NAME_INSTRUCTIONS = new Instruction[]
{
new ConstantInstruction(InstructionConstants.OP_LDC, X),
new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
};
// (SomeClass)Class.forName(someName).newInstance().
private final Instruction[] CLASS_FOR_NAME_CAST_INSTRUCTIONS = new Instruction[]
{
new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 6),
new ConstantInstruction(InstructionConstants.OP_CHECKCAST, X),
};
// private Constant[] DOT_CLASS_JAVAC_CONSTANTS = new Constant[]
// {
// new MethodrefConstant(A, 1, null, null),
// new NameAndTypeConstant(2, 3),
// new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS_JAVAC),
// new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC),
// };
private final Constant[] DOT_CLASS_JAVAC_CONSTANTS = new Constant[]
{
new MethodrefConstant(A, 1, null, null),
new NameAndTypeConstant(B, 2),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC),
};
// SomeClass.class = class$("SomeClass") (javac).
private final Instruction[] DOT_CLASS_JAVAC_INSTRUCTIONS = new Instruction[]
{
new ConstantInstruction(InstructionConstants.OP_LDC, X),
new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
};
// private Constant[] DOT_CLASS_JIKES_CONSTANTS = new Constant[]
// {
// new MethodrefConstant(A, 1, null, null),
// new NameAndTypeConstant(2, 3),
// new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS_JIKES),
// new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JIKES),
// };
private final Constant[] DOT_CLASS_JIKES_CONSTANTS = new Constant[]
{
new MethodrefConstant(A, 1, null, null),
new NameAndTypeConstant(B, 2),
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JIKES),
};
// SomeClass.class = class("SomeClass", false) (jikes).
private final Instruction[] DOT_CLASS_JIKES_INSTRUCTIONS = new Instruction[]
{
new ConstantInstruction(InstructionConstants.OP_LDC, X),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
};
// return Class.forName(v0).
private final Instruction[] DOT_CLASS_JAVAC_IMPLEMENTATION_INSTRUCTIONS = new Instruction[]
{
new VariableInstruction(InstructionConstants.OP_ALOAD_0),
new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
new SimpleInstruction(InstructionConstants.OP_ARETURN),
};
// return Class.forName(v0), if (!v1) .getComponentType().
private final Instruction[] DOT_CLASS_JIKES_IMPLEMENTATION_INSTRUCTIONS = new Instruction[]
{
new VariableInstruction(InstructionConstants.OP_ALOAD_0),
new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
new VariableInstruction(InstructionConstants.OP_ALOAD_1),
new BranchInstruction(InstructionConstants.OP_IFNE, +6),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 10),
new SimpleInstruction(InstructionConstants.OP_ARETURN),
};
// return Class.forName(v0).getComponentType().
private final Instruction[] DOT_CLASS_JIKES_IMPLEMENTATION_INSTRUCTIONS2 = new Instruction[]
{
new VariableInstruction(InstructionConstants.OP_ALOAD_0),
new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 10),
new SimpleInstruction(InstructionConstants.OP_ARETURN),
};
private final ClassPool programClassPool;
private final ClassPool libraryClassPool;
private final WarningPrinter missingNotePrinter;
private final WarningPrinter dependencyWarningPrinter;
private final WarningPrinter notePrinter;
private final StringMatcher noteExceptionMatcher;
private final InstructionSequenceMatcher constantClassForNameMatcher =
new InstructionSequenceMatcher(CLASS_FOR_NAME_CONSTANTS,
CONSTANT_CLASS_FOR_NAME_INSTRUCTIONS);
private final InstructionSequenceMatcher classForNameCastMatcher =
new InstructionSequenceMatcher(CLASS_FOR_NAME_CONSTANTS,
CLASS_FOR_NAME_CAST_INSTRUCTIONS);
private final InstructionSequenceMatcher dotClassJavacMatcher =
new InstructionSequenceMatcher(DOT_CLASS_JAVAC_CONSTANTS,
DOT_CLASS_JAVAC_INSTRUCTIONS);
private final InstructionSequenceMatcher dotClassJikesMatcher =
new InstructionSequenceMatcher(DOT_CLASS_JIKES_CONSTANTS,
DOT_CLASS_JIKES_INSTRUCTIONS);
private final InstructionSequenceMatcher dotClassJavacImplementationMatcher =
new InstructionSequenceMatcher(CLASS_FOR_NAME_CONSTANTS,
DOT_CLASS_JAVAC_IMPLEMENTATION_INSTRUCTIONS);
private final InstructionSequenceMatcher dotClassJikesImplementationMatcher =
new InstructionSequenceMatcher(CLASS_FOR_NAME_CONSTANTS,
DOT_CLASS_JIKES_IMPLEMENTATION_INSTRUCTIONS);
private final InstructionSequenceMatcher dotClassJikesImplementationMatcher2 =
new InstructionSequenceMatcher(CLASS_FOR_NAME_CONSTANTS,
DOT_CLASS_JIKES_IMPLEMENTATION_INSTRUCTIONS2);
// A field acting as a return variable for the visitors.
private boolean isClassForNameInvocation;
/**
* Creates a new DynamicClassReferenceInitializer that optionally prints
* warnings and notes, with optional class specifications for which never
* to print notes.
*/
public DynamicClassReferenceInitializer(ClassPool programClassPool,
ClassPool libraryClassPool,
WarningPrinter missingNotePrinter,
WarningPrinter dependencyWarningPrinter,
WarningPrinter notePrinter,
StringMatcher noteExceptionMatcher)
{
this.programClassPool = programClassPool;
this.libraryClassPool = libraryClassPool;
this.missingNotePrinter = missingNotePrinter;
this.dependencyWarningPrinter = dependencyWarningPrinter;
this.notePrinter = notePrinter;
this.noteExceptionMatcher = noteExceptionMatcher;
}
// Implementations for InstructionVisitor.
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
{
// Try to match the Class.forName("SomeClass") construct.
instruction.accept(clazz, method, codeAttribute, offset,
constantClassForNameMatcher);
// Did we find a match?
if (constantClassForNameMatcher.isMatching())
{
// Fill out the matched string constant.
clazz.constantPoolEntryAccept(constantClassForNameMatcher.matchedConstantIndex(X), this);
// Don't look for the dynamic construct.
classForNameCastMatcher.reset();
}
// Try to match the (SomeClass)Class.forName(someName).newInstance()
// construct.
instruction.accept(clazz, method, codeAttribute, offset,
classForNameCastMatcher);
// Did we find a match?
if (classForNameCastMatcher.isMatching())
{
// Print out a note about the construct.
clazz.constantPoolEntryAccept(classForNameCastMatcher.matchedConstantIndex(X), this);
}
// Try to match the javac .class construct.
instruction.accept(clazz, method, codeAttribute, offset,
dotClassJavacMatcher);
// Did we find a match?
if (dotClassJavacMatcher.isMatching() &&
isDotClassMethodref(clazz, dotClassJavacMatcher.matchedConstantIndex(0)))
{
// Fill out the matched string constant.
clazz.constantPoolEntryAccept(dotClassJavacMatcher.matchedConstantIndex(X), this);
}
// Try to match the jikes .class construct.
instruction.accept(clazz, method, codeAttribute, offset,
dotClassJikesMatcher);
// Did we find a match?
if (dotClassJikesMatcher.isMatching() &&
isDotClassMethodref(clazz, dotClassJikesMatcher.matchedConstantIndex(0)))
{
// Fill out the matched string constant.
clazz.constantPoolEntryAccept(dotClassJikesMatcher.matchedConstantIndex(X), this);
}
}
// Implementations for ConstantVisitor.
/**
* Fills out the link to the referenced class.
*/
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
// Save a reference to the corresponding class.
String externalClassName = stringConstant.getString(clazz);
String internalClassName = ClassUtil.internalClassName(
ClassUtil.externalBaseType(externalClassName));
stringConstant.referencedClass = findClass(clazz.getName(), internalClassName);
}
/**
* Prints out a note about the class cast to this class, if applicable.
*/
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Print out a note about the class cast.
if (noteExceptionMatcher == null ||
!noteExceptionMatcher.matches(classConstant.getName(clazz)))
{
notePrinter.print(clazz.getName(),
classConstant.getName(clazz),
"Note: " +
ClassUtil.externalClassName(clazz.getName()) +
" calls '(" +
ClassUtil.externalClassName(classConstant.getName(clazz)) +
")Class.forName(variable).newInstance()'");
}
}
/**
* Checks whether the referenced method is a .class method.
*/
public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
{
String methodType = methodrefConstant.getType(clazz);
// Do the method's class and type match?
if (methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC) ||
methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JIKES))
{
String methodName = methodrefConstant.getName(clazz);
// Does the method's name match one of the special names?
isClassForNameInvocation =
methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS_JAVAC) ||
methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS_JIKES);
if (isClassForNameInvocation)
{
return;
}
String className = methodrefConstant.getClassName(clazz);
// Note that we look for the class by name, since the referenced
// class has not been initialized yet.
Clazz referencedClass = programClassPool.getClass(className);
if (referencedClass != null)
{
// Check if the code of the referenced method is .class code.
// Note that we look for the method by name and type, since the
// referenced method has not been initialized yet.
referencedClass.methodAccept(methodName,
methodType,
new AllAttributeVisitor(this));
}
}
}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
// Check whether this is class$(String), as generated by javac, or
// class(String, boolean), as generated by jikes, or an optimized
// version.
isClassForNameInvocation =
isDotClassMethodCode(clazz, method, codeAttribute,
dotClassJavacImplementationMatcher, 5) ||
isDotClassMethodCode(clazz, method, codeAttribute,
dotClassJikesImplementationMatcher, 12) ||
isDotClassMethodCode(clazz, method, codeAttribute,
dotClassJikesImplementationMatcher2, 8);
}
// Small utility methods.
/**
* Returns whether the given method reference corresponds to a .class
* method, as generated by javac or by jikes.
*/
private boolean isDotClassMethodref(Clazz clazz, int methodrefConstantIndex)
{
isClassForNameInvocation = false;
// Check if the code of the referenced method is .class code.
clazz.constantPoolEntryAccept(methodrefConstantIndex, this);
return isClassForNameInvocation;
}
/**
* Returns whether the first whether the first instructions of the
* given code attribute match with the given instruction matcher.
*/
private boolean isDotClassMethodCode(Clazz clazz,
Method method,
CodeAttribute codeAttribute,
InstructionSequenceMatcher codeMatcher,
int codeLength)
{
// Check the minimum code length.
if (codeAttribute.u4codeLength < codeLength)
{
return false;
}
// Check the actual instructions.
codeMatcher.reset();
codeAttribute.instructionsAccept(clazz, method, 0, codeLength, codeMatcher);
return codeMatcher.isMatching();
}
/**
* Returns the class with the given name, either for the program class pool
* or from the library class pool, or
* A
Why the visitor pattern? Class files frequently contain lists of elements of
various mixed types: class items, constant pool entries, attributes,...
These lists and types are largely fixed; they won't change much in future
releases of the Java class file specifications. On the other hand, the kinds
of operations that we may wish to perform on the class files may change and
expand. We want to separate the objects and the operations performed upon them.
This is a good place to use the visitor pattern.
Visitor interfaces avoid having to do series of
As already mentioned, the main advantage is avoiding lots of
A disadvantage is that the visitor methods always get the same names, specified
by the visitor interface. These names aren't descriptive at all, making code
harder to read. It's the visitor classes that describe the operations now.
Also, the visitor methods always have the same parameters and return values, as
specified by the visitor interfaces. Passing additional parameters is done by
means of extra fields in the visitor, which is somewhat of a kludge.
Because objects (the visitor accepters) and the operations performed upon them
(the visitors) are now separated, it becomes harder to associate some state
with the objects. For convenience, we always provide an extra visitor
info field in visitor accepters, in which visitors can put any temporary
information they want.
proguard4.8/src/proguard/classfile/visitor/MemberCounter.java 0000644 0001750 0001750 00000003671 11736333524 023267 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This MemberVisitor counts the number of class members that have been visited.
*
* @author Eric Lafortune
*/
public class MemberCounter implements MemberVisitor
{
private int count;
/**
* Returns the number of class members that has been visited so far.
*/
public int getCount()
{
return count;
}
// Implementations for MemberVisitor.
public void visitLibraryField(LibraryClass libraryClass,
LibraryField libraryField)
{
count++;
}
public void visitLibraryMethod(LibraryClass libraryClass,
LibraryMethod libraryMethod)
{
count++;
}
public void visitProgramField(ProgramClass programClass,
ProgramField programField)
{
count++;
}
public void visitProgramMethod(ProgramClass programClass,
ProgramMethod programMethod)
{
count++;
}
}
proguard4.8/src/proguard/classfile/visitor/MemberToClassVisitor.java 0000644 0001750 0001750 00000005034 11736333524 024573 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This MemberVisitor delegates all visits to a given ClassVisitor.
* The latter visits the class of each visited class member, although
* never twice in a row.
*
* @author Eric Lafortune
*/
public class MemberToClassVisitor implements MemberVisitor
{
private final ClassVisitor classVisitor;
private Clazz lastVisitedClass;
public MemberToClassVisitor(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (!programClass.equals(lastVisitedClass))
{
classVisitor.visitProgramClass(programClass);
lastVisitedClass = programClass;
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (!programClass.equals(lastVisitedClass))
{
classVisitor.visitProgramClass(programClass);
lastVisitedClass = programClass;
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
if (!libraryClass.equals(lastVisitedClass))
{
classVisitor.visitLibraryClass(libraryClass);
lastVisitedClass = libraryClass;
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (!libraryClass.equals(lastVisitedClass))
{
classVisitor.visitLibraryClass(libraryClass);
lastVisitedClass = libraryClass;
}
}
}
proguard4.8/src/proguard/classfile/visitor/DotClassClassVisitor.java 0000644 0001750 0001750 00000006057 11736333524 024603 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
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;
/**
* This InstructionVisitor lets a given
* Note that before JDK 1.5,
* If conflicting access flags (public/private/protected) are specified,
* having one of them set will be considered sufficient.
*
* @see ClassConstants
*
* @author Eric Lafortune
*/
public class MemberAccessFilter
implements MemberVisitor
{
// A mask of conflicting access flags. These are interpreted in a special
// way if more of them are required at the same time. In that case, one
// of them being set is sufficient.
private static final int ACCESS_MASK =
ClassConstants.INTERNAL_ACC_PUBLIC |
ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_PROTECTED;
private final int requiredSetAccessFlags;
private final int requiredUnsetAccessFlags;
private final int requiredOneSetAccessFlags;
private final MemberVisitor memberVisitor;
/**
* Creates a new MemberAccessFilter.
* @param requiredSetAccessFlags the class access flags that should be
* set.
* @param requiredUnsetAccessFlags the class access flags that should be
* unset.
* @param memberVisitor the
* Class files are read as ProgramClass objects or LibraryClass objects,
* depending on the
* In case of libraries, only public classes are considered, if the
* null
if it can't be found.
*/
private Clazz findClass(String referencingClassName, String name)
{
// First look for the class in the program class pool.
Clazz clazz = programClassPool.getClass(name);
// Otherwise look for the class in the library class pool.
if (clazz == null)
{
clazz = libraryClassPool.getClass(name);
if (clazz == null &&
missingWarningPrinter != null)
{
// We didn't find the superclass or interface. Print a warning.
missingWarningPrinter.print(referencingClassName,
name,
"Warning: " +
ClassUtil.externalClassName(referencingClassName) +
": can't find superclass or interface " +
ClassUtil.externalClassName(name));
}
}
else if (dependencyWarningPrinter != null)
{
// The superclass or interface was found in the program class pool.
// Print a warning.
dependencyWarningPrinter.print(referencingClassName,
name,
"Warning: library class " +
ClassUtil.externalClassName(referencingClassName) +
" extends or implements program class " +
ClassUtil.externalClassName(name));
}
return clazz;
}
}
proguard4.8/src/proguard/classfile/util/MethodLinker.java 0000644 0001750 0001750 00000012223 11736333524 022354 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.visitor.*;
import java.util.*;
/**
* 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
*/
public class MethodLinker
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor
{
// An object that is reset and reused every time.
// The map: [class member name+' '+descriptor - class member info]
private final Map memberMap = new HashMap();
// Implementations for ClassVisitor.
public void visitAnyClass(Clazz clazz)
{
// Collect all non-private members in this class hierarchy.
clazz.hierarchyAccept(true, true, true, false,
new AllMethodVisitor(
new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE | ClassConstants.INTERNAL_ACC_STATIC,
this)));
// Clean up for the next class hierarchy.
memberMap.clear();
}
// Implementations for MemberVisitor.
public void visitAnyMember(Clazz clazz, Member member)
{
// Get the class member's name and descriptor.
String name = member.getName(clazz);
String descriptor = member.getDescriptor(clazz);
// Special cases: Class.forName
or
* .class
references of all classes it visits. More specifically,
* it fills out the references of string constant pool entries that refer to a
* class in the program class pool or in the library class pool.
* (SomeClass)Class.forName(variable).newInstance()
.
* null
if it can't be found.
*/
private Clazz findClass(String referencingClassName, String name)
{
// Is it an array type?
if (ClassUtil.isInternalArrayType(name))
{
// 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.
Clazz clazz = programClassPool.getClass(name);
// Otherwise look for the class in the library class pool.
if (clazz == null)
{
clazz = libraryClassPool.getClass(name);
if (clazz == null &&
missingNotePrinter != null)
{
// We didn't find the superclass or interface. Print a note.
missingNotePrinter.print(referencingClassName,
name,
"Note: " +
ClassUtil.externalClassName(referencingClassName) +
": can't find dynamically referenced class " +
ClassUtil.externalClassName(name));
}
}
else if (dependencyWarningPrinter != null)
{
// The superclass or interface was found in the program class pool.
// Print a warning.
dependencyWarningPrinter.print(referencingClassName,
name,
"Warning: library class " +
ClassUtil.externalClassName(referencingClassName) +
" depends dynamically on program class " +
ClassUtil.externalClassName(name));
}
return clazz;
}
}
proguard4.8/src/proguard/classfile/util/SimplifiedVisitor.java 0000644 0001750 0001750 00000067136 11736333524 023451 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.preverification.*;
import proguard.classfile.constant.*;
import proguard.classfile.instruction.*;
/**
* This abstract utility class allows to implement various visitor interfaces
* with simplified methods. The provided methods delegate to other versions
* with fewer arguments or more general arguments.
*
* @author Eric Lafortune
* @noinspection AbstractClassWithoutAbstractMethods
*/
public abstract class SimplifiedVisitor
{
// Simplifications for ClassVisitor.
/**
* Visits any type of class member of the given class.
*/
public void visitAnyClass(Clazz clazz)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
public void visitProgramClass(ProgramClass programClass)
{
visitAnyClass(programClass);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
visitAnyClass(libraryClass);
}
// Simplifications for MemberVisitor.
/**
* Visits any type of class member of the given class.
*/
public void visitAnyMember(Clazz clazz, Member member)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
/**
* Visits any type of class member of the given program class.
*/
public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
visitAnyMember(programClass, programMember);
}
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
visitProgramMember(programClass, programField);
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
visitProgramMember(programClass, programMethod);
}
/**
* Visits any type of class member of the given library class.
*/
public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
{
visitAnyMember(libraryClass, libraryMember);
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
visitLibraryMember(libraryClass, libraryField);
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
visitLibraryMember(libraryClass, libraryMethod);
}
// Simplifications for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
visitAnyConstant(clazz, integerConstant);
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
visitAnyConstant(clazz, longConstant);
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
visitAnyConstant(clazz, floatConstant);
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
visitAnyConstant(clazz, doubleConstant);
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
visitAnyConstant(clazz, stringConstant);
}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
visitAnyConstant(clazz, utf8Constant);
}
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.
*/
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
visitAnyConstant(clazz, refConstant);
}
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
visitAnyRefConstant(clazz, fieldrefConstant);
}
/**
* Visits any type of method RefConstant of the given class.
*/
public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
{
visitAnyRefConstant(clazz, refConstant);
}
public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
{
visitAnyMethodrefConstant(clazz, interfaceMethodrefConstant);
}
public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
{
visitAnyMethodrefConstant(clazz, methodrefConstant);
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
visitAnyConstant(clazz, classConstant);
}
public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
{
visitAnyConstant(clazz, methodTypeConstant);
}
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
visitAnyConstant(clazz, nameAndTypeConstant);
}
// Simplifications for AttributeVisitor.
/**
* Visit any type of attribute.
*/
public void visitAnyAttribute(Clazz clazz, Attribute attribute)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
visitAnyAttribute(clazz, unknownAttribute);
}
public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
{
visitAnyAttribute(clazz, bootstrapMethodsAttribute);
}
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
visitAnyAttribute(clazz, sourceFileAttribute);
}
public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
{
visitAnyAttribute(clazz, sourceDirAttribute);
}
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
visitAnyAttribute(clazz, innerClassesAttribute);
}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
visitAnyAttribute(clazz, enclosingMethodAttribute);
}
public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
{
visitAnyAttribute(clazz, deprecatedAttribute);
}
/**
* Visits the given DeprecatedAttribute of any type of class member.
*/
public void visitDeprecatedAttribute(Clazz clazz, Member member, DeprecatedAttribute deprecatedAttribute)
{
visitDeprecatedAttribute(clazz, deprecatedAttribute);
}
public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
{
visitDeprecatedAttribute(clazz, (Member)field, deprecatedAttribute);
}
public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
{
visitDeprecatedAttribute(clazz, (Member)method, deprecatedAttribute);
}
public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
{
visitAnyAttribute(clazz, syntheticAttribute);
}
/**
* Visits the given SyntheticAttribute of any type of class member.
*/
public void visitSyntheticAttribute(Clazz clazz, Member member, SyntheticAttribute syntheticAttribute)
{
visitSyntheticAttribute(clazz, syntheticAttribute);
}
public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
{
visitSyntheticAttribute(clazz, (Member)field, syntheticAttribute);
}
public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
{
visitSyntheticAttribute(clazz, (Member)method, syntheticAttribute);
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
visitAnyAttribute(clazz, signatureAttribute);
}
/**
* Visits the given SignatureAttribute of any type of class member.
*/
public void visitSignatureAttribute(Clazz clazz, Member member, SignatureAttribute signatureAttribute)
{
visitSignatureAttribute(clazz, signatureAttribute);
}
public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute)
{
visitSignatureAttribute(clazz, (Member)field, signatureAttribute);
}
public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute)
{
visitSignatureAttribute(clazz, (Member)method, signatureAttribute);
}
public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
{
visitAnyAttribute(clazz, constantValueAttribute);
}
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
visitAnyAttribute(clazz, exceptionsAttribute);
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
visitAnyAttribute(clazz, codeAttribute);
}
public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
{
visitAnyAttribute(clazz, stackMapAttribute);
}
public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
{
visitAnyAttribute(clazz, stackMapTableAttribute);
}
public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
{
visitAnyAttribute(clazz, lineNumberTableAttribute);
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
visitAnyAttribute(clazz, localVariableTableAttribute);
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
visitAnyAttribute(clazz, localVariableTypeTableAttribute);
}
/**
* Visits any type of AnnotationsAttribute of a class.
*/
public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
{
visitAnyAttribute(clazz, annotationsAttribute);
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
visitAnyAnnotationsAttribute(clazz, runtimeVisibleAnnotationsAttribute);
}
/**
* Visits the given RuntimeVisibleAnnotationsAttribute of any type of class member.
*/
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Member member, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
visitRuntimeVisibleAnnotationsAttribute(clazz, runtimeVisibleAnnotationsAttribute);
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
visitRuntimeVisibleAnnotationsAttribute(clazz, (Member)field, runtimeVisibleAnnotationsAttribute);
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
visitRuntimeVisibleAnnotationsAttribute(clazz, (Member)method, runtimeVisibleAnnotationsAttribute);
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
visitAnyAnnotationsAttribute(clazz, runtimeInvisibleAnnotationsAttribute);
}
/**
* Visits the given RuntimeInvisibleAnnotationsAttribute of any type of class member.
*/
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Member member, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
visitRuntimeInvisibleAnnotationsAttribute(clazz, runtimeInvisibleAnnotationsAttribute);
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
visitRuntimeInvisibleAnnotationsAttribute(clazz, (Member)field, runtimeInvisibleAnnotationsAttribute);
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
visitRuntimeInvisibleAnnotationsAttribute(clazz, (Member)method, runtimeInvisibleAnnotationsAttribute);
}
/**
* Visits any type of ParameterAnnotationsAttribute.
*/
public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
{
visitAnyAttribute(clazz, parameterAnnotationsAttribute);
}
public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
{
visitAnyParameterAnnotationsAttribute(clazz, method, runtimeVisibleParameterAnnotationsAttribute);
}
public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
{
visitAnyParameterAnnotationsAttribute(clazz, method, runtimeInvisibleParameterAnnotationsAttribute);
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
visitAnyAttribute(clazz, annotationDefaultAttribute);
}
// Simplifications for InstructionVisitor.
/**
* Visits any type of Instruction.
*/
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
{
visitAnyInstruction(clazz, method, codeAttribute, offset, simpleInstruction);
}
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
{
visitAnyInstruction(clazz, method, codeAttribute, offset, variableInstruction);
}
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
visitAnyInstruction(clazz, method, codeAttribute, offset, constantInstruction);
}
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
{
visitAnyInstruction(clazz, method, codeAttribute, offset, branchInstruction);
}
/**
* Visits either type of SwitchInstruction.
*/
public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction)
{
visitAnyInstruction(clazz, method, codeAttribute, offset, switchInstruction);
}
public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)
{
visitAnySwitchInstruction(clazz, method, codeAttribute, offset, tableSwitchInstruction);
}
public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
{
visitAnySwitchInstruction(clazz, method, codeAttribute, offset, lookUpSwitchInstruction);
}
// Simplifications for StackMapFrameVisitor.
/**
* Visits any type of VerificationType.
*/
public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame)
{
visitAnyStackMapFrame(clazz, method, codeAttribute, offset, sameZeroFrame);
}
public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
{
visitAnyStackMapFrame(clazz, method, codeAttribute, offset, sameOneFrame);
}
public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame)
{
visitAnyStackMapFrame(clazz, method, codeAttribute, offset, lessZeroFrame);
}
public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
{
visitAnyStackMapFrame(clazz, method, codeAttribute, offset, moreZeroFrame);
}
public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
{
visitAnyStackMapFrame(clazz, method, codeAttribute, offset, fullFrame);
}
// Simplifications for VerificationTypeVisitor.
/**
* Visits any type of VerificationType.
*/
public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
public void visitIntegerType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, IntegerType integerType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, integerType);
}
public void visitFloatType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FloatType floatType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, floatType);
}
public void visitLongType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LongType longType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, longType);
}
public void visitDoubleType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, DoubleType doubleType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, doubleType);
}
public void visitTopType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TopType topType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, topType);
}
public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, objectType);
}
public void visitNullType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, NullType nullType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, nullType);
}
public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, uninitializedType);
}
public void visitUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedThisType uninitializedThisType)
{
visitAnyVerificationType(clazz, method, codeAttribute, offset, uninitializedThisType);
}
public void visitStackIntegerType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, IntegerType integerType)
{
visitIntegerType(clazz, method, codeAttribute, offset, integerType);
}
public void visitStackFloatType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, FloatType floatType)
{
visitFloatType(clazz, method, codeAttribute, offset, floatType);
}
public void visitStackLongType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, LongType longType)
{
visitLongType(clazz, method, codeAttribute, offset, longType);
}
public void visitStackDoubleType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, DoubleType doubleType)
{
visitDoubleType(clazz, method, codeAttribute, offset, doubleType);
}
public void visitStackTopType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, TopType topType)
{
visitTopType(clazz, method, codeAttribute, offset, topType);
}
public void visitStackObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, ObjectType objectType)
{
visitObjectType(clazz, method, codeAttribute, offset, objectType);
}
public void visitStackNullType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, NullType nullType)
{
visitNullType(clazz, method, codeAttribute, offset, nullType);
}
public void visitStackUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, UninitializedType uninitializedType)
{
visitUninitializedType(clazz, method, codeAttribute, offset, uninitializedType);
}
public void visitStackUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, UninitializedThisType uninitializedThisType)
{
visitUninitializedThisType(clazz, method, codeAttribute, offset, uninitializedThisType);
}
public void visitVariablesIntegerType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, IntegerType integerType)
{
visitIntegerType(clazz, method, codeAttribute, offset, integerType);
}
public void visitVariablesFloatType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, FloatType floatType)
{
visitFloatType(clazz, method, codeAttribute, offset, floatType);
}
public void visitVariablesLongType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, LongType longType)
{
visitLongType(clazz, method, codeAttribute, offset, longType);
}
public void visitVariablesDoubleType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, DoubleType doubleType)
{
visitDoubleType(clazz, method, codeAttribute, offset, doubleType);
}
public void visitVariablesTopType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, TopType topType)
{
visitTopType(clazz, method, codeAttribute, offset, topType);
}
public void visitVariablesObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, ObjectType objectType)
{
visitObjectType(clazz, method, codeAttribute, offset, objectType);
}
public void visitVariablesNullType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, NullType nullType)
{
visitNullType(clazz, method, codeAttribute, offset, nullType);
}
public void visitVariablesUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, UninitializedType uninitializedType)
{
visitUninitializedType(clazz, method, codeAttribute, offset, uninitializedType);
}
public void visitVariablesUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, int index, UninitializedThisType uninitializedThisType)
{
visitUninitializedThisType(clazz, method, codeAttribute, offset, uninitializedThisType);
}
// Simplifications for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
/**
* Visits the given Annotation of any type of class member.
*/
public void visitAnnotation(Clazz clazz, Member member, Annotation annotation)
{
visitAnnotation(clazz, annotation);
}
public void visitAnnotation(Clazz clazz, Field field, Annotation annotation)
{
visitAnnotation(clazz, (Member)field, annotation);
}
public void visitAnnotation(Clazz clazz, Method method, Annotation annotation)
{
visitAnnotation(clazz, (Member)method, annotation);
}
public void visitAnnotation(Clazz clazz, Method method, int parameterIndex, Annotation annotation)
{
visitAnnotation(clazz, method, annotation);
}
// Simplifications for ElementValueVisitor.
public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
{
visitAnyElementValue(clazz, annotation, constantElementValue);
}
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
{
visitAnyElementValue(clazz, annotation, enumConstantElementValue);
}
public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
{
visitAnyElementValue(clazz, annotation, classElementValue);
}
public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
{
visitAnyElementValue(clazz, annotation, annotationElementValue);
}
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
visitAnyElementValue(clazz, annotation, arrayElementValue);
}
}
proguard4.8/src/proguard/classfile/util/ExternalTypeEnumeration.java 0000644 0001750 0001750 00000005645 11736333524 024634 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.ClassConstants;
/**
* An ExternalTypeEnumeration
provides an enumeration of all
* types listed in a given external descriptor string. The method name can
* be retrieved separately.
* ExternalTypeEnumeration
object can be reused for processing
* different subsequent descriptors, by means of the setDescriptor
* method.
*
* @author Eric Lafortune
*/
public class ExternalTypeEnumeration
{
private String descriptor;
private int index;
public ExternalTypeEnumeration(String descriptor)
{
setDescriptor(descriptor);
}
ExternalTypeEnumeration()
{
}
void setDescriptor(String descriptor)
{
this.descriptor = descriptor;
reset();
}
public void reset()
{
index = descriptor.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN) + 1;
if (index < 1)
{
throw new IllegalArgumentException("Missing opening parenthesis in descriptor ["+descriptor+"]");
}
}
public boolean hasMoreTypes()
{
return index < descriptor.length() - 1;
}
public String nextType()
{
int startIndex = index;
// Find the next separating comma.
index = descriptor.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_SEPARATOR,
startIndex);
// Otherwise find the closing parenthesis.
if (index < 0)
{
index = descriptor.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_CLOSE,
startIndex);
if (index < 0)
{
throw new IllegalArgumentException("Missing closing parenthesis in descriptor ["+descriptor+"]");
}
}
return descriptor.substring(startIndex, index++).trim();
}
public String methodName()
{
return descriptor.substring(0, descriptor.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN)).trim();
}
}
proguard4.8/src/proguard/classfile/util/DescriptorClassEnumeration.java 0000644 0001750 0001750 00000016065 11736333524 025312 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.ClassConstants;
import java.util.Stack;
/**
* A DescriptorClassEnumeration
provides an enumeration of all
* classes mentioned in a given descriptor or signature.
*
* @author Eric Lafortune
*/
public class DescriptorClassEnumeration
{
private String descriptor;
private int index;
private int nestingLevel;
private boolean isInnerClassName;
private String accumulatedClassName;
private Stack accumulatedClassNames;
/**
* Creates a new DescriptorClassEnumeration for the given descriptor.
*/
public DescriptorClassEnumeration(String descriptor)
{
this.descriptor = descriptor;
}
/**
* Returns the number of classes contained in the descriptor. This
* is the number of class names that the enumeration will return.
*/
public int classCount()
{
int count = 0;
nextFluff();
while (hasMoreClassNames())
{
count++;
nextClassName();
nextFluff();
}
index = 0;
return count;
}
/**
* Returns whether the enumeration can provide more class names from the
* descriptor.
*/
public boolean hasMoreClassNames()
{
return index < descriptor.length();
}
/**
* Returns the next fluff (surrounding class names) from the descriptor.
*/
public String nextFluff()
{
int fluffStartIndex = index;
// Find the first token marking the start of a class name 'L' or '.'.
loop: while (index < descriptor.length())
{
switch (descriptor.charAt(index++))
{
case ClassConstants.INTERNAL_TYPE_GENERIC_START:
{
nestingLevel++;
// Make sure we have a stack.
if (accumulatedClassNames == null)
{
accumulatedClassNames = new Stack();
}
// Remember the accumulated class name.
accumulatedClassNames.push(accumulatedClassName);
break;
}
case ClassConstants.INTERNAL_TYPE_GENERIC_END:
{
nestingLevel--;
// Return to the accumulated class name outside the
// generic block.
accumulatedClassName = (String)accumulatedClassNames.pop();
continue loop;
}
case ClassConstants.INTERNAL_TYPE_GENERIC_BOUND:
{
continue loop;
}
case ClassConstants.INTERNAL_TYPE_CLASS_START:
{
// We've found the start of an ordinary class name.
nestingLevel += 2;
isInnerClassName = false;
break loop;
}
case ClassConstants.INTERNAL_TYPE_CLASS_END:
{
nestingLevel -= 2;
break;
}
case ClassConstants.EXTERNAL_INNER_CLASS_SEPARATOR:
{
// We've found the start of an inner class name in a signature.
isInnerClassName = true;
break loop;
}
case ClassConstants.INTERNAL_TYPE_GENERIC_VARIABLE_START:
{
// We've found the start of a type identifier. Skip to the end.
while (descriptor.charAt(index++) != ClassConstants.INTERNAL_TYPE_CLASS_END);
break;
}
}
if (nestingLevel == 1 &&
descriptor.charAt(index) != ClassConstants.INTERNAL_TYPE_GENERIC_END)
{
// We're at the start of a type parameter. Skip to the start
// of the bounds.
while (descriptor.charAt(index++) != ClassConstants.INTERNAL_TYPE_GENERIC_BOUND);
}
}
return descriptor.substring(fluffStartIndex, index);
}
/**
* Returns the next class name from the descriptor.
*/
public String nextClassName()
{
int classNameStartIndex = index;
// Find the first token marking the end of a class name '<' or ';'.
loop: while (true)
{
switch (descriptor.charAt(index))
{
case ClassConstants.INTERNAL_TYPE_GENERIC_START:
case ClassConstants.INTERNAL_TYPE_CLASS_END:
case ClassConstants.EXTERNAL_INNER_CLASS_SEPARATOR:
{
break loop;
}
}
index++;
}
String className = descriptor.substring(classNameStartIndex, index);
// Recompose the inner class name if necessary.
accumulatedClassName = isInnerClassName ?
accumulatedClassName + ClassConstants.INTERNAL_INNER_CLASS_SEPARATOR + className :
className;
return accumulatedClassName;
}
/**
* Returns whether the most recently returned class name was a recomposed
* inner class name from a signature.
*/
public boolean isInnerClassName()
{
return isInnerClassName;
}
/**
* A main method for testing the class name enumeration.
*/
public static void main(String[] args)
{
try
{
for (int index = 0; index < args.length; index++)
{
String descriptor = args[index];
System.out.println("Descriptor ["+descriptor+"]");
DescriptorClassEnumeration enumeration = new DescriptorClassEnumeration(descriptor);
System.out.println(" Fluff: ["+enumeration.nextFluff()+"]");
while (enumeration.hasMoreClassNames())
{
System.out.println(" Name: ["+enumeration.nextClassName()+"]");
System.out.println(" Fluff: ["+enumeration.nextFluff()+"]");
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
proguard4.8/src/proguard/classfile/util/WarningPrinter.java 0000644 0001750 0001750 00000006774 11736333524 022756 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.util.*;
import java.io.PrintStream;
import java.util.List;
/**
* This class prints out and counts warnings.
*
* @author Eric Lafortune
*/
public class WarningPrinter
{
private final PrintStream printStream;
private final StringMatcher classFilter;
private int warningCount;
/**
* Creates a new WarningPrinter that prints to the System.err print stream.
*/
public WarningPrinter()
{
this(System.err);
}
/**
* Creates a new WarningPrinter that prints to the given print stream.
*/
public WarningPrinter(PrintStream printStream)
{
this.printStream = printStream;
this.classFilter = null;
}
/**
* Creates a new WarningPrinter that prints to the given print stream,
* except if the names of any involved classes matches the given filter.
*/
public WarningPrinter(PrintStream printStream, List classFilter)
{
this.printStream = printStream;
this.classFilter = classFilter == null ? null :
new ListParser(new ClassNameParser()).parse(classFilter);
}
/**
* Prints out the given warning and increments the warning count, if
* the given class name passes the class name filter.
*/
public void print(String className, String warning)
{
if (accepts(className))
{
print(warning);
}
}
/**
* Returns whether the given class name passes the class name filter.
*/
public boolean accepts(String className)
{
return classFilter == null ||
!classFilter.matches(className);
}
/**
* Prints out the given warning and increments the warning count, if
* the given class names pass the class name filter.
*/
public void print(String className1, String className2, String warning)
{
if (accepts(className1, className2))
{
print(warning);
}
}
/**
* Returns whether the given class names pass the class name filter.
*/
public boolean accepts(String className1, String className2)
{
return classFilter == null ||
!(classFilter.matches(className1) ||
classFilter.matches(className2));
}
/**
* Prints out the given warning and increments the warning count.
*/
private void print(String warning)
{
printStream.println(warning);
warningCount++;
}
/**
* Returns the number of warnings printed so far.
*/
public int getWarningCount()
{
return warningCount;
}
}
proguard4.8/src/proguard/classfile/util/StringReferenceInitializer.java 0000644 0001750 0001750 00000005633 11736333524 025267 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
/**
* This ConstantVisitor initializes any class references of all string constants
* it visits. More specifically, it fills out the references of string constant
* pool entries that happen to refer to a class in the program class pool or in
* the library class pool.
*
* @author Eric Lafortune
*/
public class StringReferenceInitializer
extends SimplifiedVisitor
implements ConstantVisitor
{
private final ClassPool programClassPool;
private final ClassPool libraryClassPool;
/**
* Creates a new StringReferenceInitializer.
*/
public StringReferenceInitializer(ClassPool programClassPool,
ClassPool libraryClassPool)
{
this.programClassPool = programClassPool;
this.libraryClassPool = libraryClassPool;
}
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant) {}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
if (stringConstant.referencedClass == null)
{
// See if we can find the referenced class.
stringConstant.referencedClass =
findClass(ClassUtil.internalClassName(
ClassUtil.externalBaseType(stringConstant.getString(clazz))));
}
}
// Small utility methods.
/**
* Returns the class with the given name, either for the program class pool
* or from the library class pool, or null
if it can't be found.
*/
private Clazz findClass(String name)
{
// First look for the class in the program class pool.
Clazz clazz = programClassPool.getClass(name);
// Otherwise look for the class in the library class pool.
if (clazz == null)
{
clazz = libraryClassPool.getClass(name);
}
return clazz;
}
} proguard4.8/src/proguard/classfile/util/StringSharer.java 0000644 0001750 0001750 00000013201 11736333524 022377 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.util;
import proguard.classfile.*;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.visitor.ClassVisitor;
/**
* This ClassVisitor shares strings in the class files that it visits.
*
* @author Eric Lafortune
*/
public class StringSharer
extends SimplifiedVisitor
implements ClassVisitor,
ConstantVisitor,
AttributeVisitor
{
// A fields acting as an argument for the visitor methods.
private String name;
private String type;
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Replace name strings in the constant pool by shared strings.
programClass.constantPoolEntriesAccept(this);
// Replace attribute name strings in the constant pool by internalized
// strings.
programClass.attributesAccept(this);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Replace the super class name string by the shared name string.
Clazz superClass = libraryClass.superClass;
if (superClass != null)
{
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();
}
}
}
}
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant) {}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
Member referencedMember = stringConstant.referencedMember;
if (referencedMember != null)
{
Clazz referencedClass = stringConstant.referencedClass;
// Put the actual class member's name in the class pool.
name = referencedMember.getName(referencedClass);
clazz.constantPoolEntryAccept(stringConstant.u2stringIndex, this);
}
}
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
Member referencedMember = refConstant.referencedMember;
if (referencedMember != null)
{
Clazz referencedClass = refConstant.referencedClass;
// Put the actual class member's name and type strings in the class
// pool.
name = referencedMember.getName(referencedClass);
type = referencedMember.getDescriptor(referencedClass);
clazz.constantPoolEntryAccept(refConstant.u2nameAndTypeIndex, this);
}
}
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
if (name != null)
{
// Put the actual class member's name and type strings in the class
// pool.
clazz.constantPoolEntryAccept(nameAndTypeConstant.u2nameIndex, this);
name = type;
clazz.constantPoolEntryAccept(nameAndTypeConstant.u2descriptorIndex, this);
}
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
Clazz referencedClass = classConstant.referencedClass;
if (referencedClass != null)
{
// Put the actual class's name string in the class pool.
name = referencedClass.getName();
clazz.constantPoolEntryAccept(classConstant.u2nameIndex, this);
}
}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
// Do we have a new string to put into this constant?
if (name != null)
{
// Replace the string, if it's actually the same.
if (name.equals(utf8Constant.getString()))
{
utf8Constant.setString(name);
}
name = null;
}
}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute)
{
// Put the internalized attribute's name string in the class pool.
name = attribute.getAttributeName(clazz).intern();
clazz.constantPoolEntryAccept(attribute.u2attributeNameIndex, this);
}
}
proguard4.8/src/proguard/classfile/visitor/ 0000775 0001750 0001750 00000000000 11760503005 017636 5 ustar eric eric proguard4.8/src/proguard/classfile/visitor/package.html 0000644 0001750 0001750 00000004373 11736333524 022136 0 ustar eric eric {@link proguard.classfile proguard.classfile}
package using
the visitor pattern. Cfr., for instance, "Design Patterns, Elements of
Reusable OO Software", by Gamma, Helm, Johnson, and Vlissider.
instanceof
tests
on the elements of a list, followed by type casts and the proper operations.
Every list element is a visitor accepter. When its accept
method
is called by a visitor, it calls its corresponding visitX
method
in the visitor, passing itself as an argument. This technique is called
double-dispatch.
instanceof
tests and type casts. Also, implementing a visitor
interface ensures you're handling all possible visitor accepter types. Each
type has its own method, which you simply have to implement.
ClassVisitor
visit all
* classes involved in any .class
constructs that it visits.
* .class
constructs are actually
* compiled differently, using Class.forName
constructs.
*
* @author Eric Lafortune
*/
public class DotClassClassVisitor
extends SimplifiedVisitor
implements InstructionVisitor,
ConstantVisitor
{
private final ClassVisitor classVisitor;
/**
* Creates a new ClassHierarchyTraveler.
* @param classVisitor the ClassVisitor
to which visits will
* be delegated.
*/
public DotClassClassVisitor(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// 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)
{
byte opcode = constantInstruction.opcode;
// Could this instruction be a .class construct?
if (opcode == InstructionConstants.OP_LDC ||
opcode == InstructionConstants.OP_LDC_W)
{
clazz.constantPoolEntryAccept(constantInstruction.constantIndex,
this);
}
}
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant) {}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Visit the referenced class from the .class construct.
classConstant.referencedClassAccept(classVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/ImplementedClassFilter.java 0000644 0001750 0001750 00000004445 11736333524 025117 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, except for classes that extend or implement
* a given class.
*
* @author Eric Lafortune
*/
public class ImplementedClassFilter implements ClassVisitor
{
private final Clazz implementedClass;
private final ClassVisitor classVisitor;
/**
* Creates a new ImplementedClassFilter.
* @param implementedClass the class whose implementations will not be
* visited.
* @param classVisitor the ClassVisitor
to which visits will
* be delegated.
*/
public ImplementedClassFilter(Clazz implementedClass,
ClassVisitor classVisitor)
{
this.implementedClass = implementedClass;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (!programClass.extendsOrImplements(implementedClass))
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
if (!libraryClass.extendsOrImplements(implementedClass))
{
classVisitor.visitLibraryClass(libraryClass);
}
}
} proguard4.8/src/proguard/classfile/visitor/SimilarMemberVisitor.java 0000644 0001750 0001750 00000013327 11736333524 024627 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This MemberVisitor
lets a given MemberVisitor
* visit all members that have the same name and type as the visited methods
* in the class hierarchy of a given target class.
*
* @author Eric Lafortune
*/
public class SimilarMemberVisitor
implements MemberVisitor
{
private final Clazz targetClass;
private final boolean visitThisMember;
private final boolean visitSuperMembers;
private final boolean visitInterfaceMembers;
private final boolean visitOverridingMembers;
private final MemberVisitor memberVisitor;
/**
* Creates a new SimilarMemberVisitor.
* @param targetClass the class in whose hierarchy to look for
* the visited class members.
* @param visitThisMember specifies whether to visit the class
* members in the target class itself.
* @param visitSuperMembers specifies whether to visit the class
* members in the super classes of the target
* class.
* @param visitInterfaceMembers specifies whether to visit the class
* members in the interface classes of the
* target class.
* @param visitOverridingMembers specifies whether to visit the class
* members in the subclasses of the target
* class.
* @param memberVisitor the MemberVisitor
to which
* visits will be delegated.
*/
public SimilarMemberVisitor(Clazz targetClass,
boolean visitThisMember,
boolean visitSuperMembers,
boolean visitInterfaceMembers,
boolean visitOverridingMembers,
MemberVisitor memberVisitor)
{
this.targetClass = targetClass;
this.visitThisMember = visitThisMember;
this.visitSuperMembers = visitSuperMembers;
this.visitInterfaceMembers = visitInterfaceMembers;
this.visitOverridingMembers = visitOverridingMembers;
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
targetClass.hierarchyAccept(visitThisMember,
visitSuperMembers,
visitInterfaceMembers,
visitOverridingMembers,
new NamedFieldVisitor(programField.getName(programClass),
programField.getDescriptor(programClass),
memberVisitor));
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
targetClass.hierarchyAccept(visitThisMember,
visitSuperMembers,
visitInterfaceMembers,
visitOverridingMembers,
new NamedFieldVisitor(libraryField.getName(libraryClass),
libraryField.getDescriptor(libraryClass),
memberVisitor));
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
targetClass.hierarchyAccept(visitThisMember,
visitSuperMembers,
visitInterfaceMembers,
visitOverridingMembers,
new NamedMethodVisitor(programMethod.getName(programClass),
programMethod.getDescriptor(programClass),
memberVisitor));
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
targetClass.hierarchyAccept(visitThisMember,
visitSuperMembers,
visitInterfaceMembers,
visitOverridingMembers,
new NamedMethodVisitor(libraryMethod.getName(libraryClass),
libraryMethod.getDescriptor(libraryClass),
memberVisitor));
}
} proguard4.8/src/proguard/classfile/visitor/MemberAccessFilter.java 0000644 0001750 0001750 00000010360 11736333524 024210 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This MemberVisitor
delegates its visits to another given
* MemberVisitor
, but only when the visited member has the proper
* access flags.
* MemberVisitor
to
* which visits will be delegated.
*/
public MemberAccessFilter(int requiredSetAccessFlags,
int requiredUnsetAccessFlags,
MemberVisitor memberVisitor)
{
this.requiredSetAccessFlags = requiredSetAccessFlags & ~ACCESS_MASK;
this.requiredUnsetAccessFlags = requiredUnsetAccessFlags;
this.requiredOneSetAccessFlags = requiredSetAccessFlags & ACCESS_MASK;
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (accepted(programField.getAccessFlags()))
{
memberVisitor.visitProgramField(programClass, programField);
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (accepted(programMethod.getAccessFlags()))
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
if (accepted(libraryField.getAccessFlags()))
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (accepted(libraryMethod.getAccessFlags()))
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
}
// Small utility methods.
private boolean accepted(int accessFlags)
{
return (requiredSetAccessFlags & ~accessFlags) == 0 &&
(requiredUnsetAccessFlags & accessFlags) == 0 &&
(requiredOneSetAccessFlags == 0 ||
(requiredOneSetAccessFlags & accessFlags) != 0);
}
}
proguard4.8/src/proguard/classfile/visitor/VariableMemberVisitor.java 0000644 0001750 0001750 00000005032 11736333524 024746 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This MemberVisitor delegates all method calls to a MemberVisitor
* that can be changed at any time.
*
* @author Eric Lafortune
*/
public class VariableMemberVisitor implements MemberVisitor
{
private MemberVisitor memberVisitor;
public VariableMemberVisitor()
{
this(null);
}
public VariableMemberVisitor(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
public void setMemberVisitor(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
public MemberVisitor getMemberVisitor()
{
return memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (memberVisitor != null)
{
memberVisitor.visitProgramField(programClass, programField);
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (memberVisitor != null)
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
if (memberVisitor != null)
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (memberVisitor != null)
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
}
}
proguard4.8/src/proguard/classfile/visitor/SubclassTraveler.java 0000644 0001750 0001750 00000003443 11736333524 024001 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
lets a given ClassVisitor
* travel to direct subclasses of the visited class.
*
* @author Eric Lafortune
*/
public class SubclassTraveler implements ClassVisitor
{
private final ClassVisitor classVisitor;
/**
* Creates a new ClassHierarchyTraveler.
* @param classVisitor the ClassVisitor
to
* which visits will be delegated.
*/
public SubclassTraveler(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.subclassesAccept(classVisitor);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
libraryClass.subclassesAccept(classVisitor);
}
} proguard4.8/src/proguard/classfile/visitor/ExceptionRangeFilter.java 0000644 0001750 0001750 00000005102 11736333524 024570 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.ExceptionInfoVisitor;
/**
* This ExceptionInfoVisitor
delegates its visits to another given
* ExceptionInfoVisitor
, but only when the visited exception
* overlaps with the given instruction range.
*
* @author Eric Lafortune
*/
public class ExceptionRangeFilter
implements ExceptionInfoVisitor
{
private final int startOffset;
private final int endOffset;
private final ExceptionInfoVisitor exceptionInfoVisitor;
/**
* Creates a new ExceptionRangeFilter.
* @param startOffset the start offset of the instruction range.
* @param endOffset the end offset of the instruction range.
* @param exceptionInfoVisitor the ExceptionInfoVisitor to which visits
* will be delegated.
*/
public ExceptionRangeFilter(int startOffset,
int endOffset,
ExceptionInfoVisitor exceptionInfoVisitor)
{
this.startOffset = startOffset;
this.endOffset = endOffset;
this.exceptionInfoVisitor = exceptionInfoVisitor;
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
if (exceptionInfo.isApplicable(startOffset, endOffset))
{
exceptionInfoVisitor.visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
}
}
}
proguard4.8/src/proguard/classfile/visitor/ExceptionOffsetFilter.java 0000644 0001750 0001750 00000004524 11736333524 024771 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.ExceptionInfoVisitor;
/**
* This ExceptionInfoVisitor
delegates its visits to another given
* ExceptionInfoVisitor
, but only when the visited exception
* covers the instruction at the given offset.
*
* @author Eric Lafortune
*/
public class ExceptionOffsetFilter
implements ExceptionInfoVisitor
{
private final int instructionOffset;
private final ExceptionInfoVisitor exceptionInfoVisitor;
/**
* Creates a new ExceptionOffsetFilter.
* @param instructionOffset the instruction offset.
* @param exceptionInfoVisitor the ExceptionInfoVisitor to which visits
* will be delegated.
*/
public ExceptionOffsetFilter(int instructionOffset,
ExceptionInfoVisitor exceptionInfoVisitor)
{
this.instructionOffset = instructionOffset;
this.exceptionInfoVisitor = exceptionInfoVisitor;
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
if (exceptionInfo.isApplicable(instructionOffset))
{
exceptionInfoVisitor.visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
}
}
}
proguard4.8/src/proguard/classfile/visitor/ClassVersionSetter.java 0000644 0001750 0001750 00000004746 11736333524 024326 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import java.util.Set;
/**
* This ClassVisitor
sets the version number of the program classes
* that it visits.
*
* @author Eric Lafortune
*/
public class ClassVersionSetter implements ClassVisitor
{
private final int classVersion;
private final Set newerClassVersions;
/**
* Creates a new ClassVersionSetter.
* @param classVersion the class version number.
*/
public ClassVersionSetter(int classVersion)
{
this(classVersion, null);
}
/**
* Creates a new ClassVersionSetter that also stores any newer class version
* numbers that it encounters while visiting program classes.
* @param classVersion the class version number.
* @param newerClassVersions the Set
in which newer class
* version numbers can be collected.
*/
public ClassVersionSetter(int classVersion,
Set newerClassVersions)
{
this.classVersion = classVersion;
this.newerClassVersions = newerClassVersions;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (programClass.u4version > classVersion &&
newerClassVersions != null)
{
newerClassVersions.add(new Integer(programClass.u4version));
}
programClass.u4version = classVersion;
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Library classes don't have version numbers.
}
}
proguard4.8/src/proguard/classfile/visitor/ProgramMemberFilter.java 0000644 0001750 0001750 00000004350 11736333524 024420 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This MemberVisitor
delegates its visits to another given
* MemberVisitor
, but only when visiting members of program
* classes.
*
* @author Eric Lafortune
*/
public class ProgramMemberFilter implements MemberVisitor
{
private final MemberVisitor memberVisitor;
/**
* Creates a new ProgramMemberFilter.
* @param memberVisitor the MemberVisitor
to which
* visits will be delegated.
*/
public ProgramMemberFilter(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
memberVisitor.visitProgramField(programClass, programField);
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
// Don't delegate visits to library members.
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
// Don't delegate visits to library members.
}
}
proguard4.8/src/proguard/classfile/visitor/ClassHierarchyTraveler.java 0000644 0001750 0001750 00000006550 11736333524 025130 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
lets a given ClassVisitor
* optionally travel to the visited class, its superclass, its interfaces, and
* its subclasses.
*
* @author Eric Lafortune
*/
public class ClassHierarchyTraveler implements ClassVisitor
{
private final boolean visitThisClass;
private final boolean visitSuperClass;
private final boolean visitInterfaces;
private final boolean visitSubclasses;
private final ClassVisitor classVisitor;
/**
* Creates a new ClassHierarchyTraveler.
* @param visitThisClass specifies whether to visit the originally visited
* classes.
* @param visitSuperClass specifies whether to visit the super classes of
* the visited classes.
* @param visitInterfaces specifies whether to visit the interfaces of
* the visited classes.
* @param visitSubclasses specifies whether to visit the subclasses of
* the visited classes.
* @param classVisitor the ClassVisitor
to
* which visits will be delegated.
*/
public ClassHierarchyTraveler(boolean visitThisClass,
boolean visitSuperClass,
boolean visitInterfaces,
boolean visitSubclasses,
ClassVisitor classVisitor)
{
this.visitThisClass = visitThisClass;
this.visitSuperClass = visitSuperClass;
this.visitInterfaces = visitInterfaces;
this.visitSubclasses = visitSubclasses;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.hierarchyAccept(visitThisClass,
visitSuperClass,
visitInterfaces,
visitSubclasses,
classVisitor);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
libraryClass.hierarchyAccept(visitThisClass,
visitSuperClass,
visitInterfaces,
visitSubclasses,
classVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/ExceptClassesFilter.java 0000644 0001750 0001750 00000005006 11736333524 024426 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, except for classes are in a given list.
*
* @author Eric Lafortune
*/
public class ExceptClassesFilter implements ClassVisitor
{
private final Clazz[] exceptClasses;
private final ClassVisitor classVisitor;
/**
* Creates a new ExceptClassesFilter.
* @param exceptClasses the classes that will not be visited.
* @param classVisitor the ClassVisitor
to which visits will
* be delegated.
*/
public ExceptClassesFilter(Clazz[] exceptClasses,
ClassVisitor classVisitor)
{
this.exceptClasses = exceptClasses;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (!present(programClass))
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
if (!present(libraryClass))
{
classVisitor.visitLibraryClass(libraryClass);
}
}
// Small utility methods.
private boolean present(Clazz clazz)
{
if (exceptClasses == null)
{
return false;
}
for (int index = 0; index < exceptClasses.length; index++)
{
if (exceptClasses[index].equals(clazz))
{
return true;
}
}
return false;
}
} proguard4.8/src/proguard/classfile/visitor/AllClassVisitor.java 0000644 0001750 0001750 00000002651 11736333524 023573 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.ClassPool;
/**
* This ClassPoolVisitor lets a given ClassVisitor visit all Clazz
* objects of the class pools it visits.
*
* @author Eric Lafortune
*/
public class AllClassVisitor implements ClassPoolVisitor
{
private final ClassVisitor classVisitor;
public AllClassVisitor(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
public void visitClassPool(ClassPool classPool)
{
classPool.classesAccept(classVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/MethodImplementationTraveler.java 0000644 0001750 0001750 00000012634 11736333524 026352 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This MemberVisitor
lets a given MemberVisitor
* travel to all concrete and abstract implementations of the visited methods
* in their class hierarchies.
*
* @author Eric Lafortune
*/
public class MethodImplementationTraveler
extends SimplifiedVisitor
implements MemberVisitor
{
private final boolean visitThisMethod;
private final boolean visitSuperMethods;
private final boolean visitInterfaceMethods;
private final boolean visitOverridingMethods;
private final MemberVisitor memberVisitor;
/**
* Creates a new MethodImplementationTraveler.
* @param visitThisMethod specifies whether to visit the originally
* visited methods.
* @param visitSuperMethods specifies whether to visit the method in
* the super classes.
* @param visitInterfaceMethods specifies whether to visit the method in
* the interface classes.
* @param visitOverridingMethods specifies whether to visit the method in
* the subclasses.
* @param memberVisitor the MemberVisitor
to which
* visits will be delegated.
*/
public MethodImplementationTraveler(boolean visitThisMethod,
boolean visitSuperMethods,
boolean visitInterfaceMethods,
boolean visitOverridingMethods,
MemberVisitor memberVisitor)
{
this.visitThisMethod = visitThisMethod;
this.visitSuperMethods = visitSuperMethods;
this.visitInterfaceMethods = visitInterfaceMethods;
this.visitOverridingMethods = visitOverridingMethods;
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (visitThisMethod)
{
programMethod.accept(programClass, memberVisitor);
}
if (!isSpecial(programClass, programMethod))
{
programClass.hierarchyAccept(false,
visitSuperMethods,
visitInterfaceMethods,
visitOverridingMethods,
new NamedMethodVisitor(programMethod.getName(programClass),
programMethod.getDescriptor(programClass),
new MemberAccessFilter(0,
ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_STATIC,
memberVisitor)));
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (visitThisMethod)
{
libraryMethod.accept(libraryClass, memberVisitor);
}
if (!isSpecial(libraryClass, libraryMethod))
{
libraryClass.hierarchyAccept(false,
visitSuperMethods,
visitInterfaceMethods,
visitOverridingMethods,
new NamedMethodVisitor(libraryMethod.getName(libraryClass),
libraryMethod.getDescriptor(libraryClass),
new MemberAccessFilter(0,
ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_STATIC,
memberVisitor)));
}
}
// Small utility methods.
private boolean isSpecial(Clazz clazz, Method method)
{
return (method.getAccessFlags() &
(ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_STATIC)) != 0 ||
method.getName(clazz).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT);
}
}
proguard4.8/src/proguard/classfile/visitor/ReferencedClassVisitor.java 0000644 0001750 0001750 00000021223 11736333524 025121 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.annotation.visitor.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This ClassVisitor, MemberVisitor, ConstantVisitor, AttributeVisitor, etc.
* lets a given ClassVisitor visit all the referenced classes of the elements
* that it visits. Only downstream elements are considered (in order to avoid
* loops and repeated visits).
*
* @author Eric Lafortune
*/
public class ReferencedClassVisitor
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
ConstantVisitor,
AttributeVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
ElementValueVisitor
{
private final ClassVisitor classVisitor;
public ReferencedClassVisitor(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Visit the constant pool entries.
programClass.constantPoolEntriesAccept(this);
// Visit the fields and methods.
programClass.fieldsAccept(this);
programClass.methodsAccept(this);
// Visit the attributes.
programClass.attributesAccept(this);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Visit the superclass and interfaces.
libraryClass.superClassAccept(classVisitor);
libraryClass.interfacesAccept(classVisitor);
// Visit the fields and methods.
libraryClass.fieldsAccept(this);
libraryClass.methodsAccept(this);
}
// Implementations for MemberVisitor.
public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
// Let the visitor visit the classes referenced in the descriptor string.
programMember.referencedClassesAccept(classVisitor);
// Visit the attributes.
programMember.attributesAccept(programClass, this);
}
public void visitLibraryMember(LibraryClass programClass, LibraryMember libraryMember)
{
// Let the visitor visit the classes referenced in the descriptor string.
libraryMember.referencedClassesAccept(classVisitor);
}
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant) {}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
// Let the visitor visit the class referenced in the string constant.
stringConstant.referencedClassAccept(classVisitor);
}
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
// Let the visitor visit the class referenced in the reference constant.
refConstant.referencedClassAccept(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.
classConstant.referencedClassAccept(classVisitor);
}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
// Let the visitor visit the class of the enclosing method.
enclosingMethodAttribute.referencedClassAccept(classVisitor);
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
// Visit the attributes of the code attribute.
codeAttribute.attributesAccept(clazz, method, this);
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
// Visit the local variables.
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
// Visit the local variable types.
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
// Let the visitor visit the classes referenced in the signature string.
signatureAttribute.referencedClassesAccept(classVisitor);
}
public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
{
// Visit the annotations.
annotationsAttribute.annotationsAccept(clazz, this);
}
public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
{
// Visit the parameter annotations.
parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
// Visit the default element value.
annotationDefaultAttribute.defaultValueAccept(clazz, this);
}
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
// Let the visitor visit the class referenced in the local variable.
localVariableInfo.referencedClassAccept(classVisitor);
}
// Implementations for LocalVariableTypeInfoVisitor.
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
// Let the visitor visit the classes referenced in the local variable type.
localVariableTypeInfo.referencedClassesAccept(classVisitor);
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
// Let the visitor visit the classes referenced in the annotation.
annotation.referencedClassesAccept(classVisitor);
// Visit the element values.
annotation.elementValuesAccept(clazz, this);
}
// Implementations for ElementValueVisitor.
public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue) {}
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
{
// Let the visitor visit the classes referenced in the constant element value.
enumConstantElementValue.referencedClassesAccept(classVisitor);
}
public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
{
// Let the visitor visit the classes referenced in the class element value.
classElementValue.referencedClassesAccept(classVisitor);
}
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
// Visit the element values.
arrayElementValue.elementValuesAccept(clazz, annotation, this);
}
}
proguard4.8/src/proguard/classfile/visitor/NamedClassVisitor.java 0000644 0001750 0001750 00000002764 11736333524 024114 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.ClassPool;
/**
* This class visits Clazz objects with the given name.
*
* @author Eric Lafortune
*/
public class NamedClassVisitor implements ClassPoolVisitor
{
private final ClassVisitor classVisitor;
private final String name;
public NamedClassVisitor(ClassVisitor classVisitor,
String name)
{
this.classVisitor = classVisitor;
this.name = name;
}
public void visitClassPool(ClassPool classPool)
{
classPool.classAccept(name, classVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/AllMethodVisitor.java 0000644 0001750 0001750 00000003137 11736333524 023746 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor lets a given MemberVisitor visit all MethodMember
* objects of the classes it visits.
*
* @author Eric Lafortune
*/
public class AllMethodVisitor implements ClassVisitor
{
private final MemberVisitor memberVisitor;
public AllMethodVisitor(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.methodsAccept(memberVisitor);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
libraryClass.methodsAccept(memberVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/ClassCleaner.java 0000644 0001750 0001750 00000017527 11736333524 023064 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
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.Constant;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This ClassVisitor
removes all visitor information of the
* classes it visits.
*
* @author Eric Lafortune
*/
public class ClassCleaner
extends SimplifiedVisitor
implements ClassVisitor,
ConstantVisitor,
MemberVisitor,
AttributeVisitor,
ExceptionInfoVisitor,
InnerClassesInfoVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
AnnotationVisitor,
ElementValueVisitor
{
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
clean(programClass);
programClass.constantPoolEntriesAccept(this);
programClass.fieldsAccept(this);
programClass.methodsAccept(this);
programClass.attributesAccept(this);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
clean(libraryClass);
libraryClass.fieldsAccept(this);
libraryClass.methodsAccept(this);
}
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant)
{
clean(constant);
}
// Implementations for MemberVisitor.
public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
clean(programMember);
programMember.attributesAccept(programClass, this);
}
public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
{
clean(libraryMember);
}
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute)
{
clean(attribute);
}
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
clean(innerClassesAttribute);
innerClassesAttribute.innerClassEntriesAccept(clazz, this);
}
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
clean(exceptionsAttribute);
exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this);
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
clean(codeAttribute);
codeAttribute.exceptionsAccept(clazz, method, this);
codeAttribute.attributesAccept(clazz, method, this);
}
public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
{
clean(stackMapAttribute);
stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
}
public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
{
clean(stackMapTableAttribute);
stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
}
public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
{
clean(annotationsAttribute);
annotationsAttribute.annotationsAccept(clazz, this);
}
public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
{
clean(parameterAnnotationsAttribute);
parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
clean(annotationDefaultAttribute);
annotationDefaultAttribute.defaultValueAccept(clazz, this);
}
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
{
clean(innerClassesInfo);
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
clean(exceptionInfo);
}
// Implementations for StackMapFrameVisitor.
public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame)
{
clean(sameZeroFrame);
}
public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
{
clean(sameOneFrame);
sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
}
public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame)
{
clean(lessZeroFrame);
}
public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
{
clean(moreZeroFrame);
moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
}
public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
{
clean(fullFrame);
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)
{
clean(verificationType);
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
clean(annotation);
annotation.elementValuesAccept(clazz, this);
}
// Implementations for ElementValueVisitor.
public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
{
clean(elementValue);
}
public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
{
clean(annotationElementValue);
annotationElementValue.annotationAccept(clazz, this);
}
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
clean(arrayElementValue);
}
// Small utility methods.
private void clean(VisitorAccepter visitorAccepter)
{
visitorAccepter.setVisitorInfo(null);
}
}
proguard4.8/src/proguard/classfile/visitor/MethodImplementationFilter.java 0000644 0001750 0001750 00000004413 11736333524 026007 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This MemberVisitor
delegates its visits to methods to
* another given MemberVisitor
, but only when the visited
* method may have implementations.
*
* @see Clazz#mayHaveImplementations(Method)
* @author Eric Lafortune
*/
public class MethodImplementationFilter
extends SimplifiedVisitor
implements MemberVisitor
{
private final MemberVisitor memberVisitor;
/**
* Creates a new MethodImplementationFilter.
* @param memberVisitor the MemberVisitor
to which
* visits will be delegated.
*/
public MethodImplementationFilter(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (programClass.mayHaveImplementations(programMethod))
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (libraryClass.mayHaveImplementations(libraryMethod))
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
}
}
proguard4.8/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java 0000644 0001750 0001750 00000005022 11736333524 026621 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.constant.ClassConstant;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This ConstantVisitor
delegates its visits to class constants
* to another given ConstantVisitor
, except for classes that
* extend or implement a given class. This exception includes the class itself.
*
* @author Eric Lafortune
*/
public class ImplementedClassConstantFilter
extends SimplifiedVisitor
implements ConstantVisitor
{
private final Clazz implementedClass;
private final ConstantVisitor constantVisitor;
/**
* Creates a new ImplementedClassConstantFilter.
* @param implementedClass the class whose implementations will not be
* visited.
* @param constantVisitor the ConstantVisitor
to which visits
* will be delegated.
*/
public ImplementedClassConstantFilter(Clazz implementedClass,
ConstantVisitor constantVisitor)
{
this.implementedClass = implementedClass;
this.constantVisitor = constantVisitor;
}
// Implementations for ConstantVisitor.
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
Clazz referencedClass = classConstant.referencedClass;
if (referencedClass == null ||
!referencedClass.extendsOrImplements(implementedClass))
{
constantVisitor.visitClassConstant(clazz, classConstant);
}
}
} proguard4.8/src/proguard/classfile/visitor/ExceptClassFilter.java 0000644 0001750 0001750 00000004166 11736333524 024104 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, except for one given class.
*
* @author Eric Lafortune
*/
public class ExceptClassFilter implements ClassVisitor
{
private final Clazz exceptClass;
private final ClassVisitor classVisitor;
/**
* Creates a new ClassNameFilter.
* @param exceptClass the class that will not be visited.
* @param classVisitor the ClassVisitor
to which visits will
* be delegated.
*/
public ExceptClassFilter(Clazz exceptClass,
ClassVisitor classVisitor)
{
this.exceptClass = exceptClass;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (!programClass.equals(exceptClass))
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
if (!libraryClass.equals(exceptClass))
{
classVisitor.visitLibraryClass(libraryClass);
}
}
} proguard4.8/src/proguard/classfile/visitor/ClassVisitor.java 0000644 0001750 0001750 00000002342 11736333524 023137 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This interface specifies the methods for a visitor of
* Clazz
objects.
*
* @author Eric Lafortune
*/
public interface ClassVisitor
{
public void visitProgramClass(ProgramClass programClass);
public void visitLibraryClass(LibraryClass libraryClass);
}
proguard4.8/src/proguard/classfile/visitor/ClassPoolVisitor.java 0000644 0001750 0001750 00000002475 11736333524 024000 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.ClassPool;
/**
* This interface specifies the methods for a visitor of
* ClassPool
objects. Note that there is only a single
* implementation of ClassPool
, such that this interface
* is not strictly necessary as a visitor.
*
* @author Eric Lafortune
*/
public interface ClassPoolVisitor
{
public void visitClassPool(ClassPool classPool);
}
proguard4.8/src/proguard/classfile/visitor/ClassPresenceFilter.java 0000644 0001750 0001750 00000006143 11736333524 024415 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to one of two
* ClassVisitor
instances, depending on whether the name of
* the visited class file is present in a given ClassPool
or not.
*
* @author Eric Lafortune
*/
public class ClassPresenceFilter implements ClassVisitor
{
private final ClassPool classPool;
private final ClassVisitor presentClassVisitor;
private final ClassVisitor missingClassVisitor;
/**
* Creates a new ClassPresenceFilter.
* @param classPool the ClassPool
in which the
* presence will be tested.
* @param presentClassVisitor the ClassVisitor
to which visits
* of present class files will be delegated.
* @param missingClassVisitor the ClassVisitor
to which visits
* of missing class files will be delegated.
*/
public ClassPresenceFilter(ClassPool classPool,
ClassVisitor presentClassVisitor,
ClassVisitor missingClassVisitor)
{
this.classPool = classPool;
this.presentClassVisitor = presentClassVisitor;
this.missingClassVisitor = missingClassVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
ClassVisitor classFileVisitor = classFileVisitor(programClass);
if (classFileVisitor != null)
{
classFileVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
ClassVisitor classFileVisitor = classFileVisitor(libraryClass);
if (classFileVisitor != null)
{
classFileVisitor.visitLibraryClass(libraryClass);
}
}
// Small utility methods.
/**
* Returns the appropriate ClassVisitor
.
*/
private ClassVisitor classFileVisitor(Clazz clazz)
{
return classPool.getClass(clazz.getName()) != null ?
presentClassVisitor :
missingClassVisitor;
}
}
proguard4.8/src/proguard/classfile/visitor/MultiMemberVisitor.java 0000644 0001750 0001750 00000006504 11736333524 024320 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This MemberVisitor delegates all visits to each MemberVisitor
* in a given list.
*
* @author Eric Lafortune
*/
public class MultiMemberVisitor implements MemberVisitor
{
private static final int ARRAY_SIZE_INCREMENT = 5;
private MemberVisitor[] memberVisitors;
private int memberVisitorCount;
public MultiMemberVisitor()
{
}
public MultiMemberVisitor(MemberVisitor[] memberVisitors)
{
this.memberVisitors = memberVisitors;
this.memberVisitorCount = memberVisitors.length;
}
public void addMemberVisitor(MemberVisitor memberVisitor)
{
ensureArraySize();
memberVisitors[memberVisitorCount++] = memberVisitor;
}
private void ensureArraySize()
{
if (memberVisitors == null)
{
memberVisitors = new MemberVisitor[ARRAY_SIZE_INCREMENT];
}
else if (memberVisitors.length == memberVisitorCount)
{
MemberVisitor[] newMemberVisitors =
new MemberVisitor[memberVisitorCount +
ARRAY_SIZE_INCREMENT];
System.arraycopy(memberVisitors, 0,
newMemberVisitors, 0,
memberVisitorCount);
memberVisitors = newMemberVisitors;
}
}
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
for (int index = 0; index < memberVisitorCount; index++)
{
memberVisitors[index].visitProgramField(programClass, programField);
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
for (int index = 0; index < memberVisitorCount; index++)
{
memberVisitors[index].visitProgramMethod(programClass, programMethod);
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
for (int index = 0; index < memberVisitorCount; index++)
{
memberVisitors[index].visitLibraryField(libraryClass, libraryField);
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
for (int index = 0; index < memberVisitorCount; index++)
{
memberVisitors[index].visitLibraryMethod(libraryClass, libraryMethod);
}
}
}
proguard4.8/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java 0000644 0001750 0001750 00000004575 11736333524 026455 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.ExceptionInfoVisitor;
/**
* This ExceptionInfoVisitor
delegates its visits to another given
* ExceptionInfoVisitor
, but only when the visited exception
* does not cover the instruction at the given offset.
*
* @author Eric Lafortune
*/
public class ExceptionExcludedOffsetFilter
implements ExceptionInfoVisitor
{
private final int instructionOffset;
private final ExceptionInfoVisitor exceptionInfoVisitor;
/**
* Creates a new ExceptionExcludedOffsetFilter.
* @param instructionOffset the instruction offset.
* @param exceptionInfoVisitor the ExceptionInfoVisitor to which visits
* will be delegated.
*/
public ExceptionExcludedOffsetFilter(int instructionOffset,
ExceptionInfoVisitor exceptionInfoVisitor)
{
this.instructionOffset = instructionOffset;
this.exceptionInfoVisitor = exceptionInfoVisitor;
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
if (!exceptionInfo.isApplicable(instructionOffset))
{
exceptionInfoVisitor.visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
}
}
}
proguard4.8/src/proguard/classfile/visitor/SimpleClassPrinter.java 0000644 0001750 0001750 00000013554 11736333524 024304 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.util.ClassUtil;
import java.io.PrintStream;
/**
* This ClassVisitor
and MemberVisitor
* prints out the class names of the classes it visits, and the full class
* member descriptions of the class members it visits. The names are printed
* in a readable, Java-like format. The access modifiers can be included or not.
*
* @author Eric Lafortune
*/
public class SimpleClassPrinter
implements ClassVisitor,
MemberVisitor
{
private final boolean printAccessModifiers;
private final PrintStream ps;
/**
* Creates a new SimpleClassPrinter that prints to
* System.out
, including the access modifiers.
*/
public SimpleClassPrinter()
{
this(true);
}
/**
* Creates a new SimpleClassPrinter that prints to
* System.out
, with or without the access modifiers.
*/
public SimpleClassPrinter(boolean printAccessModifiers)
{
this(printAccessModifiers, System.out);
}
/**
* Creates a new SimpleClassPrinter that prints to the given
* PrintStream
, with or without the access modifiers.
*/
public SimpleClassPrinter(boolean printAccessModifiers,
PrintStream printStream)
{
this.printAccessModifiers = printAccessModifiers;
this.ps = printStream;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
ps.println(ClassUtil.externalFullClassDescription(
printAccessModifiers ?
programClass.getAccessFlags() :
0,
programClass.getName()));
}
public void visitLibraryClass(LibraryClass libraryClass)
{
ps.println(ClassUtil.externalFullClassDescription(
printAccessModifiers ?
libraryClass.getAccessFlags() :
0,
libraryClass.getName()));
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
ps.println(ClassUtil.externalFullClassDescription(
printAccessModifiers ?
programClass.getAccessFlags() :
0,
programClass.getName()) +
": " +
ClassUtil.externalFullFieldDescription(
printAccessModifiers ?
programField.getAccessFlags() :
0,
programField.getName(programClass),
programField.getDescriptor(programClass)));
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
ps.println(ClassUtil.externalFullClassDescription(
printAccessModifiers ?
programClass.getAccessFlags() :
0,
programClass.getName()) +
": " +
ClassUtil.externalFullMethodDescription(
programClass.getName(),
printAccessModifiers ?
programMethod.getAccessFlags() :
0,
programMethod.getName(programClass),
programMethod.getDescriptor(programClass)));
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
ps.println(ClassUtil.externalFullClassDescription(
printAccessModifiers ?
libraryClass.getAccessFlags() :
0,
libraryClass.getName()) +
": " +
ClassUtil.externalFullFieldDescription(
printAccessModifiers ?
libraryField.getAccessFlags() :
0,
libraryField.getName(libraryClass),
libraryField.getDescriptor(libraryClass)));
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
ps.println(ClassUtil.externalFullClassDescription(
printAccessModifiers ?
libraryClass.getAccessFlags() :
0,
libraryClass.getName()) +
": " +
ClassUtil.externalFullMethodDescription(
libraryClass.getName(),
printAccessModifiers ?
libraryMethod.getAccessFlags() :
0,
libraryMethod.getName(libraryClass),
libraryMethod.getDescriptor(libraryClass)));
}
}
proguard4.8/src/proguard/classfile/visitor/ReferencedMemberVisitor.java 0000644 0001750 0001750 00000004507 11736333524 025271 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.Clazz;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This ConstantVisitor and ElementValueVisitor lets a given MemberVisitor
* visit all the referenced class members of the elements that it visits.
*
* @author Eric Lafortune
*/
public class ReferencedMemberVisitor
extends SimplifiedVisitor
implements ConstantVisitor,
ElementValueVisitor
{
private final MemberVisitor memberVisitor;
public ReferencedMemberVisitor(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant) {}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
stringConstant.referencedMemberAccept(memberVisitor);
}
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
refConstant.referencedMemberAccept(memberVisitor);
}
// Implementations for ElementValueVisitor.
public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
{
elementValue.referencedMethodAccept(memberVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java 0000644 0001750 0001750 00000004133 11736333524 027040 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.ExceptionInfoVisitor;
/**
* This ExceptionInfoVisitor
lets a given
* ConstantVisitor
visit all catch class constants of exceptions
* that it visits.
*
* @author Eric Lafortune
*/
public class ExceptionHandlerConstantVisitor
implements ExceptionInfoVisitor
{
private final ConstantVisitor constantVisitor;
/**
* Creates a new ExceptionHandlerConstantVisitor.
* @param constantVisitor the ConstantVisitor that will visit the catch
* class constants.
*/
public ExceptionHandlerConstantVisitor(ConstantVisitor constantVisitor)
{
this.constantVisitor = constantVisitor;
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
int catchType = exceptionInfo.u2catchType;
if (catchType != 0)
{
clazz.constantPoolEntryAccept(catchType, constantVisitor);
}
}
} proguard4.8/src/proguard/classfile/visitor/BottomClassFilter.java 0000644 0001750 0001750 00000004116 11736333524 024113 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, but only when visiting classes that don't
* have any subclasses.
*
* @author Eric Lafortune
*/
public class BottomClassFilter implements ClassVisitor
{
private final ClassVisitor classVisitor;
/**
* Creates a new ProgramClassFilter.
* @param classVisitor the ClassVisitor
to which visits
* will be delegated.
*/
public BottomClassFilter(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Is this a bottom class in the class hierarchy?
if (programClass.subClasses == null)
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Is this a bottom class in the class hierarchy?
if (libraryClass.subClasses == null)
{
classVisitor.visitLibraryClass(libraryClass);
}
}
}
proguard4.8/src/proguard/classfile/visitor/ProgramClassFilter.java 0000644 0001750 0001750 00000003467 11736333524 024266 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, but only when visiting program classes.
*
* @author Eric Lafortune
*/
public class ProgramClassFilter implements ClassVisitor
{
private final ClassVisitor classVisitor;
/**
* Creates a new ProgramClassFilter.
* @param classVisitor the ClassVisitor
to which visits
* will be delegated.
*/
public ProgramClassFilter(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
classVisitor.visitProgramClass(programClass);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Don't delegate visits to library classes.
}
}
proguard4.8/src/proguard/classfile/visitor/MemberDescriptorFilter.java 0000644 0001750 0001750 00000007336 11736333524 025136 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.util.*;
/**
* This MemberVisitor
delegates its visits to another given
* MemberVisitor
, but only when the visited member
* has a descriptor that matches a given regular expression.
*
* @author Eric Lafortune
*/
public class MemberDescriptorFilter implements MemberVisitor
{
private final StringMatcher regularExpressionMatcher;
private final MemberVisitor memberVisitor;
/**
* Creates a new MemberDescriptorFilter.
* @param regularExpression the regular expression against which member
* descriptors will be matched.
* @param memberVisitor the MemberVisitor
to which visits
* will be delegated.
*/
public MemberDescriptorFilter(String regularExpression,
MemberVisitor memberVisitor)
{
this(new ClassNameParser().parse(regularExpression), memberVisitor);
}
/**
* Creates a new MemberDescriptorFilter.
* @param regularExpressionMatcher the regular expression against which
* member descriptors will be matched.
* @param memberVisitor the MemberVisitor
to which
* visits will be delegated.
*/
public MemberDescriptorFilter(StringMatcher regularExpressionMatcher,
MemberVisitor memberVisitor)
{
this.regularExpressionMatcher = regularExpressionMatcher;
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (accepted(programField.getDescriptor(programClass)))
{
memberVisitor.visitProgramField(programClass, programField);
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (accepted(programMethod.getDescriptor(programClass)))
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
if (accepted(libraryField.getDescriptor(libraryClass)))
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (accepted(libraryMethod.getDescriptor(libraryClass)))
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
}
// Small utility methods.
private boolean accepted(String name)
{
return regularExpressionMatcher.matches(name);
}
}
proguard4.8/src/proguard/classfile/visitor/ClassAccessFilter.java 0000644 0001750 0001750 00000005550 11736333524 024053 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, but only when the visited class
* has the proper access flags.
*
* @see ClassConstants
*
* @author Eric Lafortune
*/
public class ClassAccessFilter implements ClassVisitor
{
private final int requiredSetAccessFlags;
private final int requiredUnsetAccessFlags;
private final ClassVisitor classVisitor;
/**
* Creates a new ClassAccessFilter.
* @param requiredSetAccessFlags the class access flags that should be
* set.
* @param requiredUnsetAccessFlags the class access flags that should be
* unset.
* @param classVisitor the ClassVisitor
to
* which visits will be delegated.
*/
public ClassAccessFilter(int requiredSetAccessFlags,
int requiredUnsetAccessFlags,
ClassVisitor classVisitor)
{
this.requiredSetAccessFlags = requiredSetAccessFlags;
this.requiredUnsetAccessFlags = requiredUnsetAccessFlags;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (accepted(programClass.getAccessFlags()))
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
if (accepted(libraryClass.getAccessFlags()))
{
classVisitor.visitLibraryClass(libraryClass);
}
}
// Small utility methods.
private boolean accepted(int accessFlags)
{
return (requiredSetAccessFlags & ~accessFlags) == 0 &&
(requiredUnsetAccessFlags & accessFlags) == 0;
}
}
proguard4.8/src/proguard/classfile/visitor/NamedFieldVisitor.java 0000644 0001750 0001750 00000003603 11736333524 024063 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This class visits ProgramMember objects referring to fields, identified by
* a name and descriptor pair.
*
* @author Eric Lafortune
*/
public class NamedFieldVisitor implements ClassVisitor
{
private final String name;
private final String descriptor;
private final MemberVisitor memberVisitor;
public NamedFieldVisitor(String name,
String descriptor,
MemberVisitor memberVisitor)
{
this.name = name;
this.descriptor = descriptor;
this.memberVisitor = memberVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.fieldAccept(name, descriptor, memberVisitor);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
libraryClass.fieldAccept(name, descriptor, memberVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/AllMemberVisitor.java 0000644 0001750 0001750 00000003275 11736333524 023740 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor lets a given MemberVisitor visit all Member
* objects of the classes it visits.
*
* @author Eric Lafortune
*/
public class AllMemberVisitor implements ClassVisitor
{
private final MemberVisitor memberVisitor;
public AllMemberVisitor(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.fieldsAccept(memberVisitor);
programClass.methodsAccept(memberVisitor);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
libraryClass.fieldsAccept(memberVisitor);
libraryClass.methodsAccept(memberVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/ExceptionHandlerFilter.java 0000644 0001750 0001750 00000005225 11736333524 025117 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.ExceptionInfoVisitor;
/**
* This ExceptionInfoVisitor
delegates its visits to another given
* ExceptionInfoVisitor
, but only when the visited exception
* targets an instruction in the given range of offsets.
*
* @author Eric Lafortune
*/
public class ExceptionHandlerFilter
implements ExceptionInfoVisitor
{
private final int startOffset;
private final int endOffset;
private final ExceptionInfoVisitor exceptionInfoVisitor;
/**
* Creates a new ExceptionHandlerFilter.
* @param startOffset the start of the instruction offset range.
* @param endOffset the end of the instruction offset range.
* @param exceptionInfoVisitor the ExceptionInfoVisitor to which visits
* will be delegated.
*/
public ExceptionHandlerFilter(int startOffset,
int endOffset,
ExceptionInfoVisitor exceptionInfoVisitor)
{
this.startOffset = startOffset;
this.endOffset = endOffset;
this.exceptionInfoVisitor = exceptionInfoVisitor;
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
int handlerPC = exceptionInfo.u2handlerPC;
if (handlerPC >= startOffset &&
handlerPC < endOffset)
{
exceptionInfoVisitor.visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
}
}
} proguard4.8/src/proguard/classfile/visitor/MultiClassVisitor.java 0000644 0001750 0001750 00000005316 11736333524 024156 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor delegates all visits to each ClassVisitor
* in a given list.
*
* @author Eric Lafortune
*/
public class MultiClassVisitor implements ClassVisitor
{
private static final int ARRAY_SIZE_INCREMENT = 5;
private ClassVisitor[] classVisitors;
private int classVisitorCount;
public MultiClassVisitor()
{
}
public MultiClassVisitor(ClassVisitor[] classVisitors)
{
this.classVisitors = classVisitors;
this.classVisitorCount = classVisitors.length;
}
public void addClassVisitor(ClassVisitor classVisitor)
{
ensureArraySize();
classVisitors[classVisitorCount++] = classVisitor;
}
private void ensureArraySize()
{
if (classVisitors == null)
{
classVisitors = new ClassVisitor[ARRAY_SIZE_INCREMENT];
}
else if (classVisitors.length == classVisitorCount)
{
ClassVisitor[] newClassVisitors =
new ClassVisitor[classVisitorCount +
ARRAY_SIZE_INCREMENT];
System.arraycopy(classVisitors, 0,
newClassVisitors, 0,
classVisitorCount);
classVisitors = newClassVisitors;
}
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
for (int index = 0; index < classVisitorCount; index++)
{
classVisitors[index].visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
for (int index = 0; index < classVisitorCount; index++)
{
classVisitors[index].visitLibraryClass(libraryClass);
}
}
}
proguard4.8/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java 0000644 0001750 0001750 00000006167 11736333524 025610 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
lets a given ClassVisitor
* travel to the first concrete subclasses down in its hierarchy of abstract
* classes and concrete classes.
*
* @author Eric Lafortune
*/
public class ConcreteClassDownTraveler
implements ClassVisitor
{
private final ClassVisitor classVisitor;
/**
* Creates a new ConcreteClassDownTraveler.
* @param classVisitor the ClassVisitor
to
* which visits will be delegated.
*/
public ConcreteClassDownTraveler(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Is this an abstract class or an interface?
if ((programClass.getAccessFlags() &
(ClassConstants.INTERNAL_ACC_INTERFACE |
ClassConstants.INTERNAL_ACC_ABSTRACT)) != 0)
{
// Travel down the hierarchy.
Clazz[] subClasses = programClass.subClasses;
if (subClasses != null)
{
for (int index = 0; index < subClasses.length; index++)
{
subClasses[index].accept(this);
}
}
}
else
{
// Visit the class. Don't descend any further.
programClass.accept(classVisitor);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Is this an abstract class or interface?
if ((libraryClass.getAccessFlags() &
(ClassConstants.INTERNAL_ACC_INTERFACE |
ClassConstants.INTERNAL_ACC_ABSTRACT)) != 0)
{
// Travel down the hierarchy.
Clazz[] subClasses = libraryClass.subClasses;
if (subClasses != null)
{
for (int index = 0; index < subClasses.length; index++)
{
subClasses[index].accept(this);
}
}
}
else
{
// Visit the class. Don't descend any further.
libraryClass.accept(classVisitor);
}
}
}
proguard4.8/src/proguard/classfile/visitor/LibraryMemberFilter.java 0000644 0001750 0001750 00000004350 11736333524 024415 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This MemberVisitor
delegates its visits to another given
* MemberVisitor
, but only when visiting members of library
* classes.
*
* @author Eric Lafortune
*/
public class LibraryMemberFilter implements MemberVisitor
{
private final MemberVisitor memberVisitor;
/**
* Creates a new ProgramMemberFilter.
* @param memberVisitor the MemberVisitor
to which
* visits will be delegated.
*/
public LibraryMemberFilter(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
// Don't delegate visits to program members.
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
// Don't delegate visits to program members.
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
}
proguard4.8/src/proguard/classfile/visitor/ClassCollector.java 0000644 0001750 0001750 00000003154 11736333524 023430 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.Clazz;
import proguard.classfile.util.SimplifiedVisitor;
import java.util.Set;
/**
* This ClassVisitor
collects the classes that it visits in the
* given collection.
*
* @author Eric Lafortune
*/
public class ClassCollector
extends SimplifiedVisitor
implements ClassVisitor
{
private final Set set;
/**
* Creates a new ClassCollector.
* @param set the Set
in which all class names will be
* collected.
*/
public ClassCollector(Set set)
{
this.set = set;
}
// Implementations for ClassVisitor.
public void visitAnyClass(Clazz clazz)
{
set.add(clazz);
}
}
proguard4.8/src/proguard/classfile/visitor/NamedMethodVisitor.java 0000644 0001750 0001750 00000003612 11736333524 024260 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This class visits ProgramMember objects referring to methods, identified by
* a name and descriptor pair.
*
* @author Eric Lafortune
*/
public class NamedMethodVisitor implements ClassVisitor
{
private final String name;
private final String descriptor;
private final MemberVisitor memberVisitor;
public NamedMethodVisitor(String name,
String descriptor,
MemberVisitor memberVisitor)
{
this.name = name;
this.descriptor = descriptor;
this.memberVisitor = memberVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.methodAccept(name, descriptor, memberVisitor);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
libraryClass.methodAccept(name, descriptor, memberVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/MemberCollector.java 0000644 0001750 0001750 00000003321 11736333524 023566 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.util.SimplifiedVisitor;
import java.util.Set;
/**
* This MemberVisitor collects the concatenated name/descriptor strings of
* class members that have been visited.
*
* @author Eric Lafortune
*/
public class MemberCollector
extends SimplifiedVisitor
implements MemberVisitor
{
private final Set set;
/**
* Creates a new MemberCollector.
* @param set the Set
in which all method names/descriptor
* strings will be collected.
*/
public MemberCollector(Set set)
{
this.set = set;
}
// Implementations for MemberVisitor.
public void visitAnyMember(Clazz clazz, Member member)
{
set.add(member.getName(clazz) + member.getDescriptor(clazz));
}
} proguard4.8/src/proguard/classfile/visitor/AllFieldVisitor.java 0000644 0001750 0001750 00000003132 11736333524 023544 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor lets a given MemberVisitor visit all FieldMember
* objects of the classes it visits.
*
* @author Eric Lafortune
*/
public class AllFieldVisitor implements ClassVisitor
{
private final MemberVisitor memberVisitor;
public AllFieldVisitor(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.fieldsAccept(memberVisitor);
}
public void visitLibraryClass(LibraryClass libraryClass)
{
libraryClass.fieldsAccept(memberVisitor);
}
}
proguard4.8/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java 0000644 0001750 0001750 00000005072 11736333524 027013 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.constant.ClassConstant;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This ConstantVisitor
delegates its visits to class constants
* to another given ConstantVisitor
, except for classes that
* are extended or implemented by a given class. This exception includes the
* class itself.
*
* @author Eric Lafortune
*/
public class ImplementingClassConstantFilter
extends SimplifiedVisitor
implements ConstantVisitor
{
private final Clazz implementingClass;
private final ConstantVisitor constantVisitor;
/**
* Creates a new ImplementingClassConstantFilter.
* @param implementingClass the class whose superclasses and interfaces will
* not be visited.
* @param constantVisitor the ConstantVisitor
to which visits
* will be delegated.
*/
public ImplementingClassConstantFilter(Clazz implementingClass,
ConstantVisitor constantVisitor)
{
this.implementingClass = implementingClass;
this.constantVisitor = constantVisitor;
}
// Implementations for ConstantVisitor.
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
Clazz referencedClass = classConstant.referencedClass;
if (referencedClass == null ||
!implementingClass.extendsOrImplements(referencedClass))
{
constantVisitor.visitClassConstant(clazz, classConstant);
}
}
} proguard4.8/src/proguard/classfile/visitor/ClassPoolFiller.java 0000644 0001750 0001750 00000003017 11736333524 023547 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This ClassVisitor collects all the classes it visits in a given
* class pool.
*
* @author Eric Lafortune
*/
public class ClassPoolFiller
extends SimplifiedVisitor
implements ClassVisitor
{
private final ClassPool classPool;
/**
* Creates a new ClassPoolFiller.
*/
public ClassPoolFiller(ClassPool classPool)
{
this.classPool = classPool;
}
// Implementations for ClassVisitor.
public void visitAnyClass(Clazz clazz)
{
classPool.addClass(clazz);
}
}
proguard4.8/src/proguard/classfile/visitor/VariableClassVisitor.java 0000644 0001750 0001750 00000003725 11736333524 024613 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor delegates all method calls to a ClassVisitor
* that can be changed at any time.
*
* @author Eric Lafortune
*/
public class VariableClassVisitor implements ClassVisitor
{
private ClassVisitor classVisitor;
public VariableClassVisitor()
{
this(null);
}
public VariableClassVisitor(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
public void setClassVisitor(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
public ClassVisitor getClassVisitor()
{
return classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (classVisitor != null)
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
if (classVisitor != null)
{
classVisitor.visitLibraryClass(libraryClass);
}
}
}
proguard4.8/src/proguard/classfile/visitor/MemberClassAccessFilter.java 0000644 0001750 0001750 00000007445 11736333524 025210 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.util.*;
/**
* This MemberVisitor
delegates its visits to another given
* MemberVisitor
, but only when the visited member is accessible
* from the given referencing class.
*
* @author Eric Lafortune
*/
public class MemberClassAccessFilter
implements MemberVisitor
{
private final Clazz referencingClass;
private final MemberVisitor memberVisitor;
/**
* Creates a new MemberAccessFilter.
* @param referencingClass the class that is accessing the member.
* @param memberVisitor the MemberVisitor
to which visits
* will be delegated.
*/
public MemberClassAccessFilter(Clazz referencingClass,
MemberVisitor memberVisitor)
{
this.referencingClass = referencingClass;
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (accepted(programClass, programField.getAccessFlags()))
{
memberVisitor.visitProgramField(programClass, programField);
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (accepted(programClass, programMethod.getAccessFlags()))
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
if (accepted(libraryClass, libraryField.getAccessFlags()))
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (accepted(libraryClass, libraryMethod.getAccessFlags()))
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
}
// Small utility methods.
private boolean accepted(Clazz clazz, int memberAccessFlags)
{
int accessLevel = AccessUtil.accessLevel(memberAccessFlags);
return
(accessLevel >= AccessUtil.PUBLIC ) ||
(accessLevel >= AccessUtil.PRIVATE && referencingClass.equals(clazz) ) ||
(accessLevel >= AccessUtil.PACKAGE_VISIBLE && (ClassUtil.internalPackageName(referencingClass.getName()).equals(
ClassUtil.internalPackageName(clazz.getName())))) ||
(accessLevel >= AccessUtil.PROTECTED && (referencingClass.extends_(clazz) ||
referencingClass.extendsOrImplements(clazz)) );
}
}
proguard4.8/src/proguard/classfile/visitor/ExceptionCounter.java 0000644 0001750 0001750 00000003137 11736333524 024013 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.ExceptionInfoVisitor;
/**
* This ExceptionInfoVisitor counts the number of exceptions that has been visited.
*
* @author Eric Lafortune
*/
public class ExceptionCounter implements ExceptionInfoVisitor
{
private int count;
/**
* Returns the number of exceptions that has been visited so far.
*/
public int getCount()
{
return count;
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
count++;
}
}
proguard4.8/src/proguard/classfile/visitor/ClassNameFilter.java 0000664 0001750 0001750 00000007122 11740563614 023531 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.util.*;
import java.util.List;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, but only when the visited class has a name that
* matches a given regular expression.
*
* @author Eric Lafortune
*/
public class ClassNameFilter implements ClassVisitor
{
private final StringMatcher regularExpressionMatcher;
private final ClassVisitor classVisitor;
/**
* Creates a new ClassNameFilter.
* @param regularExpression the regular expression against which class names
* will be matched.
* @param classVisitor the ClassVisitor
to which visits
* will be delegated.
*/
public ClassNameFilter(String regularExpression,
ClassVisitor classVisitor)
{
this(new ListParser(new ClassNameParser()).parse(regularExpression),
classVisitor);
}
/**
* Creates a new ClassNameFilter.
* @param regularExpression the regular expression against which class names
* will be matched.
* @param classVisitor the ClassVisitor
to which visits
* will be delegated.
*/
public ClassNameFilter(List regularExpression,
ClassVisitor classVisitor)
{
this(new ListParser(new ClassNameParser()).parse(regularExpression),
classVisitor);
}
/**
* Creates a new ClassNameFilter.
* @param regularExpressionMatcher the string matcher against which
* class names will be matched.
* @param classVisitor the ClassVisitor
to which
* visits will be delegated.
*/
public ClassNameFilter(StringMatcher regularExpressionMatcher,
ClassVisitor classVisitor)
{
this.regularExpressionMatcher = regularExpressionMatcher;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (accepted(programClass.getName()))
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
if (accepted(libraryClass.getName()))
{
classVisitor.visitLibraryClass(libraryClass);
}
}
// Small utility methods.
private boolean accepted(String name)
{
return regularExpressionMatcher.matches(name);
}
}
proguard4.8/src/proguard/classfile/visitor/MemberVisitor.java 0000644 0001750 0001750 00000003010 11736333524 023272 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This interface specifies the methods for a visitor of
* ProgramMember
objects and LibraryMember
* objects.
*
* @author Eric Lafortune
*/
public interface MemberVisitor
{
public void visitProgramField( ProgramClass programClass, ProgramField programField);
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod);
public void visitLibraryField( LibraryClass libraryClass, LibraryField libraryField);
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod);
}
proguard4.8/src/proguard/classfile/visitor/ClassPrinter.java 0000644 0001750 0001750 00000107347 11736333524 023136 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
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.*;
import java.io.PrintStream;
/**
* This ClassVisitor
prints out the complete internal
* structure of the classes it visits.
*
* @author Eric Lafortune
*/
public class ClassPrinter
extends SimplifiedVisitor
implements ClassVisitor,
ConstantVisitor,
MemberVisitor,
AttributeVisitor,
BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
LineNumberInfoVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
ElementValueVisitor,
InstructionVisitor
{
private static final String INDENTATION = " ";
private final PrintStream ps;
private int indentation;
/**
* Creates a new ClassPrinter that prints to System.out
.
*/
public ClassPrinter()
{
this(System.out);
}
/**
* Creates a new ClassPrinter that prints to the given
* PrintStream
.
*/
public ClassPrinter(PrintStream printStream)
{
ps = printStream;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
println("_____________________________________________________________________");
println(visitorInfo(programClass) + " " +
"Program class: " + programClass.getName());
indent();
println("Superclass: " + programClass.getSuperName());
println("Major version: 0x" + Integer.toHexString(ClassUtil.internalMajorClassVersion(programClass.u4version)));
println("Minor version: 0x" + Integer.toHexString(ClassUtil.internalMinorClassVersion(programClass.u4version)));
println("Access flags: 0x" + Integer.toHexString(programClass.u2accessFlags));
println(" = " +
((programClass.u2accessFlags & ClassConstants.INTERNAL_ACC_ANNOTATTION) != 0 ? "@ " : "") +
ClassUtil.externalClassAccessFlags(programClass.u2accessFlags) +
((programClass.u2accessFlags & ClassConstants.INTERNAL_ACC_ENUM) != 0 ? "enum " :
(programClass.u2accessFlags & ClassConstants.INTERNAL_ACC_INTERFACE) == 0 ? "class " :
"") +
ClassUtil.externalClassName(programClass.getName()) +
(programClass.u2superClass == 0 ? "" : " extends " +
ClassUtil.externalClassName(programClass.getSuperName())));
outdent();
println();
println("Interfaces (count = " + programClass.u2interfacesCount + "):");
indent();
programClass.interfaceConstantsAccept(this);
outdent();
println();
println("Constant Pool (count = " + programClass.u2constantPoolCount + "):");
indent();
programClass.constantPoolEntriesAccept(this);
outdent();
println();
println("Fields (count = " + programClass.u2fieldsCount + "):");
indent();
programClass.fieldsAccept(this);
outdent();
println();
println("Methods (count = " + programClass.u2methodsCount + "):");
indent();
programClass.methodsAccept(this);
outdent();
println();
println("Class file attributes (count = " + programClass.u2attributesCount + "):");
indent();
programClass.attributesAccept(this);
outdent();
println();
}
public void visitLibraryClass(LibraryClass libraryClass)
{
println("_____________________________________________________________________");
println(visitorInfo(libraryClass) + " " +
"Library class: " + libraryClass.getName());
indent();
println("Superclass: " + libraryClass.getSuperName());
println("Access flags: 0x" + Integer.toHexString(libraryClass.u2accessFlags));
println(" = " +
((libraryClass.u2accessFlags & ClassConstants.INTERNAL_ACC_ANNOTATTION) != 0 ? "@ " : "") +
ClassUtil.externalClassAccessFlags(libraryClass.u2accessFlags) +
((libraryClass.u2accessFlags & ClassConstants.INTERNAL_ACC_ENUM) != 0 ? "enum " :
(libraryClass.u2accessFlags & ClassConstants.INTERNAL_ACC_INTERFACE) == 0 ? "class " :
"") +
ClassUtil.externalClassName(libraryClass.getName()) +
(libraryClass.getSuperName() == null ? "" : " extends " +
ClassUtil.externalClassName(libraryClass.getSuperName())));
outdent();
println();
println("Interfaces (count = " + libraryClass.interfaceClasses.length + "):");
for (int index = 0; index < libraryClass.interfaceClasses.length; index++)
{
Clazz interfaceClass = libraryClass.interfaceClasses[index];
if (interfaceClass != null)
{
println(" + " + interfaceClass.getName());
}
}
println("Fields (count = " + libraryClass.fields.length + "):");
libraryClass.fieldsAccept(this);
println("Methods (count = " + libraryClass.methods.length + "):");
libraryClass.methodsAccept(this);
}
// Implementations for ConstantVisitor.
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
println(visitorInfo(integerConstant) + " Integer [" +
integerConstant.getValue() + "]");
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
println(visitorInfo(longConstant) + " Long [" +
longConstant.getValue() + "]");
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
println(visitorInfo(floatConstant) + " Float [" +
floatConstant.getValue() + "]");
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
println(visitorInfo(doubleConstant) + " Double [" +
doubleConstant.getValue() + "]");
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
println(visitorInfo(stringConstant) + " String [" +
clazz.getString(stringConstant.u2stringIndex) + "]");
}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
{
println(visitorInfo(utf8Constant) + " Utf8 [" +
utf8Constant.getString() + "]");
}
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.getName(fieldrefConstant.u2nameAndTypeIndex) + " " +
clazz.getType(fieldrefConstant.u2nameAndTypeIndex) + "]");
}
public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
{
println(visitorInfo(interfaceMethodrefConstant) + " InterfaceMethodref [" +
clazz.getClassName(interfaceMethodrefConstant.u2classIndex) + "." +
clazz.getName(interfaceMethodrefConstant.u2nameAndTypeIndex) + " " +
clazz.getType(interfaceMethodrefConstant.u2nameAndTypeIndex) + "]");
}
public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
{
println(visitorInfo(methodrefConstant) + " Methodref [" +
clazz.getClassName(methodrefConstant.u2classIndex) + "." +
clazz.getName(methodrefConstant.u2nameAndTypeIndex) + " " +
clazz.getType(methodrefConstant.u2nameAndTypeIndex) + "]");
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
println(visitorInfo(classConstant) + " Class [" +
clazz.getString(classConstant.u2nameIndex) + "]");
}
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 [" +
clazz.getString(nameAndTypeConstant.u2nameIndex) + " " +
clazz.getString(nameAndTypeConstant.u2descriptorIndex) + "]");
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
println(visitorInfo(programField) + " " +
"Field: " +
programField.getName(programClass) + " " +
programField.getDescriptor(programClass));
indent();
println("Access flags: 0x" + Integer.toHexString(programField.u2accessFlags));
println(" = " +
ClassUtil.externalFullFieldDescription(programField.u2accessFlags,
programField.getName(programClass),
programField.getDescriptor(programClass)));
visitMember(programClass, programField);
outdent();
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
println(visitorInfo(programMethod) + " " +
"Method: " +
programMethod.getName(programClass) +
programMethod.getDescriptor(programClass));
indent();
println("Access flags: 0x" + Integer.toHexString(programMethod.u2accessFlags));
println(" = " +
ClassUtil.externalFullMethodDescription(programClass.getName(),
programMethod.u2accessFlags,
programMethod.getName(programClass),
programMethod.getDescriptor(programClass)));
visitMember(programClass, programMethod);
outdent();
}
private void visitMember(ProgramClass programClass, ProgramMember programMember)
{
if (programMember.u2attributesCount > 0)
{
println("Class member attributes (count = " + programMember.u2attributesCount + "):");
programMember.attributesAccept(programClass, this);
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
println(visitorInfo(libraryField) + " " +
"Field: " +
libraryField.getName(libraryClass) + " " +
libraryField.getDescriptor(libraryClass));
indent();
println("Access flags: 0x" + Integer.toHexString(libraryField.u2accessFlags));
println(" = " +
ClassUtil.externalFullFieldDescription(libraryField.u2accessFlags,
libraryField.getName(libraryClass),
libraryField.getDescriptor(libraryClass)));
outdent();
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
println(visitorInfo(libraryMethod) + " " +
"Method: " +
libraryMethod.getName(libraryClass) + " " +
libraryMethod.getDescriptor(libraryClass));
indent();
println("Access flags: 0x" + Integer.toHexString(libraryMethod.u2accessFlags));
println(" = " +
ClassUtil.externalFullMethodDescription(libraryClass.getName(),
libraryMethod.u2accessFlags,
libraryMethod.getName(libraryClass),
libraryMethod.getDescriptor(libraryClass)));
outdent();
}
// Implementations for AttributeVisitor.
// Note that attributes are typically only referenced once, so we don't
// test if they are marked already.
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
println(visitorInfo(unknownAttribute) +
" Unknown attribute (" + clazz.getString(unknownAttribute.u2attributeNameIndex) + ")");
}
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) +
" Source file attribute:");
indent();
clazz.constantPoolEntryAccept(sourceFileAttribute.u2sourceFileIndex, this);
outdent();
}
public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
{
println(visitorInfo(sourceDirAttribute) +
" Source dir attribute:");
indent();
clazz.constantPoolEntryAccept(sourceDirAttribute.u2sourceDirIndex, this);
outdent();
}
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
println(visitorInfo(innerClassesAttribute) +
" Inner classes attribute (count = " + innerClassesAttribute.u2classesCount + ")");
indent();
innerClassesAttribute.innerClassEntriesAccept(clazz, this);
outdent();
}
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
println(visitorInfo(enclosingMethodAttribute) +
" Enclosing method attribute:");
indent();
clazz.constantPoolEntryAccept(enclosingMethodAttribute.u2classIndex, this);
if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
{
clazz.constantPoolEntryAccept(enclosingMethodAttribute.u2nameAndTypeIndex, this);
}
outdent();
}
public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
{
println(visitorInfo(deprecatedAttribute) +
" Deprecated attribute");
}
public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
{
println(visitorInfo(syntheticAttribute) +
" Synthetic attribute");
}
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
println(visitorInfo(signatureAttribute) +
" Signature attribute:");
indent();
clazz.constantPoolEntryAccept(signatureAttribute.u2signatureIndex, this);
outdent();
}
public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
{
println(visitorInfo(constantValueAttribute) +
" Constant value attribute:");
clazz.constantPoolEntryAccept(constantValueAttribute.u2constantValueIndex, this);
}
public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
{
println(visitorInfo(exceptionsAttribute) +
" Exceptions attribute (count = " + exceptionsAttribute.u2exceptionIndexTableLength + ")");
indent();
exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this);
outdent();
}
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
println(visitorInfo(codeAttribute) +
" Code attribute instructions (code length = "+ codeAttribute.u4codeLength +
", locals = "+ codeAttribute.u2maxLocals +
", stack = "+ codeAttribute.u2maxStack + "):");
indent();
codeAttribute.instructionsAccept(clazz, method, this);
println("Code attribute exceptions (count = " +
codeAttribute.u2exceptionTableLength + "):");
codeAttribute.exceptionsAccept(clazz, method, this);
println("Code attribute attributes (attribute count = " +
codeAttribute.u2attributesCount + "):");
codeAttribute.attributesAccept(clazz, method, this);
outdent();
}
public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
{
println(visitorInfo(codeAttribute) +
" Stack map attribute (count = "+
stackMapAttribute.u2stackMapFramesCount + "):");
indent();
stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
outdent();
}
public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
{
println(visitorInfo(codeAttribute) +
" Stack map table attribute (count = "+
stackMapTableAttribute.u2stackMapFramesCount + "):");
indent();
stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
outdent();
}
public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
{
println(visitorInfo(lineNumberTableAttribute) +
" Line number table attribute (count = " +
lineNumberTableAttribute.u2lineNumberTableLength + ")");
indent();
lineNumberTableAttribute.lineNumbersAccept(clazz, method, codeAttribute, this);
outdent();
}
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
println(visitorInfo(localVariableTableAttribute) +
" Local variable table attribute (count = " +
localVariableTableAttribute.u2localVariableTableLength + ")");
indent();
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
outdent();
}
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
println(visitorInfo(localVariableTypeTableAttribute) +
" Local variable type table attribute (count = "+
localVariableTypeTableAttribute.u2localVariableTypeTableLength + ")");
indent();
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
outdent();
}
public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
{
println(visitorInfo(runtimeVisibleAnnotationsAttribute) +
" Runtime visible annotations attribute:");
indent();
runtimeVisibleAnnotationsAttribute.annotationsAccept(clazz, this);
outdent();
}
public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
{
println(visitorInfo(runtimeInvisibleAnnotationsAttribute) +
" Runtime invisible annotations attribute:");
indent();
runtimeInvisibleAnnotationsAttribute.annotationsAccept(clazz, this);
outdent();
}
public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
{
println(visitorInfo(runtimeVisibleParameterAnnotationsAttribute) +
" Runtime visible parameter annotations attribute (parameter count = " + runtimeVisibleParameterAnnotationsAttribute.u2parametersCount + "):");
indent();
runtimeVisibleParameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
outdent();
}
public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
{
println(visitorInfo(runtimeInvisibleParameterAnnotationsAttribute) +
" Runtime invisible parameter annotations attribute (parameter count = " + runtimeInvisibleParameterAnnotationsAttribute.u2parametersCount + "):");
indent();
runtimeInvisibleParameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
outdent();
}
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
println(visitorInfo(annotationDefaultAttribute) +
" Annotation default attribute:");
indent();
annotationDefaultAttribute.defaultValueAccept(clazz, this);
outdent();
}
// 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)
{
println(visitorInfo(innerClassesInfo) +
" 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);
outdent();
}
// Implementations for InstructionVisitor.
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
{
println(instruction.toString(offset));
}
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
println(constantInstruction.toString(offset));
indent();
clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
outdent();
}
public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)
{
println(tableSwitchInstruction.toString(offset));
indent();
int[] jumpOffsets = tableSwitchInstruction.jumpOffsets;
for (int index = 0; index < jumpOffsets.length; index++)
{
int jumpOffset = jumpOffsets[index];
println(Integer.toString(tableSwitchInstruction.lowCase + index) + ": offset = " + jumpOffset + ", target = " + (offset + jumpOffset));
}
int defaultOffset = tableSwitchInstruction.defaultOffset;
println("default: offset = " + defaultOffset + ", target = "+ (offset + defaultOffset));
outdent();
}
public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
{
println(lookUpSwitchInstruction.toString(offset));
indent();
int[] cases = lookUpSwitchInstruction.cases;
int[] jumpOffsets = lookUpSwitchInstruction.jumpOffsets;
for (int index = 0; index < jumpOffsets.length; index++)
{
int jumpOffset = jumpOffsets[index];
println(Integer.toString(cases[index]) + ": offset = " + jumpOffset + ", target = " + (offset + jumpOffset));
}
int defaultOffset = lookUpSwitchInstruction.defaultOffset;
println("default: offset = " + defaultOffset + ", target = "+ (offset + defaultOffset));
outdent();
}
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
println(visitorInfo(exceptionInfo) +
" ExceptionInfo (" +
exceptionInfo.u2startPC + " -> " +
exceptionInfo.u2endPC + ": " +
exceptionInfo.u2handlerPC + "):");
if (exceptionInfo.u2catchType != 0)
{
clazz.constantPoolEntryAccept(exceptionInfo.u2catchType, this);
}
}
// Implementations for StackMapFrameVisitor.
public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame)
{
println(visitorInfo(sameZeroFrame) +
" [" + offset + "]" +
" Var: ..., Stack: (empty)");
}
public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
{
print(visitorInfo(sameOneFrame) +
" [" + offset + "]" +
" Var: ..., Stack: ");
sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
println();
}
public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame)
{
println(visitorInfo(lessZeroFrame) +
" [" + offset + "]" +
" Var: -" + lessZeroFrame.choppedVariablesCount +
", Stack: (empty)");
}
public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
{
print(visitorInfo(moreZeroFrame) +
" [" + offset + "]" +
" Var: ...");
moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
ps.println(", Stack: (empty)");
}
public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
{
print(visitorInfo(fullFrame) +
" [" + offset + "]" +
" Var: ");
fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);
ps.print(", Stack: ");
fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);
println();
}
// Implementations for VerificationTypeVisitor.
public void visitIntegerType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, IntegerType integerType)
{
ps.print("[i]");
}
public void visitFloatType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FloatType floatType)
{
ps.print("[f]");
}
public void visitLongType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LongType longType)
{
ps.print("[l]");
}
public void visitDoubleType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, DoubleType doubleType)
{
ps.print("[d]");
}
public void visitTopType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TopType topType)
{
ps.print("[T]");
}
public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
{
ps.print("[a:" + clazz.getClassName(objectType.u2classIndex) + "]");
}
public void visitNullType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, NullType nullType)
{
ps.print("[n]");
}
public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType)
{
ps.print("[u:" + uninitializedType.u2newInstructionOffset + "]");
}
public void visitUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedThisType uninitializedThisType)
{
ps.print("[u:this]");
}
// Implementations for LineNumberInfoVisitor.
public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo)
{
println("[" + lineNumberInfo.u2startPC + "] -> line " +
lineNumberInfo.u2lineNumber);
}
// Implementations for LocalVariableInfoVisitor.
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
println("v" + localVariableInfo.u2index + ": " +
localVariableInfo.u2startPC + " -> " +
(localVariableInfo.u2startPC + localVariableInfo.u2length) + " [" +
clazz.getString(localVariableInfo.u2descriptorIndex) + " " +
clazz.getString(localVariableInfo.u2nameIndex) + "]");
}
// Implementations for LocalVariableTypeInfoVisitor.
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
println("v" + localVariableTypeInfo.u2index + ": " +
localVariableTypeInfo.u2startPC + " -> " +
(localVariableTypeInfo.u2startPC + localVariableTypeInfo.u2length) + " [" +
clazz.getString(localVariableTypeInfo.u2signatureIndex) + " " +
clazz.getString(localVariableTypeInfo.u2nameIndex) + "]");
}
// Implementations for AnnotationVisitor.
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
println(visitorInfo(annotation) +
" Annotation [" + clazz.getString(annotation.u2typeIndex) + "]:");
indent();
annotation.elementValuesAccept(clazz, this);
outdent();
}
// Implementations for ElementValueVisitor.
public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
{
println(visitorInfo(constantElementValue) +
" Constant element value [" +
(constantElementValue.u2elementNameIndex == 0 ? "(default)" :
clazz.getString(constantElementValue.u2elementNameIndex)) + " '" +
constantElementValue.u1tag + "']");
indent();
clazz.constantPoolEntryAccept(constantElementValue.u2constantValueIndex, this);
outdent();
}
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
{
println(visitorInfo(enumConstantElementValue) +
" Enum constant element value [" +
(enumConstantElementValue.u2elementNameIndex == 0 ? "(default)" :
clazz.getString(enumConstantElementValue.u2elementNameIndex)) + ", " +
clazz.getString(enumConstantElementValue.u2typeNameIndex) + ", " +
clazz.getString(enumConstantElementValue.u2constantNameIndex) + "]");
}
public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
{
println(visitorInfo(classElementValue) +
" Class element value [" +
(classElementValue.u2elementNameIndex == 0 ? "(default)" :
clazz.getString(classElementValue.u2elementNameIndex)) + ", " +
clazz.getString(classElementValue.u2classInfoIndex) + "]");
}
public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
{
println(visitorInfo(annotationElementValue) +
" Annotation element value [" +
(annotationElementValue.u2elementNameIndex == 0 ? "(default)" :
clazz.getString(annotationElementValue.u2elementNameIndex)) + "]:");
indent();
annotationElementValue.annotationAccept(clazz, this);
outdent();
}
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
println(visitorInfo(arrayElementValue) +
" Array element value [" +
(arrayElementValue.u2elementNameIndex == 0 ? "(default)" :
clazz.getString(arrayElementValue.u2elementNameIndex)) + "]:");
indent();
arrayElementValue.elementValuesAccept(clazz, annotation, this);
outdent();
}
// Small utility methods.
private void indent()
{
indentation++;
}
private void outdent()
{
indentation--;
}
private void println(String string)
{
print(string);
println();
}
private void print(String string)
{
for (int index = 0; index < indentation; index++)
{
ps.print(INDENTATION);
}
ps.print(string);
}
private void println()
{
ps.println();
}
private String visitorInfo(VisitorAccepter visitorAccepter)
{
return visitorAccepter.getVisitorInfo() == null ? "-" : "+";
}
}
proguard4.8/src/proguard/classfile/visitor/SubclassFilter.java 0000644 0001750 0001750 00000005033 11736333524 023437 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, except for classes that have a given class as
* direct subclass.
*
* @author Eric Lafortune
*/
public class SubclassFilter implements ClassVisitor
{
private final Clazz subclass;
private final ClassVisitor classVisitor;
/**
* Creates a new SubclassFilter.
* @param subclass the class whose superclasses will not be visited.
* @param classVisitor the ClassVisitor
to which visits will
* be delegated.
*/
public SubclassFilter(Clazz subclass,
ClassVisitor classVisitor)
{
this.subclass = subclass;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (!present(programClass.subClasses))
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
if (!present(libraryClass.subClasses))
{
classVisitor.visitLibraryClass(libraryClass);
}
}
// Small utility methods.
private boolean present(Clazz[] subclasses)
{
if (subclasses == null)
{
return false;
}
for (int index = 0; index < subclasses.length; index++)
{
if (subclasses[index].equals(subclass))
{
return true;
}
}
return false;
}
} proguard4.8/src/proguard/classfile/visitor/MemberNameFilter.java 0000644 0001750 0001750 00000007205 11736333524 023673 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
import proguard.util.*;
/**
* This MemberVisitor
delegates its visits to another given
* MemberVisitor
, but only when the visited member
* has a name that matches a given regular expression.
*
* @author Eric Lafortune
*/
public class MemberNameFilter implements MemberVisitor
{
private final StringMatcher regularExpressionMatcher;
private final MemberVisitor memberVisitor;
/**
* Creates a new MemberNameFilter.
* @param regularExpression the regular expression against which member
* names will be matched.
* @param memberVisitor the MemberVisitor
to which visits
* will be delegated.
*/
public MemberNameFilter(String regularExpression,
MemberVisitor memberVisitor)
{
this(new NameParser().parse(regularExpression), memberVisitor);
}
/**
* Creates a new MemberNameFilter.
* @param regularExpressionMatcher the regular expression against which
* member names will be matched.
* @param memberVisitor the MemberVisitor
to which
* visits will be delegated.
*/
public MemberNameFilter(StringMatcher regularExpressionMatcher,
MemberVisitor memberVisitor)
{
this.regularExpressionMatcher = regularExpressionMatcher;
this.memberVisitor = memberVisitor;
}
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (accepted(programField.getName(programClass)))
{
memberVisitor.visitProgramField(programClass, programField);
}
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
if (accepted(programMethod.getName(programClass)))
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
if (accepted(libraryField.getName(libraryClass)))
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
if (accepted(libraryMethod.getName(libraryClass)))
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
}
// Small utility methods.
private boolean accepted(String name)
{
return regularExpressionMatcher.matches(name);
}
}
proguard4.8/src/proguard/classfile/visitor/ClassCounter.java 0000644 0001750 0001750 00000002764 11736333524 023127 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor counts the number of classes that has been visited.
*
* @author Eric Lafortune
*/
public class ClassCounter implements ClassVisitor
{
private int count;
/**
* Returns the number of classes that has been visited so far.
*/
public int getCount()
{
return count;
}
// Implementations for ClassVisitor.
public void visitLibraryClass(LibraryClass libraryClass)
{
count++;
}
public void visitProgramClass(ProgramClass programClass)
{
count++;
}
}
proguard4.8/src/proguard/classfile/visitor/LibraryClassFilter.java 0000644 0001750 0001750 00000003467 11736333524 024263 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to another given
* ClassVisitor
, but only when visiting library classes.
*
* @author Eric Lafortune
*/
public class LibraryClassFilter implements ClassVisitor
{
private final ClassVisitor classVisitor;
/**
* Creates a new LibraryClassFilter.
* @param classVisitor the ClassVisitor
to which visits
* will be delegated.
*/
public LibraryClassFilter(ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Don't delegate visits to program classes.
}
public void visitLibraryClass(LibraryClass libraryClass)
{
classVisitor.visitLibraryClass(libraryClass);
}
}
proguard4.8/src/proguard/classfile/visitor/MultiClassPoolVisitor.java 0000644 0001750 0001750 00000005202 11736333524 025002 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.ClassPool;
/**
* This ClassPoolVisitor delegates all visits to each ClassPoolVisitor
* in a given list.
*
* @author Eric Lafortune
*/
public class MultiClassPoolVisitor implements ClassPoolVisitor
{
private static final int ARRAY_SIZE_INCREMENT = 5;
private ClassPoolVisitor[] classPoolVisitors;
private int classPoolVisitorCount;
public MultiClassPoolVisitor()
{
}
public MultiClassPoolVisitor(ClassPoolVisitor[] classPoolVisitors)
{
this.classPoolVisitors = classPoolVisitors;
this.classPoolVisitorCount = classPoolVisitors.length;
}
public void addClassPoolVisitor(ClassPoolVisitor classPoolVisitor)
{
ensureArraySize();
classPoolVisitors[classPoolVisitorCount++] = classPoolVisitor;
}
private void ensureArraySize()
{
if (classPoolVisitors == null)
{
classPoolVisitors = new ClassPoolVisitor[ARRAY_SIZE_INCREMENT];
}
else if (classPoolVisitors.length == classPoolVisitorCount)
{
ClassPoolVisitor[] newClassPoolVisitors =
new ClassPoolVisitor[classPoolVisitorCount +
ARRAY_SIZE_INCREMENT];
System.arraycopy(classPoolVisitors, 0,
newClassPoolVisitors, 0,
classPoolVisitorCount);
classPoolVisitors = newClassPoolVisitors;
}
}
// Implementations for ClassPoolVisitor.
public void visitClassPool(ClassPool classPool)
{
for (int index = 0; index < classPoolVisitorCount; index++)
{
classPoolVisitors[index].visitClassPool(classPool);
}
}
}
proguard4.8/src/proguard/classfile/visitor/ClassVersionFilter.java 0000644 0001750 0001750 00000005713 11736333524 024300 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor;
import proguard.classfile.*;
/**
* This ClassVisitor
delegates its visits to program classes to
* another given ClassVisitor
, but only when the class version
* number of the visited program class lies in a given range.
*
* @author Eric Lafortune
*/
public class ClassVersionFilter implements ClassVisitor
{
private final int minimumClassVersion;
private final int maximumClassVersion;
private final ClassVisitor classVisitor;
/**
* Creates a new ClassVersionFilter.
* @param minimumClassVersion the minimum class version number.
* @param classVisitor the ClassVisitor
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 ClassVisitor
to which visits
* will be delegated.
*/
public ClassVersionFilter(int minimumClassVersion,
int maximumClassVersion,
ClassVisitor classVisitor)
{
this.minimumClassVersion = minimumClassVersion;
this.maximumClassVersion = maximumClassVersion;
this.classVisitor = classVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
if (programClass.u4version >= minimumClassVersion &&
programClass.u4version <= maximumClassVersion)
{
classVisitor.visitProgramClass(programClass);
}
}
public void visitLibraryClass(LibraryClass libraryClass)
{
// Library classes don't have version numbers.
}
}
proguard4.8/src/proguard/classfile/ProgramMember.java 0000644 0001750 0001750 00000011151 11736333524 021550 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.visitor.MemberVisitor;
/**
* Representation of a field or method from a program class.
*
* @author Eric Lafortune
*/
public abstract class ProgramMember implements Member
{
public int u2accessFlags;
public int u2nameIndex;
public int u2descriptorIndex;
public int u2attributesCount;
public Attribute[] attributes;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Creates an uninitialized ProgramMember.
*/
protected ProgramMember()
{
}
/**
* Creates an initialized ProgramMember.
*/
protected ProgramMember(int u2accessFlags,
int u2nameIndex,
int u2descriptorIndex,
int u2attributesCount,
Attribute[] attributes)
{
this.u2accessFlags = u2accessFlags;
this.u2nameIndex = u2nameIndex;
this.u2descriptorIndex = u2descriptorIndex;
this.u2attributesCount = u2attributesCount;
this.attributes = attributes;
}
/**
* Returns the line number range of the given class member as "m:n",
* if it can find it, or null
otherwise.
*/
public String getLineNumberRange(Clazz clazz)
{
CodeAttribute codeAttribute =
(CodeAttribute)getAttribute(clazz, ClassConstants.ATTR_Code);
if (codeAttribute == null)
{
return null;
}
LineNumberTableAttribute lineNumberTableAttribute =
(LineNumberTableAttribute)codeAttribute.getAttribute(clazz,
ClassConstants.ATTR_LineNumberTable);
if (lineNumberTableAttribute == null)
{
return null;
}
return "" +
lineNumberTableAttribute.getLineNumber(0) +
":" +
lineNumberTableAttribute.getLineNumber(Integer.MAX_VALUE);
}
/**
* Returns the (first) attribute with the given name.
*/
private Attribute getAttribute(Clazz clazz, String name)
{
for (int index = 0; index < u2attributesCount; index++)
{
Attribute attribute = attributes[index];
if (attribute.getAttributeName(clazz).equals(name))
{
return attribute;
}
}
return null;
}
/**
* Accepts the given member info visitor.
*/
public abstract void accept(ProgramClass programClass,
MemberVisitor memberVisitor);
/**
* Lets the given attribute info visitor visit all the attributes of
* this member info.
*/
public abstract void attributesAccept(ProgramClass programClass,
AttributeVisitor attributeVisitor);
// Implementations for Member.
public int getAccessFlags()
{
return u2accessFlags;
}
public String getName(Clazz clazz)
{
return clazz.getString(u2nameIndex);
}
public String getDescriptor(Clazz clazz)
{
return clazz.getString(u2descriptorIndex);
}
public void accept(Clazz clazz, MemberVisitor memberVisitor)
{
accept((ProgramClass)clazz, memberVisitor);
}
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
}
proguard4.8/src/proguard/classfile/VisitorAccepter.java 0000644 0001750 0001750 00000003070 11736333524 022120 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
/**
* This interface is a base interface for visitor accepters. It allows
* visitors to set and get any temporary information they desire on the
* objects they are visiting. Note that every visitor accepter has only one
* such property, so visitors will have to take care not to overwrite each
* other's information, if it is still required.
*
* @author Eric Lafortune
*/
public interface VisitorAccepter
{
/**
* Gets the visitor information of the visitor accepter.
*/
public Object getVisitorInfo();
/**
* Sets the visitor information of the visitor accepter.
*/
public void setVisitorInfo(Object visitorInfo);
}
proguard4.8/src/proguard/classfile/LibraryField.java 0000644 0001750 0001750 00000004257 11736333524 021372 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.visitor.*;
/**
* Representation of a field from a class-file.
*
* @author Eric Lafortune
*/
public class LibraryField extends LibraryMember implements Field
{
/**
* An extra field pointing to the Clazz object referenced in the
* descriptor string. This field is filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz referencedClass;
/**
* Creates an uninitialized LibraryField.
*/
public LibraryField()
{
}
/**
* Creates an initialized LibraryField.
*/
public LibraryField(int u2accessFlags,
String name,
String descriptor)
{
super(u2accessFlags, name, descriptor);
}
// Implementations for LibraryMember.
public void accept(LibraryClass libraryClass, MemberVisitor memberVisitor)
{
memberVisitor.visitLibraryField(libraryClass, this);
}
// Implementations for Member.
public void referencedClassesAccept(ClassVisitor classVisitor)
{
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
}
proguard4.8/src/proguard/classfile/Field.java 0000644 0001750 0001750 00000002034 11736333524 020034 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
/**
* Representation of a field from a class.
*
* @author Eric Lafortune
*/
public interface Field extends Member
{
}
proguard4.8/src/proguard/classfile/ProgramClass.java 0000644 0001750 0001750 00000037304 11736333524 021416 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.ClassSubHierarchyInitializer;
import proguard.classfile.visitor.*;
/**
* This Clazz is a complete representation of the data in a Java class.
*
* @author Eric Lafortune
*/
public class ProgramClass implements Clazz
{
public int u4magic;
public int u4version;
public int u2constantPoolCount;
public Constant[] constantPool;
public int u2accessFlags;
public int u2thisClass;
public int u2superClass;
public int u2interfacesCount;
public int[] u2interfaces;
public int u2fieldsCount;
public ProgramField[] fields;
public int u2methodsCount;
public ProgramMethod[] methods;
public int u2attributesCount;
public Attribute[] attributes;
/**
* An extra field pointing to the subclasses of this class.
* This field is filled out by the {@link ClassSubHierarchyInitializer}.
*/
public Clazz[] subClasses;
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
/**
* Creates an uninitialized ProgramClass.
*/
public ProgramClass() {}
/**
* Returns the Constant at the given index in the constant pool.
*/
public Constant getConstant(int constantIndex)
{
return constantPool[constantIndex];
}
// Implementations for Clazz.
public int getAccessFlags()
{
return u2accessFlags;
}
public String getName()
{
return getClassName(u2thisClass);
}
public String getSuperName()
{
return u2superClass == 0 ? null : getClassName(u2superClass);
}
public int getInterfaceCount()
{
return u2interfacesCount;
}
public String getInterfaceName(int index)
{
return getClassName(u2interfaces[index]);
}
public int getTag(int constantIndex)
{
return constantPool[constantIndex].getTag();
}
public String getString(int constantIndex)
{
try
{
return ((Utf8Constant)constantPool[constantIndex]).getString();
}
catch (ClassCastException ex)
{
throw ((IllegalStateException)new IllegalStateException("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
public String getStringString(int constantIndex)
{
try
{
return ((StringConstant)constantPool[constantIndex]).getString(this);
}
catch (ClassCastException ex)
{
throw ((IllegalStateException)new IllegalStateException("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
public String getClassName(int constantIndex)
{
try
{
return ((ClassConstant)constantPool[constantIndex]).getName(this);
}
catch (ClassCastException ex)
{
throw ((IllegalStateException)new IllegalStateException("Expected ClassConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
public String getName(int constantIndex)
{
try
{
return ((NameAndTypeConstant)constantPool[constantIndex]).getName(this);
}
catch (ClassCastException ex)
{
throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
public String getType(int constantIndex)
{
try
{
return ((NameAndTypeConstant)constantPool[constantIndex]).getType(this);
}
catch (ClassCastException ex)
{
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));
}
}
public void addSubClass(Clazz clazz)
{
if (subClasses == null)
{
subClasses = new Clazz[1];
}
else
{
// Copy the old elements into new larger array.
Clazz[] temp = new Clazz[subClasses.length+1];
System.arraycopy(subClasses, 0, temp, 0, subClasses.length);
subClasses = temp;
}
subClasses[subClasses.length-1] = clazz;
}
public Clazz getSuperClass()
{
return u2superClass != 0 ?
((ClassConstant)constantPool[u2superClass]).referencedClass :
null;
}
public Clazz getInterface(int index)
{
return ((ClassConstant)constantPool[u2interfaces[index]]).referencedClass;
}
public boolean extends_(Clazz clazz)
{
if (this.equals(clazz))
{
return true;
}
Clazz superClass = getSuperClass();
return superClass != null &&
superClass.extends_(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))
{
return true;
}
Clazz superClass = getSuperClass();
if (superClass != null &&
superClass.extendsOrImplements(clazz))
{
return true;
}
for (int index = 0; index < u2interfacesCount; index++)
{
Clazz interfaceClass = getInterface(index);
if (interfaceClass != null &&
interfaceClass.extendsOrImplements(clazz))
{
return true;
}
}
return false;
}
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++)
{
Field field = fields[index];
if ((name == null || field.getName(this).equals(name)) &&
(descriptor == null || field.getDescriptor(this).equals(descriptor)))
{
return field;
}
}
return null;
}
public Method findMethod(String name, String descriptor)
{
for (int index = 0; index < u2methodsCount; index++)
{
Method method = methods[index];
if ((name == null || method.getName(this).equals(name)) &&
(descriptor == null || method.getDescriptor(this).equals(descriptor)))
{
return method;
}
}
return null;
}
public void accept(ClassVisitor classVisitor)
{
classVisitor.visitProgramClass(this);
}
public void hierarchyAccept(boolean visitThisClass,
boolean visitSuperClass,
boolean visitInterfaces,
boolean visitSubclasses,
ClassVisitor classVisitor)
{
// First visit the current classfile.
if (visitThisClass)
{
accept(classVisitor);
}
// Then visit its superclass, recursively.
if (visitSuperClass)
{
Clazz superClass = getSuperClass();
if (superClass != null)
{
superClass.hierarchyAccept(true,
true,
visitInterfaces,
false,
classVisitor);
}
}
// Then visit its interfaces, recursively.
if (visitInterfaces)
{
// Visit the interfaces of the superclasses, if we haven't done so yet.
if (!visitSuperClass)
{
Clazz superClass = getSuperClass();
if (superClass != null)
{
superClass.hierarchyAccept(false,
false,
true,
false,
classVisitor);
}
}
// Visit the interfaces.
for (int index = 0; index < u2interfacesCount; index++)
{
Clazz interfaceClass = getInterface(index);
if (interfaceClass != null)
{
interfaceClass.hierarchyAccept(true,
false,
true,
false,
classVisitor);
}
}
}
// Then visit its subclasses, recursively.
if (visitSubclasses)
{
if (subClasses != null)
{
for (int index = 0; index < subClasses.length; index++)
{
Clazz subClass = subClasses[index];
subClass.hierarchyAccept(true,
false,
false,
true,
classVisitor);
}
}
}
}
public void subclassesAccept(ClassVisitor classVisitor)
{
if (subClasses != null)
{
for (int index = 0; index < subClasses.length; index++)
{
subClasses[index].accept(classVisitor);
}
}
}
public void constantPoolEntriesAccept(ConstantVisitor constantVisitor)
{
for (int index = 1; index < u2constantPoolCount; index++)
{
if (constantPool[index] != null)
{
constantPool[index].accept(this, constantVisitor);
}
}
}
public void constantPoolEntryAccept(int index, ConstantVisitor constantVisitor)
{
constantPool[index].accept(this, constantVisitor);
}
public void thisClassConstantAccept(ConstantVisitor constantVisitor)
{
constantPool[u2thisClass].accept(this, constantVisitor);
}
public void superClassConstantAccept(ConstantVisitor constantVisitor)
{
if (u2superClass != 0)
{
constantPool[u2superClass].accept(this, constantVisitor);
}
}
public void interfaceConstantsAccept(ConstantVisitor constantVisitor)
{
for (int index = 0; index < u2interfacesCount; index++)
{
constantPool[u2interfaces[index]].accept(this, constantVisitor);
}
}
public void fieldsAccept(MemberVisitor memberVisitor)
{
for (int index = 0; index < u2fieldsCount; index++)
{
fields[index].accept(this, memberVisitor);
}
}
public void fieldAccept(String name, String descriptor, MemberVisitor memberVisitor)
{
Field field = findField(name, descriptor);
if (field != null)
{
field.accept(this, memberVisitor);
}
}
public void methodsAccept(MemberVisitor memberVisitor)
{
for (int index = 0; index < u2methodsCount; index++)
{
methods[index].accept(this, memberVisitor);
}
}
public void methodAccept(String name, String descriptor, MemberVisitor memberVisitor)
{
Method method = findMethod(name, descriptor);
if (method != null)
{
method.accept(this, memberVisitor);
}
}
public boolean mayHaveImplementations(Method method)
{
return
(u2accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0 &&
(method == null ||
((method.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_STATIC |
ClassConstants.INTERNAL_ACC_FINAL)) == 0 &&
!method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)));
}
public void attributesAccept(AttributeVisitor attributeVisitor)
{
for (int index = 0; index < u2attributesCount; index++)
{
attributes[index].accept(this, attributeVisitor);
}
}
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()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
// Implementations for Object.
public String toString()
{
return "ProgramClass("+getName()+")";
}
}
proguard4.8/src/proguard/classfile/Member.java 0000644 0001750 0001750 00000003245 11736333524 020225 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.visitor.*;
/**
* Representation of a field or method from a class.
*
* @author Eric Lafortune
*/
public interface Member extends VisitorAccepter
{
/**
* Returns the access flags.
*/
public int getAccessFlags();
/**
* Returns the class member name.
*/
public String getName(Clazz clazz);
/**
* Returns the class member's descriptor.
*/
public String getDescriptor(Clazz clazz);
/**
* Accepts the given class visitor.
*/
public void accept(Clazz clazz, MemberVisitor memberVisitor);
/**
* Lets the Clazz objects referenced in the descriptor string
* accept the given visitor.
*/
public void referencedClassesAccept(ClassVisitor classVisitor);
}
proguard4.8/src/proguard/classfile/Method.java 0000644 0001750 0001750 00000002036 11736333524 020233 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
/**
* Representation of a method from a class.
*
* @author Eric Lafortune
*/
public interface Method extends Member
{
}
proguard4.8/src/proguard/classfile/ProgramMethod.java 0000644 0001750 0001750 00000006057 11736333524 021572 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.visitor.*;
/**
* Representation of a method from a program class.
*
* @author Eric Lafortune
*/
public class ProgramMethod extends ProgramMember implements Method
{
/**
* An extra field pointing to the Clazz objects referenced in the
* descriptor string. This field is filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}
.
* References to primitive types are ignored.
*/
public Clazz[] referencedClasses;
/**
* Creates an uninitialized ProgramMethod.
*/
public ProgramMethod()
{
}
/**
* Creates an initialized ProgramMethod.
*/
public ProgramMethod(int u2accessFlags,
int u2nameIndex,
int u2descriptorIndex,
int u2attributesCount,
Attribute[] attributes,
Clazz[] referencedClasses)
{
super(u2accessFlags, u2nameIndex, u2descriptorIndex, u2attributesCount, attributes);
this.referencedClasses = referencedClasses;
}
// Implementations for ProgramMember.
public void accept(ProgramClass programClass, MemberVisitor memberVisitor)
{
memberVisitor.visitProgramMethod(programClass, this);
}
public void attributesAccept(ProgramClass programClass, AttributeVisitor attributeVisitor)
{
for (int index = 0; index < u2attributesCount; index++)
{
attributes[index].accept(programClass, this, attributeVisitor);
}
}
// Implementations for Member.
public void referencedClassesAccept(ClassVisitor classVisitor)
{
if (referencedClasses != null)
{
for (int index = 0; index < referencedClasses.length; index++)
{
if (referencedClasses[index] != null)
{
referencedClasses[index].accept(classVisitor);
}
}
}
}
}
proguard4.8/src/proguard/classfile/constant/ 0000775 0001750 0001750 00000000000 11760503005 017770 5 ustar eric eric proguard4.8/src/proguard/classfile/constant/LongConstant.java 0000644 0001750 0001750 00000003705 11736333524 023261 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 long constant in the constant pool.
*
* @author Eric Lafortune
*/
public class LongConstant extends Constant
{
public long u8value;
/**
* Creates an uninitialized LongConstant.
*/
public LongConstant()
{
}
/**
* Creates a new LongConstant with the given long value.
*/
public LongConstant(long value)
{
u8value = value;
}
/**
* Returns the long value of this LongConstant.
*/
public long getValue()
{
return u8value;
}
/**
* Sets the long value of this LongConstant.
*/
public void setValue(long value)
{
u8value = value;
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_Long;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitLongConstant(clazz, this);
}
}
proguard4.8/src/proguard/classfile/constant/NameAndTypeConstant.java 0000644 0001750 0001750 00000005622 11736333524 024527 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 name and type constant in the constant pool.
*
* @author Eric Lafortune
*/
public class NameAndTypeConstant extends Constant
{
public int u2nameIndex;
public int u2descriptorIndex;
/**
* Creates an uninitialized NameAndTypeConstant.
*/
public NameAndTypeConstant()
{
}
/**
* Creates a new NameAndTypeConstant with the given name and type indices.
* @param u2nameIndex the index of the name in the constant pool.
* @param u2descriptorIndex the index of the descriptor in the constant
* pool.
*/
public NameAndTypeConstant(int u2nameIndex,
int u2descriptorIndex)
{
this.u2nameIndex = u2nameIndex;
this.u2descriptorIndex = u2descriptorIndex;
}
/**
* Returns the name index.
*/
protected int getNameIndex()
{
return u2nameIndex;
}
/**
* Sets the name index.
*/
protected void setNameIndex(int index)
{
u2nameIndex = index;
}
/**
* Returns the descriptor index.
*/
protected int getDescriptorIndex()
{
return u2descriptorIndex;
}
/**
* Sets the descriptor index.
*/
protected void setDescriptorIndex(int index)
{
u2descriptorIndex = index;
}
/**
* Returns the name.
*/
public String getName(Clazz clazz)
{
return clazz.getString(u2nameIndex);
}
/**
* Returns the type.
*/
public String getType(Clazz clazz)
{
return clazz.getString(u2descriptorIndex);
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_NameAndType;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitNameAndTypeConstant(clazz, this);
}
}
proguard4.8/src/proguard/classfile/constant/MethodrefConstant.java 0000644 0001750 0001750 00000004533 11736333524 024277 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 reference constant in the constant pool.
*
* @author Eric Lafortune
*/
public class MethodrefConstant extends RefConstant
{
/**
* Creates an uninitialized MethodrefConstant.
*/
public MethodrefConstant()
{
}
/**
* Creates a new MethodrefConstant with the given name and type indices.
* @param u2classIndex the index of the class in the constant pool.
* @param u2nameAndTypeIndex the index of the name and type entry in the constant pool.
* @param referencedClass the referenced class.
* @param referencedMember the referenced member info.
*/
public MethodrefConstant(int u2classIndex,
int u2nameAndTypeIndex,
Clazz referencedClass,
Member referencedMember)
{
this.u2classIndex = u2classIndex;
this.u2nameAndTypeIndex = u2nameAndTypeIndex;
this.referencedClass = referencedClass;
this.referencedMember = referencedMember;
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_Methodref;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitMethodrefConstant(clazz, this);
}
}
proguard4.8/src/proguard/classfile/constant/FloatConstant.java 0000644 0001750 0001750 00000003726 11736333524 023432 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 float constant in the constant pool.
*
* @author Eric Lafortune
*/
public class FloatConstant extends Constant
{
public float f4value;
/**
* Creates an uninitialized FloatConstant.
*/
public FloatConstant()
{
}
/**
* Creates a new FloatConstant with the given float value.
*/
public FloatConstant(float value)
{
f4value = value;
}
/**
* Returns the float value of this FloatConstant.
*/
public float getValue()
{
return f4value;
}
/**
* Sets the float value of this FloatConstant.
*/
public void setValue(float value)
{
f4value = value;
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_Float;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitFloatConstant(clazz, this);
}
}
proguard4.8/src/proguard/classfile/constant/Constant.java 0000644 0001750 0001750 00000003631 11736333524 022437 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 abstract class represents an entry in the ConstantPool. Specific types
* of entries are subclassed from it.
*
* @author Eric Lafortune
*/
public abstract class Constant implements VisitorAccepter
{
//public int u1tag;
//public byte info[];
/**
* An extra field in which visitors can store information.
*/
public Object visitorInfo;
// Abstract methods to be implemented by extensions.
/**
* Returns the constant pool info tag that specifies the entry type.
*/
public abstract int getTag();
/**
* Accepts the given visitor.
*/
public abstract void accept(Clazz clazz, ConstantVisitor constantVisitor);
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
{
return visitorInfo;
}
public void setVisitorInfo(Object visitorInfo)
{
this.visitorInfo = visitorInfo;
}
}
proguard4.8/src/proguard/classfile/constant/Utf8Constant.java 0000644 0001750 0001750 00000022113 11736333524 023202 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import java.io.UnsupportedEncodingException;
/**
* This Constant represents a UTF-8 constant in the constant pool.
*
* @author Eric Lafortune
*/
public class Utf8Constant extends Constant
{
private static final char TWO_BYTE_LIMIT = 0x80;
private static final int TWO_BYTE_CONSTANT1 = 0xc0;
private static final int TWO_BYTE_CONSTANT2 = 0x80;
private static final int TWO_BYTE_SHIFT1 = 6;
private static final int TWO_BYTE_MASK1 = 0x1f;
private static final int TWO_BYTE_MASK2 = 0x3f;
private static final char THREE_BYTE_LIMIT = 0x800;
private static final int THREE_BYTE_CONSTANT1 = 0xe0;
private static final int THREE_BYTE_CONSTANT2 = 0x80;
private static final int THREE_BYTE_CONSTANT3 = 0x80;
private static final int THREE_BYTE_SHIFT1 = 12;
private static final int THREE_BYTE_SHIFT2 = 6;
private static final int THREE_BYTE_MASK1 = 0x0f;
private static final int THREE_BYTE_MASK2 = 0x3f;
private static final int THREE_BYTE_MASK3 = 0x3f;
// There are a lot of Utf8Constant objects, so we're optimising their storage.
// Initially, we're storing the UTF-8 bytes in a byte array.
// When the corresponding String is requested, we ditch the array and just
// store the String.
//private int u2length;
private byte[] bytes;
private String string;
/**
* Creates an uninitialized Utf8Constant.
*
*/
public Utf8Constant()
{
}
/**
* Creates a Utf8Constant containing the given string.
*/
public Utf8Constant(String string)
{
this.bytes = null;
this.string = string;
}
/**
* Initializes the UTF-8 data with an array of bytes.
*/
public void setBytes(byte[] bytes)
{
this.bytes = bytes;
this.string = null;
}
/**
* Returns the UTF-8 data as an array of bytes.
*/
public byte[] getBytes()
{
try
{
switchToByteArrayRepresentation();
}
catch (UnsupportedEncodingException ex)
{
throw new RuntimeException(ex.getMessage());
}
return bytes;
}
/**
* Initializes the UTF-8 data with a String.
*/
public void setString(String utf8String)
{
this.bytes = null;
this.string = utf8String;
}
/**
* Returns the UTF-8 data as a String.
*/
public String getString()
{
try
{
switchToStringRepresentation();
}
catch (UnsupportedEncodingException ex)
{
throw new RuntimeException(ex.getMessage());
}
return string;
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_Utf8;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitUtf8Constant(clazz, this);
}
// Small utility methods.
/**
* Switches to a byte array representation of the UTF-8 data.
*/
private void switchToByteArrayRepresentation() throws UnsupportedEncodingException
{
if (bytes == null)
{
bytes = getByteArrayRepresentation(string);
string = null;
}
}
/**
* Switches to a String representation of the UTF-8 data.
*/
private void switchToStringRepresentation() throws UnsupportedEncodingException
{
if (string == null)
{
string = getStringRepresentation(bytes);
bytes = null;
}
}
/**
* Returns the modified UTF-8 byte array representation of the given string.
*/
private byte[] getByteArrayRepresentation(String string) throws UnsupportedEncodingException
{
// We're computing the byte array ourselves, because the implementation
// of String.getBytes("UTF-8") has a bug, at least up to JRE 1.4.2.
// Also note the special treatment of the 0 character.
// Compute the byte array length.
int byteLength = 0;
int stringLength = string.length();
for (int stringIndex = 0; stringIndex < stringLength; stringIndex++)
{
char c = string.charAt(stringIndex);
// The character is represented by one, two, or three bytes.
byteLength += c == 0 ? 2 :
c < TWO_BYTE_LIMIT ? 1 :
c < THREE_BYTE_LIMIT ? 2 :
3;
}
// Allocate the byte array with the computed length.
byte[] bytes = new byte[byteLength];
// Fill out the array.
int byteIndex = 0;
for (int stringIndex = 0; stringIndex < stringLength; stringIndex++)
{
char c = string.charAt(stringIndex);
if (c == 0)
{
// The 0 character gets a two-byte representation in classes.
bytes[byteIndex++] = (byte)TWO_BYTE_CONSTANT1;
bytes[byteIndex++] = (byte)TWO_BYTE_CONSTANT2;
}
else if (c < TWO_BYTE_LIMIT)
{
// The character is represented by a single byte.
bytes[byteIndex++] = (byte)c;
}
else if (c < THREE_BYTE_LIMIT)
{
// The character is represented by two bytes.
bytes[byteIndex++] = (byte)(TWO_BYTE_CONSTANT1 | ((c >>> TWO_BYTE_SHIFT1) & TWO_BYTE_MASK1));
bytes[byteIndex++] = (byte)(TWO_BYTE_CONSTANT2 | ( c & TWO_BYTE_MASK2));
}
else
{
// The character is represented by three bytes.
bytes[byteIndex++] = (byte)(THREE_BYTE_CONSTANT1 | ((c >>> THREE_BYTE_SHIFT1) & THREE_BYTE_MASK1));
bytes[byteIndex++] = (byte)(THREE_BYTE_CONSTANT2 | ((c >>> THREE_BYTE_SHIFT2) & THREE_BYTE_MASK2));
bytes[byteIndex++] = (byte)(THREE_BYTE_CONSTANT3 | ( c & THREE_BYTE_MASK3));
}
}
return bytes;
}
/**
* Returns the String representation of the given modified UTF-8 byte array.
*/
private String getStringRepresentation(byte[] bytes) throws UnsupportedEncodingException
{
// We're computing the string ourselves, because the implementation
// of "new String(bytes)" doesn't honor the special treatment of
// the 0 character in JRE 1.6_u11.
// Allocate the byte array with the computed length.
char[] chars = new char[bytes.length];
// Fill out the array.
int charIndex = 0;
int byteIndex = 0;
while (byteIndex < bytes.length)
{
int b = bytes[byteIndex++] & 0xff;
// Depending on the flag bits in the first byte, the character
// is represented by a single byte, by two bytes, or by three
// bytes. We're not checking the redundant flag bits in the
// second byte and the third byte.
try
{
chars[charIndex++] =
(char)(b < TWO_BYTE_CONSTANT1 ? b :
b < THREE_BYTE_CONSTANT1 ? ((b & TWO_BYTE_MASK1) << TWO_BYTE_SHIFT1) |
((bytes[byteIndex++] & TWO_BYTE_MASK2) ) :
((b & THREE_BYTE_MASK1) << THREE_BYTE_SHIFT1) |
((bytes[byteIndex++] & THREE_BYTE_MASK2) << THREE_BYTE_SHIFT2) |
((bytes[byteIndex++] & THREE_BYTE_MASK3) ));
}
catch (ArrayIndexOutOfBoundsException e)
{
throw new UnsupportedEncodingException("Missing UTF-8 bytes after initial byte [0x"+Integer.toHexString(b)+"] in string ["+new String(chars, 0, charIndex)+"]");
}
}
return new String(chars, 0, charIndex);
}
}
proguard4.8/src/proguard/classfile/constant/FieldrefConstant.java 0000644 0001750 0001750 00000004530 11736333524 024077 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 field reference constant in the constant pool.
*
* @author Eric Lafortune
*/
public class FieldrefConstant extends RefConstant
{
/**
* Creates an uninitialized FieldrefConstant.
*/
public FieldrefConstant()
{
}
/**
* Creates a new FieldrefConstant with the given name and type indices.
* @param u2classIndex the index of the class in the constant pool.
* @param u2nameAndTypeIndex the index of the name and type entry in the constant pool.
* @param referencedClass the referenced class.
* @param referencedMember the referenced member info.
*/
public FieldrefConstant(int u2classIndex,
int u2nameAndTypeIndex,
Clazz referencedClass,
Member referencedMember)
{
this.u2classIndex = u2classIndex;
this.u2nameAndTypeIndex = u2nameAndTypeIndex;
this.referencedClass = referencedClass;
this.referencedMember = referencedMember;
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_Fieldref;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitFieldrefConstant(clazz, this);
}
}
proguard4.8/src/proguard/classfile/constant/ClassConstant.java 0000644 0001750 0001750 00000005624 11736333524 023431 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.visitor.ClassVisitor;
/**
* This Constant represents a class constant in the constant pool.
*
* @author Eric Lafortune
*/
public class ClassConstant extends Constant
{
public int u2nameIndex;
/**
* An extra field pointing to the referenced Clazz object.
* This field is filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}
.
*/
public Clazz referencedClass;
/**
* An extra field pointing to the java.lang.Class Clazz object.
* This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
..
*/
public Clazz javaLangClassClass;
/**
* Creates an uninitialized ClassConstant.
*/
public ClassConstant()
{
}
/**
* Creates a new ClassConstant with the given name index.
* @param u2nameIndex the index of the name in the constant pool.
* @param referencedClass the referenced class.
*/
public ClassConstant(int u2nameIndex,
Clazz referencedClass)
{
this.u2nameIndex = u2nameIndex;
this.referencedClass = referencedClass;
}
/**
* Returns the name.
*/
public String getName(Clazz clazz)
{
return clazz.getString(u2nameIndex);
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_Class;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitClassConstant(clazz, this);
}
/**
* Lets the referenced class accept the given visitor.
*/
public void referencedClassAccept(ClassVisitor classVisitor)
{
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
}
proguard4.8/src/proguard/classfile/constant/DoubleConstant.java 0000644 0001750 0001750 00000003747 11736333524 023602 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 double constant in the constant pool.
*
* @author Eric Lafortune
*/
public class DoubleConstant extends Constant
{
public double f8value;
/**
* Creates an uninitialized DoubleConstant.
*/
public DoubleConstant()
{
}
/**
* Creates a new DoubleConstant with the given double value.
*/
public DoubleConstant(double value)
{
f8value = value;
}
/**
* Returns the double value of this DoubleConstant.
*/
public double getValue()
{
return f8value;
}
/**
* Sets the double value of this DoubleConstant.
*/
public void setValue(double value)
{
f8value = value;
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_Double;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitDoubleConstant(clazz, this);
}
}
proguard4.8/src/proguard/classfile/constant/InvokeDynamicConstant.java 0000755 0001750 0001750 00000010722 11736333524 025122 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 {@link
* proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}
.
* 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);
}
}
proguard4.8/src/proguard/classfile/constant/visitor/ 0000775 0001750 0001750 00000000000 11760503005 021467 5 ustar eric eric proguard4.8/src/proguard/classfile/constant/visitor/package.html 0000644 0001750 0001750 00000000103 11736333524 023752 0 ustar eric eric Constant
* objects.
*
* @author Eric Lafortune
*/
public interface ConstantVisitor
{
public void visitIntegerConstant( Clazz clazz, IntegerConstant integerConstant);
public void visitLongConstant( Clazz clazz, LongConstant longConstant);
public void visitFloatConstant( Clazz clazz, FloatConstant floatConstant);
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);
}
proguard4.8/src/proguard/classfile/constant/visitor/ConstantTagFilter.java 0000644 0001750 0001750 00000005536 11736333524 025746 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 ConstantVisitor
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 ConstantVisitor
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 ConstantVisitor
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);
}
}
} proguard4.8/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java 0000644 0001750 0001750 00000006734 11736333524 030313 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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);
}
}
proguard4.8/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java 0000644 0001750 0001750 00000004735 11736333524 027451 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.editor.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.preverification.*;
import proguard.classfile.constant.ClassConstant;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.SimplifiedVisitor;
/**
* This ConstantVisitor
delegates its visits to class constants
* to another given ConstantVisitor
, except for one given class.
*
* @author Eric Lafortune
*/
public class ExceptClassConstantFilter
extends SimplifiedVisitor
implements ConstantVisitor
{
private final String exceptClassName;
private final ConstantVisitor constantVisitor;
/**
* Creates a new ExceptClassConstantFilter.
* @param exceptClassName the name of the class that will not be visited.
* @param constantVisitor the ConstantVisitor
to which visits
* will be delegated.
*/
public ExceptClassConstantFilter(String exceptClassName,
ConstantVisitor constantVisitor)
{
this.exceptClassName = exceptClassName;
this.constantVisitor = constantVisitor;
}
// Implementations for ConstantVisitor.
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
if (!classConstant.getName(clazz).equals(exceptClassName))
{
constantVisitor.visitClassConstant(clazz, classConstant);
}
}
} proguard4.8/src/proguard/classfile/constant/visitor/AllConstantVisitor.java 0000644 0001750 0001750 00000003200 11736333524 026137 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor.ClassVisitor;
/**
* This ClassVisitor lets a given ConstantVisitor visit all constant pool
* entries of the program classes it visits.
*
* @author Eric Lafortune
*/
public class AllConstantVisitor implements ClassVisitor
{
private final ConstantVisitor constantVisitor;
public AllConstantVisitor(ConstantVisitor constantVisitor)
{
this.constantVisitor = constantVisitor;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
programClass.constantPoolEntriesAccept(constantVisitor);
}
public void visitLibraryClass(LibraryClass libraryClass) {}
}
proguard4.8/src/proguard/classfile/constant/StringConstant.java 0000644 0001750 0001750 00000010065 11736333524 023625 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.visitor.*;
/**
* This Constant represents a string constant in the constant pool.
*
* @author Eric Lafortune
*/
public class StringConstant extends Constant
{
public int u2stringIndex;
/**
* An extra field pointing to the referenced Clazz object, if this
* string is being used in Class.forName(), .class, or
* Class.getDeclaredField/Method constructs.
* This field is typically filled out by the {@link
* proguard.classfile.util.DynamicClassReferenceInitializer
* DynamicClassReferenceInitializer}
or by the {@link
* proguard.classfile.util.DynamicMemberReferenceInitializer
* DynamicMemberReferenceInitializer}
.
*/
public Clazz referencedClass;
/**
* An extra field pointing to the referenced Member object, if this
* string is being used in Class.getDeclaredField/Method constructs.
* This field is typically filled out by the {@link
* proguard.classfile.util.DynamicMemberReferenceInitializer
* DynamicMemberReferenceInitializer}
.
*/
public Member referencedMember;
/**
* An extra field pointing to the java.lang.String Clazz object.
* This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
..
*/
public Clazz javaLangStringClass;
/**
* Creates an uninitialized StringConstant.
*/
public StringConstant()
{
}
/**
* Creates a new StringConstant with the given string index.
* @param u2stringIndex the index of the string in the constant pool.
* @param referencedClass the referenced class, if any.
* @param referenceMember the referenced class member, if any.
*/
public StringConstant(int u2stringIndex,
Clazz referencedClass,
Member referenceMember)
{
this.u2stringIndex = u2stringIndex;
this.referencedClass = referencedClass;
this.referencedMember = referenceMember;
}
/**
* Returns the string value.
*/
public String getString(Clazz clazz)
{
return clazz.getString(u2stringIndex);
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_String;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitStringConstant(clazz, this);
}
/**
* Lets the referenced class accept the given visitor.
*/
public void referencedClassAccept(ClassVisitor classVisitor)
{
if (referencedClass != null &&
referencedMember == null)
{
referencedClass.accept(classVisitor);
}
}
/**
* Lets the referenced member accept the given visitor.
*/
public void referencedMemberAccept(MemberVisitor memberVisitor)
{
if (referencedMember != null)
{
referencedMember.accept(referencedClass, memberVisitor);
}
}
}
proguard4.8/src/proguard/classfile/constant/MethodTypeConstant.java 0000644 0001750 0001750 00000004733 11736333524 024446 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
..
*/
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);
}
}
proguard4.8/src/proguard/classfile/constant/InterfaceMethodrefConstant.java 0000644 0001750 0001750 00000004703 11736333524 026117 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 interface method reference constant in the constant pool.
*
* @author Eric Lafortune
*/
public class InterfaceMethodrefConstant extends RefConstant
{
/**
* Creates an uninitialized InterfaceMethodrefConstant.
*/
public InterfaceMethodrefConstant()
{
}
/**
* Creates a new InterfaceMethodrefConstant with the given name and type indices.
* @param u2classIndex the index of the class in the constant pool.
* @param u2nameAndTypeIndex the index of the name and type entry in the constant pool.
* @param referencedClass the referenced class.
* @param referencedMember the referenced member info.
*/
public InterfaceMethodrefConstant(int u2classIndex,
int u2nameAndTypeIndex,
Clazz referencedClass,
Member referencedMember)
{
this.u2classIndex = u2classIndex;
this.u2nameAndTypeIndex = u2nameAndTypeIndex;
this.referencedClass = referencedClass;
this.referencedMember = referencedMember;
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_InterfaceMethodref;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitInterfaceMethodrefConstant(clazz, this);
}
}
proguard4.8/src/proguard/classfile/constant/RefConstant.java 0000644 0001750 0001750 00000006323 11736333524 023075 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.visitor.*;
/**
* This Constant represents a ref constant in the constant pool.
*
* @author Eric Lafortune
*/
public abstract class RefConstant extends Constant
{
public int u2classIndex;
public int u2nameAndTypeIndex;
/**
* An extra field pointing to the referenced Clazz object.
* This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
.
*/
public Clazz referencedClass;
/**
* An extra field optionally pointing to the referenced Member object.
* This field is typically filled out by the {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
.
*/
public Member referencedMember;
protected RefConstant()
{
}
/**
* Returns the class index.
*/
public int getClassIndex()
{
return u2classIndex;
}
/**
* Returns the name-and-type index.
*/
public int getNameAndTypeIndex()
{
return u2nameAndTypeIndex;
}
/**
* Sets the name-and-type index.
*/
public void setNameAndTypeIndex(int index)
{
u2nameAndTypeIndex = index;
}
/**
* Returns the class name.
*/
public String getClassName(Clazz clazz)
{
return clazz.getClassName(u2classIndex);
}
/**
* Returns the method/field name.
*/
public String getName(Clazz clazz)
{
return clazz.getName(u2nameAndTypeIndex);
}
/**
* Returns the type.
*/
public String getType(Clazz clazz)
{
return clazz.getType(u2nameAndTypeIndex);
}
/**
* Lets the referenced class accept the given visitor.
*/
public void referencedClassAccept(ClassVisitor classVisitor)
{
if (referencedClass != null)
{
referencedClass.accept(classVisitor);
}
}
/**
* Lets the referenced class member accept the given visitor.
*/
public void referencedMemberAccept(MemberVisitor memberVisitor)
{
if (referencedMember != null)
{
referencedMember.accept(referencedClass,
memberVisitor);
}
}
}
proguard4.8/src/proguard/classfile/constant/MethodHandleConstant.java 0000755 0001750 0001750 00000007212 11736333524 024716 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 {@link
* proguard.classfile.util.ClassReferenceInitializer
* ClassReferenceInitializer}
..
*/
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);
}
}
proguard4.8/src/proguard/classfile/constant/IntegerConstant.java 0000644 0001750 0001750 00000003750 11736333524 023757 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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 integer constant in the constant pool.
*
* @author Eric Lafortune
*/
public class IntegerConstant extends Constant
{
public int u4value;
/**
* Creates an uninitialized IntegerConstant.
*/
public IntegerConstant()
{
}
/**
* Creates a new IntegerConstant with the given integer value.
*/
public IntegerConstant(int value)
{
u4value = value;
}
/**
* Returns the integer value of this IntegerConstant.
*/
public int getValue()
{
return u4value;
}
/**
* Sets the integer value of this IntegerConstant.
*/
public void setValue(int value)
{
u4value = value;
}
// Implementations for Constant.
public int getTag()
{
return ClassConstants.CONSTANT_Integer;
}
public void accept(Clazz clazz, ConstantVisitor constantVisitor)
{
constantVisitor.visitIntegerConstant(clazz, this);
}
}
proguard4.8/src/proguard/ClassPath.java 0000644 0001750 0001750 00000004514 11736333524 016733 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import java.util.*;
/**
* This class represents a class path, as a list of ClassPathEntry objects.
*
* @author Eric Lafortune
*/
public class ClassPath
{
private final List classPathEntries = new ArrayList();
/**
* Returns whether the class path contains any output entries.
*/
public boolean hasOutput()
{
for (int index = 0; index < classPathEntries.size(); index++)
{
if (((ClassPathEntry)classPathEntries.get(index)).isOutput())
{
return true;
}
}
return false;
}
// Delegates to List.
public void clear()
{
classPathEntries.clear();
}
public void add(int index, ClassPathEntry classPathEntry)
{
classPathEntries.add(index, classPathEntry);
}
public boolean add(ClassPathEntry classPathEntry)
{
return classPathEntries.add(classPathEntry);
}
public boolean addAll(ClassPath classPath)
{
return classPathEntries.addAll(classPath.classPathEntries);
}
public ClassPathEntry get(int index)
{
return (ClassPathEntry)classPathEntries.get(index);
}
public ClassPathEntry remove(int index)
{
return (ClassPathEntry)classPathEntries.remove(index);
}
public boolean isEmpty()
{
return classPathEntries.isEmpty();
}
public int size()
{
return classPathEntries.size();
}
}
proguard4.8/src/proguard/ClassSpecificationVisitorFactory.java 0000644 0001750 0001750 00000050164 11736333524 023531 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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;
import proguard.classfile.attribute.annotation.visitor.*;
import proguard.classfile.attribute.visitor.AllAttributeVisitor;
import proguard.classfile.visitor.*;
import java.util.List;
/**
* This factory creates visitors to efficiently travel to specified classes and
* class members.
*
* @author Eric Lafortune
*/
public class ClassSpecificationVisitorFactory
{
/**
* Constructs a ClassPoolVisitor to efficiently travel to the specified
* classes and class members.
*
* @param keepClassSpecifications the list of KeepClassSpecification
* instances, defining of the classes and
* class members to visit.
* @param classVisitor the ClassVisitor to be applied to matching
* classes.
* @param memberVisitor the MemberVisitor to be applied to matching
* class members.
*/
public static ClassPoolVisitor createClassPoolVisitor(List keepClassSpecifications,
ClassVisitor classVisitor,
MemberVisitor memberVisitor,
boolean shrinking,
boolean optimizing,
boolean obfuscating)
{
MultiClassPoolVisitor multiClassPoolVisitor = new MultiClassPoolVisitor();
if (keepClassSpecifications != null)
{
for (int index = 0; index < keepClassSpecifications.size(); index++)
{
KeepClassSpecification keepClassSpecification =
(KeepClassSpecification)keepClassSpecifications.get(index);
if ((shrinking && !keepClassSpecification.allowShrinking) ||
(optimizing && !keepClassSpecification.allowOptimization) ||
(obfuscating && !keepClassSpecification.allowObfuscation))
{
multiClassPoolVisitor.addClassPoolVisitor(
createClassPoolVisitor(keepClassSpecification,
classVisitor,
memberVisitor));
}
}
}
return multiClassPoolVisitor;
}
/**
* Constructs a ClassPoolVisitor to efficiently travel to the specified
* classes and class members.
*
* @param classSpecifications the list of ClassSpecification instances,
* defining of the classes and class members to
* visit.
* @param classVisitor the ClassVisitor to be applied to matching
* classes.
* @param memberVisitor the MemberVisitor to be applied to matching
* class members.
*/
public static ClassPoolVisitor createClassPoolVisitor(List classSpecifications,
ClassVisitor classVisitor,
MemberVisitor memberVisitor)
{
MultiClassPoolVisitor multiClassPoolVisitor = new MultiClassPoolVisitor();
if (classSpecifications != null)
{
for (int index = 0; index < classSpecifications.size(); index++)
{
ClassSpecification classSpecification =
(ClassSpecification)classSpecifications.get(index);
multiClassPoolVisitor.addClassPoolVisitor(
createClassPoolVisitor(classSpecification,
classVisitor,
memberVisitor));
}
}
return multiClassPoolVisitor;
}
/**
* Constructs a ClassPoolVisitor to efficiently travel to the specified
* classes and class members.
*
* @param keepClassSpecification the specifications of the class(es) and class
* members to visit.
* @param classVisitor the ClassVisitor to be applied to matching
* classes.
* @param memberVisitor the MemberVisitor to be applied to matching
* class members.
*/
private static ClassPoolVisitor createClassPoolVisitor(KeepClassSpecification keepClassSpecification,
ClassVisitor classVisitor,
MemberVisitor memberVisitor)
{
// Don't visit the classes if not specified.
if (!keepClassSpecification.markClasses &&
!keepClassSpecification.markConditionally)
{
classVisitor = null;
}
// If specified, let the marker visit the class and its class
// members conditionally.
if (keepClassSpecification.markConditionally)
{
// Combine both visitors.
ClassVisitor composedClassVisitor =
createCombinedClassVisitor(keepClassSpecification,
classVisitor,
memberVisitor);
// Replace the class visitor.
classVisitor =
createClassMemberTester(keepClassSpecification,
composedClassVisitor);
// Discard the member visitor, because it has already been included.
memberVisitor = null;
}
return createClassPoolVisitor((ClassSpecification)keepClassSpecification,
classVisitor,
memberVisitor);
}
/**
* Constructs a ClassPoolVisitor to efficiently travel to the specified
* classes and class members.
*
* @param classSpecification the specifications of the class(es) and class
* members to visit.
* @param classVisitor the ClassVisitor to be applied to matching
* classes.
* @param memberVisitor the MemberVisitor to be applied to matching
* class members.
*/
private static ClassPoolVisitor createClassPoolVisitor(ClassSpecification classSpecification,
ClassVisitor classVisitor,
MemberVisitor memberVisitor)
{
// Combine both visitors.
ClassVisitor composedClassVisitor =
createCombinedClassVisitor(classSpecification,
classVisitor,
memberVisitor);
// By default, start visiting from the named class name, if specified.
String className = classSpecification.className;
// Although we may have to start from the extended class.
String extendsAnnotationType = classSpecification.extendsAnnotationType;
String extendsClassName = classSpecification.extendsClassName;
// If wildcarded, only visit classes with matching names.
if (className != null &&
(extendsAnnotationType != null ||
extendsClassName != null ||
containsWildCards(className)))
{
composedClassVisitor =
new ClassNameFilter(className, composedClassVisitor);
// We'll have to visit all classes now.
className = null;
}
// If specified, only visit classes with the right annotation.
String annotationType = classSpecification.annotationType;
if (annotationType != null)
{
composedClassVisitor =
new AllAttributeVisitor(
new AllAnnotationVisitor(
new AnnotationTypeFilter(annotationType,
new AnnotatedClassVisitor(composedClassVisitor))));
}
// If specified, only visit classes with the right access flags.
if (classSpecification.requiredSetAccessFlags != 0 ||
classSpecification.requiredUnsetAccessFlags != 0)
{
composedClassVisitor =
new ClassAccessFilter(classSpecification.requiredSetAccessFlags,
classSpecification.requiredUnsetAccessFlags,
composedClassVisitor);
}
// If it's specified, start visiting from the extended class.
if (extendsAnnotationType != null ||
extendsClassName != null)
{
// Start visiting from the extended class.
composedClassVisitor =
new ClassHierarchyTraveler(false, false, false, true,
composedClassVisitor);
// If specified, only visit extended classes with the right annotation.
if (extendsAnnotationType != null)
{
composedClassVisitor =
new AllAttributeVisitor(
new AllAnnotationVisitor(
new AnnotationTypeFilter(extendsAnnotationType,
new AnnotatedClassVisitor(composedClassVisitor))));
}
// If specified, only visit extended classes with matching names.
if (extendsClassName != null)
{
// If wildcarded, only visit extended classes with matching names.
if (containsWildCards(extendsClassName))
{
composedClassVisitor =
new ClassNameFilter(extendsClassName,
composedClassVisitor);
}
else
{
// Start visiting from the named extended class.
className = extendsClassName;
}
}
}
// If specified, visit a single named class, otherwise visit all classes.
return className != null ?
(ClassPoolVisitor)new NamedClassVisitor(composedClassVisitor, className) :
(ClassPoolVisitor)new AllClassVisitor(composedClassVisitor);
}
/**
* Constructs a ClassVisitor to efficiently travel to the specified
* classes and class members.
*
* @param classSpecification the specifications of the class(es) and class
* members to visit.
* @param classVisitor the ClassVisitor to be applied to matching
* classes.
* @param memberVisitor the MemberVisitor to be applied to matching
* class members.
*/
private static ClassVisitor createCombinedClassVisitor(ClassSpecification classSpecification,
ClassVisitor classVisitor,
MemberVisitor memberVisitor)
{
// Don't visit any members if there aren't any member specifications.
if (classSpecification.fieldSpecifications == null &&
classSpecification.methodSpecifications == null)
{
memberVisitor = null;
}
// The class visitor for classes and their members.
MultiClassVisitor multiClassVisitor = new MultiClassVisitor();
// If specified, let the class visitor visit the class itself.
if (classVisitor != null)
{
// This class visitor may be the only one.
if (memberVisitor == null)
{
return classVisitor;
}
multiClassVisitor.addClassVisitor(classVisitor);
}
// If specified, let the member info visitor visit the class members.
if (memberVisitor != null)
{
ClassVisitor memberClassVisitor =
createClassVisitor(classSpecification, memberVisitor);
// This class visitor may be the only one.
if (classVisitor == null)
{
return memberClassVisitor;
}
multiClassVisitor.addClassVisitor(memberClassVisitor);
}
return multiClassVisitor;
}
/**
* Constructs a ClassVisitor to efficiently travel to the specified class
* members.
*
* @param classSpecification the specifications of the class members to visit.
* @param memberVisitor the MemberVisitor to be applied to matching
* class members.
*/
private static ClassVisitor createClassVisitor(ClassSpecification classSpecification,
MemberVisitor memberVisitor)
{
MultiClassVisitor multiClassVisitor = new MultiClassVisitor();
addMemberVisitors(classSpecification.fieldSpecifications, true, multiClassVisitor, memberVisitor);
addMemberVisitors(classSpecification.methodSpecifications, false, multiClassVisitor, memberVisitor);
// Mark the class member in this class and in super classes.
return new ClassHierarchyTraveler(true, true, false, false,
multiClassVisitor);
}
/**
* Adds elements to the given MultiClassVisitor, to apply the given
* MemberVisitor to all class members that match the given List
* of options (of the given type).
*/
private static void addMemberVisitors(List memberSpecifications,
boolean isField,
MultiClassVisitor multiClassVisitor,
MemberVisitor memberVisitor)
{
if (memberSpecifications != null)
{
for (int index = 0; index < memberSpecifications.size(); index++)
{
MemberSpecification memberSpecification =
(MemberSpecification)memberSpecifications.get(index);
multiClassVisitor.addClassVisitor(
createClassVisitor(memberSpecification,
isField,
memberVisitor));
}
}
}
/**
* Constructs a ClassVisitor that conditionally applies the given
* ClassVisitor to all classes that contain the given class members.
*/
private static ClassVisitor createClassMemberTester(ClassSpecification classSpecification,
ClassVisitor classVisitor)
{
// Create a linked list of conditional visitors, for fields and for
// methods.
return createClassMemberTester(classSpecification.fieldSpecifications,
true,
createClassMemberTester(classSpecification.methodSpecifications,
false,
classVisitor));
}
/**
* Constructs a ClassVisitor that conditionally applies the given
* ClassVisitor to all classes that contain the given List of class
* members (of the given type).
*/
private static ClassVisitor createClassMemberTester(List memberSpecifications,
boolean isField,
ClassVisitor classVisitor)
{
// Create a linked list of conditional visitors.
if (memberSpecifications != null)
{
for (int index = 0; index < memberSpecifications.size(); index++)
{
MemberSpecification memberSpecification =
(MemberSpecification)memberSpecifications.get(index);
classVisitor =
createClassVisitor(memberSpecification,
isField,
new MemberToClassVisitor(classVisitor));
}
}
return classVisitor;
}
/**
* Creates a new ClassVisitor to efficiently travel to the specified class
* members.
*
* @param memberSpecification the specification of the class member(s) to
* visit.
* @param memberVisitor the MemberVisitor to be applied to matching
* class member(s).
*/
private static ClassVisitor createClassVisitor(MemberSpecification memberSpecification,
boolean isField,
MemberVisitor memberVisitor)
{
String name = memberSpecification.name;
String descriptor = memberSpecification.descriptor;
// If name or descriptor are not fully specified, only visit matching
// class members.
boolean fullySpecified =
name != null &&
descriptor != null &&
!containsWildCards(name) &&
!containsWildCards(descriptor);
if (!fullySpecified)
{
if (descriptor != null)
{
memberVisitor =
new MemberDescriptorFilter(descriptor, memberVisitor);
}
if (name != null)
{
memberVisitor =
new MemberNameFilter(name, memberVisitor);
}
}
// If specified, only visit class members with the right annotation.
if (memberSpecification.annotationType != null)
{
memberVisitor =
new AllAttributeVisitor(
new AllAnnotationVisitor(
new AnnotationTypeFilter(memberSpecification.annotationType,
new AnnotationToMemberVisitor(memberVisitor))));
}
// If any access flags are specified, only visit matching class members.
if (memberSpecification.requiredSetAccessFlags != 0 ||
memberSpecification.requiredUnsetAccessFlags != 0)
{
memberVisitor =
new MemberAccessFilter(memberSpecification.requiredSetAccessFlags,
memberSpecification.requiredUnsetAccessFlags,
memberVisitor);
}
// Depending on what's specified, visit a single named class member,
// or all class members, filtering the matching ones.
return isField ?
fullySpecified ?
(ClassVisitor)new NamedFieldVisitor(name, descriptor, memberVisitor) :
(ClassVisitor)new AllFieldVisitor(memberVisitor) :
fullySpecified ?
(ClassVisitor)new NamedMethodVisitor(name, descriptor, memberVisitor) :
(ClassVisitor)new AllMethodVisitor(memberVisitor);
}
// Small utility methods.
private static boolean containsWildCards(String string)
{
return string != null &&
(string.indexOf('!') >= 0 ||
string.indexOf('*') >= 0 ||
string.indexOf('?') >= 0 ||
string.indexOf('%') >= 0 ||
string.indexOf(',') >= 0 ||
string.indexOf("///") >= 0);
}
}
proguard4.8/src/proguard/io/ 0000775 0001750 0001750 00000000000 11760503005 014601 5 ustar eric eric proguard4.8/src/proguard/io/package.html 0000644 0001750 0001750 00000000204 11736333524 017066 0 ustar eric eric
This package contains classes to read and write files, optionally wrapped in
jars, wars, ears, zips, directories,...
proguard4.8/src/proguard/io/FilteredDataEntryReader.java 0000664 0001750 0001750 00000006617 11736333524 022165 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.IOException;
/**
* This DataEntryReader delegates to one of two other DataEntryReader instances,
* depending on whether the data entry passes through a given data entry filter
* or not.
*
* @author Eric Lafortune
*/
public class FilteredDataEntryReader implements DataEntryReader
{
private final DataEntryFilter dataEntryFilter;
private final DataEntryReader acceptedDataEntryReader;
private final DataEntryReader rejectedDataEntryReader;
/**
* Creates a new FilteredDataEntryReader with only a reader for accepted
* data entries.
* @param dataEntryFilter the data entry filter.
* @param acceptedDataEntryReader the DataEntryReader to which the reading
* will be delegated if the filter accepts
* the data entry. May be null
.
*/
public FilteredDataEntryReader(DataEntryFilter dataEntryFilter,
DataEntryReader acceptedDataEntryReader)
{
this(dataEntryFilter, acceptedDataEntryReader, null);
}
/**
* Creates a new FilteredDataEntryReader.
* @param dataEntryFilter the data entry filter.
* @param acceptedDataEntryReader the DataEntryReader to which the reading
* will be delegated if the filter accepts
* the data entry. May be null
.
* @param rejectedDataEntryReader the DataEntryReader to which the reading
* will be delegated if the filter does not
* accept the data entry. May be
* null
.
*/
public FilteredDataEntryReader(DataEntryFilter dataEntryFilter,
DataEntryReader acceptedDataEntryReader,
DataEntryReader rejectedDataEntryReader)
{
this.dataEntryFilter = dataEntryFilter;
this.acceptedDataEntryReader = acceptedDataEntryReader;
this.rejectedDataEntryReader = rejectedDataEntryReader;
}
// Implementations for DataEntryReader.
public void read(DataEntry dataEntry)
throws IOException
{
DataEntryReader dataEntryReader = dataEntryFilter.accepts(dataEntry) ?
acceptedDataEntryReader :
rejectedDataEntryReader;
if (dataEntryReader != null)
{
dataEntryReader.read(dataEntry);
}
}
}
proguard4.8/src/proguard/io/ZipDataEntry.java 0000644 0001750 0001750 00000005076 11736333524 020042 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.ClassConstants;
import java.io.*;
import java.util.zip.*;
/**
* This DataEntry
represents a ZIP entry.
*
* @author Eric Lafortune
*/
public class ZipDataEntry implements DataEntry
{
private final DataEntry parent;
private final ZipEntry zipEntry;
private ZipInputStream zipInputStream;
public ZipDataEntry(DataEntry parent,
ZipEntry zipEntry,
ZipInputStream zipInputStream)
{
this.parent = parent;
this.zipEntry = zipEntry;
this.zipInputStream = zipInputStream;
}
// Implementations for DataEntry.
public String getName()
{
// Get the right separators.
String name = zipEntry.getName()
.replace(File.separatorChar, ClassConstants.INTERNAL_PACKAGE_SEPARATOR);
// Chop the trailing directory slash, if any.
int length = name.length();
return length > 0 &&
name.charAt(length-1) == ClassConstants.INTERNAL_PACKAGE_SEPARATOR ?
name.substring(0, length -1) :
name;
}
public boolean isDirectory()
{
return zipEntry.isDirectory();
}
public InputStream getInputStream() throws IOException
{
return zipInputStream;
}
public void closeInputStream() throws IOException
{
zipInputStream.closeEntry();
zipInputStream = null;
}
public DataEntry getParent()
{
return parent;
}
// Implementations for Object.
public String toString()
{
return parent.toString() + ':' + getName();
}
}
proguard4.8/src/proguard/io/NameFilter.java 0000644 0001750 0001750 00000005523 11736333524 017507 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.util.*;
import java.util.List;
/**
* This DataEntryReader delegates to one of two other DataEntryReader instances,
* depending on the name of the data entry.
*
* @author Eric Lafortune
*/
public class NameFilter extends FilteredDataEntryReader
{
/**
* Creates a new NameFilter that delegates to the given reader, depending
* on the given list of filters.
*/
public NameFilter(String regularExpression,
DataEntryReader acceptedDataEntryReader)
{
this(regularExpression, acceptedDataEntryReader, null);
}
/**
* Creates a new NameFilter that delegates to either of the two given
* readers, depending on the given list of filters.
*/
public NameFilter(String regularExpression,
DataEntryReader acceptedDataEntryReader,
DataEntryReader rejectedDataEntryReader)
{
super(new DataEntryNameFilter(new ListParser(new FileNameParser()).parse(regularExpression)),
acceptedDataEntryReader,
rejectedDataEntryReader);
}
/**
* Creates a new NameFilter that delegates to the given reader, depending
* on the given list of filters.
*/
public NameFilter(List regularExpressions,
DataEntryReader acceptedDataEntryReader)
{
this(regularExpressions, acceptedDataEntryReader, null);
}
/**
* Creates a new NameFilter that delegates to either of the two given
* readers, depending on the given list of filters.
*/
public NameFilter(List regularExpressions,
DataEntryReader acceptedDataEntryReader,
DataEntryReader rejectedDataEntryReader)
{
super(new DataEntryNameFilter(new ListParser(new FileNameParser()).parse(regularExpressions)),
acceptedDataEntryReader,
rejectedDataEntryReader);
}
} proguard4.8/src/proguard/io/DirectoryWriter.java 0000644 0001750 0001750 00000011027 11736333524 020616 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.ClassConstants;
import java.io.*;
/**
* This DataEntryWriter writes data entries to individual files in a given
* directory.
*
* @author Eric Lafortune
*/
public class DirectoryWriter implements DataEntryWriter
{
private final File baseFile;
private final boolean isFile;
private File currentFile;
private OutputStream currentOutputStream;
private Finisher currentFinisher;
/**
* Creates a new DirectoryWriter.
* @param baseFile the base directory to which all files will be written.
*/
public DirectoryWriter(File baseFile,
boolean isFile)
{
this.baseFile = baseFile;
this.isFile = isFile;
}
// Implementations for DataEntryWriter.
public boolean createDirectory(DataEntry dataEntry) throws IOException
{
// Should we close the current file?
if (!isFile &&
currentFile != null)
{
closeEntry();
}
File directory = getFile(dataEntry);
if (!directory.exists() &&
!directory.mkdirs())
{
throw new IOException("Can't create directory [" + directory.getPath() + "]");
}
return true;
}
public OutputStream getOutputStream(DataEntry dataEntry) throws IOException
{
return getOutputStream(dataEntry, null);
}
public OutputStream getOutputStream(DataEntry dataEntry,
Finisher finisher) throws IOException
{
File file = getFile(dataEntry);
// Should we close the current file?
if (!isFile &&
currentFile != null &&
!currentFile.equals(file))
{
closeEntry();
}
// Do we need a new stream?
if (currentOutputStream == null)
{
// Make sure the parent directories exist.
File parentDirectory = file.getParentFile();
if (parentDirectory != null &&
!parentDirectory.exists() &&
!parentDirectory.mkdirs())
{
throw new IOException("Can't create directory [" + parentDirectory.getPath() + "]");
}
// Open a new output stream for writing to the file.
currentOutputStream =
new BufferedOutputStream(
new FileOutputStream(file));
currentFinisher = finisher;
currentFile = file;
}
return currentOutputStream;
}
public void close() throws IOException
{
// Close the file stream, if any.
closeEntry();
}
// Small utility methods.
/**
* Returns the file for the given data entry.
*/
private File getFile(DataEntry dataEntry)
{
// Use the specified file, or construct a new file.
return isFile ?
baseFile :
new File(baseFile,
dataEntry.getName().replace(ClassConstants.INTERNAL_PACKAGE_SEPARATOR,
File.separatorChar));
}
/**
* Closes the previous file, if any.
*/
private void closeEntry() throws IOException
{
// Close the file stream, if any.
if (currentOutputStream != null)
{
// Let any finisher finish up first.
if (currentFinisher != null)
{
currentFinisher.finish();
currentFinisher = null;
}
currentOutputStream.close();
currentOutputStream = null;
currentFile = null;
}
}
}
proguard4.8/src/proguard/io/FileDataEntry.java 0000644 0001750 0001750 00000004600 11736333524 020147 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.ClassConstants;
import java.io.*;
/**
* This DataEntry
represents a file.
*
* @author Eric Lafortune
*/
public class FileDataEntry implements DataEntry
{
private final File directory;
private final File file;
private InputStream inputStream;
public FileDataEntry(File directory,
File file)
{
this.directory = directory;
this.file = file;
}
// Implementations for DataEntry.
public String getName()
{
// Chop the directory name from the file name and get the right separators.
return file.equals(directory) ?
file.getName() :
file.getPath()
.substring(directory.getPath().length() + File.separator.length())
.replace(File.separatorChar, ClassConstants.INTERNAL_PACKAGE_SEPARATOR);
}
public boolean isDirectory()
{
return file.isDirectory();
}
public InputStream getInputStream() throws IOException
{
if (inputStream == null)
{
inputStream = new BufferedInputStream(new FileInputStream(file));
}
return inputStream;
}
public void closeInputStream() throws IOException
{
inputStream.close();
inputStream = null;
}
public DataEntry getParent()
{
return null;
}
// Implementations for Object.
public String toString()
{
return getName();
}
}
proguard4.8/src/proguard/io/DirectoryPump.java 0000644 0001750 0001750 00000004323 11736333524 020264 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This class can read a given file or directory, recursively, applying a given
* DataEntryReader to all files it comes across.
*
* @author Eric Lafortune
*/
public class DirectoryPump implements DataEntryPump
{
private final File directory;
public DirectoryPump(File directory)
{
this.directory = directory;
}
// Implementations for DataEntryPump.
public void pumpDataEntries(DataEntryReader dataEntryReader)
throws IOException
{
if (!directory.exists())
{
throw new IOException("No such file or directory");
}
readFiles(directory, dataEntryReader);
}
/**
* Reads the given subdirectory recursively, applying the given DataEntryReader
* to all files that are encountered.
*/
private void readFiles(File file, DataEntryReader dataEntryReader)
throws IOException
{
// Pass the file data entry to the reader.
dataEntryReader.read(new FileDataEntry(directory, file));
if (file.isDirectory())
{
// Recurse into the subdirectory.
File[] files = file.listFiles();
for (int index = 0; index < files.length; index++)
{
readFiles(files[index], dataEntryReader);
}
}
}
}
proguard4.8/src/proguard/io/DataEntryRenamer.java 0000644 0001750 0001750 00000007164 11736333524 020671 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.ClassConstants;
import java.io.IOException;
import java.util.Map;
/**
* This DataEntryReader delegates to another DataEntryReader, renaming the
* data entries based on the given map. Entries whose name does not appear
* in the map may be passed to an alternative DataEntryReader.
*
* @author Eric Lafortune
*/
public class DataEntryRenamer implements DataEntryReader
{
private final Map nameMap;
private final DataEntryReader renamedDataEntryReader;
private final DataEntryReader missingDataEntryReader;
/**
* Creates a new DataEntryRenamer.
* @param nameMap the map from old names to new names.
* @param renamedDataEntryReader the DataEntryReader to which renamed data
* entries will be passed.
*/
public DataEntryRenamer(Map nameMap,
DataEntryReader renamedDataEntryReader)
{
this(nameMap, renamedDataEntryReader, null);
}
/**
* Creates a new DataEntryRenamer.
* @param nameMap the map from old names to new names.
* @param renamedDataEntryReader the DataEntryReader to which renamed data
* entries will be passed.
* @param missingDataEntryReader the optional DataEntryReader to which data
* entries that can't be renamed will be
* passed.
*/
public DataEntryRenamer(Map nameMap,
DataEntryReader renamedDataEntryReader,
DataEntryReader missingDataEntryReader)
{
this.nameMap = nameMap;
this.renamedDataEntryReader = renamedDataEntryReader;
this.missingDataEntryReader = missingDataEntryReader;
}
// Implementations for DataEntryReader.
public void read(DataEntry dataEntry) throws IOException
{
String name = dataEntry.getName();
// Add a directory separator if necessary.
if (dataEntry.isDirectory() &&
name.length() > 0)
{
name += ClassConstants.INTERNAL_PACKAGE_SEPARATOR;
}
String newName = (String)nameMap.get(name);
if (newName != null)
{
// Remove the directory separator if necessary.
if (dataEntry.isDirectory() &&
newName.length() > 0)
{
newName = newName.substring(0, newName.length() - 1);
}
renamedDataEntryReader.read(new RenamedDataEntry(dataEntry, newName));
}
else if (missingDataEntryReader != null)
{
missingDataEntryReader.read(dataEntry);
}
}
}
proguard4.8/src/proguard/io/ClassRewriter.java 0000644 0001750 0001750 00000005443 11736333524 020253 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.*;
import proguard.classfile.io.ProgramClassWriter;
import java.io.*;
/**
* This DataEntryReader reads class entries and writes their corresponding
* versions from the ClassPool to a given DataEntryWriter.
*
* @author Eric Lafortune
*/
public class ClassRewriter implements DataEntryReader
{
private final ClassPool classPool;
private final DataEntryWriter dataEntryWriter;
public ClassRewriter(ClassPool classPool,
DataEntryWriter dataEntryWriter)
{
this.classPool = classPool;
this.dataEntryWriter = dataEntryWriter;
}
// Implementations for DataEntryReader.
public void read(DataEntry dataEntry) throws IOException
{
String inputName = dataEntry.getName();
String className = inputName.substring(0, inputName.length() - ClassConstants.CLASS_FILE_EXTENSION.length());
// Find the modified class corrsponding to the input entry.
ProgramClass programClass = (ProgramClass)classPool.getClass(className);
if (programClass != null)
{
// Rename the data entry if necessary.
String newClassName = programClass.getName();
if (!className.equals(newClassName))
{
dataEntry = new RenamedDataEntry(dataEntry, newClassName + ClassConstants.CLASS_FILE_EXTENSION);
}
// Get the output entry corresponding to this input entry.
OutputStream outputStream = dataEntryWriter.getOutputStream(dataEntry);
if (outputStream != null)
{
// Write the class to the output entry.
DataOutputStream classOutputStream = new DataOutputStream(outputStream);
new ProgramClassWriter(classOutputStream).visitProgramClass(programClass);
classOutputStream.flush();
}
}
}
}
proguard4.8/src/proguard/io/ParentDataEntryWriter.java 0000644 0001750 0001750 00000004313 11736333524 021717 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This DataEntryWriter lets another DataEntryWriter write the parent data
* entries.
*
* @author Eric Lafortune
*/
public class ParentDataEntryWriter implements DataEntryWriter
{
private DataEntryWriter dataEntryWriter;
/**
* Creates a new ParentDataEntryWriter.
* @param dataEntryWriter the DataEntryWriter to which the writing will be
* delegated, passing the data entries' parents.
*/
public ParentDataEntryWriter(DataEntryWriter dataEntryWriter)
{
this.dataEntryWriter = dataEntryWriter;
}
// Implementations for DataEntryWriter.
public boolean createDirectory(DataEntry dataEntry) throws IOException
{
return getOutputStream(dataEntry) != null;
}
public OutputStream getOutputStream(DataEntry dataEntry) throws IOException
{
return getOutputStream(dataEntry, null);
}
public OutputStream getOutputStream(DataEntry dataEntry,
Finisher finisher) throws IOException
{
return dataEntryWriter.getOutputStream(dataEntry.getParent(),
finisher);
}
public void close() throws IOException
{
dataEntryWriter.close();
dataEntryWriter = null;
}
}
proguard4.8/src/proguard/io/ClassReader.java 0000644 0001750 0001750 00000010344 11736333524 017646 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.*;
import proguard.classfile.io.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.ClassVisitor;
import java.io.*;
/**
* This DataEntryReader applies a given ClassVisitor to the class
* definitions that it reads.
* isLibrary
flag.
* skipNonPublicLibraryClasses
flag is set.
*
* @author Eric Lafortune
*/
public class ClassReader implements DataEntryReader
{
private final boolean isLibrary;
private final boolean skipNonPublicLibraryClasses;
private final boolean skipNonPublicLibraryClassMembers;
private final WarningPrinter warningPrinter;
private final ClassVisitor classVisitor;
/**
* Creates a new DataEntryClassFilter for reading the specified
* Clazz objects.
*/
public ClassReader(boolean isLibrary,
boolean skipNonPublicLibraryClasses,
boolean skipNonPublicLibraryClassMembers,
WarningPrinter warningPrinter,
ClassVisitor classVisitor)
{
this.isLibrary = isLibrary;
this.skipNonPublicLibraryClasses = skipNonPublicLibraryClasses;
this.skipNonPublicLibraryClassMembers = skipNonPublicLibraryClassMembers;
this.warningPrinter = warningPrinter;
this.classVisitor = classVisitor;
}
// Implementations for DataEntryReader.
public void read(DataEntry dataEntry) throws IOException
{
try
{
// Get the input stream.
InputStream inputStream = dataEntry.getInputStream();
// Wrap it into a data input stream.
DataInputStream dataInputStream = new DataInputStream(inputStream);
// Create a Clazz representation.
Clazz clazz;
if (isLibrary)
{
clazz = new LibraryClass();
clazz.accept(new LibraryClassReader(dataInputStream, skipNonPublicLibraryClasses, skipNonPublicLibraryClassMembers));
}
else
{
clazz = new ProgramClass();
clazz.accept(new ProgramClassReader(dataInputStream));
}
// Apply the visitor, if we have a real class.
String className = clazz.getName();
if (className != null)
{
if (!dataEntry.getName().replace(File.pathSeparatorChar, ClassConstants.INTERNAL_PACKAGE_SEPARATOR).equals(className+ClassConstants.CLASS_FILE_EXTENSION) &&
warningPrinter != null)
{
warningPrinter.print(className,
"Warning: class [" + dataEntry.getName() + "] unexpectedly contains class [" + ClassUtil.externalClassName(className) + "]");
}
clazz.accept(classVisitor);
}
dataEntry.closeInputStream();
}
catch (Exception ex)
{
throw (IOException)new IOException("Can't process class ["+dataEntry.getName()+"] ("+ex.getMessage()+")").initCause(ex);
}
}
}
proguard4.8/src/proguard/io/DirectoryFilter.java 0000644 0001750 0001750 00000003471 11736333524 020573 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.ClassConstants;
import proguard.util.ExtensionMatcher;
import java.io.IOException;
/**
* This DataEntryReader delegates to one of two other DataEntryReader instances,
* depending on whether the data entry represents a directory or not.
*
* @author Eric Lafortune
*/
public class DirectoryFilter extends FilteredDataEntryReader
{
/**
* Creates a new ClassFilter that delegates reading directories to the
* given reader.
*/
public DirectoryFilter(DataEntryReader directoryReader)
{
this (directoryReader, null);
}
/**
* Creates a new ClassFilter that delegates to either of the two given
* readers.
*/
public DirectoryFilter(DataEntryReader directoryReader,
DataEntryReader otherReader)
{
super(new DataEntryDirectoryFilter(),
directoryReader,
otherReader);
}
} proguard4.8/src/proguard/io/JarReader.java 0000644 0001750 0001750 00000004402 11736333524 017313 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.IOException;
import java.util.zip.*;
/**
* This DataEntryReader lets a given DataEntryReader read all data entries of
* the read jar/war/zip data entries.
*
* @author Eric Lafortune
*/
public class JarReader implements DataEntryReader
{
private final DataEntryReader dataEntryReader;
/**
* Creates a new JarReader.
*/
public JarReader(DataEntryReader dataEntryReader)
{
this.dataEntryReader = dataEntryReader;
}
// Implementation for DataEntryReader.
public void read(DataEntry dataEntry) throws IOException
{
ZipInputStream zipInputStream = new ZipInputStream(dataEntry.getInputStream());
try
{
// Get all entries from the input jar.
while (true)
{
// Can we get another entry?
ZipEntry zipEntry = zipInputStream.getNextEntry();
if (zipEntry == null)
{
break;
}
// Delegate the actual reading to the data entry reader.
dataEntryReader.read(new ZipDataEntry(dataEntry,
zipEntry,
zipInputStream));
}
}
finally
{
dataEntry.closeInputStream();
}
}
}
proguard4.8/src/proguard/io/FilteredDataEntryWriter.java 0000644 0001750 0001750 00000010744 11736333524 022231 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This DataEntryWriter delegates to one of two other DataEntryWriter instances,
* depending on whether the data entry passes through a given data entry filter
* or not.
*
* @author Eric Lafortune
*/
public class FilteredDataEntryWriter implements DataEntryWriter
{
private final DataEntryFilter dataEntryFilter;
private DataEntryWriter acceptedDataEntryWriter;
private DataEntryWriter rejectedDataEntryWriter;
/**
* Creates a new FilteredDataEntryWriter with only a writer for accepted
* data entries.
* @param dataEntryFilter the data entry filter.
* @param acceptedDataEntryWriter the DataEntryWriter to which the writing
* will be delegated if the filter accepts
* the data entry. May be null
.
*/
public FilteredDataEntryWriter(DataEntryFilter dataEntryFilter,
DataEntryWriter acceptedDataEntryWriter)
{
this(dataEntryFilter, acceptedDataEntryWriter, null);
}
/**
* Creates a new FilteredDataEntryWriter.
* @param dataEntryFilter the data entry filter.
* @param acceptedDataEntryWriter the DataEntryWriter to which the writing
* will be delegated if the filter accepts
* the data entry. May be null
.
* @param rejectedDataEntryWriter the DataEntryWriter to which the writing
* will be delegated if the filter does not
* accept the data entry. May be
* null
.
*/
public FilteredDataEntryWriter(DataEntryFilter dataEntryFilter,
DataEntryWriter acceptedDataEntryWriter,
DataEntryWriter rejectedDataEntryWriter)
{
this.dataEntryFilter = dataEntryFilter;
this.acceptedDataEntryWriter = acceptedDataEntryWriter;
this.rejectedDataEntryWriter = rejectedDataEntryWriter;
}
// Implementations for DataEntryWriter.
public boolean createDirectory(DataEntry dataEntry) throws IOException
{
// Get the right data entry writer.
DataEntryWriter dataEntryWriter = dataEntryFilter.accepts(dataEntry) ?
acceptedDataEntryWriter :
rejectedDataEntryWriter;
// Delegate to it, if it's not null.
return dataEntryWriter != null &&
dataEntryWriter.createDirectory(dataEntry);
}
public OutputStream getOutputStream(DataEntry dataEntry) throws IOException
{
return getOutputStream(dataEntry, null);
}
public OutputStream getOutputStream(DataEntry dataEntry,
Finisher finisher) throws IOException
{
// Get the right data entry writer.
DataEntryWriter dataEntryWriter = dataEntryFilter.accepts(dataEntry) ?
acceptedDataEntryWriter :
rejectedDataEntryWriter;
// Delegate to it, if it's not null.
return dataEntryWriter != null ?
dataEntryWriter.getOutputStream(dataEntry, finisher) :
null;
}
public void close() throws IOException
{
if (acceptedDataEntryWriter != null)
{
acceptedDataEntryWriter.close();
acceptedDataEntryWriter = null;
}
if (rejectedDataEntryWriter != null)
{
rejectedDataEntryWriter.close();
rejectedDataEntryWriter = null;
}
}
}
proguard4.8/src/proguard/io/CascadingDataEntryWriter.java 0000644 0001750 0001750 00000006213 11736333524 022343 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This DataEntryWriter delegates to a given DataEntryWriter, or failing that,
* to another given DataEntryWriter.
*
* @author Eric Lafortune
*/
public class CascadingDataEntryWriter implements DataEntryWriter
{
private DataEntryWriter dataEntryWriter1;
private DataEntryWriter dataEntryWriter2;
/**
* Creates a new CascadingDataEntryWriter.
* @param dataEntryWriter1 the DataEntryWriter to which the writing will be
* delegated first.
* @param dataEntryWriter2 the DataEntryWriter to which the writing will be
* delegated, if the first one can't provide an
* output stream.
*/
public CascadingDataEntryWriter(DataEntryWriter dataEntryWriter1,
DataEntryWriter dataEntryWriter2)
{
this.dataEntryWriter1 = dataEntryWriter1;
this.dataEntryWriter2 = dataEntryWriter2;
}
// Implementations for DataEntryWriter.
public boolean createDirectory(DataEntry dataEntry) throws IOException
{
// Try to create a directory with the first data entry writer, or
// otherwise with the second data entry writer.
return dataEntryWriter1.createDirectory(dataEntry) ||
dataEntryWriter2.createDirectory(dataEntry);
}
public OutputStream getOutputStream(DataEntry dataEntry) throws IOException
{
return getOutputStream(dataEntry, null);
}
public OutputStream getOutputStream(DataEntry dataEntry,
Finisher finisher) throws IOException
{
// Try to get an output stream from the first data entry writer.
OutputStream outputStream =
dataEntryWriter1.getOutputStream(dataEntry, finisher);
// Return it, if it's not null. Otherwise try to get an output stream
// from the second data entry writer.
return outputStream != null ?
outputStream :
dataEntryWriter2.getOutputStream(dataEntry, finisher);
}
public void close() throws IOException
{
dataEntryWriter1.close();
dataEntryWriter2.close();
dataEntryWriter1 = null;
dataEntryWriter2 = null;
}
}
proguard4.8/src/proguard/io/DataEntryParentFilter.java 0000644 0001750 0001750 00000003160 11736333524 021667 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
/**
* This DataEntryFilter delegates filtering to a DataEntryFilter for its parent.
*
* @author Eric Lafortune
*/
public class DataEntryParentFilter
implements DataEntryFilter
{
private final DataEntryFilter dataEntryFilter;
/**
* Creates a new ParentFilter.
* @param dataEntryFilter the filter that will be applied to the data
* entry's parent.
*/
public DataEntryParentFilter(DataEntryFilter dataEntryFilter)
{
this.dataEntryFilter = dataEntryFilter;
}
// Implementations for DataEntryFilter.
public boolean accepts(DataEntry dataEntry)
{
return dataEntry != null && dataEntryFilter.accepts(dataEntry.getParent());
}
}
proguard4.8/src/proguard/io/JarWriter.java 0000644 0001750 0001750 00000015363 11736333524 017375 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.ClassConstants;
import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
/**
* This DataEntryWriter sends data entries to a given jar/zip file.
* The manifest and comment properties can optionally be set.
*
* @author Eric Lafortune
*/
public class JarWriter implements DataEntryWriter, Finisher
{
private final DataEntryWriter dataEntryWriter;
private final Manifest manifest;
private final String comment;
private OutputStream currentParentOutputStream;
private ZipOutputStream currentJarOutputStream;
private Finisher currentFinisher;
private DataEntry currentDataEntry;
// The names of the jar entries that are already in the jar.
private final Set jarEntryNames = new HashSet();
/**
* Creates a new JarWriter without manifest or comment.
*/
public JarWriter(DataEntryWriter dataEntryWriter)
{
this(dataEntryWriter, null, null);
}
/**
* Creates a new JarWriter.
*/
public JarWriter(DataEntryWriter dataEntryWriter,
Manifest manifest,
String comment)
{
this.dataEntryWriter = dataEntryWriter;
this.manifest = manifest;
this.comment = comment;
}
// Implementations for DataEntryWriter.
public boolean createDirectory(DataEntry dataEntry) throws IOException
{
//Make sure we can start with a new entry.
if (!prepareEntry(dataEntry))
{
return false;
}
// Close the previous ZIP entry, if any.
closeEntry();
// Get the directory entry name.
String name = dataEntry.getName() + ClassConstants.INTERNAL_PACKAGE_SEPARATOR;
// We have to check if the name is already used, because
// ZipOutputStream doesn't handle this case properly (it throws
// an exception which can be caught, but the ZipDataEntry is
// remembered anyway).
if (jarEntryNames.add(name))
{
// Create a new directory entry.
currentJarOutputStream.putNextEntry(new ZipEntry(name));
currentJarOutputStream.closeEntry();
}
// Clear the finisher.
currentFinisher = null;
currentDataEntry = null;
return true;
}
public OutputStream getOutputStream(DataEntry dataEntry) throws IOException
{
return getOutputStream(dataEntry, null);
}
public OutputStream getOutputStream(DataEntry dataEntry,
Finisher finisher) throws IOException
{
//Make sure we can start with a new entry.
if (!prepareEntry(dataEntry))
{
return null;
}
// Do we need a new entry?
if (!dataEntry.equals(currentDataEntry))
{
// Close the previous ZIP entry, if any.
closeEntry();
// Get the entry name.
String name = dataEntry.getName();
// We have to check if the name is already used, because
// ZipOutputStream doesn't handle this case properly (it throws
// an exception which can be caught, but the ZipDataEntry is
// remembered anyway).
if (!jarEntryNames.add(name))
{
throw new IOException("Duplicate zip entry ["+dataEntry+"]");
}
// Create a new entry.
currentJarOutputStream.putNextEntry(new ZipEntry(name));
// Set up the finisher for the entry.
currentFinisher = finisher;
currentDataEntry = dataEntry;
}
return currentJarOutputStream;
}
public void finish() throws IOException
{
// Finish the entire ZIP stream, if any.
if (currentJarOutputStream != null)
{
// Close the previous ZIP entry, if any.
closeEntry();
// Finish the entire ZIP stream.
currentJarOutputStream.finish();
currentJarOutputStream = null;
currentParentOutputStream = null;
jarEntryNames.clear();
}
}
public void close() throws IOException
{
// Close the parent stream.
dataEntryWriter.close();
}
// Small utility methods.
/**
* Makes sure the current output stream is set up for the given entry.
*/
private boolean prepareEntry(DataEntry dataEntry) throws IOException
{
// Get the parent stream, new or exisiting.
// This may finish our own jar output stream.
OutputStream parentOutputStream =
dataEntryWriter.getOutputStream(dataEntry.getParent(), this);
// Did we get a stream?
if (parentOutputStream == null)
{
return false;
}
// Do we need a new stream?
if (currentParentOutputStream == null)
{
currentParentOutputStream = parentOutputStream;
// Create a new jar stream, with a manifest, if set.
currentJarOutputStream = manifest != null ?
new JarOutputStream(parentOutputStream, manifest) :
new ZipOutputStream(parentOutputStream);
// Add a comment, if set.
if (comment != null)
{
currentJarOutputStream.setComment(comment);
}
}
return true;
}
/**
* Closes the previous ZIP entry, if any.
*/
private void closeEntry() throws IOException
{
if (currentDataEntry != null)
{
// Let any finisher finish up first.
if (currentFinisher != null)
{
currentFinisher.finish();
currentFinisher = null;
}
currentJarOutputStream.closeEntry();
currentDataEntry = null;
}
}
}
proguard4.8/src/proguard/io/DataEntryRewriter.java 0000644 0001750 0001750 00000010361 11736333524 021074 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.*;
import java.io.*;
/**
* This DataEntryReader writes the resource data entries that it reads to a
* given DataEntryWriter, updating their contents based on the renamed classes
* in the given ClassPool.
*
* @author Eric Lafortune
*/
public class DataEntryRewriter extends DataEntryCopier
{
private final ClassPool classPool;
/**
* Creates a new DataEntryRewriter.
*/
public DataEntryRewriter(ClassPool classPool,
DataEntryWriter dataEntryWriter)
{
super(dataEntryWriter);
this.classPool = classPool;
}
// Implementations for DataEntryCopier.
protected void copyData(InputStream inputStream,
OutputStream outputStream)
throws IOException
{
Reader reader = new BufferedReader(new InputStreamReader(inputStream));
Writer writer = new BufferedWriter(new OutputStreamWriter(outputStream));
copyData(reader, writer);
writer.flush();
outputStream.flush();
}
/**
* Copies all data that it can read from the given reader to the given
* writer.
*/
protected void copyData(Reader reader,
Writer writer)
throws IOException
{
StringBuffer word = new StringBuffer();
while (true)
{
int i = reader.read();
if (i < 0)
{
break;
}
// Is the character part of a word?
char c = (char)i;
if (Character.isJavaIdentifierPart(c) ||
c == '.' ||
c == '-')
{
// Collect the characters in this word.
word.append(c);
}
else
{
// Write out the updated word, if any.
writeUpdatedWord(writer, word.toString());
word.setLength(0);
// Write out the character that terminated it.
writer.write(c);
}
}
// Write out the final word.
writeUpdatedWord(writer, word.toString());
}
// Small utility methods.
/**
* Writes the given word to the given writer, after having adapted it,
* based on the renamed class names.
*/
private void writeUpdatedWord(Writer writer, String word)
throws IOException
{
if (word.length() > 0)
{
String newWord = word;
boolean containsDots = word.indexOf('.') >= 0;
// Replace dots by forward slashes.
String className = containsDots ?
word.replace('.', ClassConstants.INTERNAL_PACKAGE_SEPARATOR) :
word;
// Find the class corrsponding to the word.
Clazz clazz = classPool.getClass(className);
if (clazz != null)
{
// Update the word if necessary.
String newClassName = clazz.getName();
if (!className.equals(newClassName))
{
// Replace forward slashes by dots.
newWord = containsDots ?
newClassName.replace(ClassConstants.INTERNAL_PACKAGE_SEPARATOR, '.') :
newClassName;
}
}
writer.write(newWord);
}
}
}
proguard4.8/src/proguard/io/DataEntryFilter.java 0000644 0001750 0001750 00000002466 11736333524 020525 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
/**
* This interface provides a method to filter data entries.
*
* @author Eric Lafortune
*/
public interface DataEntryFilter
{
/**
* Checks whether the filter accepts the given data entry.
* @param dataEntry the data entry to filter.
* @return a boolean indicating whether the filter accepts the given data
* entry.
*/
public boolean accepts(DataEntry dataEntry);
}
proguard4.8/src/proguard/io/RenamedDataEntry.java 0000664 0001750 0001750 00000003734 11740564025 020651 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This DataEntry wraps another data entry, returning a different name instead
* of the wrapped data entry's name.
*
* @author Eric Lafortune
*/
public class RenamedDataEntry implements DataEntry
{
private final DataEntry dataEntry;
private final String name;
public RenamedDataEntry(DataEntry dataEntry,
String name)
{
this.dataEntry = dataEntry;
this.name = name;
}
// Implementations for DataEntry.
public String getName()
{
return name;
}
public boolean isDirectory()
{
return dataEntry.isDirectory();
}
public InputStream getInputStream() throws IOException
{
return dataEntry.getInputStream();
}
public void closeInputStream() throws IOException
{
dataEntry.closeInputStream();
}
public DataEntry getParent()
{
return dataEntry.getParent();
}
// Implementations for Object.
public String toString()
{
return name + " == " + dataEntry;
}
}
proguard4.8/src/proguard/io/DataEntryReader.java 0000644 0001750 0001750 00000002374 11736333524 020500 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.IOException;
/**
* This interface provides methods for reading data entries. The implementation
* determines what to do with the read data, if anything.
*
* @author Eric Lafortune
*/
public interface DataEntryReader
{
/**
* Reads the given data entry.
*/
public void read(DataEntry dataEntry) throws IOException;
}
proguard4.8/src/proguard/io/DataEntryWriter.java 0000644 0001750 0001750 00000005474 11736333524 020556 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This interface provides methods for writing data entries, such as ZIP entries
* or files. The implementation determines to which type of data entry the
* data will be written.
*
* @author Eric Lafortune
*/
public interface DataEntryWriter
{
/**
* Creates a directory.
* @param dataEntry the data entry for which the directory is to be created.
* @return whether the directory has been created.
*/
public boolean createDirectory(DataEntry dataEntry) throws IOException;
/**
* Returns an output stream for writing data. The caller must not close
* the output stream; closing the output stream is the responsibility of
* the implementation of this interface.
* @param dataEntry the data entry for which the output stream is to be created.
* @return the output stream. The stream may be null
to indicate
* that the data entry should not be written.
*/
public OutputStream getOutputStream(DataEntry dataEntry) throws IOException;
/**
* Returns an output stream for writing data. The caller must not close
* the output stream; closing the output stream is the responsibility of
* the implementation of this interface.
* @param dataEntry the data entry for which the output stream is to be created.
* @param finisher the optional finisher that will be called before this
* class closes the output stream (at some later point in
* time) that will be returned (now).
* @return the output stream. The stream may be null
to indicate
* that the data entry should not be written.
*/
public OutputStream getOutputStream(DataEntry dataEntry,
Finisher finisher) throws IOException;
/**
* Finishes writing all data entries.
*/
public void close() throws IOException;
}
proguard4.8/src/proguard/io/ManifestRewriter.java 0000664 0001750 0001750 00000013002 11736333524 020744 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.*;
import java.io.*;
/**
* This DataEntryReader writes the manifest data entries that it reads to a
* given DataEntryWriter, updating their contents based on the renamed classes
* in the given ClassPool.
*
* @author Eric Lafortune
*/
public class ManifestRewriter extends DataEntryRewriter
{
/**
* Creates a new ManifestRewriter.
*/
public ManifestRewriter(ClassPool classPool,
DataEntryWriter dataEntryWriter)
{
super(classPool, dataEntryWriter);
}
// Implementations for DataEntryRewriter.
protected void copyData(Reader reader,
Writer writer)
throws IOException
{
super.copyData(new SplitLineReader(reader),
new SplitLineWriter(writer));
}
/**
* This Reader reads manifest files, joining any split lines. It replaces
* the allowed CR/LF/CR+LF alternatives by simple LF in the process.
*/
private static class SplitLineReader extends FilterReader
{
private static final int NONE = -2;
private int bufferedCharacter = NONE;
public SplitLineReader(Reader reader)
{
super(reader);
}
// Implementations for Reader.
public int read() throws IOException
{
while (true)
{
// Get the buffered character or the first character.
int c1 = bufferedCharacter != NONE ?
bufferedCharacter :
super.read();
// Clear the buffered character.
bufferedCharacter = NONE;
// Return it if it's an ordinary character.
if (c1 != '\n' && c1 != '\r')
{
return c1;
}
// It's a newline. Read the second character to see if it's a
// continuation.
int c2 = super.read();
// Skip any corresponding, redundant \n or \r.
if ((c2 == '\n' || c2 == '\r') && c1 != c2)
{
c2 = super.read();
}
// Isn't it a continuation after all?
if (c2 != ' ')
{
// Buffer the second character and return a newline.
bufferedCharacter = c2;
return '\n';
}
// Just continue after the continuation characters.
}
}
public int read(char[] cbuf, int off, int len) throws IOException
{
// Delegate to reading a single character at a time.
int count = 0;
while (count < len)
{
int c = read();
if (c == -1)
{
break;
}
cbuf[off + count++] = (char)c;
}
return count;
}
public long skip(long n) throws IOException
{
// Delegate to reading a single character at a time.
int count = 0;
while (count < n)
{
int c = read();
if (c == -1)
{
break;
}
count++;
}
return count;
}
}
/**
* This Writer writes manifest files, splitting any long lines.
*/
private static class SplitLineWriter extends FilterWriter
{
private int counter = 0;
public SplitLineWriter(Writer writer)
{
super(writer);
}
// Implementations for Reader.
public void write(int c) throws IOException
{
// TODO: We should actually count the Utf-8 bytes, not the characters.
if (c == '\n')
{
// Reset the character count.
counter = 0;
}
else if (counter == 70)
{
// Insert a newline and a space.
super.write('\n');
super.write(' ');
counter = 2;
}
else
{
counter++;
}
super.write(c);
}
public void write(char[] cbuf, int off, int len) throws IOException
{
for (int count = 0; count < len; count++)
{
write(cbuf[off + count]);
}
}
public void write(String str, int off, int len) throws IOException
{
write(str.toCharArray(), off, len);
}
}
} proguard4.8/src/proguard/io/DataEntryPump.java 0000644 0001750 0001750 00000003055 11736333524 020214 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.IOException;
/**
* This interface provides a method to pump data entries. The implementation
* determines the source and the type of the data entries. Typical examples
* are zip entries coming from a zip file of file entries coming from a
* directory structure. The reader can for instance collect the classes,
* or copy the resource files that are presented.
*
* @author Eric Lafortune
*/
public interface DataEntryPump
{
/**
* Applies the given DataEntryReader to all data entries that the
* implementation can provide.
*/
public void pumpDataEntries(DataEntryReader dataEntryReader)
throws IOException;
}
proguard4.8/src/proguard/io/ClassFilter.java 0000644 0001750 0001750 00000003513 11736333524 017671 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.ClassConstants;
import proguard.util.ExtensionMatcher;
import java.io.IOException;
/**
* This DataEntryReader delegates to one of two other DataEntryReader instances,
* depending on the extension of the data entry.
*
* @author Eric Lafortune
*/
public class ClassFilter extends FilteredDataEntryReader
{
/**
* Creates a new ClassFilter that delegates reading classes to the
* given reader.
*/
public ClassFilter(DataEntryReader classReader)
{
this(classReader, null);
}
/**
* Creates a new ClassFilter that delegates to either of the two given
* readers.
*/
public ClassFilter(DataEntryReader classReader,
DataEntryReader dataEntryReader)
{
super(new DataEntryNameFilter(
new ExtensionMatcher(ClassConstants.CLASS_FILE_EXTENSION)),
classReader,
dataEntryReader);
}
}
proguard4.8/src/proguard/io/DataEntryObfuscator.java 0000644 0001750 0001750 00000012306 11736333524 021401 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.*;
import proguard.classfile.util.ClassUtil;
import java.io.IOException;
import java.util.Map;
/**
* This DataEntryReader delegates to another DataEntryReader, renaming the
* data entries based on the renamed classes in the given ClassPool.
*
* @author Eric Lafortune
*/
public class DataEntryObfuscator implements DataEntryReader
{
private final ClassPool classPool;
private final Map packagePrefixMap;
private final DataEntryReader dataEntryReader;
/**
* Creates a new DataEntryObfuscator.
* @param classPool the class pool that maps from old names to new
* names.
* @param packagePrefixMap the map from old package prefixes to new package
* prefixes.
* @param dataEntryReader the DataEntryReader to which calls will be
* delegated.
*/
public DataEntryObfuscator(ClassPool classPool,
Map packagePrefixMap,
DataEntryReader dataEntryReader)
{
this.classPool = classPool;
this.packagePrefixMap = packagePrefixMap;
this.dataEntryReader = dataEntryReader;
}
// Implementations for DataEntryReader.
public void read(DataEntry dataEntry) throws IOException
{
// Delegate to the actual data entry reader.
dataEntryReader.read(renamedDataEntry(dataEntry));
}
/**
* Create a renamed data entry, if possible.
*/
private DataEntry renamedDataEntry(DataEntry dataEntry)
{
String dataEntryName = dataEntry.getName();
// Try to find a corresponding class name by removing increasingly
// long suffixes.
for (int suffixIndex = dataEntryName.length() - 1;
suffixIndex > 0;
suffixIndex--)
{
char c = dataEntryName.charAt(suffixIndex);
if (!Character.isLetterOrDigit(c))
{
// Chop off the suffix.
String className = dataEntryName.substring(0, suffixIndex);
// Did we get to the package separator?
if (c == ClassConstants.INTERNAL_PACKAGE_SEPARATOR)
{
break;
}
// Is there a class corresponding to the data entry?
Clazz clazz = classPool.getClass(className);
if (clazz != null)
{
// Did the class get a new name?
String newClassName = clazz.getName();
if (!className.equals(newClassName))
{
// Return a renamed data entry.
String newDataEntryName =
newClassName + dataEntryName.substring(suffixIndex);
return new RenamedDataEntry(dataEntry, newDataEntryName);
}
else
{
// Otherwise stop looking.
return dataEntry;
}
}
}
}
// Try to find a corresponding package name by increasingly removing
// more subpackages.
String packagePrefix = dataEntryName;
do
{
// Chop off the class name or the last subpackage name.
packagePrefix = ClassUtil.internalPackagePrefix(packagePrefix);
// Is there a package corresponding to the package prefix?
String newPackagePrefix = (String)packagePrefixMap.get(packagePrefix);
if (newPackagePrefix != null)
{
// Did the package get a new name?
if (!packagePrefix.equals(newPackagePrefix))
{
// Return a renamed data entry.
String newDataEntryName =
newPackagePrefix + dataEntryName.substring(packagePrefix.length());
return new RenamedDataEntry(dataEntry, newDataEntryName);
}
else
{
// Otherwise stop looking.
return dataEntry;
}
}
}
while (packagePrefix.length() > 0);
return dataEntry;
}
}
proguard4.8/src/proguard/io/Finisher.java 0000644 0001750 0001750 00000002333 11736333524 017224 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.IOException;
/**
* This interface specifies a listener that is called to finish an output stream
* before it is closed.
*
* @author Eric Lafortune
*/
public interface Finisher
{
/**
* Finishes an output stream right before it is closed.
*/
public void finish() throws IOException;
}
proguard4.8/src/proguard/io/DataEntryNameFilter.java 0000664 0001750 0001750 00000003264 11736333524 021325 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.util.StringMatcher;
/**
* This DataEntryFilter filters data entries based on whether their names match
* a given StringMatcher.
*
* @author Eric Lafortune
*/
public class DataEntryNameFilter
implements DataEntryFilter
{
private final StringMatcher stringMatcher;
/**
* Creates a new DataEntryNameFilter.
* @param stringMatcher the string matcher that will be applied to the names
* of the filtered data entries.
*/
public DataEntryNameFilter(StringMatcher stringMatcher)
{
this.stringMatcher = stringMatcher;
}
// Implementations for DataEntryFilter.
public boolean accepts(DataEntry dataEntry)
{
return dataEntry != null && stringMatcher.matches(dataEntry.getName());
}
}
proguard4.8/src/proguard/io/DataEntryCopier.java 0000644 0001750 0001750 00000020323 11736333524 020511 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.util.ExtensionMatcher;
import java.io.*;
/**
* This DataEntryReader writes the ZIP entries and files that it reads to a
* given DataEntryWriter.
*
* @author Eric Lafortune
*/
public class DataEntryCopier implements DataEntryReader
{
private static final int BUFFER_SIZE = 1024;
private final DataEntryWriter dataEntryWriter;
private final byte[] buffer = new byte[BUFFER_SIZE];
public DataEntryCopier(DataEntryWriter dataEntryWriter)
{
this.dataEntryWriter = dataEntryWriter;
}
// Implementations for DataEntryReader.
public void read(DataEntry dataEntry) throws IOException
{
try
{
if (dataEntry.isDirectory())
{
dataEntryWriter.createDirectory(dataEntry);
}
else
{
// Get the output entry corresponding to this input entry.
OutputStream outputStream = dataEntryWriter.getOutputStream(dataEntry);
if (outputStream != null)
{
InputStream inputStream = dataEntry.getInputStream();
// Copy the data from the input entry to the output entry.
copyData(inputStream, outputStream);
// Close the data entries.
dataEntry.closeInputStream();
}
}
}
catch (IOException ex)
{
System.err.println("Warning: can't write resource [" + dataEntry.getName() + "] (" + ex.getMessage() + ")");
}
}
/**
* Copies all data that it can read from the given input stream to the
* given output stream.
*/
protected void copyData(InputStream inputStream,
OutputStream outputStream)
throws IOException
{
while (true)
{
int count = inputStream.read(buffer);
if (count < 0)
{
break;
}
outputStream.write(buffer, 0, count);
}
outputStream.flush();
}
/**
* A main method for testing file/jar/war/directory copying.
*/
public static void main(String[] args)
{
try
{
String input = args[0];
String output = args[1];
boolean outputIsJar = output.endsWith(".jar");
boolean outputIsWar = output.endsWith(".war");
boolean outputIsEar = output.endsWith(".ear");
boolean outputIsZip = output.endsWith(".zip");
DataEntryWriter writer = new DirectoryWriter(new File(output),
outputIsJar ||
outputIsWar ||
outputIsEar ||
outputIsZip);
if (!outputIsJar)
{
// Zip up any zips, if necessary.
DataEntryWriter zipWriter = new JarWriter(writer);
if (outputIsZip)
{
// Always zip.
writer = zipWriter;
}
else
{
// Only zip up zips.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".zip"))),
zipWriter,
writer);
}
// Zip up any wars, if necessary.
DataEntryWriter warWriter = new JarWriter(writer);
if (outputIsWar)
{
// Always zip.
writer = warWriter;
}
else
{
// Only zip up wars.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".war"))),
warWriter,
writer);
}
}
// Zip up any jars, if necessary.
DataEntryWriter jarWriter = new JarWriter(writer);
if (outputIsJar)
{
// Always zip.
writer = jarWriter;
}
else
{
// Only zip up jars.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".jar"))),
jarWriter,
writer);
}
// Create the copying DataEntryReader.
DataEntryReader reader = new DataEntryCopier(writer);
boolean inputIsJar = input.endsWith(".jar");
boolean inputIsWar = input.endsWith(".war");
boolean inputIsZip = input.endsWith(".zip");
// Unzip any jars, if necessary.
DataEntryReader jarReader = new JarReader(reader);
if (inputIsJar)
{
// Always unzip.
reader = jarReader;
}
else
{
// Only unzip jar entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".jar")),
jarReader,
reader);
// Unzip any wars, if necessary.
DataEntryReader warReader = new JarReader(reader);
if (inputIsWar)
{
// Always unzip.
reader = warReader;
}
else
{
// Only unzip war entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".war")),
warReader,
reader);
}
// Unzip any zips, if necessary.
DataEntryReader zipReader = new JarReader(reader);
if (inputIsZip)
{
// Always unzip.
reader = zipReader;
}
else
{
// Only unzip zip entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".zip")),
zipReader,
reader);
}
}
DirectoryPump directoryReader = new DirectoryPump(new File(input));
directoryReader.pumpDataEntries(reader);
writer.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
proguard4.8/src/proguard/io/DataEntryClassWriter.java 0000644 0001750 0001750 00000005631 11736333524 021537 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.classfile.*;
import proguard.classfile.io.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
import java.io.*;
/**
* This ClassVisitor writes out the ProgramClass objects that it visits to the
* given DataEntry, modified to have the correct name.
*
* @author Eric Lafortune
*/
public class DataEntryClassWriter
extends SimplifiedVisitor
implements ClassVisitor
{
private final DataEntryWriter dataEntryWriter;
private final DataEntry templateDataEntry;
/**
* Creates a new DataEntryClassWriter for writing to the given
* DataEntryWriter, based on the given template DataEntry.
*/
public DataEntryClassWriter(DataEntryWriter dataEntryWriter,
DataEntry templateDataEntry)
{
this.dataEntryWriter = dataEntryWriter;
this.templateDataEntry = templateDataEntry;
}
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
// Rename the data entry if necessary.
String actualClassName = programClass.getName();
DataEntry actualDataEntry =
new RenamedDataEntry(templateDataEntry,
actualClassName + ClassConstants.CLASS_FILE_EXTENSION);
try
{
// Get the output entry corresponding to this input entry.
OutputStream outputStream = dataEntryWriter.getOutputStream(actualDataEntry);
if (outputStream != null)
{
// Write the class to the output entry.
DataOutputStream classOutputStream = new DataOutputStream(outputStream);
new ProgramClassWriter(classOutputStream).visitProgramClass(programClass);
classOutputStream.flush();
}
}
catch (IOException e)
{
throw new RuntimeException("Can't write program class ["+actualClassName+"] to ["+actualDataEntry+"] ("+e.getMessage()+")", e);
}
}
}
proguard4.8/src/proguard/io/DataEntry.java 0000644 0001750 0001750 00000003362 11736333524 017353 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import java.io.*;
/**
* This interface describes a data entry, e.g. a ZIP entry, a file, or a
* directory.
*
* @author Eric Lafortune
*/
public interface DataEntry
{
/**
* Returns the name of this data entry.
*/
public String getName();
/**
* Returns whether the data entry represents a directory.
*/
public boolean isDirectory();
/**
* Returns an input stream for reading the content of this data entry.
* The data entry may not represent a directory.
*/
public InputStream getInputStream() throws IOException;
/**
* Closes the previously retrieved InputStream.
*/
public void closeInputStream() throws IOException;
/**
* Returns the parent of this data entry, or null if it doesn't
* have one.
*/
public DataEntry getParent();
}
proguard4.8/src/proguard/io/DataEntryDirectoryFilter.java 0000644 0001750 0001750 00000002454 11736333524 022407 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.io;
import proguard.util.StringMatcher;
/**
* This DataEntryFilter filters data entries based on whether they represent
* directories.
*
* @author Eric Lafortune
*/
public class DataEntryDirectoryFilter
implements DataEntryFilter
{
// Implementations for DataEntryFilter.
public boolean accepts(DataEntry dataEntry)
{
return dataEntry != null && dataEntry.isDirectory();
}
} proguard4.8/src/proguard/gui/ 0000775 0001750 0001750 00000000000 11760503005 014756 5 ustar eric eric proguard4.8/src/proguard/gui/package.html 0000644 0001750 0001750 00000000105 11736333524 017243 0 ustar eric eric
This package contains a GUI for ProGuard and ReTrace.
proguard4.8/src/proguard/gui/ReTraceRunnable.java 0000644 0001750 0001750 00000011732 11736333524 020651 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui;
import proguard.retrace.ReTrace;
import javax.swing.*;
import java.awt.*;
import java.io.*;
/**
* This
Runnable
runs ReTrace, sending console output to a text
* area and any exceptions to message dialogs.
*
* @see ReTrace
* @author Eric Lafortune
*/
final class ReTraceRunnable implements Runnable
{
private final JTextArea consoleTextArea;
private final boolean verbose;
private final File mappingFile;
private final String stackTrace;
/**
* Creates a new ProGuardRunnable object.
* @param consoleTextArea the text area to send the console output to.
* @param verbose specifies whether the de-obfuscated stack trace
* should be verbose.
* @param mappingFile the mapping file that was written out by ProGuard.
*/
public ReTraceRunnable(JTextArea consoleTextArea,
boolean verbose,
File mappingFile,
String stackTrace)
{
this.consoleTextArea = consoleTextArea;
this.verbose = verbose;
this.mappingFile = mappingFile;
this.stackTrace = stackTrace;
}
// Implementation for Runnable.
public void run()
{
consoleTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
consoleTextArea.setText("");
// Redirect the stack trace string to the System's in stream, and the
// out and err streams to the console text area.
InputStream oldIn = System.in;
PrintStream oldOut = System.out;
PrintStream oldErr = System.err;
ByteArrayInputStream inputStream =
new ByteArrayInputStream(stackTrace.getBytes());
PrintStream printStream =
new PrintStream(new TextAreaOutputStream(consoleTextArea), true);
System.setIn(inputStream);
System.setOut(printStream);
System.setErr(printStream);
try
{
// Create a new ProGuard object with the GUI's configuration.
ReTrace reTrace = new ReTrace(ReTrace.STACK_TRACE_EXPRESSION,
verbose,
mappingFile);
// Run it.
reTrace.execute();
}
catch (Exception ex)
{
// Print out the exception message.
System.out.println(ex.getMessage());
// Show a dialog as well.
MessageDialogRunnable.showMessageDialog(consoleTextArea,
ex.getMessage(),
msg("errorReTracing"),
JOptionPane.ERROR_MESSAGE);
}
catch (OutOfMemoryError er)
{
// Forget about the ProGuard object as quickly as possible.
System.gc();
// Print out a message suggesting what to do next.
System.out.println(msg("outOfMemory"));
// Show a dialog as well.
MessageDialogRunnable.showMessageDialog(consoleTextArea,
msg("outOfMemory"),
msg("errorReTracing"),
JOptionPane.ERROR_MESSAGE);
}
// Make sure all output has been sent to the console text area.
printStream.flush();
// Restore the old System's in, out, and err streams.
System.setIn(oldIn);
System.setOut(oldOut);
System.setErr(oldErr);
consoleTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
consoleTextArea.setCaretPosition(0);
// Reset the global static redirection lock.
ProGuardGUI.systemOutRedirected = false;
}
// Small utility methods.
/**
* Returns the message from the GUI resources that corresponds to the given
* key.
*/
private String msg(String messageKey)
{
return GUIResources.getMessage(messageKey);
}
}
proguard4.8/src/proguard/gui/ClassSpecificationsPanel.java 0000644 0001750 0001750 00000016033 11736333524 022545 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui;
import proguard.ClassSpecification;
import proguard.classfile.util.ClassUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
/**
* This ListPanel
allows the user to add, edit, move, and remove
* ClassSpecification entries in a list.
*
* @author Eric Lafortune
*/
class ClassSpecificationsPanel extends ListPanel
{
protected final ClassSpecificationDialog classSpecificationDialog;
public ClassSpecificationsPanel(JFrame owner, boolean fullKeepOptions)
{
super();
list.setCellRenderer(new MyListCellRenderer());
classSpecificationDialog = new ClassSpecificationDialog(owner, fullKeepOptions);
addAddButton();
addEditButton();
addRemoveButton();
addUpButton();
addDownButton();
enableSelectionButtons();
}
protected void addAddButton()
{
JButton addButton = new JButton(msg("add"));
addButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
setClassSpecification(createClassSpecification());
int returnValue = classSpecificationDialog.showDialog();
if (returnValue == ClassSpecificationDialog.APPROVE_OPTION)
{
// Add the new element.
addElement(getClassSpecification());
}
}
});
addButton(tip(addButton, "addTip"));
}
protected void addEditButton()
{
JButton editButton = new JButton(msg("edit"));
editButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
ClassSpecification selectedClassSpecification =
(ClassSpecification)list.getSelectedValue();
setClassSpecification(selectedClassSpecification);
int returnValue = classSpecificationDialog.showDialog();
if (returnValue == ClassSpecificationDialog.APPROVE_OPTION)
{
// Replace the old element.
setElementAt(getClassSpecification(),
list.getSelectedIndex());
}
}
});
addButton(tip(editButton, "editTip"));
}
protected ClassSpecification createClassSpecification()
{
return new ClassSpecification();
}
protected void setClassSpecification(ClassSpecification classSpecification)
{
classSpecificationDialog.setClassSpecification(classSpecification);
}
protected ClassSpecification getClassSpecification()
{
return classSpecificationDialog.getClassSpecification();
}
/**
* Sets the ClassSpecification objects to be represented in this panel.
*/
public void setClassSpecifications(List classSpecifications)
{
listModel.clear();
if (classSpecifications != null)
{
for (int index = 0; index < classSpecifications.size(); index++)
{
listModel.addElement(classSpecifications.get(index));
}
}
// Make sure the selection buttons are properly enabled,
// since the clear method doesn't seem to notify the listener.
enableSelectionButtons();
}
/**
* Returns the ClassSpecification objects currently represented in this panel.
*/
public List getClassSpecifications()
{
int size = listModel.size();
if (size == 0)
{
return null;
}
List classSpecifications = new ArrayList(size);
for (int index = 0; index < size; index++)
{
classSpecifications.add(listModel.get(index));
}
return classSpecifications;
}
/**
* Attaches the tool tip from the GUI resources that corresponds to the
* given key, to the given component.
*/
private static JComponent tip(JComponent component, String messageKey)
{
component.setToolTipText(msg(messageKey));
return component;
}
/**
* Returns the message from the GUI resources that corresponds to the given
* key.
*/
private static String msg(String messageKey)
{
return GUIResources.getMessage(messageKey);
}
/**
* This ListCellRenderer renders ClassSpecification objects.
*/
private static class MyListCellRenderer implements ListCellRenderer
{
private final JLabel label = new JLabel();
// Implementations for ListCellRenderer.
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
ClassSpecification classSpecification = (ClassSpecification)value;
String comments = classSpecification.comments;
label.setText(comments != null ? comments.trim() :
classSpecification.className != null ? (msg("class") + ' ' + ClassUtil.externalClassName(classSpecification.className)) :
classSpecification.extendsClassName != null ? (msg("extensionsOf") + ' ' + ClassUtil.externalClassName(classSpecification.extendsClassName)) :
(msg("specificationNumber") + index));
if (isSelected)
{
label.setBackground(list.getSelectionBackground());
label.setForeground(list.getSelectionForeground());
}
else
{
label.setBackground(list.getBackground());
label.setForeground(list.getForeground());
}
label.setOpaque(true);
return label;
}
}
}
proguard4.8/src/proguard/gui/MemberSpecificationsPanel.java 0000644 0001750 0001750 00000024321 11736333524 022706 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui;
import proguard.*;
import proguard.classfile.ClassConstants;
import proguard.classfile.util.ClassUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
/**
* This ListPanel
allows the user to add, edit, move, and remove
* MemberSpecification entries in a list.
*
* @author Eric Lafortune
*/
final class MemberSpecificationsPanel extends ListPanel
{
private final MemberSpecificationDialog fieldSpecificationDialog;
private final MemberSpecificationDialog methodSpecificationDialog;
public MemberSpecificationsPanel(JDialog owner, boolean fullKeepOptions)
{
super();
super.firstSelectionButton = fullKeepOptions ? 3 : 2;
list.setCellRenderer(new MyListCellRenderer());
fieldSpecificationDialog = new MemberSpecificationDialog(owner, true);
methodSpecificationDialog = new MemberSpecificationDialog(owner, false);
if (fullKeepOptions)
{
addAddFieldButton();
}
addAddMethodButton();
addEditButton();
addRemoveButton();
addUpButton();
addDownButton();
enableSelectionButtons();
}
protected void addAddFieldButton()
{
JButton addFieldButton = new JButton(msg("addField"));
addFieldButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
fieldSpecificationDialog.setMemberSpecification(new MemberSpecification());
int returnValue = fieldSpecificationDialog.showDialog();
if (returnValue == MemberSpecificationDialog.APPROVE_OPTION)
{
// Add the new element.
addElement(new MyMemberSpecificationWrapper(fieldSpecificationDialog.getMemberSpecification(),
true));
}
}
});
addButton(tip(addFieldButton, "addFieldTip"));
}
protected void addAddMethodButton()
{
JButton addMethodButton = new JButton(msg("addMethod"));
addMethodButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
methodSpecificationDialog.setMemberSpecification(new MemberSpecification());
int returnValue = methodSpecificationDialog.showDialog();
if (returnValue == MemberSpecificationDialog.APPROVE_OPTION)
{
// Add the new element.
addElement(new MyMemberSpecificationWrapper(methodSpecificationDialog.getMemberSpecification(),
false));
}
}
});
addButton(tip(addMethodButton, "addMethodTip"));
}
protected void addEditButton()
{
JButton editButton = new JButton(msg("edit"));
editButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
MyMemberSpecificationWrapper wrapper =
(MyMemberSpecificationWrapper)list.getSelectedValue();
MemberSpecificationDialog memberSpecificationDialog =
wrapper.isField ?
fieldSpecificationDialog :
methodSpecificationDialog;
memberSpecificationDialog.setMemberSpecification(wrapper.memberSpecification);
int returnValue = memberSpecificationDialog.showDialog();
if (returnValue == MemberSpecificationDialog.APPROVE_OPTION)
{
// Replace the old element.
wrapper.memberSpecification = memberSpecificationDialog.getMemberSpecification();
setElementAt(wrapper,
list.getSelectedIndex());
}
}
});
addButton(tip(editButton, "editTip"));
}
/**
* Sets the MemberSpecification instances to be represented in this panel.
*/
public void setMemberSpecifications(List fieldSpecifications,
List methodSpecifications)
{
listModel.clear();
if (fieldSpecifications != null)
{
for (int index = 0; index < fieldSpecifications.size(); index++)
{
listModel.addElement(
new MyMemberSpecificationWrapper((MemberSpecification)fieldSpecifications.get(index),
true));
}
}
if (methodSpecifications != null)
{
for (int index = 0; index < methodSpecifications.size(); index++)
{
listModel.addElement(
new MyMemberSpecificationWrapper((MemberSpecification)methodSpecifications.get(index),
false));
}
}
// Make sure the selection buttons are properly enabled,
// since the clear method doesn't seem to notify the listener.
enableSelectionButtons();
}
/**
* Returns the MemberSpecification instances currently represented in
* this panel, referring to fields or to methods.
*
* @param isField specifies whether specifications referring to fields or
* specifications referring to methods should be returned.
*/
public List getMemberSpecifications(boolean isField)
{
int size = listModel.size();
if (size == 0)
{
return null;
}
List memberSpecifications = new ArrayList(size);
for (int index = 0; index < size; index++)
{
MyMemberSpecificationWrapper wrapper =
(MyMemberSpecificationWrapper)listModel.get(index);
if (wrapper.isField == isField)
{
memberSpecifications.add(wrapper.memberSpecification);
}
}
return memberSpecifications;
}
/**
* This ListCellRenderer renders MemberSpecification objects.
*/
private static class MyListCellRenderer implements ListCellRenderer
{
private final JLabel label = new JLabel();
// Implementations for ListCellRenderer.
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
MyMemberSpecificationWrapper wrapper = (MyMemberSpecificationWrapper)value;
MemberSpecification option = wrapper.memberSpecification;
String name = option.name;
String descriptor = option.descriptor;
label.setText(wrapper.isField ?
(descriptor == null ? name == null ?
"Jpanel
allows the user to move and remove entries in a
* list and between lists. Extensions of this class should add buttons to add
* and possibly edit entries, and to set and get the resulting list.
*
* @author Eric Lafortune
*/
abstract class ListPanel extends JPanel
{
protected final DefaultListModel listModel = new DefaultListModel();
protected final JList list = new JList(listModel);
protected int firstSelectionButton = 2;
protected ListPanel()
{
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
GridBagConstraints listConstraints = new GridBagConstraints();
listConstraints.gridheight = GridBagConstraints.REMAINDER;
listConstraints.fill = GridBagConstraints.BOTH;
listConstraints.weightx = 1.0;
listConstraints.weighty = 1.0;
listConstraints.anchor = GridBagConstraints.NORTHWEST;
listConstraints.insets = new Insets(0, 2, 0, 2);
// Make sure some buttons are disabled or enabled depending on whether
// the selection is empty or not.
list.addListSelectionListener(new ListSelectionListener()
{
public void valueChanged(ListSelectionEvent e)
{
enableSelectionButtons();
}
});
add(new JScrollPane(list), listConstraints);
// something like the following calls are up to the extending class:
//addAddButton();
//addEditButton();
//addRemoveButton();
//addUpButton();
//addDownButton();
//
//enableSelectionButtons();
}
protected void addRemoveButton()
{
JButton removeButton = new JButton(msg("remove"));
removeButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// Remove the selected elements.
removeElementsAt(list.getSelectedIndices());
}
});
addButton(tip(removeButton, "removeTip"));
}
protected void addUpButton()
{
JButton upButton = new JButton(msg("moveUp"));
upButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
int[] selectedIndices = list.getSelectedIndices();
if (selectedIndices.length > 0 &&
selectedIndices[0] > 0)
{
// Move the selected elements up.
moveElementsAt(selectedIndices, -1);
}
}
});
addButton(tip(upButton, "moveUpTip"));
}
protected void addDownButton()
{
JButton downButton = new JButton(msg("moveDown"));
downButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
int[] selectedIndices = list.getSelectedIndices();
if (selectedIndices.length > 0 &&
selectedIndices[selectedIndices.length-1] < listModel.getSize()-1)
{
// Move the selected elements down.
moveElementsAt(selectedIndices, 1);
}
}
});
addButton(tip(downButton, "moveDownTip"));
}
/**
* Adds a button that allows to copy or move entries to another ListPanel.
*
* @param buttonTextKey the button text key.
* @param tipKey the tool tip key.
* @param panel the other ListPanel.
*/
public void addCopyToPanelButton(String buttonTextKey,
String tipKey,
final ListPanel panel)
{
JButton moveButton = new JButton(msg(buttonTextKey));
moveButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
int[] selectedIndices = list.getSelectedIndices();
Object[] selectedElements = list.getSelectedValues();
// Remove the selected elements from this panel.
removeElementsAt(selectedIndices);
// Add the elements to the other panel.
panel.addElements(selectedElements);
}
});
addButton(tip(moveButton, tipKey));
}
protected void addButton(JComponent button)
{
GridBagConstraints buttonConstraints = new GridBagConstraints();
buttonConstraints.gridwidth = GridBagConstraints.REMAINDER;
buttonConstraints.fill = GridBagConstraints.HORIZONTAL;
buttonConstraints.anchor = GridBagConstraints.NORTHWEST;
buttonConstraints.insets = new Insets(0, 2, 0, 2);
add(button, buttonConstraints);
}
/**
* Returns a list of all right-hand side buttons.
*/
public List getButtons()
{
List list = new ArrayList(getComponentCount()-1);
// Add all buttons.
for (int index = 1; index < getComponentCount(); index++)
{
list.add(getComponent(index));
}
return list;
}
protected void addElement(Object element)
{
listModel.addElement(element);
// Make sure it is selected.
list.setSelectedIndex(listModel.size() - 1);
}
protected void addElements(Object[] elements)
{
// Add the elements one by one.
for (int index = 0; index < elements.length; index++)
{
listModel.addElement(elements[index]);
}
// Make sure they are selected.
int[] selectedIndices = new int[elements.length];
for (int index = 0; index < selectedIndices.length; index++)
{
selectedIndices[index] =
listModel.size() - selectedIndices.length + index;
}
list.setSelectedIndices(selectedIndices);
}
protected void moveElementsAt(int[] indices, int offset)
{
// Remember the selected elements.
Object[] selectedElements = list.getSelectedValues();
// Remove the selected elements.
removeElementsAt(indices);
// Update the element indices.
for (int index = 0; index < indices.length; index++)
{
indices[index] += offset;
}
// Reinsert the selected elements.
insertElementsAt(selectedElements, indices);
}
protected void insertElementsAt(Object[] elements, int[] indices)
{
for (int index = 0; index < elements.length; index++)
{
listModel.insertElementAt(elements[index], indices[index]);
}
// Make sure they are selected.
list.setSelectedIndices(indices);
}
protected void setElementAt(Object element, int index)
{
listModel.setElementAt(element, index);
// Make sure it is selected.
list.setSelectedIndex(index);
}
protected void setElementsAt(Object[] elements, int[] indices)
{
for (int index = 0; index < elements.length; index++)
{
listModel.setElementAt(elements[index], indices[index]);
}
// Make sure they are selected.
list.setSelectedIndices(indices);
}
protected void removeElementsAt(int[] indices)
{
for (int index = indices.length - 1; index >= 0; index--)
{
listModel.removeElementAt(indices[index]);
}
// Make sure nothing is selected.
list.clearSelection();
// Make sure the selection buttons are properly enabled,
// since the above method doesn't seem to notify the listener.
enableSelectionButtons();
}
protected void removeAllElements()
{
listModel.removeAllElements();
// Make sure the selection buttons are properly enabled,
// since the above method doesn't seem to notify the listener.
enableSelectionButtons();
}
/**
* Enables or disables the buttons that depend on a selection.
*/
protected void enableSelectionButtons()
{
boolean selected = !list.isSelectionEmpty();
// Loop over all components, except the list itself and the Add button.
for (int index = firstSelectionButton; index < getComponentCount(); index++)
{
getComponent(index).setEnabled(selected);
}
}
/**
* Attaches the tool tip from the GUI resources that corresponds to the
* given key, to the given component.
*/
private static JComponent tip(JComponent component, String messageKey)
{
component.setToolTipText(msg(messageKey));
return component;
}
/**
* Returns the message from the GUI resources that corresponds to the given
* key.
*/
private static String msg(String messageKey)
{
return GUIResources.getMessage(messageKey);
}
}
proguard4.8/src/proguard/gui/TabbedPane.java 0000644 0001750 0001750 00000015040 11736333524 017616 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
* This Jpanel
is similar to a JTabbedPane
.
* It uses buttons on the left-hand side to switch between panels.
* An image can be added below these buttons.
* Some methods are provided to switch between tabs.
*
* @author Eric Lafortune
*/
public class TabbedPane
extends JPanel
{
private final CardLayout cardLayout = new CardLayout();
private final JPanel cardPanel = new JPanel(cardLayout);
private final ButtonGroup buttonGroup = new ButtonGroup();
/**
* Creates a new TabbedPane.
*/
public TabbedPane()
{
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
GridBagConstraints cardConstraints = new GridBagConstraints();
cardConstraints.gridx = 1;
cardConstraints.gridy = 0;
cardConstraints.gridheight = GridBagConstraints.REMAINDER;
cardConstraints.fill = GridBagConstraints.BOTH;
cardConstraints.weightx = 1.0;
cardConstraints.weighty = 1.0;
cardConstraints.anchor = GridBagConstraints.NORTHWEST;
add(cardPanel, cardConstraints);
}
/**
* Adds a component with a given title to the tabbed pane.
*
* @param title the title that will be used in the tab button.
* @param component the component that will be added as a tab.
*/
public Component add(final String title, Component component)
{
GridBagConstraints buttonConstraints = new GridBagConstraints();
buttonConstraints.gridx = 0;
buttonConstraints.fill = GridBagConstraints.HORIZONTAL;
buttonConstraints.anchor = GridBagConstraints.NORTHWEST;
buttonConstraints.ipadx = 10;
buttonConstraints.ipady = 4;
JToggleButton button = new JToggleButton(title);
// Let the button react on the mouse press, instead of waiting for the
// mouse release.
button.setModel(new JToggleButton.ToggleButtonModel()
{
public void setPressed(boolean b)
{
if ((isPressed() == b) || !isEnabled())
{
return;
}
if (!b && isArmed())
{
setSelected(!this.isSelected());
}
if (b)
{
stateMask |= PRESSED;
}
else
{
stateMask &= ~PRESSED;
}
fireStateChanged();
if (isPressed())
{
fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, getActionCommand()));
}
}
});
// Switch to the tab on a button press.
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
cardLayout.show(cardPanel, title);
}
});
// Only one button can be selected at the same time.
buttonGroup.add(button);
// If this is the first tab, make sure its button is selected.
if (cardPanel.getComponentCount() == 0)
{
button.setSelected(true);
}
// Add the button and its panel.
add(button, buttonConstraints);
cardPanel.add(title, component);
return component;
}
/**
* Adds an image below the tab buttons, after all tabs have been added.
* The image will only be as visible as permitted by the available space.
*
* @param image the image.
* @return the component containing the image.
*/
public Component addImage(final Image image)
{
GridBagConstraints imageConstraints = new GridBagConstraints();
imageConstraints.gridx = 0;
imageConstraints.weighty = 1.0;
imageConstraints.fill = GridBagConstraints.BOTH;
imageConstraints.anchor = GridBagConstraints.SOUTHWEST;
JButton component = new JButton(new ImageIcon(image));
component.setFocusPainted(false);
component.setFocusable(false);
component.setRequestFocusEnabled(false);
component.setRolloverEnabled(false);
component.setMargin(new Insets(0, 0, 0, 0));
component.setHorizontalAlignment(JButton.LEFT);
component.setVerticalAlignment(JButton.BOTTOM);
component.setPreferredSize(new Dimension(0, 0));
add(component, imageConstraints);
return component;
}
/**
* Selects the first tab.
*/
public void first()
{
cardLayout.first(cardPanel);
updateButtonSelection();
}
/**
* Selects the last tab.
*/
public void last()
{
cardLayout.last(cardPanel);
updateButtonSelection();
}
/**
* Selects the previous tab.
*/
public void previous()
{
cardLayout.previous(cardPanel);
updateButtonSelection();
}
/**
* Selects the next tab.
*/
public void next()
{
cardLayout.next(cardPanel);
updateButtonSelection();
}
/**
* Lets the button selection reflect the currently visible panel.
*/
private void updateButtonSelection()
{
int count = cardPanel.getComponentCount();
for (int index = 0 ; index < count ; index++) {
Component card = cardPanel.getComponent(index);
if (card.isShowing())
{
JToggleButton button = (JToggleButton)getComponent(index+1);
button.setSelected(true);
}
}
}
}
proguard4.8/src/proguard/gui/boilerplate.pro 0000644 0001750 0001750 00000041152 11163773611 020014 0 ustar eric eric # Keep - Applications. Keep all application classes, along with their 'main'
# methods.
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
# Keep - Applets. Keep all extensions of java.applet.Applet.
-keep public class * extends java.applet.Applet
# Keep - Servlets. Keep all extensions of javax.servlet.Servlet.
-keep public class * extends javax.servlet.Servlet
# Keep - Midlets. Keep all extensions of javax.microedition.midlet.MIDlet.
-keep public class * extends javax.microedition.midlet.MIDlet
# Keep - Xlets. Keep all extensions of javax.tv.xlet.Xlet.
-keep public class * extends javax.tv.xlet.Xlet
# Keep - Library. Keep all public and protected classes, fields, and methods.
-keep public class * {
public protected SwingUtilities
class.
*
* @see SwingUtilities
* @author Eric Lafortune
*/
public class SwingUtil
{
/**
* Invokes the given Runnable in the AWT event dispatching thread,
* and waits for it to finish. This method may be called from any thread,
* including the event dispatching thread itself.
* @see SwingUtilities#invokeAndWait(Runnable)
* @param runnable the Runnable to be executed.
*/
public static void invokeAndWait(Runnable runnable)
throws InterruptedException, InvocationTargetException
{
try
{
if (SwingUtilities.isEventDispatchThread())
{
runnable.run();
}
else
{
SwingUtilities.invokeAndWait(runnable);
}
}
catch (Exception ex)
{
// Ignore any exceptions.
}
}
/**
* Invokes the given Runnable in the AWT event dispatching thread, not
* necessarily right away. This method may be called from any thread,
* including the event dispatching thread itself.
* @see SwingUtilities#invokeLater(Runnable)
* @param runnable the Runnable to be executed.
*/
public static void invokeLater(Runnable runnable)
{
if (SwingUtilities.isEventDispatchThread())
{
runnable.run();
}
else
{
SwingUtilities.invokeLater(runnable);
}
}
}
proguard4.8/src/proguard/gui/default.pro 0000644 0001750 0001750 00000033021 11163773611 017132 0 ustar eric eric # The default configuration when starting up the GUI.
-libraryjars JDialog
allows the user to enter a String.
*
* @author Eric Lafortune
*/
final class ClassSpecificationDialog extends JDialog
{
/**
* Return value if the dialog is canceled (with the Cancel button or by
* closing the dialog window).
*/
public static final int CANCEL_OPTION = 1;
/**
* Return value if the dialog is approved (with the Ok button).
*/
public static final int APPROVE_OPTION = 0;
private final JTextArea commentsTextArea = new JTextArea(4, 20);
private final JRadioButton keepClassesAndMembersRadioButton = new JRadioButton(msg("keep"));
private final JRadioButton keepClassMembersRadioButton = new JRadioButton(msg("keepClassMembers"));
private final JRadioButton keepClassesWithMembersRadioButton = new JRadioButton(msg("keepClassesWithMembers"));
private final JCheckBox allowShrinkingCheckBox = new JCheckBox(msg("allowShrinking"));
private final JCheckBox allowOptimizationCheckBox = new JCheckBox(msg("allowOptimization"));
private final JCheckBox allowObfuscationCheckBox = new JCheckBox(msg("allowObfuscation"));
private final JRadioButton[] publicRadioButtons;
private final JRadioButton[] finalRadioButtons;
private final JRadioButton[] abstractRadioButtons;
private final JRadioButton[] interfaceRadioButtons;
private final JRadioButton[] annotationRadioButtons;
private final JRadioButton[] enumRadioButtons;
private final JRadioButton[] syntheticRadioButtons;
private final JTextField annotationTypeTextField = new JTextField(20);
private final JTextField classNameTextField = new JTextField(20);
private final JTextField extendsAnnotationTypeTextField = new JTextField(20);
private final JTextField extendsClassNameTextField = new JTextField(20);
private final MemberSpecificationsPanel memberSpecificationsPanel;
private int returnValue;
public ClassSpecificationDialog(JFrame owner, boolean fullKeepOptions)
{
super(owner, msg("specifyClasses"), true);
setResizable(true);
// Create some constraints that can be reused.
GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.WEST;
constraints.insets = new Insets(1, 2, 1, 2);
GridBagConstraints constraintsStretch = new GridBagConstraints();
constraintsStretch.fill = GridBagConstraints.HORIZONTAL;
constraintsStretch.weightx = 1.0;
constraintsStretch.anchor = GridBagConstraints.WEST;
constraintsStretch.insets = constraints.insets;
GridBagConstraints constraintsLast = new GridBagConstraints();
constraintsLast.gridwidth = GridBagConstraints.REMAINDER;
constraintsLast.anchor = GridBagConstraints.WEST;
constraintsLast.insets = constraints.insets;
GridBagConstraints constraintsLastStretch = new GridBagConstraints();
constraintsLastStretch.gridwidth = GridBagConstraints.REMAINDER;
constraintsLastStretch.fill = GridBagConstraints.HORIZONTAL;
constraintsLastStretch.weightx = 1.0;
constraintsLastStretch.anchor = GridBagConstraints.WEST;
constraintsLastStretch.insets = constraints.insets;
GridBagConstraints panelConstraints = new GridBagConstraints();
panelConstraints.gridwidth = GridBagConstraints.REMAINDER;
panelConstraints.fill = GridBagConstraints.HORIZONTAL;
panelConstraints.weightx = 1.0;
panelConstraints.weighty = 0.0;
panelConstraints.anchor = GridBagConstraints.NORTHWEST;
panelConstraints.insets = constraints.insets;
GridBagConstraints stretchPanelConstraints = new GridBagConstraints();
stretchPanelConstraints.gridwidth = GridBagConstraints.REMAINDER;
stretchPanelConstraints.fill = GridBagConstraints.BOTH;
stretchPanelConstraints.weightx = 1.0;
stretchPanelConstraints.weighty = 1.0;
stretchPanelConstraints.anchor = GridBagConstraints.NORTHWEST;
stretchPanelConstraints.insets = constraints.insets;
GridBagConstraints labelConstraints = new GridBagConstraints();
labelConstraints.anchor = GridBagConstraints.CENTER;
labelConstraints.insets = new Insets(2, 10, 2, 10);
GridBagConstraints lastLabelConstraints = new GridBagConstraints();
lastLabelConstraints.gridwidth = GridBagConstraints.REMAINDER;
lastLabelConstraints.anchor = GridBagConstraints.CENTER;
lastLabelConstraints.insets = labelConstraints.insets;
GridBagConstraints advancedButtonConstraints = new GridBagConstraints();
advancedButtonConstraints.weightx = 1.0;
advancedButtonConstraints.weighty = 1.0;
advancedButtonConstraints.anchor = GridBagConstraints.SOUTHWEST;
advancedButtonConstraints.insets = new Insets(4, 4, 8, 4);
GridBagConstraints okButtonConstraints = new GridBagConstraints();
okButtonConstraints.weightx = 1.0;
okButtonConstraints.weighty = 1.0;
okButtonConstraints.anchor = GridBagConstraints.SOUTHEAST;
okButtonConstraints.insets = advancedButtonConstraints.insets;
GridBagConstraints cancelButtonConstraints = new GridBagConstraints();
cancelButtonConstraints.gridwidth = GridBagConstraints.REMAINDER;
cancelButtonConstraints.weighty = 1.0;
cancelButtonConstraints.anchor = GridBagConstraints.SOUTHEAST;
cancelButtonConstraints.insets = advancedButtonConstraints.insets;
GridBagLayout layout = new GridBagLayout();
Border etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
// Create the comments panel.
JPanel commentsPanel = new JPanel(layout);
commentsPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("comments")));
JScrollPane commentsScrollPane = new JScrollPane(commentsTextArea);
commentsScrollPane.setBorder(classNameTextField.getBorder());
commentsPanel.add(tip(commentsScrollPane, "commentsTip"), constraintsLastStretch);
// Create the keep option panel.
ButtonGroup keepButtonGroup = new ButtonGroup();
keepButtonGroup.add(keepClassesAndMembersRadioButton);
keepButtonGroup.add(keepClassMembersRadioButton);
keepButtonGroup.add(keepClassesWithMembersRadioButton);
JPanel keepOptionPanel = new JPanel(layout);
keepOptionPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("keepTitle")));
keepOptionPanel.add(tip(keepClassesAndMembersRadioButton, "keepTip"), constraintsLastStretch);
keepOptionPanel.add(tip(keepClassMembersRadioButton, "keepClassMembersTip"), constraintsLastStretch);
keepOptionPanel.add(tip(keepClassesWithMembersRadioButton, "keepClassesWithMembersTip"), constraintsLastStretch);
// Create the allow option panel.
final JPanel allowOptionPanel = new JPanel(layout);
allowOptionPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("allowTitle")));
allowOptionPanel.add(tip(allowShrinkingCheckBox, "allowShrinkingTip"), constraintsLastStretch);
allowOptionPanel.add(tip(allowOptimizationCheckBox, "allowOptimizationTip"), constraintsLastStretch);
allowOptionPanel.add(tip(allowObfuscationCheckBox, "allowObfuscationTip"), constraintsLastStretch);
// Create the access panel.
JPanel accessPanel = new JPanel(layout);
accessPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("access")));
accessPanel.add(Box.createGlue(), labelConstraints);
accessPanel.add(tip(new JLabel(msg("required")), "requiredTip"), labelConstraints);
accessPanel.add(tip(new JLabel(msg("not")), "notTip"), labelConstraints);
accessPanel.add(tip(new JLabel(msg("dontCare")), "dontCareTip"), labelConstraints);
accessPanel.add(Box.createGlue(), constraintsLastStretch);
publicRadioButtons = addRadioButtonTriplet("Public", accessPanel);
finalRadioButtons = addRadioButtonTriplet("Final", accessPanel);
abstractRadioButtons = addRadioButtonTriplet("Abstract", accessPanel);
interfaceRadioButtons = addRadioButtonTriplet("Interface", accessPanel);
annotationRadioButtons = addRadioButtonTriplet("Annotation", accessPanel);
enumRadioButtons = addRadioButtonTriplet("Enum", accessPanel);
syntheticRadioButtons = addRadioButtonTriplet("Synthetic", accessPanel);
// Create the annotation type panel.
final JPanel annotationTypePanel = new JPanel(layout);
annotationTypePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("annotation")));
annotationTypePanel.add(tip(annotationTypeTextField, "classNameTip"), constraintsLastStretch);
// Create the class name panel.
JPanel classNamePanel = new JPanel(layout);
classNamePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("class")));
classNamePanel.add(tip(classNameTextField, "classNameTip"), constraintsLastStretch);
// Create the extends annotation type panel.
final JPanel extendsAnnotationTypePanel = new JPanel(layout);
extendsAnnotationTypePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("extendsImplementsAnnotation")));
extendsAnnotationTypePanel.add(tip(extendsAnnotationTypeTextField, "classNameTip"), constraintsLastStretch);
// Create the extends class name panel.
JPanel extendsClassNamePanel = new JPanel(layout);
extendsClassNamePanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("extendsImplementsClass")));
extendsClassNamePanel.add(tip(extendsClassNameTextField, "classNameTip"), constraintsLastStretch);
// Create the class member list panel.
memberSpecificationsPanel = new MemberSpecificationsPanel(this, fullKeepOptions);
memberSpecificationsPanel.setBorder(BorderFactory.createTitledBorder(etchedBorder,
msg("classMembers")));
// Create the Advanced button.
final JButton advancedButton = new JButton(msg("basic"));
advancedButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
boolean visible = !allowOptionPanel.isVisible();
allowOptionPanel .setVisible(visible);
annotationTypePanel .setVisible(visible);
extendsAnnotationTypePanel.setVisible(visible);
advancedButton.setText(msg(visible ? "basic" : "advanced"));
pack();
}
});
advancedButton.doClick();
// Create the Ok button.
JButton okButton = new JButton(msg("ok"));
okButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
returnValue = APPROVE_OPTION;
hide();
}
});
// Create the Cancel button.
JButton cancelButton = new JButton(msg("cancel"));
cancelButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
hide();
}
});
// Add all panels to the main panel.
JPanel mainPanel = new JPanel(layout);
mainPanel.add(tip(commentsPanel, "commentsTip"), panelConstraints);
if (fullKeepOptions)
{
mainPanel.add(tip(keepOptionPanel, "keepTitleTip"), panelConstraints);
mainPanel.add(tip(allowOptionPanel, "allowTitleTip"), panelConstraints);
}
mainPanel.add(tip(accessPanel, "accessTip"), panelConstraints);
mainPanel.add(tip(annotationTypePanel, "annotationTip"), panelConstraints);
mainPanel.add(tip(classNamePanel, "classTip"), panelConstraints);
mainPanel.add(tip(extendsAnnotationTypePanel, "extendsImplementsAnnotationTip"), panelConstraints);
mainPanel.add(tip(extendsClassNamePanel, "extendsImplementsClassTip"), panelConstraints);
mainPanel.add(tip(memberSpecificationsPanel, "classMembersTip"), stretchPanelConstraints);
mainPanel.add(tip(advancedButton, "advancedTip"), advancedButtonConstraints);
mainPanel.add(okButton, okButtonConstraints);
mainPanel.add(cancelButton, cancelButtonConstraints);
getContentPane().add(new JScrollPane(mainPanel));
}
/**
* Adds a JLabel and three JRadioButton instances in a ButtonGroup to the
* given panel with a GridBagLayout, and returns the buttons in an array.
*/
private JRadioButton[] addRadioButtonTriplet(String labelText,
JPanel panel)
{
GridBagConstraints labelConstraints = new GridBagConstraints();
labelConstraints.anchor = GridBagConstraints.WEST;
labelConstraints.insets = new Insets(2, 10, 2, 10);
GridBagConstraints buttonConstraints = new GridBagConstraints();
buttonConstraints.insets = labelConstraints.insets;
GridBagConstraints lastGlueConstraints = new GridBagConstraints();
lastGlueConstraints.gridwidth = GridBagConstraints.REMAINDER;
lastGlueConstraints.weightx = 1.0;
// Create the radio buttons.
JRadioButton radioButton0 = new JRadioButton();
JRadioButton radioButton1 = new JRadioButton();
JRadioButton radioButton2 = new JRadioButton();
// Put them in a button group.
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(radioButton0);
buttonGroup.add(radioButton1);
buttonGroup.add(radioButton2);
// Add the label and the buttons to the panel.
panel.add(new JLabel(labelText), labelConstraints);
panel.add(radioButton0, buttonConstraints);
panel.add(radioButton1, buttonConstraints);
panel.add(radioButton2, buttonConstraints);
panel.add(Box.createGlue(), lastGlueConstraints);
return new JRadioButton[]
{
radioButton0,
radioButton1,
radioButton2
};
}
/**
* Sets the KeepClassSpecification to be represented in this dialog.
*/
public void setKeepSpecification(KeepClassSpecification keepClassSpecification)
{
boolean markClasses = keepClassSpecification.markClasses;
boolean markConditionally = keepClassSpecification.markConditionally;
boolean allowShrinking = keepClassSpecification.allowShrinking;
boolean allowOptimization = keepClassSpecification.allowOptimization;
boolean allowObfuscation = keepClassSpecification.allowObfuscation;
// Figure out the proper keep radio button and set it.
JRadioButton keepOptionRadioButton =
markConditionally ? keepClassesWithMembersRadioButton :
markClasses ? keepClassesAndMembersRadioButton :
keepClassMembersRadioButton;
keepOptionRadioButton.setSelected(true);
// Set the allow radio buttons.
allowShrinkingCheckBox .setSelected(allowShrinking);
allowOptimizationCheckBox.setSelected(allowOptimization);
allowObfuscationCheckBox .setSelected(allowObfuscation);
setClassSpecification(keepClassSpecification);
}
/**
* Sets the ClassSpecification to be represented in this dialog.
*/
public void setClassSpecification(ClassSpecification classSpecification)
{
String comments = classSpecification.comments;
String annotationType = classSpecification.annotationType;
String className = classSpecification.className;
String extendsAnnotationType = classSpecification.extendsAnnotationType;
String extendsClassName = classSpecification.extendsClassName;
List keepFieldOptions = classSpecification.fieldSpecifications;
List keepMethodOptions = classSpecification.methodSpecifications;
// Set the comments text area.
commentsTextArea.setText(comments == null ? "" : comments);
// Set the access radio buttons.
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_PUBLIC, publicRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_INTERFACE, interfaceRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
// Set the class and annotation text fields.
annotationTypeTextField .setText(annotationType == null ? "" : ClassUtil.externalType(annotationType));
classNameTextField .setText(className == null ? "*" : ClassUtil.externalClassName(className));
extendsAnnotationTypeTextField.setText(extendsAnnotationType == null ? "" : ClassUtil.externalType(extendsAnnotationType));
extendsClassNameTextField .setText(extendsClassName == null ? "" : ClassUtil.externalClassName(extendsClassName));
// Set the keep class member option list.
memberSpecificationsPanel.setMemberSpecifications(keepFieldOptions, keepMethodOptions);
}
/**
* Returns the KeepClassSpecification currently represented in this dialog.
*/
public KeepClassSpecification getKeepSpecification()
{
boolean markClasses = !keepClassMembersRadioButton .isSelected();
boolean markConditionally = keepClassesWithMembersRadioButton.isSelected();
boolean allowShrinking = allowShrinkingCheckBox .isSelected();
boolean allowOptimization = allowOptimizationCheckBox .isSelected();
boolean allowObfuscation = allowObfuscationCheckBox .isSelected();
return new KeepClassSpecification(markClasses,
markConditionally,
allowShrinking,
allowOptimization,
allowObfuscation,
getClassSpecification());
}
/**
* Returns the ClassSpecification currently represented in this dialog.
*/
public ClassSpecification getClassSpecification()
{
String comments = commentsTextArea.getText();
String annotationType = annotationTypeTextField.getText();
String className = classNameTextField.getText();
String extendsAnnotationType = extendsAnnotationTypeTextField.getText();
String extendsClassName = extendsClassNameTextField.getText();
ClassSpecification classSpecification =
new ClassSpecification(comments.equals("") ? null : comments,
0,
0,
annotationType.equals("") ? null : ClassUtil.internalType(annotationType),
className.equals("") ||
className.equals("*") ? null : ClassUtil.internalClassName(className),
extendsAnnotationType.equals("") ? null : ClassUtil.internalType(extendsAnnotationType),
extendsClassName.equals("") ? null : ClassUtil.internalClassName(extendsClassName));
// Also get the access radio button settings.
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_PUBLIC, publicRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_INTERFACE, interfaceRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
// Get the keep class member option lists.
classSpecification.fieldSpecifications = memberSpecificationsPanel.getMemberSpecifications(true);
classSpecification.methodSpecifications = memberSpecificationsPanel.getMemberSpecifications(false);
return classSpecification;
}
/**
* Shows this dialog. This method only returns when the dialog is closed.
*
* @return CANCEL_OPTION
or APPROVE_OPTION
,
* depending on the choice of the user.
*/
public int showDialog()
{
returnValue = CANCEL_OPTION;
// Open the dialog in the right place, then wait for it to be closed,
// one way or another.
pack();
setLocationRelativeTo(getOwner());
show();
return returnValue;
}
/**
* Sets the appropriate radio button of a given triplet, based on the access
* flags of the given keep option.
*/
private void setClassSpecificationRadioButtons(ClassSpecification classSpecification,
int flag,
JRadioButton[] radioButtons)
{
int index = (classSpecification.requiredSetAccessFlags & flag) != 0 ? 0 :
(classSpecification.requiredUnsetAccessFlags & flag) != 0 ? 1 :
2;
radioButtons[index].setSelected(true);
}
/**
* Updates the access flag of the given keep option, based on the given radio
* button triplet.
*/
private void getClassSpecificationRadioButtons(ClassSpecification classSpecification,
int flag,
JRadioButton[] radioButtons)
{
if (radioButtons[0].isSelected())
{
classSpecification.requiredSetAccessFlags |= flag;
}
else if (radioButtons[1].isSelected())
{
classSpecification.requiredUnsetAccessFlags |= flag;
}
}
/**
* Attaches the tool tip from the GUI resources that corresponds to the
* given key, to the given component.
*/
private static JComponent tip(JComponent component, String messageKey)
{
component.setToolTipText(msg(messageKey));
return component;
}
/**
* Returns the message from the GUI resources that corresponds to the given
* key.
*/
private static String msg(String messageKey)
{
return GUIResources.getMessage(messageKey);
}
}
proguard4.8/src/proguard/gui/KeepSpecificationsPanel.java 0000644 0001750 0001750 00000005344 11736333525 022370 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui;
import proguard.*;
import javax.swing.*;
/**
* This ListPanel
allows the user to add, edit, move, and remove
* KeepClassSpecification entries in a list.
*
* @author Eric Lafortune
*/
final class KeepSpecificationsPanel extends ClassSpecificationsPanel
{
private final boolean markClasses;
private final boolean markConditionally;
private final boolean allowShrinking;
private final boolean allowOptimization;
private final boolean allowObfuscation;
public KeepSpecificationsPanel(JFrame owner,
boolean markClasses,
boolean markConditionally,
boolean allowShrinking,
boolean allowOptimization,
boolean allowObfuscation)
{
super(owner, true);
this.markClasses = markClasses;
this.markConditionally = markConditionally;
this.allowShrinking = allowShrinking;
this.allowOptimization = allowOptimization;
this.allowObfuscation = allowObfuscation;
}
// Factory methods for ClassSpecificationsPanel.
protected ClassSpecification createClassSpecification()
{
return new KeepClassSpecification(markClasses,
markConditionally,
allowShrinking,
allowOptimization,
allowObfuscation);
}
protected void setClassSpecification(ClassSpecification classSpecification)
{
classSpecificationDialog.setKeepSpecification((KeepClassSpecification)classSpecification);
}
protected ClassSpecification getClassSpecification()
{
return classSpecificationDialog.getKeepSpecification();
}
}
proguard4.8/src/proguard/gui/splash/ 0000775 0001750 0001750 00000000000 11760503005 016250 5 ustar eric eric proguard4.8/src/proguard/gui/splash/package.html 0000644 0001750 0001750 00000000223 11736333525 020537 0 ustar eric eric
This package contains a library for creating splash screens and animations
with text, graphical elements, and some special effects.
proguard4.8/src/proguard/gui/splash/TypeWriterString.java 0000644 0001750 0001750 00000004144 11736333525 022434 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This VariableString produces a String that grows linearly with respect to its
* Timing, as if it is being written on a typewriter. A cursor at the end
* precedes the typed characters.
*
* @author Eric Lafortune
*/
public class TypeWriterString implements VariableString
{
private final String string;
private final Timing timing;
private int cachedLength = -1;
private String cachedString;
/**
* Creates a new TypeWriterString.
* @param string the basic String.
* @param timing the applied timing.
*/
public TypeWriterString(String string, Timing timing)
{
this.string = string;
this.timing = timing;
}
// Implementation for VariableString.
public String getString(long time)
{
double t = timing.getTiming(time);
int stringLength = string.length();
int length = (int)(stringLength * t + 0.5);
if (length != cachedLength)
{
cachedLength = length;
cachedString = string.substring(0, length);
if (t > 0.0 && length < stringLength)
{
cachedString += "_";
}
}
return cachedString;
}
}
proguard4.8/src/proguard/gui/splash/TimeSwitchSprite.java 0000644 0001750 0001750 00000004253 11736333525 022377 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite displays another Sprite in a given time interval.
* The time of the encapsulated Sprite is shifted by the start time.
*
* @author Eric Lafortune
*/
public class TimeSwitchSprite implements Sprite
{
private final long onTime;
private final long offTime;
private final Sprite sprite;
/**
* Creates a new TimeSwitchSprite for displaying a given Sprite starting at
* a given time.
* @param onTime the start time.
* @param sprite the toggled Sprite.
*/
public TimeSwitchSprite(long onTime, Sprite sprite)
{
this(onTime, 0L, sprite);
}
/**
* Creates a new TimeSwitchSprite for displaying a given Sprite in a given
* time interval.
* @param onTime the start time.
* @param offTime the stop time.
* @param sprite the toggled Sprite.
*/
public TimeSwitchSprite(long onTime, long offTime, Sprite sprite)
{
this.onTime = onTime;
this.offTime = offTime;
this.sprite = sprite;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
if (time >= onTime && (offTime <= 0 || time <= offTime))
{
sprite.paint(graphics, time - onTime);
}
}
}
proguard4.8/src/proguard/gui/splash/RectangleSprite.java 0000644 0001750 0001750 00000010107 11736333525 022216 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite represents an animated rounded rectangle. It can optionally be filled.
*
* @author Eric Lafortune
*/
public class RectangleSprite implements Sprite
{
private final boolean filled;
private final VariableColor color;
private final VariableInt x;
private final VariableInt y;
private final VariableInt width;
private final VariableInt height;
private final VariableInt arcWidth;
private final VariableInt arcHeight;
/**
* Creates a new rectangular RectangleSprite.
* @param filled specifies whether the rectangle should be filled.
* @param color the variable color of the rectangle.
* @param x the variable x-ordinate of the upper-left corner of the rectangle.
* @param y the variable y-ordinate of the upper-left corner of the rectangle.
* @param width the variable width of the rectangle.
* @param height the variable height of the rectangle.
*/
public RectangleSprite(boolean filled,
VariableColor color,
VariableInt x,
VariableInt y,
VariableInt width,
VariableInt height)
{
this(filled, color, x, y, width, height, new ConstantInt(0), new ConstantInt(0));
}
/**
* Creates a new RectangleSprite with rounded corners.
* @param filled specifies whether the rectangle should be filled.
* @param color the variable color of the rectangle.
* @param x the variable x-ordinate of the upper-left corner of the rectangle.
* @param y the variable y-ordinate of the upper-left corner of the rectangle.
* @param width the variable width of the rectangle.
* @param height the variable height of the rectangle.
* @param arcWidth the variable width of the corner arcs.
* @param arcHeight the variable height of the corner arcs.
*/
public RectangleSprite(boolean filled,
VariableColor color,
VariableInt x,
VariableInt y,
VariableInt width,
VariableInt height,
VariableInt arcWidth,
VariableInt arcHeight)
{
this.filled = filled;
this.color = color;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.arcWidth = arcWidth;
this.arcHeight = arcHeight;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
graphics.setColor(color.getColor(time));
int xt = x.getInt(time);
int yt = y.getInt(time);
int w = width.getInt(time);
int h = height.getInt(time);
int aw = arcWidth.getInt(time);
int ah = arcHeight.getInt(time);
if (filled)
{
graphics.fillRoundRect(xt, yt, w, h, aw, ah);
}
else
{
graphics.drawRoundRect(xt, yt, w, h, aw, ah);
}
}
}
proguard4.8/src/proguard/gui/splash/OverrideGraphics2D.java 0000644 0001750 0001750 00000034714 11736333525 022563 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
import java.awt.RenderingHints.Key;
import java.awt.font.*;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
import java.util.Map;
/**
* This Graphics2D allows to fix some basic settings (Color, Font, Paint, Stroke,
* XORMode) of a delegate Graphics2D, overriding any subsequent attempts to
* change those settings.
*
* @author Eric Lafortune
* @noinspection deprecation
*/
final class OverrideGraphics2D extends Graphics2D
{
private final Graphics2D graphics;
private Color overrideColor;
private Font overrideFont;
private Paint overridePaint;
private Stroke overrideStroke;
private Color overrideXORMode;
private Color color;
private Font font;
private Paint paint;
private Stroke stroke;
/**
* Creates a new OverrideGraphics2D.
* @param graphics the delegate Graphics2D.
*/
public OverrideGraphics2D(Graphics2D graphics)
{
this.graphics = graphics;
this.color = graphics.getColor();
this.font = graphics.getFont();
this.paint = graphics.getPaint();
this.stroke = graphics.getStroke();
}
/**
* Fixes the Color of the Graphics2D.
*
* @param color the fixed Color, or null
to undo the fixing.
*/
public void setOverrideColor(Color color)
{
this.overrideColor = color;
graphics.setColor(color != null ? color : this.color);
}
/**
* Fixes the Font of the Graphics2D.
*
* @param font the fixed Font, or null
to undo the fixing.
*/
public void setOverrideFont(Font font)
{
this.overrideFont = font;
graphics.setFont(font != null ? font : this.font);
}
/**
* Fixes the Paint of the Graphics2D.
*
* @param paint the fixed Paint, or null
to undo the fixing.
*/
public void setOverridePaint(Paint paint)
{
this.overridePaint = paint;
graphics.setPaint(paint != null ? paint : this.paint);
}
/**
* Fixes the Stroke of the Graphics2D.
*
* @param stroke the fixed Stroke, or null
to undo the fixing.
*/
public void setOverrideStroke(Stroke stroke)
{
this.overrideStroke = stroke;
graphics.setStroke(stroke != null ? stroke : this.stroke);
}
/**
* Fixes the XORMode of the Graphics2D.
*
* @param color the fixed XORMode Color, or null
to undo the fixing.
*/
public void setOverrideXORMode(Color color)
{
this.overrideXORMode = color;
if (color != null)
{
graphics.setXORMode(color);
}
else
{
graphics.setPaintMode();
}
}
// Implementations for Graphics2D.
public void setColor(Color color)
{
this.color = color;
if (overrideColor == null)
{
graphics.setColor(color);
}
}
public void setFont(Font font)
{
this.font = font;
if (overrideFont == null)
{
graphics.setFont(font);
}
}
public void setPaint(Paint paint)
{
this.paint = paint;
if (overridePaint == null)
{
graphics.setPaint(paint);
}
}
public void setStroke(Stroke stroke)
{
this.stroke = stroke;
if (overrideStroke == null)
{
graphics.setStroke(stroke);
}
}
public void setXORMode(Color color)
{
if (overrideXORMode == null)
{
graphics.setXORMode(color);
}
}
public void setPaintMode()
{
if (overrideXORMode == null)
{
graphics.setPaintMode();
}
}
public Color getColor()
{
return overrideColor != null ? color : graphics.getColor();
}
public Font getFont()
{
return overrideFont != null ? font : graphics.getFont();
}
public Paint getPaint()
{
return overridePaint != null ? paint : graphics.getPaint();
}
public Stroke getStroke()
{
return overrideStroke != null ? stroke : graphics.getStroke();
}
public Graphics create()
{
OverrideGraphics2D g = new OverrideGraphics2D((Graphics2D)graphics.create());
g.setOverrideColor(overrideColor);
g.setOverrideFont(overrideFont);
g.setOverridePaint(overridePaint);
g.setOverrideStroke(overrideStroke);
return g;
}
public Graphics create(int x, int y, int width, int height)
{
OverrideGraphics2D g = new OverrideGraphics2D((Graphics2D)graphics.create(x, y, width, height));
g.setOverrideColor(overrideColor);
g.setOverrideFont(overrideFont);
g.setOverridePaint(overridePaint);
g.setOverrideStroke(overrideStroke);
return g;
}
// Delegation for Graphics2D
public void addRenderingHints(Map hints)
{
graphics.addRenderingHints(hints);
}
public void clearRect(int x, int y, int width, int height)
{
graphics.clearRect(x, y, width, height);
}
public void clip(Shape s)
{
graphics.clip(s);
}
public void clipRect(int x, int y, int width, int height)
{
graphics.clipRect(x, y, width, height);
}
public void copyArea(int x, int y, int width, int height, int dx, int dy)
{
graphics.copyArea(x, y, width, height, dx, dy);
}
public void dispose()
{
graphics.dispose();
}
public void draw(Shape s)
{
graphics.draw(s);
}
public void draw3DRect(int x, int y, int width, int height, boolean raised)
{
graphics.draw3DRect(x, y, width, height, raised);
}
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
{
graphics.drawArc(x, y, width, height, startAngle, arcAngle);
}
public void drawBytes(byte[] data, int offset, int length, int x, int y)
{
graphics.drawBytes(data, offset, length, x, y);
}
public void drawChars(char[] data, int offset, int length, int x, int y)
{
graphics.drawChars(data, offset, length, x, y);
}
public void drawGlyphVector(GlyphVector g, float x, float y)
{
graphics.drawGlyphVector(g, x, y);
}
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer)
{
return graphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer);
}
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
{
return graphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
}
public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer)
{
return graphics.drawImage(img, x, y, width, height, bgcolor, observer);
}
public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer)
{
return graphics.drawImage(img, x, y, width, height, observer);
}
public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer)
{
return graphics.drawImage(img, x, y, bgcolor, observer);
}
public boolean drawImage(Image img, int x, int y, ImageObserver observer)
{
return graphics.drawImage(img, x, y, observer);
}
public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
{
return graphics.drawImage(img, xform, obs);
}
public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y)
{
graphics.drawImage(img, op, x, y);
}
public void drawLine(int x1, int y1, int x2, int y2)
{
graphics.drawLine(x1, y1, x2, y2);
}
public void drawOval(int x, int y, int width, int height)
{
graphics.drawOval(x, y, width, height);
}
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
{
graphics.drawPolygon(xPoints, yPoints, nPoints);
}
public void drawPolygon(Polygon p)
{
graphics.drawPolygon(p);
}
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
{
graphics.drawPolyline(xPoints, yPoints, nPoints);
}
public void drawRect(int x, int y, int width, int height)
{
graphics.drawRect(x, y, width, height);
}
public void drawRenderableImage(RenderableImage img, AffineTransform xform)
{
graphics.drawRenderableImage(img, xform);
}
public void drawRenderedImage(RenderedImage img, AffineTransform xform)
{
graphics.drawRenderedImage(img, xform);
}
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
{
graphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
}
public void drawString(String s, float x, float y)
{
graphics.drawString(s, x, y);
}
public void drawString(String str, int x, int y)
{
graphics.drawString(str, x, y);
}
public void drawString(AttributedCharacterIterator iterator, float x, float y)
{
graphics.drawString(iterator, x, y);
}
public void drawString(AttributedCharacterIterator iterator, int x, int y)
{
graphics.drawString(iterator, x, y);
}
public boolean equals(Object obj)
{
return graphics.equals(obj);
}
public void fill(Shape s)
{
graphics.fill(s);
}
public void fill3DRect(int x, int y, int width, int height, boolean raised)
{
graphics.fill3DRect(x, y, width, height, raised);
}
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
{
graphics.fillArc(x, y, width, height, startAngle, arcAngle);
}
public void fillOval(int x, int y, int width, int height)
{
graphics.fillOval(x, y, width, height);
}
public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
{
graphics.fillPolygon(xPoints, yPoints, nPoints);
}
public void fillPolygon(Polygon p)
{
graphics.fillPolygon(p);
}
public void fillRect(int x, int y, int width, int height)
{
graphics.fillRect(x, y, width, height);
}
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
{
graphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
}
public Color getBackground()
{
return graphics.getBackground();
}
public Shape getClip()
{
return graphics.getClip();
}
public Rectangle getClipBounds()
{
return graphics.getClipBounds();
}
public Rectangle getClipBounds(Rectangle r)
{
return graphics.getClipBounds(r);
}
public Rectangle getClipRect()
{
return graphics.getClipRect();
}
public Composite getComposite()
{
return graphics.getComposite();
}
public GraphicsConfiguration getDeviceConfiguration()
{
return graphics.getDeviceConfiguration();
}
public FontMetrics getFontMetrics()
{
return graphics.getFontMetrics();
}
public FontMetrics getFontMetrics(Font f)
{
return graphics.getFontMetrics(f);
}
public FontRenderContext getFontRenderContext()
{
return graphics.getFontRenderContext();
}
public Object getRenderingHint(Key hintKey)
{
return graphics.getRenderingHint(hintKey);
}
public RenderingHints getRenderingHints()
{
return graphics.getRenderingHints();
}
public AffineTransform getTransform()
{
return graphics.getTransform();
}
public int hashCode()
{
return graphics.hashCode();
}
public boolean hit(Rectangle rect, Shape s, boolean onStroke)
{
return graphics.hit(rect, s, onStroke);
}
public boolean hitClip(int x, int y, int width, int height)
{
return graphics.hitClip(x, y, width, height);
}
public void rotate(double theta)
{
graphics.rotate(theta);
}
public void rotate(double theta, double x, double y)
{
graphics.rotate(theta, x, y);
}
public void scale(double sx, double sy)
{
graphics.scale(sx, sy);
}
public void setBackground(Color color)
{
graphics.setBackground(color);
}
public void setClip(int x, int y, int width, int height)
{
graphics.setClip(x, y, width, height);
}
public void setClip(Shape clip)
{
graphics.setClip(clip);
}
public void setComposite(Composite comp)
{
graphics.setComposite(comp);
}
public void setRenderingHint(Key hintKey, Object hintValue)
{
graphics.setRenderingHint(hintKey, hintValue);
}
public void setRenderingHints(Map hints)
{
graphics.setRenderingHints(hints);
}
public void setTransform(AffineTransform Tx)
{
graphics.setTransform(Tx);
}
public void shear(double shx, double shy)
{
graphics.shear(shx, shy);
}
public String toString()
{
return graphics.toString();
}
public void transform(AffineTransform Tx)
{
graphics.transform(Tx);
}
public void translate(double tx, double ty)
{
graphics.translate(tx, ty);
}
public void translate(int x, int y)
{
graphics.translate(x, y);
}
}
proguard4.8/src/proguard/gui/splash/ConstantFont.java 0000644 0001750 0001750 00000002427 11736333525 021551 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This VariableFont is constant over time.
*
* @author Eric Lafortune
*/
public class ConstantFont implements VariableFont
{
private final Font value;
public ConstantFont(Font value)
{
this.value = value;
}
// Implementation for VariableFont.
public Font getFont(long time)
{
return value;
}
}
proguard4.8/src/proguard/gui/splash/SplashPanel.java 0000644 0001750 0001750 00000015616 11736333525 021347 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import proguard.gui.SwingUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;
/**
* This JPanel renders an animated Sprite.
*
* @author Eric Lafortune
*/
public class SplashPanel extends JPanel
{
private final MyAnimator animator = new MyAnimator();
private final MyRepainter repainter = new MyRepainter();
private final Sprite sprite;
private final double sleepFactor;
private long startTime = Long.MAX_VALUE;
private final long stopTime;
private volatile Thread animationThread;
/**
* Creates a new SplashPanel with the given Sprite, which will be animated
* indefinitely.
* @param sprite the Sprite that will be animated.
* @param processorLoad the fraction of processing time to be spend on
* animating the Sprite (between 0 and 1).
*/
public SplashPanel(Sprite sprite, double processorLoad)
{
this(sprite, processorLoad, (long)Integer.MAX_VALUE);
}
/**
* Creates a new SplashPanel with the given Sprite, which will be animated
* for a limited period of time.
* @param sprite the Sprite that will be animated.
* @param processorLoad the fraction of processing time to be spend on
* animating the Sprite (between 0 and 1).
* @param stopTime the number of milliseconds after which the
* animation will be stopped automatically.
*/
public SplashPanel(Sprite sprite, double processorLoad, long stopTime)
{
this.sprite = sprite;
this.sleepFactor = (1.0-processorLoad) / processorLoad;
this.stopTime = stopTime;
// Restart the animation on a mouse click.
addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
SplashPanel.this.start();
}
});
}
/**
* Starts the animation.
*/
public void start()
{
// Go to the beginning of the animation.
startTime = System.currentTimeMillis();
// Make sure we have an animation thread running.
if (animationThread == null)
{
animationThread = new Thread(animator);
animationThread.start();
}
}
/**
* Stops the animation.
*/
public void stop()
{
// Go to the end of the animation.
startTime = 0L;
// Let the animation thread stop itself.
animationThread = null;
// Repaint the SplashPanel one last time.
try
{
SwingUtil.invokeAndWait(repainter);
}
catch (InterruptedException ex)
{
// Nothing.
}
catch (InvocationTargetException ex)
{
// Nothing.
}
}
// Implementation for JPanel.
public void paintComponent(Graphics graphics)
{
super.paintComponent(graphics);
sprite.paint(graphics, System.currentTimeMillis() - startTime);
}
/**
* This Runnable makes sure its SplashPanel gets repainted regularly,
* depending on the targeted processor load.
*/
private class MyAnimator implements Runnable
{
public void run()
{
try
{
while (animationThread != null)
{
// Check if we should stop the animation.
long time = System.currentTimeMillis();
if (time > startTime + stopTime)
{
animationThread = null;
}
// Do a repaint and time it.
SwingUtil.invokeAndWait(repainter);
// Sleep for a proportional while.
long repaintTime = System.currentTimeMillis() - time;
long sleepTime = (long)(sleepFactor * repaintTime);
if (sleepTime < 10L)
{
sleepTime = 10L;
}
Thread.sleep(sleepTime);
}
}
catch (InterruptedException ex)
{
// Nothing.
}
catch (InvocationTargetException ex)
{
// Nothing.
}
}
}
/**
* This Runnable repaints its SplashPanel.
*/
private class MyRepainter implements Runnable
{
public void run()
{
SplashPanel.this.repaint();
}
}
/**
* A main method for testing the splash panel.
*/
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setTitle("Animation");
frame.setSize(800, 600);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
frame.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
Sprite sprite =
new ClipSprite(
new ConstantColor(Color.white),
new ConstantColor(Color.lightGray),
new CircleSprite(true,
new LinearInt(200, 600, new SineTiming(2345L, 0L)),
new LinearInt(200, 400, new SineTiming(3210L, 0L)),
new ConstantInt(150)),
new ColorSprite(new ConstantColor(Color.gray),
new FontSprite(new ConstantFont(new Font("sansserif", Font.BOLD, 90)),
new TextSprite(new ConstantString("ProGuard"),
new ConstantInt(200),
new ConstantInt(300)))));
SplashPanel panel = new SplashPanel(sprite, 0.5);
panel.setBackground(Color.white);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
panel.start();
}
}
proguard4.8/src/proguard/gui/splash/Sprite.java 0000644 0001750 0001750 00000002554 11736333525 020400 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This interface describes objects that can paint themselves, possibly varying
* as a function of time.
*
* @author Eric Lafortune
*/
public interface Sprite
{
/**
* Paints the object.
*
* @param graphics the Graphics to paint on.
* @param time the time since the start of the animation, expressed in
* milliseconds.
*/
public void paint(Graphics graphics, long time);
}
proguard4.8/src/proguard/gui/splash/LinearInt.java 0000644 0001750 0001750 00000003346 11736333525 021017 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This VariableColor varies linearly with respect to its Timing.
*
* @author Eric Lafortune
*/
public class LinearInt implements VariableInt
{
private final int fromValue;
private final int toValue;
private final Timing timing;
/**
* Creates a new LinearInt.
* @param fromValue the value that corresponds to a timing of 0.
* @param toValue the value that corresponds to a timing of 1.
* @param timing the applied timing.
*/
public LinearInt(int fromValue, int toValue, Timing timing)
{
this.fromValue = fromValue;
this.toValue = toValue;
this.timing = timing;
}
// Implementation for VariableInt.
public int getInt(long time)
{
return (int) (fromValue + timing.getTiming(time) * (toValue - fromValue));
}
}
proguard4.8/src/proguard/gui/splash/ShadowedSprite.java 0000644 0001750 0001750 00000007013 11736333525 022052 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite adds a drop shadow to another Sprite.
*
* @author Eric Lafortune
*/
public class ShadowedSprite implements Sprite
{
private final VariableInt xOffset;
private final VariableInt yOffset;
private final VariableDouble alpha;
private final VariableInt blur;
private final Sprite sprite;
private float cachedAlpha = -1.0f;
private Color cachedColor;
/**
* Creates a new ShadowedSprite.
* @param xOffset the variable x-offset of the shadow, relative to the sprite itself.
* @param yOffset the variable y-offset of the shadow, relative to the sprite itself.
* @param alpha the variable darkness of the shadow (between 0 and 1).
* @param blur the variable blur of the shadow (0 for sharp shadows, 1 or
* more for increasingly blurry shadows).
* @param sprite the Sprite to be painted with its shadow.
*/
public ShadowedSprite(VariableInt xOffset,
VariableInt yOffset,
VariableDouble alpha,
VariableInt blur,
Sprite sprite)
{
this.xOffset = xOffset;
this.yOffset = yOffset;
this.alpha = alpha;
this.blur = blur;
this.sprite = sprite;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
double l = alpha.getDouble(time);
int b = blur.getInt(time) + 1;
float a = 1.0f - (float)Math.pow(1.0 - l, 1.0/(b*b));
if (a != cachedAlpha)
{
cachedAlpha = a;
cachedColor = new Color(0f, 0f, 0f, a);
}
// Set up the shadow graphics.
//OverrideGraphics2D g = new OverrideGraphics2D((Graphics2D)graphics);
//g.setOverrideColor(cachedColor);
// Set the shadow color.
Color actualColor = graphics.getColor();
graphics.setColor(cachedColor);
int xo = xOffset.getInt(time) - b/2;
int yo = yOffset.getInt(time) - b/2;
// Draw the sprite's shadow.
for (int x = 0; x < b; x++)
{
for (int y = 0; y < b; y++)
{
int xt = xo + x;
int yt = yo + y;
graphics.translate(xt, yt);
sprite.paint(graphics, time);
graphics.translate(-xt, -yt);
}
}
// Restore the actual sprite color.
graphics.setColor(actualColor);
// Draw the sprite itself in the ordinary graphics.
sprite.paint(graphics, time);
}
}
proguard4.8/src/proguard/gui/splash/LinearDouble.java 0000644 0001750 0001750 00000003372 11736333525 021476 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This VariableDouble varies linearly with respect to its Timing.
*
* @author Eric Lafortune
*/
public class LinearDouble implements VariableDouble
{
private final double fromValue;
private final double toValue;
private final Timing timing;
/**
* Creates a new LinearDouble.
* @param fromValue the value that corresponds to a timing of 0.
* @param toValue the value that corresponds to a timing of 1.
* @param timing the applied timing.
*/
public LinearDouble(double fromValue, double toValue, Timing timing)
{
this.fromValue = fromValue;
this.toValue = toValue;
this.timing = timing;
}
// Implementation for VariableDouble.
public double getDouble(long time)
{
return fromValue + timing.getTiming(time) * (toValue - fromValue);
}
}
proguard4.8/src/proguard/gui/splash/VariableColor.java 0000644 0001750 0001750 00000002225 11736333525 021651 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This interface represents a Color that varies with time.
*
* @author Eric Lafortune
*/
interface VariableColor
{
/**
* Returns the Color for the given time.
*/
public Color getColor(long time);
}
proguard4.8/src/proguard/gui/splash/SawToothTiming.java 0000644 0001750 0001750 00000003231 11736333525 022043 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This Timing ramps up linearly from 0 to 1 in a given repeated time interval.
*
* @author Eric Lafortune
*/
public class SawToothTiming implements Timing
{
private final long period;
private final long phase;
/**
* Creates a new SawToothTiming.
* @param period the time period for a full cycle.
* @param phase the phase of the cycle, which is added to the actual time.
*/
public SawToothTiming(long period, long phase)
{
this.period = period;
this.phase = phase;
}
// Implementation for Timing.
public double getTiming(long time)
{
// Compute the translated and scaled saw-tooth function.
return (double)((time + phase) % period) / (double)period;
}
}
proguard4.8/src/proguard/gui/splash/ConstantTiming.java 0000644 0001750 0001750 00000003005 11736333525 022063 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This Timing is constant over time.
*
* @author Eric Lafortune
*/
public class ConstantTiming implements Timing
{
private final double timing;
/**
* Creates a new ConstantTiming with a value of 0.
*/
public ConstantTiming()
{
this(0.0);
}
/**
* Creates a new ConstantTiming with a given value.
* @param timing the constant value of the timing.
*/
public ConstantTiming(double timing)
{
this.timing = timing;
}
// Implementation for Timing.
public double getTiming(long time)
{
return timing;
}
}
proguard4.8/src/proguard/gui/splash/ClipSprite.java 0000644 0001750 0001750 00000005610 11736333525 021204 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite encapsulates another Sprite, which is clipped by a clip Sprite.
*
* @author Eric Lafortune
*/
public class ClipSprite implements Sprite
{
private final VariableColor insideClipColor;
private final VariableColor outsideClipColor;
private final Sprite clipSprite;
private final Sprite sprite;
/**
* Creates a new ClipSprite.
* @param insideClipColor the background color inside the clip sprite.
* @param outsideClipColor the background color outside the clip sprite.
* @param clipSprite the clip Sprite.
* @param sprite the clipped Sprite.
*/
public ClipSprite(VariableColor insideClipColor,
VariableColor outsideClipColor,
Sprite clipSprite,
Sprite sprite)
{
this.insideClipColor = insideClipColor;
this.outsideClipColor = outsideClipColor;
this.clipSprite = clipSprite;
this.sprite = sprite;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
// Clear the background.
Color outsideColor = outsideClipColor.getColor(time);
Rectangle clip = graphics.getClipBounds();
graphics.setPaintMode();
graphics.setColor(outsideColor);
graphics.fillRect(0, 0, clip.width, clip.height);
// Draw the sprite in XOR mode.
OverrideGraphics2D g = new OverrideGraphics2D((Graphics2D)graphics);
Color insideColor = insideClipColor.getColor(time);
g.setOverrideXORMode(insideColor);
sprite.paint(g, time);
g.setOverrideXORMode(null);
// Clear the clip area.
g.setOverrideColor(insideColor);
clipSprite.paint(g, time);
g.setOverrideColor(null);
// Draw the sprite in XOR mode.
g.setOverrideXORMode(insideColor);
sprite.paint(g, time);
g.setOverrideXORMode(null);
}
}
proguard4.8/src/proguard/gui/splash/SmoothTiming.java 0000644 0001750 0001750 00000003642 11736333525 021552 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This Timing ramps up smoothly from 0 to 1 in a given time interval.
*
* @author Eric Lafortune
*/
public class SmoothTiming implements Timing
{
private final long fromTime;
private final long toTime;
/**
* Creates a new SmoothTiming.
* @param fromTime the time at which the timing starts ramping up from 0.
* @param toTime the time at which the timing stops ramping up at 1.
*/
public SmoothTiming(long fromTime, long toTime)
{
this.fromTime = fromTime;
this.toTime = toTime;
}
// Implementation for Timing.
public double getTiming(long time)
{
if (time <= fromTime)
{
return 0.0;
}
if (time >= toTime)
{
return 1.0;
}
// Compute the linear interpolation.
double timing = (double) (time - fromTime) / (double) (toTime - fromTime);
// Smooth the interpolation at the ends.
return timing * timing * (3.0 - 2.0 * timing);
}
}
proguard4.8/src/proguard/gui/splash/VariableFont.java 0000644 0001750 0001750 00000002220 11736333525 021474 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This interface represents a Font that varies with time.
*
* @author Eric Lafortune
*/
interface VariableFont
{
/**
* Returns the Font for the given time.
*/
public Font getFont(long time);
}
proguard4.8/src/proguard/gui/splash/Timing.java 0000644 0001750 0001750 00000002207 11736333525 020354 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This interface maps a time to a normalized timing between 0 and 1.
*
* @author Eric Lafortune
*/
interface Timing
{
/**
* Returns the timing for the given time.
*/
public double getTiming(long time);
}
proguard4.8/src/proguard/gui/splash/VariableSizeFont.java 0000644 0001750 0001750 00000003426 11736333525 022340 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This VariableFont varies in size with respect to its Timing.
*
* @author Eric Lafortune
*/
public class VariableSizeFont implements VariableFont
{
private final Font font;
private final VariableDouble size;
private float cachedSize = -1.0f;
private Font cachedFont;
/**
* Creates a new VariableSizeFont
* @param font the base font.
* @param size the variable size of the font.
*/
public VariableSizeFont(Font font, VariableDouble size)
{
this.font = font;
this.size = size;
}
// Implementation for VariableFont.
public Font getFont(long time)
{
float s = (float)size.getDouble(time);
if (s != cachedSize)
{
cachedSize = s;
cachedFont = font.deriveFont((float)s);
}
return cachedFont;
}
}
proguard4.8/src/proguard/gui/splash/ConstantString.java 0000644 0001750 0001750 00000002563 11736333525 022112 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This VariableString is constant over time.
*
* @author Eric Lafortune
*/
public class ConstantString implements VariableString
{
private final String value;
/**
* Creates a new ConstantString.
* @param value the constant value.
*/
public ConstantString(String value)
{
this.value = value;
}
// Implementation for VariableString.
public String getString(long time)
{
return value;
}
}
proguard4.8/src/proguard/gui/splash/ConstantDouble.java 0000644 0001750 0001750 00000002563 11736333525 022056 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This VariableDouble is constant over time.
*
* @author Eric Lafortune
*/
public class ConstantDouble implements VariableDouble
{
private final double value;
/**
* Creates a new ConstantDouble.
* @param value the constant value.
*/
public ConstantDouble(double value)
{
this.value = value;
}
// Implementation for VariableDouble.
public double getDouble(long time)
{
return value;
}
}
proguard4.8/src/proguard/gui/splash/CompositeSprite.java 0000644 0001750 0001750 00000003230 11736333525 022253 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite is the composition of a list of Sprite objects.
*
* @author Eric Lafortune
*/
public class CompositeSprite implements Sprite
{
private final Sprite[] sprites;
/**
* Creates a new CompositeSprite.
* @param sprites the array of Sprite objects to which the painting will
* be delegated, starting with the first element.
*/
public CompositeSprite(Sprite[] sprites)
{
this.sprites = sprites;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
// Draw the sprites.
for (int index = 0; index < sprites.length; index++)
{
sprites[index].paint(graphics, time);
}
}
}
proguard4.8/src/proguard/gui/splash/LinearTiming.java 0000644 0001750 0001750 00000003405 11736333525 021510 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This Timing ramps up linearly from 0 to 1 in a given time interval.
*
* @author Eric Lafortune
*/
public class LinearTiming implements Timing
{
private final long fromTime;
private final long toTime;
/**
* Creates a new LinearTiming.
* @param fromTime the time at which the timing starts ramping up from 0.
* @param toTime the time at which the timing stops ramping up at 1.
*/
public LinearTiming(long fromTime, long toTime)
{
this.fromTime = fromTime;
this.toTime = toTime;
}
// Implementation for Timing.
public double getTiming(long time)
{
// Compute the clamped linear interpolation.
return time <= fromTime ? 0.0 :
time >= toTime ? 1.0 :
(double)(time - fromTime) / (double)(toTime - fromTime);
}
}
proguard4.8/src/proguard/gui/splash/FontSprite.java 0000644 0001750 0001750 00000003553 11736333525 021227 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite sets the font for another given sprite.
*
* @author Eric Lafortune
*/
public class FontSprite implements Sprite
{
private final VariableFont font;
private final Sprite sprite;
/**
* Creates a new FontSprite.
* @param font the variable Font of the given sprite.
* @param sprite the sprite that will be provided of a font and painted.
*/
public FontSprite(VariableFont font,
Sprite sprite)
{
this.font = font;
this.sprite = sprite;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
// Save the old font.
Font oldFont = graphics.getFont();
// Set the new font.
graphics.setFont(font.getFont(time));
// Paint the actual sprite.
sprite.paint(graphics, time);
// Restore the old font.
graphics.setFont(oldFont);
}
}
proguard4.8/src/proguard/gui/splash/BufferedSprite.java 0000644 0001750 0001750 00000012140 11736333525 022033 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* This Sprite encapsulates another Sprite, which is then buffered in an Image.
*
* @author Eric Lafortune
*/
public class BufferedSprite implements Sprite
{
private final int bufferX;
private final int bufferY;
private final Image bufferImage;
private final Color backgroundColor;
private final Sprite sprite;
private final VariableInt x;
private final VariableInt y;
private long cachedTime = -1;
/**
* Creates a new BufferedSprite with an ABGR image.
* @param bufferX the x offset of the buffer image.
* @param bufferY the y offset of the buffer image.
* @param width the width of the buffer image.
* @param height the height of the buffer image.
* @param sprite the Sprite that is painted in the buffer.
* @param x the variable x ordinate of the image buffer for painting.
* @param y the variable y ordinate of the image buffer for painting.
*
*/
public BufferedSprite(int bufferX,
int bufferY,
int width,
int height,
Sprite sprite,
VariableInt x,
VariableInt y)
{
this(bufferX,
bufferY,
new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR),
null,
sprite,
x,
y);
}
/**
* Creates a new BufferedSprite with the given image.
* @param bufferX the x offset of the buffer image.
* @param bufferY the y offset of the buffer image.
* @param bufferImage the Image that is used for the buffering.
* @param backgroundColor the background color that is used for the buffer.
* @param sprite the Sprite that is painted in the buffer.
* @param x the variable x ordinate of the image buffer for
* painting.
* @param y the variable y ordinate of the image buffer for
* painting.
*/
public BufferedSprite(int bufferX,
int bufferY,
Image bufferImage,
Color backgroundColor,
Sprite sprite,
VariableInt x,
VariableInt y)
{
this.bufferX = bufferX;
this.bufferY = bufferY;
this.bufferImage = bufferImage;
this.backgroundColor = backgroundColor;
this.sprite = sprite;
this.x = x;
this.y = y;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
if (time != cachedTime)
{
Graphics bufferGraphics = bufferImage.getGraphics();
// Clear the background.
if (backgroundColor != null)
{
Graphics2D bufferGraphics2D = (Graphics2D)bufferGraphics;
bufferGraphics2D.setComposite(AlphaComposite.Clear);
bufferGraphics.fillRect(0, 0, bufferImage.getWidth(null), bufferImage.getHeight(null));
bufferGraphics2D.setComposite(AlphaComposite.Src);
}
else
{
bufferGraphics.setColor(backgroundColor);
bufferGraphics.fillRect(0, 0, bufferImage.getWidth(null), bufferImage.getHeight(null));
}
// Set up the buffer graphics.
bufferGraphics.translate(-bufferX, -bufferY);
bufferGraphics.setColor(graphics.getColor());
bufferGraphics.setFont(graphics.getFont());
// Draw the sprite.
sprite.paint(bufferGraphics, time);
bufferGraphics.dispose();
cachedTime = time;
}
// Draw the buffer image.
graphics.drawImage(bufferImage,
bufferX + x.getInt(time),
bufferY + y.getInt(time),
null);
}
}
proguard4.8/src/proguard/gui/splash/VariableDouble.java 0000644 0001750 0001750 00000002206 11736333525 022004 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This interface represents a double that varies with time.
*
* @author Eric Lafortune
*/
interface VariableDouble
{
/**
* Returns the double for the given time.
*/
public double getDouble(long time);
}
proguard4.8/src/proguard/gui/splash/VariableString.java 0000644 0001750 0001750 00000002206 11736333525 022040 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This interface represents a String that varies with time.
*
* @author Eric Lafortune
*/
interface VariableString
{
/**
* Returns the String for the given time.
*/
public String getString(long time);
}
proguard4.8/src/proguard/gui/splash/ConstantColor.java 0000644 0001750 0001750 00000002575 11736333525 021725 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This VariableColor is constant over time.
*
* @author Eric Lafortune
*/
public class ConstantColor implements VariableColor
{
private final Color value;
/**
* Creates a new ConstantColor.
* @param value the constant value.
*/
public ConstantColor(Color value)
{
this.value = value;
}
// Implementation for VariableColor.
public Color getColor(long time)
{
return value;
}
}
proguard4.8/src/proguard/gui/splash/ColorSprite.java 0000644 0001750 0001750 00000003554 11736333525 021400 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite colors another given sprite.
*
* @author Eric Lafortune
*/
public class ColorSprite implements Sprite
{
private final VariableColor color;
private final Sprite sprite;
/**
* Creates a new ColorSprite.
* @param color the variable color of the given sprite.
* @param sprite the sprite that will be colored and painted.
*/
public ColorSprite(VariableColor color,
Sprite sprite)
{
this.color = color;
this.sprite = sprite;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
// Save the old color.
Color oldColor = graphics.getColor();
// Set the new color.
graphics.setColor(color.getColor(time));
// Paint the actual sprite.
sprite.paint(graphics, time);
// Restore the old color.
graphics.setColor(oldColor);
}
}
proguard4.8/src/proguard/gui/splash/CircleSprite.java 0000644 0001750 0001750 00000004340 11736333525 021515 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite represents an animated circle. It can optionally be filled.
*
* @author Eric Lafortune
*/
public class CircleSprite implements Sprite
{
private final boolean filled;
private final VariableInt x;
private final VariableInt y;
private final VariableInt radius;
/**
* Creates a new CircleSprite.
* @param filled specifies whether the rectangle should be filled.
* @param x the variable x-coordinate of the center of the circle.
* @param y the variable y-coordinate of the center of the circle.
* @param radius the variable radius of the circle.
*/
public CircleSprite(boolean filled,
VariableInt x,
VariableInt y,
VariableInt radius)
{
this.filled = filled;
this.x = x;
this.y = y;
this.radius = radius;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
int xt = x.getInt(time);
int yt = y.getInt(time);
int r = radius.getInt(time);
if (filled)
{
graphics.fillOval(xt - r, yt - r, 2 * r, 2 * r);
}
else
{
graphics.drawOval(xt - r, yt - r, 2 * r, 2 * r);
}
}
}
proguard4.8/src/proguard/gui/splash/LinearColor.java 0000644 0001750 0001750 00000004535 11736333525 021344 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This VariableColor varies linearly with respect to its Timing.
*
* @author Eric Lafortune
*/
public class LinearColor implements VariableColor
{
private final Color fromValue;
private final Color toValue;
private final Timing timing;
private double cachedTiming = -1.0;
private Color cachedColor;
/**
* Creates a new LinearColor.
* @param fromValue the value that corresponds to a timing of 0.
* @param toValue the value that corresponds to a timing of 1.
* @param timing the applied timing.
*/
public LinearColor(Color fromValue, Color toValue, Timing timing)
{
this.fromValue = fromValue;
this.toValue = toValue;
this.timing = timing;
}
// Implementation for VariableColor.
public Color getColor(long time)
{
double t = timing.getTiming(time);
if (t != cachedTiming)
{
cachedTiming = t;
cachedColor =
t == 0.0 ? fromValue :
t == 1.0 ? toValue :
new Color((int)(fromValue.getRed() + t * (toValue.getRed() - fromValue.getRed())),
(int)(fromValue.getGreen() + t * (toValue.getGreen() - fromValue.getGreen())),
(int)(fromValue.getBlue() + t * (toValue.getBlue() - fromValue.getBlue())));
}
return cachedColor;
}
}
proguard4.8/src/proguard/gui/splash/ConstantInt.java 0000644 0001750 0001750 00000002525 11736333525 021374 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This VariableInt is constant over time.
*
* @author Eric Lafortune
*/
public class ConstantInt implements VariableInt
{
private final int value;
/**
* Creates a new ConstantInt.
* @param value the constant value.
*/
public ConstantInt(int value)
{
this.value = value;
}
// Implementation for VariableInt.
public int getInt(long time)
{
return value;
}
}
proguard4.8/src/proguard/gui/splash/VariableInt.java 0000644 0001750 0001750 00000002200 11736333525 021316 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This interface represents an integer that varies with time.
*
* @author Eric Lafortune
*/
interface VariableInt
{
/**
* Returns the integer for the given time.
*/
public int getInt(long time);
}
proguard4.8/src/proguard/gui/splash/ImageSprite.java 0000644 0001750 0001750 00000004656 11736333525 021350 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite represents an animated image.
*
* @author Eric Lafortune
*/
public class ImageSprite implements Sprite
{
private final Image image;
private final VariableInt x;
private final VariableInt y;
private final VariableDouble scaleX;
private final VariableDouble scaleY;
/**
* Creates a new ImageSprite.
* @param image the Image to be painted.
* @param x the variable x-coordinate of the upper-left corner of the image.
* @param y the variable y-coordinate of the upper-left corner of the image.
* @param scaleX the variable x-scale of the image.
* @param scaleY the variable y-scale of the image.
*/
public ImageSprite(Image image,
VariableInt x,
VariableInt y,
VariableDouble scaleX,
VariableDouble scaleY)
{
this.image = image;
this.x = x;
this.y = y;
this.scaleX = scaleX;
this.scaleY = scaleY;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
int xt = x.getInt(time);
int yt = y.getInt(time);
double scale_x = scaleX.getDouble(time);
double scale_y = scaleY.getDouble(time);
int width = (int)(image.getWidth(null) * scale_x);
int height = (int)(image.getHeight(null) * scale_y);
graphics.drawImage(image, xt, yt, width, height, null);
}
}
proguard4.8/src/proguard/gui/splash/SineTiming.java 0000644 0001750 0001750 00000003204 11736333525 021171 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
/**
* This Timing varies between 0 and 1, as a sine wave over time.
*
* @author Eric Lafortune
*/
public class SineTiming implements Timing
{
private final long period;
private final long phase;
/**
* Creates a new SineTiming.
* @param period the time period for a full cycle.
* @param phase the phase of the cycle, which is added to the actual time.
*/
public SineTiming(long period, long phase)
{
this.period = period;
this.phase = phase;
}
// Implementation for Timing.
public double getTiming(long time)
{
// Compute the translated and scaled sine function.
return 0.5 + 0.5 * Math.sin(2.0 * Math.PI * (time + phase) / period);
}
}
proguard4.8/src/proguard/gui/splash/TextSprite.java 0000644 0001750 0001750 00000005462 11736333525 021246 0 ustar eric eric /*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2012 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is 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.gui.splash;
import java.awt.*;
/**
* This Sprite represents a text.
*
* @author Eric Lafortune
*/
public class TextSprite implements Sprite
{
private final VariableString[] text;
private final VariableInt spacing;
private final VariableInt x;
private final VariableInt y;
/**
* Creates a new TextSprite containing a single line of text.
* @param text the variable text string.
* @param x the variable x-coordinate of the lower-left corner of the text.
* @param y the variable y-coordinate of the lower-left corner of the text.
*/
public TextSprite(VariableString text,
VariableInt x,
VariableInt y)
{
this(new VariableString[] { text }, new ConstantInt(0), x, y);
}
/**
* Creates a new TextSprite containing a multiple lines of text.
* @param text the variable text strings.
* @param spacing the variable spacing between the lines of text.
* @param x the variable x-coordinate of the lower-left corner of the
* first line of text.
* @param y the variable y-coordinate of the lower-left corner of the
* first line of text.
*/
public TextSprite(VariableString[] text,
VariableInt spacing,
VariableInt x,
VariableInt y)
{
this.text = text;
this.spacing = spacing;
this.x = x;
this.y = y;
}
// Implementation for Sprite.
public void paint(Graphics graphics, long time)
{
int xt = x.getInt(time);
int yt = y.getInt(time);
int spacingt = spacing.getInt(time);
for (int index = 0; index < text.length; index++)
{
graphics.drawString(text[index].getString(time), xt, yt + index * spacingt);
}
}
}
proguard4.8/src/proguard/gui/MANIFEST.MF 0000644 0001750 0001750 00000000140 11163773611 016412 0 ustar eric eric Manifest-Version: 1.0
Main-Class: proguard.gui.ProGuardGUI
Class-Path: proguard.jar retrace.jar
proguard4.8/src/proguard/gui/vtitle.png 0000644 0001750 0001750 00000055421 11170666104 017005 0 ustar eric eric PNG
IHDR H ޫ sRGB IDATx}ɒ82fzILZh%-Izꪮ;I@`2H`v+
ӏ I}q휏gx;;1?qkq0%{p|60g7Qqag$w̅Um7QѾPXmT
;pfT-<%>",f;_lBP^l>ⓌҌSЬf$o퉛VL*ڋ8O3Ό+%ȵ5)O>a)}RZ<#Yڋ^իZ {*}Fiw2(`o.x}ϒLG>Y'uVԔJp^.CL*^Ef}%|-l>1v%qJ#3S3M M13\
kF8B!Ar63(cib)*Vwq>+4U|QhqJBЌ XrC I\.V-aE3
)ԬUgeإ#l)>K9=Ka+Crq#DXN j%(5wdT)t,{q&/V'LrP}eh-RK[hSXv(hJaqo~]6Wõw"ИWjbs'W5
WG,lС S6oLSf0
Ne>Kh5vA tNfJ{mKB:h?u#SM)>({f9YC~bSAqqz?#;R>`^y|sKN Jq
L
PUIhߥA:)!eN΅'KBi@iHppNΚef^6gna^*gjpSGec:F:F7rhcMN1*~vNK3]:poW+F