aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/java/proguard/proguard5.3.3/src/proguard/shrink/ShortestUsageMarker.java
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/java/proguard/proguard5.3.3/src/proguard/shrink/ShortestUsageMarker.java')
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/shrink/ShortestUsageMarker.java277
1 files changed, 277 insertions, 0 deletions
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/shrink/ShortestUsageMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/shrink/ShortestUsageMarker.java
new file mode 100644
index 0000000000..d3da17cdeb
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/shrink/ShortestUsageMarker.java
@@ -0,0 +1,277 @@
+/*
+ * 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.shrink;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.*;
+
+
+/**
+ * This ClassVisitor and MemberVisitor recursively marks all classes
+ * and class elements that are being used. For each element, it finds the
+ * shortest chain of dependencies.
+ *
+ * @see ClassShrinker
+ *
+ * @author Eric Lafortune
+ */
+public class ShortestUsageMarker extends UsageMarker
+{
+ private static final ShortestUsageMark INITIAL_MARK =
+ new ShortestUsageMark("is kept by a directive in the configuration.\n\n");
+
+
+ // A field acting as a parameter to the visitor methods.
+ private ShortestUsageMark currentUsageMark = INITIAL_MARK;
+
+ // A utility object to check for recursive causes.
+ private final MyRecursiveCauseChecker recursiveCauseChecker = new MyRecursiveCauseChecker();
+
+
+ // Overriding implementations for UsageMarker.
+
+ protected void markProgramClassBody(ProgramClass programClass)
+ {
+ ShortestUsageMark previousUsageMark = currentUsageMark;
+
+ currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programClass),
+ "is extended by ",
+ 10000,
+ programClass);
+
+ super.markProgramClassBody(programClass);
+
+ currentUsageMark = previousUsageMark;
+ }
+
+
+ protected void markProgramFieldBody(ProgramClass programClass, ProgramField programField)
+ {
+ ShortestUsageMark previousUsageMark = currentUsageMark;
+
+ currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programField),
+ "is referenced by ",
+ 1,
+ programClass,
+ programField);
+
+ super.markProgramFieldBody(programClass, programField);
+
+ currentUsageMark = previousUsageMark;
+ }
+
+
+ protected void markProgramMethodBody(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ ShortestUsageMark previousUsageMark = currentUsageMark;
+
+ currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programMethod),
+ "is invoked by ",
+ 1,
+ programClass,
+ programMethod);
+
+ super.markProgramMethodBody(programClass, programMethod);
+
+ currentUsageMark = previousUsageMark;
+ }
+
+
+ protected void markMethodHierarchy(Clazz clazz, Method method)
+ {
+ ShortestUsageMark previousUsageMark = currentUsageMark;
+
+ currentUsageMark = new ShortestUsageMark(getShortestUsageMark(method),
+ "implements ",
+ 100,
+ clazz,
+ method);
+
+ super.markMethodHierarchy(clazz, method);
+
+ currentUsageMark = previousUsageMark;
+ }
+
+
+ // Small utility methods.
+
+ protected void markAsUsed(VisitorAccepter visitorAccepter)
+ {
+ Object visitorInfo = visitorAccepter.getVisitorInfo();
+
+ ShortestUsageMark shortestUsageMark =
+ visitorInfo != null &&
+ visitorInfo instanceof ShortestUsageMark &&
+ !((ShortestUsageMark)visitorInfo).isCertain() &&
+ !currentUsageMark.isShorter((ShortestUsageMark)visitorInfo) ?
+ new ShortestUsageMark((ShortestUsageMark)visitorInfo, true):
+ currentUsageMark;
+
+ visitorAccepter.setVisitorInfo(shortestUsageMark);
+ }
+
+
+ protected boolean shouldBeMarkedAsUsed(VisitorAccepter visitorAccepter)
+ {
+ Object visitorInfo = visitorAccepter.getVisitorInfo();
+
+ return //!(visitorAccepter instanceof Clazz &&
+ // isCausedBy(currentUsageMark, (Clazz)visitorAccepter)) &&
+ (visitorInfo == null ||
+ !(visitorInfo instanceof ShortestUsageMark) ||
+ !((ShortestUsageMark)visitorInfo).isCertain() ||
+ currentUsageMark.isShorter((ShortestUsageMark)visitorInfo));
+ }
+
+
+ protected boolean isUsed(VisitorAccepter visitorAccepter)
+ {
+ Object visitorInfo = visitorAccepter.getVisitorInfo();
+
+ return visitorInfo != null &&
+ visitorInfo instanceof ShortestUsageMark &&
+ ((ShortestUsageMark)visitorInfo).isCertain();
+ }
+
+
+ protected void markAsPossiblyUsed(VisitorAccepter visitorAccepter)
+ {
+ visitorAccepter.setVisitorInfo(new ShortestUsageMark(currentUsageMark, false));
+ }
+
+
+ protected boolean shouldBeMarkedAsPossiblyUsed(VisitorAccepter visitorAccepter)
+ {
+ Object visitorInfo = visitorAccepter.getVisitorInfo();
+
+ return visitorInfo == null ||
+ !(visitorInfo instanceof ShortestUsageMark) ||
+ (!((ShortestUsageMark)visitorInfo).isCertain() &&
+ currentUsageMark.isShorter((ShortestUsageMark)visitorInfo));
+ }
+
+
+ protected boolean isPossiblyUsed(VisitorAccepter visitorAccepter)
+ {
+ Object visitorInfo = visitorAccepter.getVisitorInfo();
+
+ return visitorInfo != null &&
+ visitorInfo instanceof ShortestUsageMark &&
+ !((ShortestUsageMark)visitorInfo).isCertain();
+ }
+
+
+ protected ShortestUsageMark getShortestUsageMark(VisitorAccepter visitorAccepter)
+ {
+ Object visitorInfo = visitorAccepter.getVisitorInfo();
+
+ return (ShortestUsageMark)visitorInfo;
+ }
+
+
+ // Small utility methods.
+
+ private boolean isCausedBy(ShortestUsageMark shortestUsageMark,
+ Clazz clazz)
+ {
+ return recursiveCauseChecker.check(shortestUsageMark, clazz);
+ }
+
+
+ private class MyRecursiveCauseChecker implements ClassVisitor, MemberVisitor
+ {
+ private Clazz checkClass;
+ private boolean isRecursing;
+
+
+ public boolean check(ShortestUsageMark shortestUsageMark,
+ Clazz clazz)
+ {
+ checkClass = clazz;
+ isRecursing = false;
+
+ shortestUsageMark.acceptClassVisitor(this);
+ shortestUsageMark.acceptMemberVisitor(this);
+
+ return isRecursing;
+ }
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ checkCause(programClass);
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ checkCause(libraryClass);
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ checkCause(programField);
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ checkCause(programMethod);
+ }
+
+
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
+ {
+ checkCause(libraryField);
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ checkCause(libraryMethod);
+ }
+
+
+ // Small utility methods.
+
+ private void checkCause(VisitorAccepter visitorAccepter)
+ {
+ if (ShortestUsageMarker.this.isUsed(visitorAccepter))
+ {
+ ShortestUsageMark shortestUsageMark = ShortestUsageMarker.this.getShortestUsageMark(visitorAccepter);
+
+ // Check the class of this mark, if any
+ isRecursing = shortestUsageMark.isCausedBy(checkClass);
+
+ // Check the causing class or method, if still necessary.
+ if (!isRecursing)
+ {
+ shortestUsageMark.acceptClassVisitor(this);
+ shortestUsageMark.acceptMemberVisitor(this);
+ }
+ }
+ }
+ }
+}