Add markers to proguard map output.
The following markers are added to the end of the Proguard-map as a comment:
compiler, compiler_version, compiler_hash, min_api.
Bug: 70040153
Change-Id: I9b3e5befc9b64a55e42f7161d4d29b2397f26183
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 901c490..525645a 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -437,9 +437,11 @@
namingLens,
options.lineNumberOptimization == LineNumberOptimization.IDENTITY_MAPPING);
timing.end();
- proguardMapSupplier = ProguardMapSupplier.fromClassNameMapper(classNameMapper);
+ proguardMapSupplier =
+ ProguardMapSupplier.fromClassNameMapper(classNameMapper, options.minApiLevel);
} else {
- proguardMapSupplier = ProguardMapSupplier.fromNamingLens(namingLens, application);
+ proguardMapSupplier =
+ ProguardMapSupplier.fromNamingLens(namingLens, application, options.minApiLevel);
}
// If a method filter is present don't produce output since the application is likely partial.
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 3863c14..495738d 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapSupplier.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapSupplier.java
@@ -3,42 +3,80 @@
// BSD-style license that can be found in the LICENSE file.
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.VersionProperties;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
public class ProguardMapSupplier {
- public static ProguardMapSupplier fromClassNameMapper(ClassNameMapper classNameMapper) {
- return new ProguardMapSupplier(classNameMapper);
+
+ public static final String MARKER_KEY_COMPILER = "compiler";
+ public static final String MARKER_VALUE_COMPILER = "R8";
+ public static final String MARKER_KEY_COMPILER_VERSION = "compiler_version";
+ public static final String MARKER_KEY_COMPILER_HASH = "compiler_hash";
+ public static final String MARKER_KEY_MIN_API = "min_api";
+
+ public static ProguardMapSupplier fromClassNameMapper(
+ ClassNameMapper classNameMapper, int minApiLevel) {
+ return new ProguardMapSupplier(classNameMapper, minApiLevel);
}
public static ProguardMapSupplier fromNamingLens(
- NamingLens namingLens, DexApplication dexApplication) {
- return new ProguardMapSupplier(namingLens, dexApplication);
+ NamingLens namingLens, DexApplication dexApplication, int minApiLevel) {
+ return new ProguardMapSupplier(namingLens, dexApplication, minApiLevel);
}
- private ProguardMapSupplier(ClassNameMapper classNameMapper) {
+ private ProguardMapSupplier(ClassNameMapper classNameMapper, int minApiLevel) {
this.useClassNameMapper = true;
this.classNameMapper = classNameMapper;
this.namingLens = null;
this.application = null;
+ this.minApiLevel = minApiLevel;
}
- private ProguardMapSupplier(NamingLens namingLens, DexApplication dexApplication) {
+ private ProguardMapSupplier(
+ NamingLens namingLens, DexApplication dexApplication, int minApiLevel) {
this.useClassNameMapper = false;
this.classNameMapper = null;
this.namingLens = namingLens;
this.application = dexApplication;
+ this.minApiLevel = minApiLevel;
}
private final boolean useClassNameMapper;
private final ClassNameMapper classNameMapper;
private final NamingLens namingLens;
private final DexApplication application;
+ private final int minApiLevel;
public String get() {
+ String shaLine = "";
+ if (Version.isDev()) {
+ shaLine = "# " + MARKER_KEY_COMPILER_HASH + ": " + VersionProperties.INSTANCE.getSha() + "\n";
+ }
+ return "# "
+ + MARKER_KEY_COMPILER
+ + ": "
+ + MARKER_VALUE_COMPILER
+ + "\n"
+ + "# "
+ + MARKER_KEY_COMPILER_VERSION
+ + ": "
+ + Version.LABEL
+ + "\n"
+ + "# "
+ + MARKER_KEY_MIN_API
+ + ": "
+ + minApiLevel
+ + "\n"
+ + shaLine
+ + getBody();
+ }
+
+ private String getBody() {
if (useClassNameMapper) {
assert classNameMapper != null;
return classNameMapper.toString();
diff --git a/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java b/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
new file mode 100644
index 0000000..8e8ca36
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
@@ -0,0 +1,83 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import com.android.tools.r8.naming.ProguardMapSupplier;
+import com.android.tools.r8.utils.VersionProperties;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Test;
+
+public class ProguardMapMarkerTest {
+ @Test
+ public void proguardMapMarkerTest24() throws CompilationFailedException {
+ proguardMapMarkerTest(24);
+ }
+
+ @Test
+ public void proguardMapMarkerTest26() throws CompilationFailedException {
+ proguardMapMarkerTest(26);
+ }
+
+ private void proguardMapMarkerTest(int minApiLevel) throws CompilationFailedException {
+ String classFile = ToolHelper.EXAMPLES_BUILD_DIR + "classes/trivial/Trivial.class";
+ R8.run(
+ R8Command.builder()
+ .addProgramFiles(Paths.get(classFile))
+ .setProgramConsumer(
+ new DexIndexedConsumer() {
+ @Override
+ public void accept(
+ int fileIndex,
+ byte[] data,
+ Set<String> descriptors,
+ DiagnosticsHandler handler) {}
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {}
+ })
+ .addLibraryFiles(ToolHelper.getAndroidJar(minApiLevel))
+ .setMinApiLevel(minApiLevel)
+ .setProguardMapConsumer(
+ (proguardMap, handler) -> {
+ verifyMarkers(proguardMap, minApiLevel);
+ })
+ .build());
+ }
+
+ private static void verifyMarkers(String proguardMap, int minApiLevel) {
+ String[] lines = proguardMap.split("\n");
+ Set<String> keysFound = new HashSet<>();
+ for (String line : lines) {
+ if (!line.startsWith("#")) {
+ continue;
+ }
+ String comment = line.substring(1).trim();
+ int colonIndex = comment.indexOf(":");
+ if (colonIndex < 0) {
+ continue;
+ }
+ String key = comment.substring(0, colonIndex).trim();
+ String value = comment.substring(colonIndex + 1).trim();
+ if (key.equals(ProguardMapSupplier.MARKER_KEY_COMPILER)) {
+ assertEquals(ProguardMapSupplier.MARKER_VALUE_COMPILER, value);
+ } else if (key.equals(ProguardMapSupplier.MARKER_KEY_COMPILER_VERSION)) {
+ assertEquals(Version.LABEL, value);
+ } else if (key.equals(ProguardMapSupplier.MARKER_KEY_MIN_API)) {
+ assertEquals(minApiLevel, Integer.parseInt(value));
+ } else if (key.equals(ProguardMapSupplier.MARKER_KEY_COMPILER_HASH)) {
+ assertEquals(VersionProperties.INSTANCE.getSha(), value);
+ } else {
+ continue;
+ }
+ assertFalse(keysFound.contains(key));
+ keysFound.add(key);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/shaking/TreeShakingSpecificTest.java b/src/test/java/com/android/tools/r8/shaking/TreeShakingSpecificTest.java
index f8a3cc9..fdb35fb 100644
--- a/src/test/java/com/android/tools/r8/shaking/TreeShakingSpecificTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/TreeShakingSpecificTest.java
@@ -21,6 +21,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
@@ -96,8 +97,11 @@
ToolHelper.runR8(builder.build(), options -> options.inlineAccessors = false);
Path outputmapping = out.resolve("mapping.txt");
- String actualMapping;
- actualMapping = new String(Files.readAllBytes(outputmapping), StandardCharsets.UTF_8);
+ // Remove comments.
+ String actualMapping =
+ Stream.of(new String(Files.readAllBytes(outputmapping), StandardCharsets.UTF_8).split("\n"))
+ .filter(line -> !line.startsWith("#"))
+ .collect(Collectors.joining("\n"));
String refMapping = new String(Files.readAllBytes(
Paths.get(EXAMPLES_DIR, "shaking1", "print-mapping.ref")), StandardCharsets.UTF_8);
Assert.assertEquals(sorted(refMapping), sorted(actualMapping));