Cleanup Proguard map supplier
Change-Id: Ibac49a3fcd5a22f05bd96d712a284bb3dcbad180
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 3c132e0..ea07dfc 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -250,7 +250,7 @@
GraphLense.getIdentityLense(),
NamingLens.getIdentityLens(),
null)
- .write(options.getClassFileConsumer(), executor);
+ .write(options.getClassFileConsumer());
} else {
NamingLens namingLens;
DexApplication finalApp = app;
diff --git a/src/main/java/com/android/tools/r8/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
index bf55656..7d5b31e 100644
--- a/src/main/java/com/android/tools/r8/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
@@ -37,7 +37,6 @@
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Reporter;
-import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.Sets;
import java.io.File;
@@ -326,7 +325,7 @@
ClassFileConsumer consumer =
new ClassFileConsumer.ArchiveConsumer(
lintFile(compilationApiLevel, minApiLevel, FileUtils.JAR_EXTENSION));
- writer.write(consumer, ThreadUtils.getExecutorService(options));
+ writer.write(consumer);
consumer.finished(options.reporter);
}
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index 50a4a70..cf9684c 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -136,7 +136,7 @@
GraphLense.getIdentityLense(),
PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView),
null)
- .write(options.getClassFileConsumer(), executor);
+ .write(options.getClassFileConsumer());
options.printWarnings();
} catch (ExecutionException e) {
throw unwrapExecutionException(e);
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index b03172f..e82c7eb 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -212,7 +212,7 @@
if (options.isGeneratingClassFiles()) {
new CfApplicationWriter(
application, appView, options, marker, graphLense, namingLens, proguardMapSupplier)
- .write(options.getClassFileConsumer(), executorService);
+ .write(options.getClassFileConsumer());
} else {
new ApplicationWriter(
application,
@@ -789,8 +789,6 @@
namingLens = NamingLens.getIdentityLens();
}
- ProguardMapSupplier proguardMapSupplier;
-
timing.begin("Line number remapping");
// When line number optimization is turned off the identity mapping for line numbers is
// used. We still run the line number optimizer to collect line numbers and inline frame
@@ -798,7 +796,6 @@
ClassNameMapper classNameMapper =
LineNumberOptimizer.run(appView, application, inputApp, namingLens);
timing.end();
- proguardMapSupplier = ProguardMapSupplier.fromClassNameMapper(classNameMapper, options);
// If a method filter is present don't produce output since the application is likely partial.
if (options.hasMethodsFilter()) {
@@ -849,7 +846,7 @@
appView.initClassLens(),
PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView, namingLens),
options,
- proguardMapSupplier);
+ ProguardMapSupplier.create(classNameMapper, options));
options.printWarnings();
} catch (ExecutionException e) {
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 79b4362..8ee86f3 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -38,9 +38,9 @@
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.ObjectToOffsetMapping;
import com.android.tools.r8.graph.ParameterAnnotationsList;
-import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.ProguardMapSupplier;
+import com.android.tools.r8.naming.ProguardMapSupplier.ProguardMapId;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.ExceptionUtils;
@@ -230,17 +230,17 @@
public void write(ExecutorService executorService) throws IOException, ExecutionException {
application.timing.begin("DexApplication.write");
- ProguardMapSupplier.ProguardMapAndId proguardMapAndId = null;
+ ProguardMapId proguardMapId = null;
if (proguardMapSupplier != null && options.proguardMapConsumer != null) {
- proguardMapAndId = proguardMapSupplier.getProguardMapAndId();
+ proguardMapId = proguardMapSupplier.writeProguardMap();
}
// If we do have a map then we're called from R8. In that case we have exactly one marker.
- assert proguardMapAndId == null || (markers != null && markers.size() == 1);
+ assert proguardMapId == null || (markers != null && markers.size() == 1);
if (markers != null && !markers.isEmpty()) {
- if (proguardMapAndId != null) {
- markers.get(0).setPgMapId(proguardMapAndId.id);
+ if (proguardMapId != null) {
+ markers.get(0).setPgMapId(proguardMapId.get());
}
markerStrings = new ArrayList<>(markers.size());
for (Marker marker : markers) {
@@ -338,13 +338,7 @@
// Fail if there are pending errors, e.g., the program consumers may have reported errors.
options.reporter.failIfPendingErrors();
// Supply info to all additional resource consumers.
- supplyAdditionalConsumers(
- application,
- appView,
- graphLense,
- namingLens,
- options,
- proguardMapAndId == null ? null : proguardMapAndId.map);
+ supplyAdditionalConsumers(application, appView, graphLense, namingLens, options);
} finally {
application.timing.end();
}
@@ -355,20 +349,13 @@
AppView<?> appView,
GraphLense graphLense,
NamingLens namingLens,
- InternalOptions options,
- String proguardMapContent) {
+ InternalOptions options) {
if (options.configurationConsumer != null) {
ExceptionUtils.withConsumeResourceHandler(
options.reporter, options.configurationConsumer,
options.getProguardConfiguration().getParsedConfiguration());
ExceptionUtils.withFinishedResourceHandler(options.reporter, options.configurationConsumer);
}
- if (proguardMapContent != null) {
- assert validateProguardMapParses(proguardMapContent);
- ExceptionUtils.withConsumeResourceHandler(
- options.reporter, options.proguardMapConsumer, proguardMapContent);
- ExceptionUtils.withFinishedResourceHandler(options.reporter, options.proguardMapConsumer);
- }
if (options.mainDexListConsumer != null) {
ExceptionUtils.withConsumeResourceHandler(
options.reporter, options.mainDexListConsumer, writeMainDexList(application, namingLens));
@@ -465,16 +452,6 @@
}
}
- private static boolean validateProguardMapParses(String content) {
- try {
- ClassNameMapper.mapperFromString(content);
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- }
- return true;
- }
-
private void insertAttributeAnnotations() {
// Convert inner-class attributes to DEX annotations
for (DexProgramClass clazz : application.classes()) {
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 1112e9c..9f51daa 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -41,7 +41,6 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Optional;
-import java.util.concurrent.ExecutorService;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
@@ -89,22 +88,18 @@
this.proguardMapSupplier = proguardMapSupplier;
}
- public void write(ClassFileConsumer consumer, ExecutorService executor) {
+ public void write(ClassFileConsumer consumer) {
application.timing.begin("CfApplicationWriter.write");
try {
- writeApplication(consumer, executor);
+ writeApplication(consumer);
} finally {
application.timing.end();
}
}
- private void writeApplication(ClassFileConsumer consumer, ExecutorService executor) {
- ProguardMapSupplier.ProguardMapAndId proguardMapAndId = null;
+ private void writeApplication(ClassFileConsumer consumer) {
if (proguardMapSupplier != null && options.proguardMapConsumer != null) {
- proguardMapAndId = proguardMapSupplier.getProguardMapAndId();
- if (proguardMapAndId != null) {
- marker.setPgMapId(proguardMapAndId.id);
- }
+ marker.setPgMapId(proguardMapSupplier.writeProguardMap().get());
}
Optional<String> markerString =
marker.isRelocator() ? Optional.empty() : Optional.of(marker.toString());
@@ -118,12 +113,7 @@
}
}
ApplicationWriter.supplyAdditionalConsumers(
- application,
- appView,
- graphLense,
- namingLens,
- options,
- proguardMapAndId == null ? null : proguardMapAndId.map);
+ application, appView, graphLense, namingLens, options);
}
private void writeClass(
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMapper.java b/src/main/java/com/android/tools/r8/naming/ClassNameMapper.java
index e45b97b..4472714 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMapper.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMapper.java
@@ -178,6 +178,10 @@
return classNameMappings.get(obfuscatedName);
}
+ public boolean isEmpty() {
+ return classNameMappings.isEmpty();
+ }
+
public void write(Writer writer) throws IOException {
// Sort classes by their original name such that the generated Proguard map is deterministic
// (and easy to navigate manually).
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapSupplier.java b/src/main/java/com/android/tools/r8/naming/ProguardMapSupplier.java
index 0cee87f..d5b915b 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapSupplier.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapSupplier.java
@@ -4,15 +4,13 @@
package com.android.tools.r8.naming;
import com.android.tools.r8.Version;
-import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.utils.Box;
+import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.VersionProperties;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Writer;
public class ProguardMapSupplier {
@@ -25,58 +23,56 @@
public static int PG_MAP_ID_LENGTH = 7;
- public static ProguardMapSupplier fromClassNameMapper(
- ClassNameMapper classNameMapper, InternalOptions options) {
- return new ProguardMapSupplier(true, classNameMapper, null, null, options);
- }
-
- public static ProguardMapSupplier fromNamingLens(
- NamingLens namingLens, DexApplication dexApplication, InternalOptions options) {
- return new ProguardMapSupplier(false, null, namingLens, dexApplication, options);
- }
-
- public static class ProguardMapAndId {
- public final String map;
- public final String id;
-
- ProguardMapAndId(String map, String id) {
- assert map != null && id != null;
- this.map = map;
- this.id = id;
+ // Truncated murmur hash of the non-whitespace codepoints of the Proguard map (excluding the
+ // marker).
+ public static class ProguardMapId extends Box<String> {
+ private ProguardMapId(String id) {
+ super(id);
+ assert id != null;
+ assert id.length() == PG_MAP_ID_LENGTH;
}
}
- public ProguardMapSupplier(
- boolean useClassNameMapper,
- ClassNameMapper classNameMapper,
- NamingLens namingLens,
- DexApplication application,
- InternalOptions options) {
- this.useClassNameMapper = useClassNameMapper;
- this.classNameMapper = classNameMapper;
- this.namingLens = namingLens;
- this.application = application;
- this.minApiLevel = options.isGeneratingClassFiles() ? null : options.minApiLevel;
- }
-
- private final boolean useClassNameMapper;
private final ClassNameMapper classNameMapper;
- private final NamingLens namingLens;
- private final DexApplication application;
- private final Integer minApiLevel;
+ private final InternalOptions options;
- public ProguardMapAndId getProguardMapAndId() {
- String body = getBody();
- if (body == null || body.trim().length() == 0) {
- return null;
- }
- // Algorithm:
- // Hash of the non-whitespace codepoints of the input string.
+ public ProguardMapSupplier(ClassNameMapper classNameMapper, InternalOptions options) {
+ this.classNameMapper = classNameMapper;
+ this.options = options;
+ }
+
+ public static ProguardMapSupplier create(
+ ClassNameMapper classNameMapper, InternalOptions options) {
+ return classNameMapper.isEmpty() ? null : new ProguardMapSupplier(classNameMapper, options);
+ }
+
+ public ProguardMapId writeProguardMap() {
+ String body = classNameMapper.toString();
+ assert body != null;
+ assert !body.trim().isEmpty();
+ ProguardMapId id = computeProguardMapId(body);
+ StringBuilder builder = new StringBuilder();
+ writeMarker(builder, id);
+ writeBody(builder, body);
+ String proguardMapContent = builder.toString();
+ assert validateProguardMapParses(proguardMapContent);
+ ExceptionUtils.withConsumeResourceHandler(
+ options.reporter, options.proguardMapConsumer, proguardMapContent);
+ ExceptionUtils.withFinishedResourceHandler(options.reporter, options.proguardMapConsumer);
+ return id;
+ }
+
+ private ProguardMapId computeProguardMapId(String body) {
Hasher hasher = Hashing.murmur3_32().newHasher();
body.codePoints().filter(c -> !Character.isWhitespace(c)).forEach(hasher::putInt);
- String proguardMapId = hasher.hash().toString().substring(0, PG_MAP_ID_LENGTH);
+ return new ProguardMapId(hasher.hash().toString().substring(0, PG_MAP_ID_LENGTH));
+ }
- StringBuilder builder = new StringBuilder();
+ private void writeBody(StringBuilder builder, String body) {
+ builder.append(body);
+ }
+
+ private void writeMarker(StringBuilder builder, ProguardMapId id) {
builder.append(
"# "
+ MARKER_KEY_COMPILER
@@ -88,44 +84,25 @@
+ ": "
+ Version.LABEL
+ "\n");
- if (minApiLevel != null) {
- builder.append("# " + MARKER_KEY_MIN_API + ": " + minApiLevel + "\n");
+ if (options.isGeneratingDex()) {
+ builder.append("# " + MARKER_KEY_MIN_API + ": " + options.minApiLevel + "\n");
}
if (Version.isDevelopmentVersion()) {
builder.append(
"# " + MARKER_KEY_COMPILER_HASH + ": " + VersionProperties.INSTANCE.getSha() + "\n");
}
- builder.append("# " + MARKER_KEY_PG_MAP_ID + ": " + proguardMapId + "\n");
+ builder.append("# " + MARKER_KEY_PG_MAP_ID + ": " + id.get() + "\n");
// Turn off linting of the mapping file in some build systems.
builder.append("# common_typos_disable" + "\n");
- builder.append(body);
-
- return new ProguardMapAndId(builder.toString(), proguardMapId);
}
- private String getBody() {
- if (useClassNameMapper) {
- assert classNameMapper != null;
- return classNameMapper.toString();
+ private static boolean validateProguardMapParses(String content) {
+ try {
+ ClassNameMapper.mapperFromString(content);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
}
- assert namingLens != null && application != null;
- // TODO(herhut): Should writing of the proguard-map file be split like this?
- if (!namingLens.isIdentityLens()) {
- StringBuilder map = new StringBuilder();
- new MinifiedNameMapPrinter(application, namingLens).write(map);
- return map.toString();
- }
- if (application.getProguardMap() != null) {
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- Writer writer = new PrintWriter(bytes);
- try {
- application.getProguardMap().write(writer);
- writer.flush();
- } catch (IOException e) {
- throw new RuntimeException("IOException while creating Proguard-map output: " + e);
- }
- return bytes.toString();
- }
- return null;
+ return true;
}
}
diff --git a/src/main/java/com/android/tools/r8/relocator/Relocator.java b/src/main/java/com/android/tools/r8/relocator/Relocator.java
index 4d6165b..5c3d003 100644
--- a/src/main/java/com/android/tools/r8/relocator/Relocator.java
+++ b/src/main/java/com/android/tools/r8/relocator/Relocator.java
@@ -116,7 +116,7 @@
GraphLense.getIdentityLense(),
PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView),
null)
- .write(command.getConsumer(), executor);
+ .write(command.getConsumer());
options.printWarnings();
} catch (ExecutionException e) {
throw unwrapExecutionException(e);