aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info')
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/AccessMethodMarker.java201
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/BackwardBranchMarker.java90
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CatchExceptionMarker.java69
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassFilter.java63
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassMarker.java63
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfo.java177
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfoSetter.java47
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassFilter.java63
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassMarker.java96
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DynamicInvocationMarker.java79
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ExceptionInstructionChecker.java260
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/FieldOptimizationInfo.java188
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassFilter.java63
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassMarker.java93
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassFilter.java62
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassMarker.java93
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MemberOptimizationInfoSetter.java59
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodInvocationMarker.java107
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodOptimizationInfo.java336
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NoSideEffectMethodMarker.java91
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonEmptyStackReturnMarker.java115
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonPrivateMemberMarker.java171
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java85
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java129
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ParameterUsageMarker.java285
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ReadWriteFieldMarker.java163
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectInstructionChecker.java375
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodFilter.java73
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodMarker.java181
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumFilter.java96
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumMarker.java75
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java62
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java65
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SuperInvocationMarker.java93
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/VariableUsageMarker.java96
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/package.html4
36 files changed, 4368 insertions, 0 deletions
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/AccessMethodMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/AccessMethodMarker.java
new file mode 100644
index 0000000000..b030c55ddb
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/AccessMethodMarker.java
@@ -0,0 +1,201 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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;
+import proguard.classfile.visitor.*;
+
+/**
+ * This InstructionVisitor marks the types of class accesses and class member
+ * accesses of the methods whose instructions it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class AccessMethodMarker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor,
+ ClassVisitor,
+ MemberVisitor
+{
+ private Method invokingMethod;
+
+
+ // 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)
+ {
+ invokingMethod = method;
+
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ // Check the referenced class or class member, if any.
+ stringConstant.referencedClassAccept(this);
+ stringConstant.referencedMemberAccept(this);
+ }
+
+
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Check the bootstrap method.
+ invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Check the method reference.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ }
+
+
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ // Check the referenced class.
+ clazz.constantPoolEntryAccept(refConstant.u2classIndex, this);
+
+ // Check the referenced class member itself.
+ refConstant.referencedClassAccept(this);
+ refConstant.referencedMemberAccept(this);
+ }
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ // Check the referenced class.
+ classConstant.referencedClassAccept(this);
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ int accessFlags = clazz.getAccessFlags();
+
+ if ((accessFlags & ClassConstants.ACC_PUBLIC) == 0)
+ {
+ setAccessesPackageCode(invokingMethod);
+ }
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitAnyMember(Clazz clazz, Member member)
+ {
+ int accessFlags = member.getAccessFlags();
+
+ if ((accessFlags & ClassConstants.ACC_PRIVATE) != 0)
+ {
+ setAccessesPrivateCode(invokingMethod);
+ }
+ else if ((accessFlags & ClassConstants.ACC_PROTECTED) != 0)
+ {
+ setAccessesProtectedCode(invokingMethod);
+ }
+ else if ((accessFlags & ClassConstants.ACC_PUBLIC) == 0)
+ {
+ setAccessesPackageCode(invokingMethod);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void setAccessesPrivateCode(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setAccessesPrivateCode();
+ }
+ }
+
+
+ /**
+ * Returns whether the given method accesses private class members.
+ */
+ public static boolean accessesPrivateCode(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null || info.accessesPrivateCode();
+ }
+
+
+ private static void setAccessesPackageCode(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setAccessesPackageCode();
+ }
+ }
+
+
+ /**
+ * Returns whether the given method accesses package visible classes or class
+ * members.
+ */
+ public static boolean accessesPackageCode(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null || info.accessesPackageCode();
+ }
+
+
+ private static void setAccessesProtectedCode(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setAccessesProtectedCode();
+ }
+ }
+
+
+ /**
+ * Returns whether the given method accesses protected class members.
+ */
+ public static boolean accessesProtectedCode(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null || info.accessesProtectedCode();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/BackwardBranchMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/BackwardBranchMarker.java
new file mode 100644
index 0000000000..af1862e36e
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/BackwardBranchMarker.java
@@ -0,0 +1,90 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.CodeAttribute;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This InstructionVisitor marks all methods that branch backward in any of the
+ * instructions that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class BackwardBranchMarker
+extends SimplifiedVisitor
+implements InstructionVisitor
+{
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
+ {
+ markBackwardBranch(method, branchInstruction.branchOffset);
+ }
+
+
+ public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction)
+ {
+ markBackwardBranch(method, switchInstruction.defaultOffset);
+
+ for (int index = 0; index < switchInstruction.jumpOffsets.length; index++)
+ {
+ markBackwardBranch(method, switchInstruction.jumpOffsets[index]);
+ }
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Marks the given method if the given branch offset is negative.
+ */
+ private void markBackwardBranch(Method method, int branchOffset)
+ {
+ if (branchOffset < 0)
+ {
+ setBranchesBackward(method);
+ }
+ }
+
+
+ private static void setBranchesBackward(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setBranchesBackward();
+ }
+ }
+
+
+ public static boolean branchesBackward(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null || info.branchesBackward();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CatchExceptionMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CatchExceptionMarker.java
new file mode 100644
index 0000000000..9105142d6e
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CatchExceptionMarker.java
@@ -0,0 +1,69 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This AttributeVisitor marks all methods that catch exceptions.
+ *
+ * @author Eric Lafortune
+ */
+public class CatchExceptionMarker
+extends SimplifiedVisitor
+implements AttributeVisitor
+{
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ if (codeAttribute.u2exceptionTableLength > 0)
+ {
+ markCatchException(method);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void markCatchException(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setCatchesExceptions();
+ }
+ }
+
+
+ public static boolean catchesExceptions(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null ||
+ info.catchesExceptions();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassFilter.java
new file mode 100644
index 0000000000..78f10cf034
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassFilter.java
@@ -0,0 +1,63 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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 caught as exceptions.
+ *
+ * @see CaughtClassMarker
+ * @author Eric Lafortune
+ */
+public class CaughtClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ public CaughtClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (CaughtClassMarker.isCaught(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (CaughtClassMarker.isCaught(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassMarker.java
new file mode 100644
index 0000000000..9d4a1e9e52
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassMarker.java
@@ -0,0 +1,63 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This ClassVisitor marks all program classes that it visits as caught.
+ * This means that these classes are exception classes that occur in exception
+ * handlers.
+ *
+ * @author Eric Lafortune
+ */
+public class CaughtClassMarker
+implements ClassVisitor
+{
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ setCaught(programClass);
+ }
+
+
+ // Small utility methods.
+
+ private static void setCaught(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setCaught();
+ }
+ }
+
+
+ public static boolean isCaught(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.isCaught();
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfo.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfo.java
new file mode 100644
index 0000000000..4bf1e9fd69
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfo.java
@@ -0,0 +1,177 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.Clazz;
+
+/**
+ * This class stores some optimization information that can be attached to
+ * a class.
+ *
+ * @author Eric Lafortune
+ */
+public class ClassOptimizationInfo
+{
+ private boolean isInstantiated = false;
+ private boolean isInstanceofed = false;
+ private boolean isDotClassed = false;
+ private boolean isCaught = false;
+ private boolean isSimpleEnum = false;
+ private boolean containsStaticInitializer = false;
+ private boolean containsPackageVisibleMembers = false;
+ private boolean invokesPackageVisibleMembers = false;
+ private Clazz targetClass;
+
+
+ public void setInstantiated()
+ {
+ isInstantiated = true;
+ }
+
+
+ public boolean isInstantiated()
+ {
+ return isInstantiated;
+ }
+
+
+ public void setInstanceofed()
+ {
+ isInstanceofed = true;
+ }
+
+
+ public boolean isInstanceofed()
+ {
+ return isInstanceofed;
+ }
+
+
+ public void setDotClassed()
+ {
+ isDotClassed = true;
+ }
+
+
+ public boolean isDotClassed()
+ {
+ return isDotClassed;
+ }
+
+
+ public void setCaught()
+ {
+ isCaught = true;
+ }
+
+
+ public boolean isCaught()
+ {
+ return isCaught;
+ }
+
+
+ public void setSimpleEnum(boolean simple)
+ {
+ isSimpleEnum = simple;
+ }
+
+
+ public boolean isSimpleEnum()
+ {
+ return isSimpleEnum;
+ }
+
+
+ public void setContainsStaticInitializer()
+ {
+ containsStaticInitializer = true;
+ }
+
+
+ public boolean containsStaticInitializer()
+ {
+ return containsStaticInitializer;
+ }
+
+
+ public void setContainsPackageVisibleMembers()
+ {
+ containsPackageVisibleMembers = true;
+ }
+
+
+ public boolean containsPackageVisibleMembers()
+ {
+ return containsPackageVisibleMembers;
+ }
+
+
+ public void setInvokesPackageVisibleMembers()
+ {
+ invokesPackageVisibleMembers = true;
+ }
+
+
+ public boolean invokesPackageVisibleMembers()
+ {
+ return invokesPackageVisibleMembers;
+ }
+
+
+ public void setTargetClass(Clazz targetClass)
+ {
+ this.targetClass = targetClass;
+ }
+
+
+ public Clazz getTargetClass()
+ {
+ return targetClass;
+ }
+
+
+ public void merge(ClassOptimizationInfo other)
+ {
+ this.isInstantiated |= other.isInstantiated;
+ this.isInstanceofed |= other.isInstanceofed;
+ this.isDotClassed |= other.isDotClassed;
+ this.isCaught |= other.isCaught;
+ this.containsStaticInitializer |= other.containsStaticInitializer;
+ this.containsPackageVisibleMembers |= other.containsPackageVisibleMembers;
+ this.invokesPackageVisibleMembers |= other.invokesPackageVisibleMembers;
+ }
+
+
+ public static void setClassOptimizationInfo(Clazz clazz)
+ {
+ clazz.setVisitorInfo(new ClassOptimizationInfo());
+ }
+
+
+ public static ClassOptimizationInfo getClassOptimizationInfo(Clazz clazz)
+ {
+ Object visitorInfo = clazz.getVisitorInfo();
+ return visitorInfo instanceof ClassOptimizationInfo ?
+ (ClassOptimizationInfo)visitorInfo :
+ null;
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfoSetter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfoSetter.java
new file mode 100644
index 0000000000..ea143d68be
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfoSetter.java
@@ -0,0 +1,47 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.ProgramClass;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.ClassVisitor;
+import proguard.optimize.KeepMarker;
+
+/**
+ * This ClassVisitor attaches a ClassOptimizationInfo instance to every class
+ * that is not being kept that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class ClassOptimizationInfoSetter
+extends SimplifiedVisitor
+implements ClassVisitor
+{
+ // Implementations for MemberVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (!KeepMarker.isKept(programClass))
+ {
+ ClassOptimizationInfo.setClassOptimizationInfo(programClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassFilter.java
new file mode 100644
index 0000000000..9c85568357
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassFilter.java
@@ -0,0 +1,63 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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 used in a .class construct.
+ *
+ * @see DotClassMarker
+ * @author Eric Lafortune
+ */
+public class DotClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ public DotClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (DotClassMarker.isDotClassed(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (DotClassMarker.isDotClassed(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassMarker.java
new file mode 100644
index 0000000000..d7f8fa3149
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassMarker.java
@@ -0,0 +1,96 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This InstructionVisitor marks all classes that are used in a .class
+ * construct by any of the instructions that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class DotClassMarker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor,
+ 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)
+ {
+ if (constantInstruction.opcode == InstructionConstants.OP_LDC ||
+ constantInstruction.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)
+ {
+ classConstant.referencedClassAccept(this);
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ setDotClassed(programClass);
+ }
+
+
+ // Small utility methods.
+
+ private static void setDotClassed(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setDotClassed();
+ }
+ }
+
+
+ public static boolean isDotClassed(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.isDotClassed();
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DynamicInvocationMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DynamicInvocationMarker.java
new file mode 100644
index 0000000000..f59244cfbf
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DynamicInvocationMarker.java
@@ -0,0 +1,79 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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;
+import proguard.classfile.visitor.*;
+
+/**
+ * This InstructionVisitor marks whether the methods whose instructions it
+ * visits contain the invokedynamic instruction.
+ *
+ * @author Eric Lafortune
+ */
+public class DynamicInvocationMarker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor,
+ ClassVisitor,
+ MemberVisitor
+{
+ // 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)
+ {
+ if (constantInstruction.opcode == InstructionConstants.OP_INVOKEDYNAMIC)
+ {
+ setInvokesDynamically(method);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void setInvokesDynamically(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setInvokesDynamically();
+ }
+ }
+
+
+ /**
+ * Returns whether the given method calls the invokedynamic instruction.
+ */
+ public static boolean invokesDynamically(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null || info.invokesDynamically();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ExceptionInstructionChecker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ExceptionInstructionChecker.java
new file mode 100644
index 0000000000..727139116f
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ExceptionInstructionChecker.java
@@ -0,0 +1,260 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.CodeAttribute;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This class can tell whether an instruction might throw exceptions.
+ *
+ * @author Eric Lafortune
+ */
+public class ExceptionInstructionChecker
+extends SimplifiedVisitor
+implements InstructionVisitor
+// ConstantVisitor,
+// MemberVisitor
+{
+ // A return value for the visitor methods.
+ private boolean mayThrowExceptions;
+
+
+ /**
+ * Returns whether the specified method may throw exceptions.
+ */
+ public boolean mayThrowExceptions(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute)
+ {
+ return mayThrowExceptions(clazz,
+ method,
+ codeAttribute,
+ 0,
+ codeAttribute.u4codeLength);
+ }
+
+
+ /**
+ * Returns whether the specified block of code may throw exceptions.
+ */
+ public boolean mayThrowExceptions(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ int startOffset,
+ int endOffset)
+ {
+ byte[] code = codeAttribute.code;
+
+ // Go over all instructions.
+ int offset = startOffset;
+ while (offset < endOffset)
+ {
+ // Get the current instruction.
+ Instruction instruction = InstructionFactory.create(code, offset);
+
+ // Check if it may be throwing exceptions.
+ if (mayThrowExceptions(clazz,
+ method,
+ codeAttribute,
+ offset,
+ instruction))
+ {
+ return true;
+ }
+
+ // Go to the next instruction.
+ offset += instruction.length(offset);
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Returns whether the specified instruction may throw exceptions.
+ */
+ public boolean mayThrowExceptions(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ int offset)
+ {
+ Instruction instruction = InstructionFactory.create(codeAttribute.code, offset);
+
+ return mayThrowExceptions(clazz,
+ method,
+ codeAttribute,
+ offset,
+ instruction);
+ }
+
+
+ /**
+ * Returns whether the given instruction may throw exceptions.
+ */
+ public boolean mayThrowExceptions(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ int offset,
+ Instruction instruction)
+ {
+ return instruction.mayThrowExceptions();
+
+// mayThrowExceptions = false;
+//
+// instruction.accept(clazz, method, codeAttribute, offset, this);
+//
+// return mayThrowExceptions;
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
+ {
+ // Check for instructions that may throw exceptions.
+ // Note that monitorexit can not sensibly throw exceptions, except the
+ // broken and deprecated asynchronous ThreadDeath. Removing the
+ // artificial infinite looping exception blocks that recent compilers
+ // add does not strictly follow the JVM specs, but it does have the
+ // additional benefit of avoiding a bug in the JVM in JDK 1.1.
+ switch (simpleInstruction.opcode)
+ {
+ case InstructionConstants.OP_IDIV:
+ case InstructionConstants.OP_LDIV:
+ case InstructionConstants.OP_IREM:
+ case InstructionConstants.OP_LREM:
+ 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_NEWARRAY:
+ case InstructionConstants.OP_ARRAYLENGTH:
+ case InstructionConstants.OP_ATHROW:
+ case InstructionConstants.OP_MONITORENTER:
+ // These instructions may throw exceptions.
+ mayThrowExceptions = true;
+ }
+ }
+
+
+ public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
+ {
+ // Check for instructions that may throw exceptions.
+ switch (constantInstruction.opcode)
+ {
+ 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:
+ // These instructions may throw exceptions.
+ mayThrowExceptions = true;
+
+// case InstructionConstants.OP_INVOKEVIRTUAL:
+// case InstructionConstants.OP_INVOKESPECIAL:
+// case InstructionConstants.OP_INVOKESTATIC:
+// case InstructionConstants.OP_INVOKEINTERFACE:
+// // Check if the invoking the method may throw an exception.
+// clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
+ }
+
+
+// // Implementations for ConstantVisitor.
+//
+// public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
+// {
+// Member referencedMember = refConstant.referencedMember;
+//
+// // Do we have a reference to the method?
+// if (referencedMember == null)
+// {
+// // We'll have to assume invoking the unknown method may throw an
+// // an exception.
+// mayThrowExceptions = true;
+// }
+// else
+// {
+// // First check the referenced method itself.
+// refConstant.referencedMemberAccept(this);
+//
+// // If the result isn't conclusive, check down the hierarchy.
+// if (!mayThrowExceptions)
+// {
+// Clazz referencedClass = refConstant.referencedClass;
+// Method referencedMethod = (Method)referencedMember;
+//
+// // Check all other implementations of the method in the class
+// // hierarchy.
+// referencedClass.methodImplementationsAccept(referencedMethod,
+// false,
+// false,
+// true,
+// true,
+// this);
+// }
+// }
+// }
+//
+//
+// // Implementations for MemberVisitor.
+//
+// public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+// {
+// mayThrowExceptions = mayThrowExceptions ||
+// ExceptionMethodMarker.mayThrowExceptions(programMethod);
+// }
+//
+//
+// public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+// {
+// mayThrowExceptions = mayThrowExceptions ||
+// !NoExceptionMethodMarker.doesntThrowExceptions(libraryMethod);
+// }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/FieldOptimizationInfo.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/FieldOptimizationInfo.java
new file mode 100644
index 0000000000..5be9ce7df3
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/FieldOptimizationInfo.java
@@ -0,0 +1,188 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.evaluation.ConstantValueFactory;
+import proguard.evaluation.value.*;
+
+/**
+ * This class stores some optimization information that can be attached to
+ * a field.
+ *
+ * @author Eric Lafortune
+ */
+public class FieldOptimizationInfo
+extends SimplifiedVisitor
+implements AttributeVisitor
+{
+ private static final ParticularValueFactory VALUE_FACTORY = new ParticularValueFactory();
+ private static final ConstantValueFactory CONSTANT_VALUE_FACTORY = new ConstantValueFactory(VALUE_FACTORY);
+ private static final InitialValueFactory INITIAL_VALUE_FACTORY = new InitialValueFactory(VALUE_FACTORY);
+
+ private boolean isWritten;
+ private boolean isRead;
+ private boolean canBeMadePrivate = true;
+ private ReferenceValue referencedClass;
+ private Value value;
+
+
+ public FieldOptimizationInfo(Clazz clazz, Field field)
+ {
+ int accessFlags = field.getAccessFlags();
+
+ isWritten =
+ isRead = (accessFlags & ClassConstants.ACC_VOLATILE) != 0;
+
+ resetValue(clazz, field);
+ }
+
+
+ public FieldOptimizationInfo(FieldOptimizationInfo FieldOptimizationInfo)
+ {
+ this.isWritten = FieldOptimizationInfo.isWritten;
+ this.isRead = FieldOptimizationInfo.isRead;
+ this.canBeMadePrivate = FieldOptimizationInfo.canBeMadePrivate;
+ this.referencedClass = FieldOptimizationInfo.referencedClass;
+ this.value = FieldOptimizationInfo.value;
+ }
+
+
+ public void setWritten()
+ {
+ isWritten = true;
+ }
+
+
+ public boolean isWritten()
+ {
+ return isWritten;
+ }
+
+
+ public void setRead()
+ {
+ isRead = true;
+ }
+
+
+ public boolean isRead()
+ {
+ return isRead;
+ }
+
+
+ public void setCanNotBeMadePrivate()
+ {
+ canBeMadePrivate = false;
+ }
+
+
+ public boolean canBeMadePrivate()
+ {
+ return canBeMadePrivate;
+ }
+
+
+ public void generalizeReferencedClass(ReferenceValue referencedClass)
+ {
+ this.referencedClass = this.referencedClass != null ?
+ this.referencedClass.generalize(referencedClass) :
+ referencedClass;
+ }
+
+
+ public ReferenceValue getReferencedClass()
+ {
+ return referencedClass;
+ }
+
+
+ public void resetValue(Clazz clazz, Field field)
+ {
+ int accessFlags = field.getAccessFlags();
+
+ value = null;
+
+ // See if we can initialize a static field with a constant value.
+ if ((accessFlags & ClassConstants.ACC_STATIC) != 0)
+ {
+ field.accept(clazz, new AllAttributeVisitor(this));
+ }
+
+ // Otherwise initialize a non-final field with the default value.
+ // Conservatively, even a final field needs to be initialized with the
+ // default value, because it may be accessed before it is set.
+ if (value == null &&
+ (SideEffectInstructionChecker.OPTIMIZE_CONSERVATIVELY ||
+ (accessFlags & ClassConstants.ACC_FINAL) == 0))
+ {
+ value = INITIAL_VALUE_FACTORY.createValue(field.getDescriptor(clazz));
+ }
+ }
+
+
+ public void generalizeValue(Value value)
+ {
+ this.value = this.value != null ?
+ this.value.generalize(value) :
+ value;
+ }
+
+
+ public Value getValue()
+ {
+ return value;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
+ {
+ // Retrieve the initial static field value.
+ value = CONSTANT_VALUE_FACTORY.constantValue(clazz, constantValueAttribute.u2constantValueIndex);
+ }
+
+
+ // Small utility methods.
+
+ public static void setFieldOptimizationInfo(Clazz clazz, Field field)
+ {
+ field.setVisitorInfo(new FieldOptimizationInfo(clazz, field));
+ }
+
+
+ public static FieldOptimizationInfo getFieldOptimizationInfo(Field field)
+ {
+ Object visitorInfo = field.getVisitorInfo();
+
+ return visitorInfo instanceof FieldOptimizationInfo ?
+ (FieldOptimizationInfo)visitorInfo :
+ null;
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassFilter.java
new file mode 100644
index 0000000000..35d3b5d2c0
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassFilter.java
@@ -0,0 +1,63 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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 used in an 'instanceof' test.
+ *
+ * @see InstanceofClassMarker
+ * @author Eric Lafortune
+ */
+public class InstanceofClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ public InstanceofClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (InstanceofClassMarker.isInstanceofed(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (InstanceofClassMarker.isInstanceofed(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassMarker.java
new file mode 100644
index 0000000000..26cc9665af
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassMarker.java
@@ -0,0 +1,93 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.CodeAttribute;
+import proguard.classfile.constant.ClassConstant;
+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.ClassVisitor;
+
+/**
+ * This InstructionVisitor marks all classes that are used in an 'instanceof'
+ * test by any of the instructions that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class InstanceofClassMarker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor,
+ 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)
+ {
+ if (constantInstruction.opcode == InstructionConstants.OP_INSTANCEOF)
+ {
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ classConstant.referencedClassAccept(this);
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ setInstanceofed(programClass);
+ }
+
+
+ // Small utility methods.
+
+ private static void setInstanceofed(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setInstanceofed();
+ }
+ }
+
+
+ public static boolean isInstanceofed(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.isInstanceofed();
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassFilter.java
new file mode 100644
index 0000000000..804e9d0caf
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassFilter.java
@@ -0,0 +1,62 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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 instantiated.
+ *
+ * @author Eric Lafortune
+ */
+public class InstantiationClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ public InstantiationClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (InstantiationClassMarker.isInstantiated(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (InstantiationClassMarker.isInstantiated(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassMarker.java
new file mode 100644
index 0000000000..610be97e48
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassMarker.java
@@ -0,0 +1,93 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.CodeAttribute;
+import proguard.classfile.constant.ClassConstant;
+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.ClassVisitor;
+
+/**
+ * This InstructionVisitor marks all classes that are instantiated by any of
+ * the instructions that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class InstantiationClassMarker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor,
+ 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)
+ {
+ if (constantInstruction.opcode == InstructionConstants.OP_NEW)
+ {
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ classConstant.referencedClassAccept(this);
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ setInstantiated(programClass);
+ }
+
+
+ // Small utility methods.
+
+ private static void setInstantiated(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setInstantiated();
+ }
+ }
+
+
+ public static boolean isInstantiated(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.isInstantiated();
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MemberOptimizationInfoSetter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MemberOptimizationInfoSetter.java
new file mode 100644
index 0000000000..4a09e09edc
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MemberOptimizationInfoSetter.java
@@ -0,0 +1,59 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.MemberVisitor;
+import proguard.optimize.KeepMarker;
+
+/**
+ * This MemberVisitor attaches a FieldOptimizationInfo instance to every field
+ * and a MethodOptimizationInfo instance to every method that is not being kept
+ * that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class MemberOptimizationInfoSetter
+extends SimplifiedVisitor
+implements MemberVisitor
+{
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ if (!KeepMarker.isKept(programField))
+ {
+ FieldOptimizationInfo.setFieldOptimizationInfo(programClass,
+ programField);
+ }
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if (!KeepMarker.isKept(programMethod))
+ {
+ MethodOptimizationInfo.setMethodOptimizationInfo(programClass,
+ programMethod);
+ }
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodInvocationMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodInvocationMarker.java
new file mode 100644
index 0000000000..2288669df6
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodInvocationMarker.java
@@ -0,0 +1,107 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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;
+import proguard.classfile.visitor.MemberVisitor;
+
+/**
+ * This InstructionVisitor counts the number of times methods are invoked from
+ * the instructions that are visited.
+ *
+ * @author Eric Lafortune
+ */
+public class MethodInvocationMarker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor,
+ MemberVisitor
+{
+ // 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)
+ {
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ // Mark the referenced method, if any.
+ stringConstant.referencedMemberAccept(this);
+ }
+
+
+ public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ // Mark the referenced method.
+ refConstant.referencedMemberAccept(this);
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitAnyMember(Clazz Clazz, Member member) {}
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ incrementInvocationCount(programMethod);
+ }
+
+
+ // Small utility methods.
+
+ private static void incrementInvocationCount(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.incrementInvocationCount();
+ }
+ }
+
+
+ /**
+ * Returns the number of times the given method was invoked by the
+ * instructions that were visited.
+ */
+ public static int getInvocationCount(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info != null ? info.getInvocationCount() :
+ Integer.MAX_VALUE;
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodOptimizationInfo.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodOptimizationInfo.java
new file mode 100644
index 0000000000..2e56910895
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodOptimizationInfo.java
@@ -0,0 +1,336 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.util.*;
+import proguard.evaluation.value.Value;
+
+/**
+ * This class stores some optimization information that can be attached to
+ * a method.
+ *
+ * @author Eric Lafortune
+ */
+public class MethodOptimizationInfo
+{
+ private boolean hasNoSideEffects = false;
+ private boolean hasSideEffects = false;
+ private boolean canBeMadePrivate = true;
+ private boolean catchesExceptions = false;
+ private boolean branchesBackward = false;
+ private boolean invokesSuperMethods = false;
+ private boolean invokesDynamically = false;
+ private boolean accessesPrivateCode = false;
+ private boolean accessesPackageCode = false;
+ private boolean accessesProtectedCode = false;
+ private boolean returnsWithNonEmptyStack = false;
+ private int invocationCount = 0;
+ private int parameterSize = 0;
+ private long usedParameters = 0L;
+ private Value[] parameters;
+ private Value returnValue;
+
+
+ /**
+ * Creates a new MethodOptimizationInfo for the given method.
+ */
+ public MethodOptimizationInfo(Clazz clazz, Method method)
+ {
+ // Set up an array of the right size for storing information about the
+ // passed parameters.
+ int parameterCount =
+ ClassUtil.internalMethodParameterCount(method.getDescriptor(clazz));
+
+ if ((method.getAccessFlags() & ClassConstants.ACC_STATIC) == 0)
+ {
+ parameterCount++;
+ }
+
+ if (parameterCount > 0)
+ {
+ parameters = new Value[parameterCount];
+ }
+ }
+
+
+ public void setNoSideEffects()
+ {
+ hasNoSideEffects = true;
+ }
+
+
+ public boolean hasNoSideEffects()
+ {
+ return hasNoSideEffects;
+ }
+
+
+ public void setSideEffects()
+ {
+ hasSideEffects = true;
+ }
+
+
+ public boolean hasSideEffects()
+ {
+ return hasSideEffects;
+ }
+
+
+ public void setCanNotBeMadePrivate()
+ {
+ canBeMadePrivate = false;
+ }
+
+
+ public boolean canBeMadePrivate()
+ {
+ return canBeMadePrivate;
+ }
+
+
+ public void setCatchesExceptions()
+ {
+ catchesExceptions = true;
+ }
+
+
+ public boolean catchesExceptions()
+ {
+ return catchesExceptions;
+ }
+
+
+ public void setBranchesBackward()
+ {
+ branchesBackward = true;
+ }
+
+
+ public boolean branchesBackward()
+ {
+ return branchesBackward;
+ }
+
+
+ public void setInvokesSuperMethods()
+ {
+ invokesSuperMethods = true;
+ }
+
+
+ public boolean invokesSuperMethods()
+ {
+ return invokesSuperMethods;
+ }
+
+
+ public void setInvokesDynamically()
+ {
+ invokesDynamically = true;
+ }
+
+
+ public boolean invokesDynamically()
+ {
+ return invokesDynamically;
+ }
+
+
+ public void setAccessesPrivateCode()
+ {
+ accessesPrivateCode = true;
+ }
+
+
+ public boolean accessesPrivateCode()
+ {
+ return accessesPrivateCode;
+ }
+
+
+ public void setAccessesPackageCode()
+ {
+ accessesPackageCode = true;
+ }
+
+
+ public boolean accessesPackageCode()
+ {
+ return accessesPackageCode;
+ }
+
+
+ public void setAccessesProtectedCode()
+ {
+ accessesProtectedCode = true;
+ }
+
+
+ public boolean accessesProtectedCode()
+ {
+ return accessesProtectedCode;
+ }
+
+
+ public void setReturnsWithNonEmptyStack()
+ {
+ returnsWithNonEmptyStack = true;
+ }
+
+
+ public boolean returnsWithNonEmptyStack()
+ {
+ return returnsWithNonEmptyStack;
+ }
+
+
+ public void incrementInvocationCount()
+ {
+ invocationCount++;
+ }
+
+
+ public int getInvocationCount()
+ {
+ return invocationCount;
+ }
+
+
+ public void setParameterSize(int parameterSize)
+ {
+ this.parameterSize = parameterSize;
+ }
+
+
+ public int getParameterSize()
+ {
+ return parameterSize;
+ }
+
+
+ public void setParameterUsed(int parameterIndex)
+ {
+ usedParameters |= 1L << parameterIndex;
+ }
+
+
+ public void setUsedParameters(long usedParameters)
+ {
+ this.usedParameters = usedParameters;
+ }
+
+
+ public boolean isParameterUsed(int parameterIndex)
+ {
+ return parameterIndex >= 64 || (usedParameters & (1L << parameterIndex)) != 0;
+ }
+
+
+ public long getUsedParameters()
+ {
+ return usedParameters;
+ }
+
+
+ public void generalizeParameter(int parameterIndex, Value parameter)
+ {
+ parameters[parameterIndex] = parameters[parameterIndex] != null ?
+ parameters[parameterIndex].generalize(parameter) :
+ parameter;
+ }
+
+
+ public Value getParameter(int parameterIndex)
+ {
+ return parameters != null ?
+ parameters[parameterIndex] :
+ null;
+ }
+
+
+ public void generalizeReturnValue(Value returnValue)
+ {
+ this.returnValue = this.returnValue != null ?
+ this.returnValue.generalize(returnValue) :
+ returnValue;
+ }
+
+
+ public Value getReturnValue()
+ {
+ return returnValue;
+ }
+
+
+ // For setting enum return values.
+ public void setReturnValue(Value returnValue)
+ {
+ this.returnValue = returnValue;
+ }
+
+
+ public void merge(MethodOptimizationInfo other)
+ {
+ if (other != null)
+ {
+ this.hasNoSideEffects &= other.hasNoSideEffects;
+ this.hasSideEffects |= other.hasSideEffects;
+ //this.canBeMadePrivate &= other.canBeMadePrivate;
+ this.catchesExceptions |= other.catchesExceptions;
+ this.branchesBackward |= other.branchesBackward;
+ this.invokesSuperMethods |= other.invokesSuperMethods;
+ this.invokesDynamically |= other.invokesDynamically;
+ this.accessesPrivateCode |= other.accessesPrivateCode;
+ this.accessesPackageCode |= other.accessesPackageCode;
+ this.accessesProtectedCode |= other.accessesProtectedCode;
+ }
+ else
+ {
+ this.hasNoSideEffects = false;
+ this.hasSideEffects = true;
+ //this.canBeMadePrivate = false;
+ this.catchesExceptions = true;
+ this.branchesBackward = true;
+ this.invokesSuperMethods = true;
+ this.accessesPrivateCode = true;
+ this.accessesPackageCode = true;
+ this.accessesProtectedCode = true;
+ }
+ }
+
+
+ public static void setMethodOptimizationInfo(Clazz clazz, Method method)
+ {
+ MethodLinker.lastMember(method).setVisitorInfo(new MethodOptimizationInfo(clazz, method));
+ }
+
+
+ public static MethodOptimizationInfo getMethodOptimizationInfo(Method method)
+ {
+ Object visitorInfo = MethodLinker.lastMember(method).getVisitorInfo();
+
+ return visitorInfo instanceof MethodOptimizationInfo ?
+ (MethodOptimizationInfo)visitorInfo :
+ null;
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NoSideEffectMethodMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NoSideEffectMethodMarker.java
new file mode 100644
index 0000000000..624b22a2ea
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NoSideEffectMethodMarker.java
@@ -0,0 +1,91 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.MemberVisitor;
+
+/**
+ * This MemberVisitor marks all methods that it visits as not having any side
+ * effects. It will make the SideEffectMethodMarker consider them as such
+ * without further analysis.
+ *
+ * @see SideEffectMethodMarker
+ * @author Eric Lafortune
+ */
+public class NoSideEffectMethodMarker
+extends SimplifiedVisitor
+implements MemberVisitor
+{
+ // A visitor info flag to indicate the visitor accepter is being kept,
+ // but that it doesn't have any side effects.
+ public static final Object KEPT_BUT_NO_SIDE_EFFECTS = new Object();
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitAnyMember(Clazz Clazz, Member member)
+ {
+ // Ignore any attempts to mark fields.
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ markNoSideEffects(programMethod);
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ markNoSideEffects(libraryMethod);
+ }
+
+
+ // Small utility methods.
+
+ private static void markNoSideEffects(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setNoSideEffects();
+ }
+ else
+ {
+ MethodLinker.lastMember(method).setVisitorInfo(KEPT_BUT_NO_SIDE_EFFECTS);
+ }
+ }
+
+
+ public static boolean hasNoSideEffects(Method method)
+ {
+ if (MethodLinker.lastVisitorAccepter(method).getVisitorInfo() == KEPT_BUT_NO_SIDE_EFFECTS)
+ {
+ return true;
+ }
+
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info != null &&
+ info.hasNoSideEffects();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonEmptyStackReturnMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonEmptyStackReturnMarker.java
new file mode 100644
index 0000000000..12124126ca
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonEmptyStackReturnMarker.java
@@ -0,0 +1,115 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.CodeAttribute;
+import proguard.classfile.attribute.visitor.StackSizeComputer;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This InstructionVisitor marks all methods that return with a non-empty stack
+ * (other than the return value).
+ *
+ * @author Eric Lafortune
+ */
+public class NonEmptyStackReturnMarker
+extends SimplifiedVisitor
+implements InstructionVisitor
+{
+ private final StackSizeComputer stackSizeComputer;
+
+
+ /**
+ * Creates a new NonEmptyStackReturnMarker
+ * @param stackSizeComputer the stack size computer that can return the
+ * stack sizes at the instructions that are
+ * visited.
+ */
+ public NonEmptyStackReturnMarker(StackSizeComputer stackSizeComputer)
+ {
+ this.stackSizeComputer = stackSizeComputer;
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
+ {
+ switch (simpleInstruction.opcode)
+ {
+ case InstructionConstants.OP_LRETURN:
+ case InstructionConstants.OP_DRETURN:
+ markReturnWithNonEmptyStack(method, offset, 2);
+ break;
+
+ case InstructionConstants.OP_IRETURN:
+ case InstructionConstants.OP_FRETURN:
+ case InstructionConstants.OP_ARETURN:
+ markReturnWithNonEmptyStack(method, offset, 1);
+ break;
+
+ case InstructionConstants.OP_RETURN:
+ markReturnWithNonEmptyStack(method, offset, 0);
+ break;
+ }
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Marks the given method if the stack before the given instruction offset
+ * has a size larger than the given size.
+ */
+ private void markReturnWithNonEmptyStack(Method method,
+ int offset,
+ int stackSize)
+ {
+ if (!stackSizeComputer.isReachable(offset) ||
+ stackSizeComputer.getStackSizeBefore(offset) > stackSize)
+ {
+ setReturnsWithNonEmptyStack(method);
+ }
+ }
+
+
+ private static void setReturnsWithNonEmptyStack(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setReturnsWithNonEmptyStack();
+ }
+ }
+
+
+ public static boolean returnsWithNonEmptyStack(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null || info.returnsWithNonEmptyStack();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonPrivateMemberMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonPrivateMemberMarker.java
new file mode 100644
index 0000000000..99056083fe
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonPrivateMemberMarker.java
@@ -0,0 +1,171 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+
+/**
+ * This ClassVisitor marks all class members that can not be made private in the
+ * classes that it visits, and in the classes to which they refer.
+ *
+ * @author Eric Lafortune
+ */
+public class NonPrivateMemberMarker
+extends SimplifiedVisitor
+implements ClassVisitor,
+ ConstantVisitor,
+ MemberVisitor
+{
+ private final MethodImplementationFilter filteredMethodMarker = new MethodImplementationFilter(this);
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Mark all referenced class members in different classes.
+ programClass.constantPoolEntriesAccept(this);
+
+ // Explicitly mark the <clinit> method.
+ programClass.methodAccept(ClassConstants.METHOD_NAME_CLINIT,
+ ClassConstants.METHOD_TYPE_CLINIT,
+ this);
+
+ // Explicitly mark the parameterless <init> method.
+ programClass.methodAccept(ClassConstants.METHOD_NAME_INIT,
+ ClassConstants.METHOD_TYPE_INIT,
+ this);
+
+ // Mark all methods that may have implementations.
+ programClass.methodsAccept(filteredMethodMarker);
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ // Go over all methods.
+ libraryClass.methodsAccept(this);
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ // The referenced class member, if any, can never be made private,
+ // even if it's in the same class.
+ stringConstant.referencedMemberAccept(this);
+ }
+
+
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ Clazz referencedClass = refConstant.referencedClass;
+
+ // Is it referring to a class member in another class?
+ // The class member might be in another class, or
+ // it may be referenced through another class.
+ if (referencedClass != null &&
+ !referencedClass.equals(clazz) ||
+ !refConstant.getClassName(clazz).equals(clazz.getName()))
+ {
+ // The referenced class member can never be made private.
+ refConstant.referencedMemberAccept(this);
+ }
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ markCanNotBeMadePrivate(programField);
+ }
+
+
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
+ {
+ markCanNotBeMadePrivate(libraryField);
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ markCanNotBeMadePrivate(programMethod);
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ markCanNotBeMadePrivate(libraryMethod);
+ }
+
+
+ // Small utility methods.
+
+ private static void markCanNotBeMadePrivate(Field field)
+ {
+ FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
+ if (info != null)
+ {
+ info.setCanNotBeMadePrivate();
+ }
+ }
+
+
+ /**
+ * Returns whether the given field can be made private.
+ */
+ public static boolean canBeMadePrivate(Field field)
+ {
+ FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
+ return info != null &&
+ info.canBeMadePrivate();
+ }
+
+
+ private static void markCanNotBeMadePrivate(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setCanNotBeMadePrivate();
+ }
+ }
+
+
+ /**
+ * Returns whether the given method can be made private.
+ */
+ public static boolean canBeMadePrivate(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info != null &&
+ info.canBeMadePrivate();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java
new file mode 100644
index 0000000000..6ac7b60c94
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java
@@ -0,0 +1,85 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+
+/**
+ * This ClassVisitor marks all classes that contain package visible members.
+ *
+ * @author Eric Lafortune
+ */
+public class PackageVisibleMemberContainingClassMarker
+extends SimplifiedVisitor
+implements ClassVisitor,
+ MemberVisitor
+{
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ // Check the class itself.
+ if ((clazz.getAccessFlags() & ClassConstants.ACC_PUBLIC) == 0)
+ {
+ setPackageVisibleMembers(clazz);
+ }
+ else
+ {
+ // Check the members.
+ clazz.fieldsAccept(this);
+ clazz.methodsAccept(this);
+ }
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitAnyMember(Clazz clazz, Member member)
+ {
+ if ((member.getAccessFlags() &
+ (ClassConstants.ACC_PRIVATE |
+ ClassConstants.ACC_PUBLIC)) == 0)
+ {
+ setPackageVisibleMembers(clazz);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void setPackageVisibleMembers(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setContainsPackageVisibleMembers();
+ }
+ }
+
+
+ public static boolean containsPackageVisibleMembers(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.containsPackageVisibleMembers();
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java
new file mode 100644
index 0000000000..86ba808591
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java
@@ -0,0 +1,129 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+
+/**
+ * This ConstantVisitor marks all classes that refer to package visible classes
+ * or class members.
+ *
+ * @author Eric Lafortune
+ */
+public class PackageVisibleMemberInvokingClassMarker
+extends SimplifiedVisitor
+implements ConstantVisitor,
+ ClassVisitor,
+ MemberVisitor
+{
+ private Clazz referencingClass;
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ // Check the referenced class and class member, if any.
+ if (stringConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ stringConstant.referencedClassAccept(this);
+ stringConstant.referencedMemberAccept(this);
+ }
+ }
+
+
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ // Check the referenced class and class member.
+ if (refConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ refConstant.referencedClassAccept(this);
+ refConstant.referencedMemberAccept(this);
+ }
+ }
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ // Check the referenced class.
+ if (classConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ classConstant.referencedClassAccept(this);
+ }
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ if ((clazz.getAccessFlags() &
+ ClassConstants.ACC_PUBLIC) == 0)
+ {
+ setInvokesPackageVisibleMembers(referencingClass);
+ }
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitAnyMember(Clazz clazz, Member member)
+ {
+ if ((member.getAccessFlags() &
+ (ClassConstants.ACC_PUBLIC |
+ ClassConstants.ACC_PRIVATE)) == 0)
+ {
+ setInvokesPackageVisibleMembers(referencingClass);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void setInvokesPackageVisibleMembers(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setInvokesPackageVisibleMembers();
+ }
+ }
+
+
+ public static boolean invokesPackageVisibleMembers(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.invokesPackageVisibleMembers();
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ParameterUsageMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ParameterUsageMarker.java
new file mode 100644
index 0000000000..85e348cc42
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ParameterUsageMarker.java
@@ -0,0 +1,285 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.MemberVisitor;
+import proguard.evaluation.value.Value;
+import proguard.optimize.evaluation.PartialEvaluator;
+
+/**
+ * This MemberVisitor counts the parameters and marks the used parameters
+ * of the methods that it visits. It also marks the 'this' parameters of
+ * methods that have hierarchies.
+ *
+ * @author Eric Lafortune
+ */
+public class ParameterUsageMarker
+extends SimplifiedVisitor
+implements MemberVisitor,
+ AttributeVisitor,
+ InstructionVisitor
+{
+ private static final boolean DEBUG = false;
+
+
+ private final boolean markThisParameter;
+ private final boolean markAllParameters;
+ private final PartialEvaluator partialEvaluator = new PartialEvaluator();
+
+
+ /**
+ * Creates a new ParameterUsageMarker.
+ */
+ public ParameterUsageMarker()
+ {
+ this(false, false);
+ }
+
+
+ /**
+ * Creates a new ParameterUsageMarker that optionally marks all parameters.
+ * @param markThisParameter specifies whether all 'this' parameters should
+ * be marked as being used.
+ * @param markAllParameters specifies whether all other parameters should
+ * be marked as being used.
+ */
+ public ParameterUsageMarker(boolean markThisParameter,
+ boolean markAllParameters)
+ {
+ this.markThisParameter = markThisParameter;
+ this.markAllParameters = markAllParameters;
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ int parameterSize =
+ ClassUtil.internalMethodParameterSize(programMethod.getDescriptor(programClass),
+ programMethod.getAccessFlags());
+
+ if (parameterSize > 0)
+ {
+ int accessFlags = programMethod.getAccessFlags();
+
+ // Must we mark the 'this' parameter?
+ if (markThisParameter &&
+ (accessFlags & ClassConstants.ACC_STATIC) == 0)
+ {
+ // Mark the 'this' parameter.
+ markParameterUsed(programMethod, 0);
+ }
+
+ // Must we mark all other parameters?
+ if (markAllParameters)
+ {
+ // Mark all parameters, without the 'this' parameter.
+ markUsedParameters(programMethod,
+ (accessFlags & ClassConstants.ACC_STATIC) != 0 ?
+ -1L : -2L);
+ }
+
+ // Is it a native method?
+ if ((accessFlags & ClassConstants.ACC_NATIVE) != 0)
+ {
+ // Mark all parameters.
+ markUsedParameters(programMethod, -1L);
+ }
+
+ // Is it an abstract method?
+ else if ((accessFlags & ClassConstants.ACC_ABSTRACT) != 0)
+ {
+ // Mark the 'this' parameter.
+ markParameterUsed(programMethod, 0);
+ }
+
+ // Is it a non-native, concrete method?
+ else
+ {
+ // Is the method not static, but synchronized, or can it have
+ // other implementations, or is it a class instance initializer?
+ if ((accessFlags & ClassConstants.ACC_STATIC) == 0 &&
+ ((accessFlags & ClassConstants.ACC_SYNCHRONIZED) != 0 ||
+ programClass.mayHaveImplementations(programMethod) ||
+ programMethod.getName(programClass).equals(ClassConstants.METHOD_NAME_INIT)))
+ {
+ // Mark the 'this' parameter.
+ markParameterUsed(programMethod, 0);
+ }
+
+ // Mark the parameters that are used by the code.
+ programMethod.attributesAccept(programClass, this);
+ }
+
+ if (DEBUG)
+ {
+ System.out.print("ParameterUsageMarker: ["+programClass.getName() +"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"]: ");
+ for (int index = 0; index < parameterSize; index++)
+ {
+ System.out.print(isParameterUsed(programMethod, index) ? '+' : '-');
+ }
+ System.out.println();
+ }
+
+ }
+
+ // Set the parameter size.
+ setParameterSize(programMethod, parameterSize);
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ // Can the method have other implementations?
+ if (libraryClass.mayHaveImplementations(libraryMethod))
+ {
+ // All implementations must keep all parameters of this method,
+ // including the 'this' parameter.
+ markUsedParameters(libraryMethod, -1L);
+ }
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ // Evaluate the code.
+ partialEvaluator.visitCodeAttribute(clazz, method, codeAttribute);
+
+ // Mark the parameters that are used by the code.
+ codeAttribute.instructionsAccept(clazz, method, this);
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
+ {
+ if (partialEvaluator.isTraced(offset) &&
+ variableInstruction.isLoad())
+ {
+ int parameterIndex = variableInstruction.variableIndex;
+ if (parameterIndex < codeAttribute.u2maxLocals)
+ {
+ Value producer =
+ partialEvaluator.getVariablesBefore(offset).getProducerValue(parameterIndex);
+ if (producer != null &&
+ producer.instructionOffsetValue().contains(PartialEvaluator.AT_METHOD_ENTRY))
+ {
+ // Mark the variable.
+ markParameterUsed(method, parameterIndex);
+
+ // Account for Category 2 instructions, which take up two entries.
+ if (variableInstruction.isCategory2())
+ {
+ markParameterUsed(method, parameterIndex + 1);
+ }
+ }
+ }
+ }
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Sets the total size of the parameters.
+ */
+ private static void setParameterSize(Method method, int parameterSize)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setParameterSize(parameterSize);
+ }
+ }
+
+
+ /**
+ * Returns the total size of the parameters.
+ */
+ public static int getParameterSize(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info != null ? info.getParameterSize() : 0;
+ }
+
+
+ /**
+ * Marks the given parameter as being used.
+ */
+ public static void markParameterUsed(Method method, int variableIndex)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setParameterUsed(variableIndex);
+ }
+ }
+
+
+ /**
+ * Marks the given parameters as being used.
+ */
+ public static void markUsedParameters(Method method, long usedParameters)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setUsedParameters(info.getUsedParameters() | usedParameters);
+ }
+ }
+
+
+ /**
+ * Returns whether the given parameter is being used.
+ */
+ public static boolean isParameterUsed(Method method, int variableIndex)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null ||
+ info.isParameterUsed(variableIndex);
+ }
+
+
+ /**
+ * Returns which parameters are being used.
+ */
+ public static long getUsedParameters(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info != null ? info.getUsedParameters() : -1L;
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ReadWriteFieldMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ReadWriteFieldMarker.java
new file mode 100644
index 0000000000..472309d3c1
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ReadWriteFieldMarker.java
@@ -0,0 +1,163 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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;
+import proguard.classfile.visitor.MemberVisitor;
+
+/**
+ * This InstructionVisitor marks all fields that are write-only.
+ *
+ * @author Eric Lafortune
+ */
+public class ReadWriteFieldMarker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor,
+ MemberVisitor
+{
+ // Parameters for the visitor methods.
+ private boolean reading = true;
+ private boolean writing = true;
+
+
+ // 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;
+
+ // Check for instructions that involve fields.
+ switch (opcode)
+ {
+ case InstructionConstants.OP_LDC:
+ case InstructionConstants.OP_LDC_W:
+ // Mark the field, if any, as being read from and written to.
+ reading = true;
+ writing = true;
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ break;
+
+ case InstructionConstants.OP_GETSTATIC:
+ case InstructionConstants.OP_GETFIELD:
+ // Mark the field as being read from.
+ reading = true;
+ writing = false;
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ break;
+
+ case InstructionConstants.OP_PUTSTATIC:
+ case InstructionConstants.OP_PUTFIELD:
+ // Mark the field as being written to.
+ reading = false;
+ writing = true;
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ break;
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ // Mark the referenced field, if any.
+ stringConstant.referencedMemberAccept(this);
+ }
+
+
+ public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
+ {
+ // Mark the referenced field.
+ fieldrefConstant.referencedMemberAccept(this);
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitAnyMember(Clazz Clazz, Member member) {}
+
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ // Mark the field if it is being read from.
+ if (reading)
+ {
+ markAsRead(programField);
+ }
+
+ // Mark the field if it is being written to.
+ if (writing)
+ {
+ markAsWritten(programField);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void markAsRead(Field field)
+ {
+ FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
+ if (info != null)
+ {
+ info.setRead();
+ }
+ }
+
+
+ public static boolean isRead(Field field)
+ {
+ FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
+ return info == null ||
+ info.isRead();
+ }
+
+
+ private static void markAsWritten(Field field)
+ {
+ FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
+ if (info != null)
+ {
+ info.setWritten();
+ }
+ }
+
+
+ public static boolean isWritten(Field field)
+ {
+ FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
+ return info == null ||
+ info.isWritten();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectInstructionChecker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectInstructionChecker.java
new file mode 100644
index 0000000000..5374c4e0c4
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectInstructionChecker.java
@@ -0,0 +1,375 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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;
+import proguard.classfile.visitor.*;
+
+import java.util.*;
+
+/**
+ * This class can tell whether an instruction has any side effects outside of
+ * its method. Return instructions and local field accesses can be included or
+ * not.
+ *
+ * @see ReadWriteFieldMarker
+ * @see StaticInitializerContainingClassMarker
+ * @see NoSideEffectMethodMarker
+ * @see SideEffectMethodMarker
+ * @author Eric Lafortune
+ */
+public class SideEffectInstructionChecker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor,
+ MemberVisitor
+{
+ static final boolean OPTIMIZE_CONSERVATIVELY = System.getProperty("optimize.conservatively") != null;
+
+
+ private final boolean includeReturnInstructions;
+ private final boolean includeLocalFieldAccess;
+
+ // A return value for the visitor methods.
+ private boolean writingField;
+ private Clazz referencingClass;
+ private boolean hasSideEffects;
+
+
+ /**
+ * Creates a new SideEffectInstructionChecker
+ * @param includeReturnInstructions specifies whether return instructions
+ * count as side effects.
+ * @param includeLocalFieldAccess specifies whether reading or writing
+ * local fields counts as side effects.
+ */
+ public SideEffectInstructionChecker(boolean includeReturnInstructions,
+ boolean includeLocalFieldAccess)
+ {
+ this.includeReturnInstructions = includeReturnInstructions;
+ this.includeLocalFieldAccess = includeLocalFieldAccess;
+ }
+
+
+ /**
+ * Returns whether the given instruction has side effects outside of its
+ * method.
+ */
+ public boolean hasSideEffects(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ int offset,
+ Instruction instruction)
+ {
+ hasSideEffects = false;
+
+ instruction.accept(clazz, method, codeAttribute, offset, this);
+
+ return hasSideEffects;
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
+ {
+ byte opcode = simpleInstruction.opcode;
+
+ // Check for instructions that might cause side effects.
+ switch (opcode)
+ {
+ case InstructionConstants.OP_IDIV:
+ case InstructionConstants.OP_LDIV:
+ case InstructionConstants.OP_IREM:
+ case InstructionConstants.OP_LREM:
+ 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_NEWARRAY:
+ case InstructionConstants.OP_ARRAYLENGTH:
+ case InstructionConstants.OP_ANEWARRAY:
+ case InstructionConstants.OP_MULTIANEWARRAY:
+ // These instructions strictly taken may cause a side effect
+ // (ArithmeticException, NullPointerException,
+ // ArrayIndexOutOfBoundsException, NegativeArraySizeException).
+ hasSideEffects = OPTIMIZE_CONSERVATIVELY;
+ break;
+
+ 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_ATHROW :
+ case InstructionConstants.OP_MONITORENTER:
+ case InstructionConstants.OP_MONITOREXIT:
+ // These instructions always cause a side effect.
+ hasSideEffects = true;
+ break;
+
+ case InstructionConstants.OP_IRETURN:
+ case InstructionConstants.OP_LRETURN:
+ case InstructionConstants.OP_FRETURN:
+ case InstructionConstants.OP_DRETURN:
+ case InstructionConstants.OP_ARETURN:
+ case InstructionConstants.OP_RETURN:
+ // These instructions may have a side effect.
+ hasSideEffects = includeReturnInstructions;
+ break;
+ }
+ }
+
+
+ public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
+ {
+ byte opcode = variableInstruction.opcode;
+
+ // Check for instructions that might cause side effects.
+ switch (opcode)
+ {
+ case InstructionConstants.OP_RET:
+ // This instruction may have a side effect.
+ hasSideEffects = includeReturnInstructions;
+ break;
+ }
+ }
+
+
+ public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
+ {
+ byte opcode = constantInstruction.opcode;
+
+ // Check for instructions that might cause side effects.
+ switch (opcode)
+ {
+ case InstructionConstants.OP_GETSTATIC:
+ // Check if accessing the field might cause any side effects.
+ writingField = false;
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ break;
+
+ case InstructionConstants.OP_PUTSTATIC:
+ // Check if accessing the field might cause any side effects.
+ writingField = true;
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ break;
+
+ case InstructionConstants.OP_GETFIELD:
+ if (OPTIMIZE_CONSERVATIVELY)
+ {
+ // These instructions strictly taken may cause a side effect
+ // (NullPointerException).
+ hasSideEffects = true;
+ }
+ else
+ {
+ // Check if the field is write-only or volatile.
+ writingField = false;
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
+ break;
+
+ case InstructionConstants.OP_PUTFIELD:
+ if (OPTIMIZE_CONSERVATIVELY)
+ {
+ // These instructions strictly taken may cause a side effect
+ // (NullPointerException).
+ hasSideEffects = true;
+ }
+ else
+ {
+ // Check if the field is write-only or volatile.
+ writingField = true;
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
+ break;
+
+ case InstructionConstants.OP_INVOKESPECIAL:
+ case InstructionConstants.OP_INVOKESTATIC:
+ // Check if the invoked method is causing any side effects.
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ break;
+
+ case InstructionConstants.OP_INVOKEVIRTUAL:
+ case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
+ if (OPTIMIZE_CONSERVATIVELY)
+ {
+ // These instructions strictly taken may cause a side effect
+ // (NullPointerException).
+ hasSideEffects = true;
+ }
+ else
+ {
+ // Check if the invoked method is causing any side effects.
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ }
+ break;
+
+ case InstructionConstants.OP_ANEWARRAY:
+ case InstructionConstants.OP_CHECKCAST:
+ case InstructionConstants.OP_MULTIANEWARRAY:
+ // This instructions strictly taken may cause a side effect
+ // (ClassCastException, NegativeArraySizeException).
+ hasSideEffects = OPTIMIZE_CONSERVATIVELY;
+ break;
+ }
+ }
+
+
+ public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
+ {
+ byte opcode = branchInstruction.opcode;
+
+ // Check for instructions that might cause side effects.
+ switch (opcode)
+ {
+ case InstructionConstants.OP_JSR:
+ case InstructionConstants.OP_JSR_W:
+ hasSideEffects = includeReturnInstructions;
+ break;
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // We'll have to assume invoking an unknown method has side effects.
+ hasSideEffects = true;
+ }
+
+
+ public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
+ {
+ // Pass the referencing class.
+ referencingClass = clazz;
+
+ // We'll have to assume accessing an unknown field has side effects.
+ hasSideEffects = true;
+
+ // Check the referenced field, if known.
+ fieldrefConstant.referencedMemberAccept(this);
+ }
+
+
+ public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ // Pass the referencing class.
+ referencingClass = clazz;
+
+ // We'll have to assume invoking an unknown method has side effects.
+ hasSideEffects = true;
+
+ // Check the referenced method, if known.
+ refConstant.referencedMemberAccept(this);
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ hasSideEffects =
+ (includeLocalFieldAccess || !programClass.equals(referencingClass)) &&
+ ((writingField && ReadWriteFieldMarker.isRead(programField)) ||
+ (programField.getAccessFlags() & ClassConstants.ACC_VOLATILE) != 0 ||
+ mayHaveSideEffects(referencingClass, programClass));
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ // Note that side effects already include synchronization of some
+ // implementation of the method.
+ hasSideEffects =
+ !NoSideEffectMethodMarker.hasNoSideEffects(programMethod) &&
+ (SideEffectMethodMarker.hasSideEffects(programMethod) ||
+ mayHaveSideEffects(referencingClass, programClass));
+ }
+
+
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
+ {
+ hasSideEffects = true;
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ hasSideEffects =
+ !NoSideEffectMethodMarker.hasNoSideEffects(libraryMethod);
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Returns whether a field reference or method invocation from the
+ * referencing class to the referenced class might have any side
+ * effects.
+ */
+ private boolean mayHaveSideEffects(Clazz referencingClass, Clazz referencedClass)
+ {
+ return
+ !referencedClass.equals(referencingClass) &&
+ !initializedSuperClasses(referencingClass).containsAll(initializedSuperClasses(referencedClass));
+ }
+
+
+ /**
+ * Returns the set of superclasses and interfaces that are initialized.
+ */
+ private Set initializedSuperClasses(Clazz clazz)
+ {
+ Set set = new HashSet();
+
+ // Visit all superclasses and interfaces, collecting the ones that have
+ // static initializers.
+ clazz.hierarchyAccept(true, true, true, false,
+ new StaticInitializerContainingClassFilter(
+ new NamedMethodVisitor(ClassConstants.METHOD_NAME_CLINIT,
+ ClassConstants.METHOD_TYPE_CLINIT,
+ new SideEffectMethodFilter(
+ new MemberToClassVisitor(
+ new ClassCollector(set))))));
+
+ return set;
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodFilter.java
new file mode 100644
index 0000000000..2e38245378
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodFilter.java
@@ -0,0 +1,73 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.MemberVisitor;
+
+/**
+ * This MemberVisitor delegates all its method calls to another MemberVisitor,
+ * but only for Method objects that are marked as having side effects.
+ *
+ * @see SideEffectMethodMarker
+ *
+ * @author Eric Lafortune
+ */
+public class SideEffectMethodFilter
+implements MemberVisitor
+{
+ private final MemberVisitor memberVisitor;
+
+
+ /**
+ * Creates a new SideEffectMethodFilter.
+ * @param memberVisitor the member visitor to which the visiting will be
+ * delegated.
+ */
+ public SideEffectMethodFilter(MemberVisitor memberVisitor)
+ {
+ this.memberVisitor = memberVisitor;
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField) {}
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) {}
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if (SideEffectMethodMarker.hasSideEffects(programMethod))
+ {
+ memberVisitor.visitProgramMethod(programClass, programMethod);
+ }
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ if (SideEffectMethodMarker.hasSideEffects(libraryMethod))
+ {
+ memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
+ }
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodMarker.java
new file mode 100644
index 0000000000..091f9e22c0
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodMarker.java
@@ -0,0 +1,181 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+
+/**
+ * This ClassPoolVisitor marks all methods that have side effects.
+ *
+ * @see ReadWriteFieldMarker
+ * @see NoSideEffectMethodMarker
+ * @author Eric Lafortune
+ */
+public class SideEffectMethodMarker
+extends SimplifiedVisitor
+implements ClassPoolVisitor,
+ ClassVisitor,
+ MemberVisitor,
+ AttributeVisitor
+{
+ // Reusable objects for checking whether instructions have side effects.
+ private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(false, true);
+ private final SideEffectInstructionChecker initializerSideEffectInstructionChecker = new SideEffectInstructionChecker(false, false);
+
+ // Parameters and values for visitor methods.
+ private int newSideEffectCount;
+ private boolean hasSideEffects;
+
+
+ // Implementations for ClassPoolVisitor.
+
+ public void visitClassPool(ClassPool classPool)
+ {
+ // Go over all classes and their methods, marking if they have side
+ // effects, until no new cases can be found.
+ do
+ {
+ newSideEffectCount = 0;
+
+ // Go over all classes and their methods once.
+ classPool.classesAccept(this);
+ }
+ while (newSideEffectCount > 0);
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Go over all methods.
+ programClass.methodsAccept(this);
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if (!hasSideEffects(programMethod) &&
+ !NoSideEffectMethodMarker.hasNoSideEffects(programMethod))
+ {
+ // Initialize the return value.
+ hasSideEffects =
+ (programMethod.getAccessFlags() &
+ (ClassConstants.ACC_NATIVE |
+ ClassConstants.ACC_SYNCHRONIZED)) != 0;
+
+ // Look further if the method hasn't been marked yet.
+ if (!hasSideEffects)
+ {
+ // Investigate the actual code.
+ programMethod.attributesAccept(programClass, this);
+ }
+
+ // Mark the method depending on the return value.
+ if (hasSideEffects)
+ {
+ markSideEffects(programMethod);
+
+ newSideEffectCount++;
+ }
+ }
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ // Remember whether the code has any side effects.
+ hasSideEffects = hasSideEffects(clazz, method, codeAttribute);
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Returns whether the given code has any side effects.
+ */
+ private boolean hasSideEffects(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute)
+ {
+ byte[] code = codeAttribute.code;
+ int length = codeAttribute.u4codeLength;
+
+ SideEffectInstructionChecker checker =
+ method.getName(clazz).equals(ClassConstants.METHOD_NAME_CLINIT) ?
+ initializerSideEffectInstructionChecker :
+ sideEffectInstructionChecker;
+
+ // Go over all instructions.
+ int offset = 0;
+ do
+ {
+ // Get the current instruction.
+ Instruction instruction = InstructionFactory.create(code, offset);
+
+ // Check if it may be throwing exceptions.
+ if (checker.hasSideEffects(clazz,
+ method,
+ codeAttribute,
+ offset,
+ instruction))
+ {
+ return true;
+ }
+
+ // Go to the next instruction.
+ offset += instruction.length(offset);
+ }
+ while (offset < length);
+
+ return false;
+ }
+
+
+ private static void markSideEffects(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setSideEffects();
+ }
+ }
+
+
+ public static boolean hasSideEffects(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null ||
+ info.hasSideEffects();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumFilter.java
new file mode 100644
index 0000000000..9d05a9f2e7
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumFilter.java
@@ -0,0 +1,96 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This ClassVisitor delegates its visits to one of two other given
+ * ClassVisitor instances, depending on whether the classes are marked
+ * as simple enums or not.
+ *
+ * @see SimpleEnumMarker
+ *
+ * @author Eric Lafortune
+ */
+public class SimpleEnumFilter
+implements ClassVisitor
+{
+ private final ClassVisitor simpleEnumClassVisitor;
+ private final ClassVisitor otherClassVisitor;
+
+
+ /**
+ * Creates a new SimpleEnumClassFilter.
+ *
+ * @param simpleEnumClassVisitor the class visitor to which visits to
+ * classes that are marked to be simpleEnum
+ * will be delegated.
+ */
+ public SimpleEnumFilter(ClassVisitor simpleEnumClassVisitor)
+ {
+ this(simpleEnumClassVisitor, null);
+ }
+
+
+ /**
+ * Creates a new SimpleEnumClassFilter.
+ *
+ * @param simpleEnumClassVisitor the class visitor to which visits to
+ * classes that are marked as simple enums
+ * will be delegated.
+ * @param otherClassVisitor the class visitor to which visits to
+ * classes that are not marked as simple
+ * enums will be delegated.
+ */
+ public SimpleEnumFilter(ClassVisitor simpleEnumClassVisitor,
+ ClassVisitor otherClassVisitor)
+ {
+ this.simpleEnumClassVisitor = simpleEnumClassVisitor;
+ this.otherClassVisitor = otherClassVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Is the class marked as a simple enum?
+ ClassVisitor classVisitor = SimpleEnumMarker.isSimpleEnum(programClass) ?
+ simpleEnumClassVisitor : otherClassVisitor;
+
+ if (classVisitor != null)
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ // A library class can't be marked as a simple enum.
+ if (otherClassVisitor != null)
+ {
+ otherClassVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumMarker.java
new file mode 100644
index 0000000000..6877f37aeb
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumMarker.java
@@ -0,0 +1,75 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This ClassVisitor marks all program classes that it visits with a given
+ * flag for simple enums.
+ *
+ * @author Eric Lafortune
+ */
+public class SimpleEnumMarker
+implements ClassVisitor
+{
+ private final boolean simple;
+
+
+ /**
+ * Creates a new SimpleEnumMarker that marks visited classes with the
+ * given flag.
+ */
+ public SimpleEnumMarker(boolean simple)
+ {
+ this.simple = simple;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ setSimpleEnum(programClass);
+ }
+
+
+ // Small utility methods.
+
+ private void setSimpleEnum(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setSimpleEnum(simple);
+ }
+ }
+
+
+ public static boolean isSimpleEnum(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info != null && info.isSimpleEnum();
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java
new file mode 100644
index 0000000000..0000b7d765
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java
@@ -0,0 +1,62 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+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 instantiated.
+ *
+ * @author Eric Lafortune
+ */
+public class StaticInitializerContainingClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ public StaticInitializerContainingClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (StaticInitializerContainingClassMarker.containsStaticInitializer(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (StaticInitializerContainingClassMarker.containsStaticInitializer(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java
new file mode 100644
index 0000000000..49fb5432d1
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java
@@ -0,0 +1,65 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This ClassVisitor marks all classes that contain static initializers.
+ *
+ * @author Eric Lafortune
+ */
+public class StaticInitializerContainingClassMarker
+extends SimplifiedVisitor
+implements ClassVisitor
+{
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ if (clazz.findMethod(ClassConstants.METHOD_NAME_CLINIT,
+ ClassConstants.METHOD_TYPE_CLINIT) != null)
+ {
+ setStaticInitializer(clazz);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void setStaticInitializer(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setContainsStaticInitializer();
+ }
+ }
+
+
+ public static boolean containsStaticInitializer(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.containsStaticInitializer();
+ }
+} \ No newline at end of file
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SuperInvocationMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SuperInvocationMarker.java
new file mode 100644
index 0000000000..63e6225504
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SuperInvocationMarker.java
@@ -0,0 +1,93 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.CodeAttribute;
+import proguard.classfile.constant.RefConstant;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This InstructionVisitor marks all methods that invoke super methods (other
+ * than initializers) from the instructions that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class SuperInvocationMarker
+extends SimplifiedVisitor
+implements InstructionVisitor,
+ ConstantVisitor
+{
+ private boolean invokesSuperMethods;
+
+
+ // 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)
+ {
+ if (constantInstruction.opcode == InstructionConstants.OP_INVOKESPECIAL)
+ {
+ invokesSuperMethods = false;
+
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+
+ if (invokesSuperMethods)
+ {
+ setInvokesSuperMethods(method);
+ }
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ invokesSuperMethods =
+ !clazz.equals(refConstant.referencedClass) &&
+ !refConstant.getName(clazz).equals(ClassConstants.METHOD_NAME_INIT);
+ }
+
+
+ // Small utility methods.
+
+ private static void setInvokesSuperMethods(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ if (info != null)
+ {
+ info.setInvokesSuperMethods();
+ }
+ }
+
+
+ public static boolean invokesSuperMethods(Method method)
+ {
+ MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
+ return info == null || info.invokesSuperMethods();
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/VariableUsageMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/VariableUsageMarker.java
new file mode 100644
index 0000000000..ba31ac4875
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/VariableUsageMarker.java
@@ -0,0 +1,96 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+
+import java.util.Arrays;
+
+/**
+ * This AttributeVisitor marks the local variables that are used in the code
+ * attributes that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class VariableUsageMarker
+extends SimplifiedVisitor
+implements AttributeVisitor,
+ InstructionVisitor
+{
+ private boolean[] variableUsed = new boolean[ClassConstants.TYPICAL_VARIABLES_SIZE];
+
+
+ /**
+ * Returns whether the given variable has been marked as being used.
+ */
+ public boolean isVariableUsed(int variableIndex)
+ {
+ return variableUsed[variableIndex];
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ int maxLocals = codeAttribute.u2maxLocals;
+
+ // Try to reuse the previous array.
+ if (variableUsed.length < maxLocals)
+ {
+ // Create a new array.
+ variableUsed = new boolean[maxLocals];
+ }
+ else
+ {
+ // Reset the array.
+ Arrays.fill(variableUsed, 0, maxLocals, false);
+ }
+
+ codeAttribute.instructionsAccept(clazz, method, this);
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
+ {
+ // Mark the variable.
+ variableUsed[variableInstruction.variableIndex] = true;
+
+ // Account for Category 2 instructions, which take up two entries.
+ if (variableInstruction.isCategory2())
+ {
+ variableUsed[variableInstruction.variableIndex + 1] = true;
+ }
+ }
+}
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/package.html b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/package.html
new file mode 100644
index 0000000000..d16486e863
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/package.html
@@ -0,0 +1,4 @@
+<body>
+This package contains classes to collect additional information about classes
+and class members, which can then be used for optimization.
+</body>