summaryrefslogtreecommitdiffstats
path: root/src/main/com/tonicsystems/jarjar/KeepProcessor.java
diff options
context:
space:
mode:
authorMarcin Kosiba <mkosiba@google.com>2014-06-17 09:56:21 +0100
committerMarcin Kosiba <mkosiba@google.com>2014-06-20 11:55:22 +0100
commitab61347a2cb3254688c42c993278cefd43e5d99d (patch)
treede9bb96cdb2bc7a710c8222edcdd3e3a33e7086e /src/main/com/tonicsystems/jarjar/KeepProcessor.java
parentfe7bad2c42f39829e8d4fd990ac1da776bcaeee2 (diff)
downloadandroid_external_jarjar-ab61347a2cb3254688c42c993278cefd43e5d99d.tar.gz
android_external_jarjar-ab61347a2cb3254688c42c993278cefd43e5d99d.tar.bz2
android_external_jarjar-ab61347a2cb3254688c42c993278cefd43e5d99d.zip
Add JarJar 1.4
Change-Id: Iadcec27828223189f579b70d050cd7246cb488c2
Diffstat (limited to 'src/main/com/tonicsystems/jarjar/KeepProcessor.java')
-rw-r--r--src/main/com/tonicsystems/jarjar/KeepProcessor.java112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/main/com/tonicsystems/jarjar/KeepProcessor.java b/src/main/com/tonicsystems/jarjar/KeepProcessor.java
new file mode 100644
index 0000000..0176b84
--- /dev/null
+++ b/src/main/com/tonicsystems/jarjar/KeepProcessor.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.tonicsystems.jarjar;
+
+import com.tonicsystems.jarjar.util.*;
+import java.io.*;
+import java.util.*;
+import org.objectweb.asm.*;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.*;
+
+// TODO: this can probably be refactored into JarClassVisitor, etc.
+class KeepProcessor extends Remapper implements JarProcessor
+{
+ private final ClassVisitor cv = new RemappingClassAdapter(new EmptyClassVisitor(), this);
+ private final List<Wildcard> wildcards;
+ private final List<String> roots = new ArrayList<String>();
+ private final Map<String, Set<String>> depend = new HashMap<String, Set<String>>();
+
+ public KeepProcessor(List<Keep> patterns) {
+ wildcards = PatternElement.createWildcards(patterns);
+ }
+
+ public boolean isEnabled() {
+ return !wildcards.isEmpty();
+ }
+
+ public Set<String> getExcludes() {
+ Set<String> closure = new HashSet<String>();
+ closureHelper(closure, roots);
+ Set<String> removable = new HashSet<String>(depend.keySet());
+ removable.removeAll(closure);
+ return removable;
+ }
+
+ private void closureHelper(Set<String> closure, Collection<String> process) {
+ if (process == null)
+ return;
+ for (String name : process) {
+ if (closure.add(name))
+ closureHelper(closure, depend.get(name));
+ }
+ }
+
+ private Set<String> curSet;
+ private byte[] buf = new byte[0x2000];
+
+ public boolean process(EntryStruct struct) throws IOException {
+ try {
+ if (struct.name.endsWith(".class")) {
+ String name = struct.name.substring(0, struct.name.length() - 6);
+ for (Wildcard wildcard : wildcards)
+ if (wildcard.matches(name))
+ roots.add(name);
+ depend.put(name, curSet = new HashSet<String>());
+ new ClassReader(new ByteArrayInputStream(struct.data)).accept(cv,
+ ClassReader.EXPAND_FRAMES);
+ curSet.remove(name);
+ }
+ } catch (Exception e) {
+ System.err.println("Error reading " + struct.name + ": " + e.getMessage());
+ }
+ return true;
+ }
+
+ public String map(String key) {
+ if (key.startsWith("java/") || key.startsWith("javax/"))
+ return null;
+ curSet.add(key);
+ return null;
+ }
+
+ public Object mapValue(Object value) {
+ if (value instanceof String) {
+ String s = (String)value;
+ if (PackageRemapper.isArrayForName(s)) {
+ mapDesc(s.replace('.', '/'));
+ } else if (isForName(s)) {
+ map(s.replace('.', '/'));
+ }
+ return value;
+ } else {
+ return super.mapValue(value);
+ }
+ }
+
+ // TODO: use this for package remapping too?
+ private static boolean isForName(String value) {
+ if (value.equals(""))
+ return false;
+ for (int i = 0, len = value.length(); i < len; i++) {
+ char c = value.charAt(i);
+ if (c != '.' && !Character.isJavaIdentifierPart(c))
+ return false;
+ }
+ return true;
+ }
+}