Add compiler API for retrieving map id
This introduces a new interface com.android.tools.r8.MapConsumer that can be used to retrieve the map id. The MapConsumer interface has a acceptMapId(String) method that will be called by R8 when the map id is known.
Clients can pass an implementation of MapConsumer to R8 using the R8Command.Builder#setProguardMapConsumer(StringConsumer) method.
This change is backwards compatible since clients can continue to pass a com.android.tools.r8.StringConsumer to setProguardMapConsumer.
Bug: b/146403477
Change-Id: I1e56ef98cb57cafc25390c79eaa033dd685000cc
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index ca01413..f5b61ea 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -22,6 +22,7 @@
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions.DesugarState;
import com.android.tools.r8.utils.ListUtils;
+import com.android.tools.r8.utils.MapConsumerUtils;
import com.android.tools.r8.utils.PartitionMapZipContainer;
import com.android.tools.r8.utils.ProgramConsumerUtils;
import com.android.tools.r8.utils.Reporter;
@@ -292,7 +293,7 @@
private BiPredicate<String, Long> dexClassChecksumFilter = (name, checksum) -> true;
private final List<AssertionsConfiguration> assertionsConfiguration = new ArrayList<>();
private final List<Consumer<Inspector>> outputInspections = new ArrayList<>();
- protected StringConsumer proguardMapConsumer = null;
+ protected MapConsumer proguardMapConsumer = null;
protected PartitionMapConsumer partitionMapConsumer = null;
private DumpInputFlags dumpInputFlags = DumpInputFlags.getDefault();
private MapIdProvider mapIdProvider = null;
@@ -372,7 +373,7 @@
/**
* Set an output destination to which proguard-map content should be written.
*
- * <p>This is a short-hand for setting a {@link StringConsumer.FileConsumer} using {@link
+ * <p>This is a short-hand for setting a {@link MapConsumer.FileConsumer} using {@link
* #setProguardMapConsumer}. Note that any subsequent call to this method or {@link
* #setProguardMapConsumer} will override the previous setting.
*
@@ -380,19 +381,22 @@
*/
B setProguardMapOutputPath(Path proguardMapOutput) {
assert proguardMapOutput != null;
- return setProguardMapConsumer(new StringConsumer.FileConsumer(proguardMapOutput));
+ return setProguardMapConsumer(new MapConsumer.FileConsumer(proguardMapOutput));
}
/**
* Set a consumer for receiving the proguard-map content.
*
+ * <p>It is possible to also retrieve the map id by passing an instance of {@link
+ * com.android.tools.r8.MapConsumer}.
+ *
* <p>Note that any subsequent call to this method or {@link #setProguardMapOutputPath} will
* override the previous setting.
*
* @param proguardMapConsumer Consumer to receive the content once produced.
*/
B setProguardMapConsumer(StringConsumer proguardMapConsumer) {
- this.proguardMapConsumer = proguardMapConsumer;
+ this.proguardMapConsumer = MapConsumerUtils.createFromStringConsumer(proguardMapConsumer);
return self();
}
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 74c5484..41db107 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -4,7 +4,7 @@
package com.android.tools.r8;
import static com.android.tools.r8.utils.InternalOptions.DETERMINISTIC_DEBUGGING;
-import static com.android.tools.r8.utils.MapConsumerUtils.wrapExistingMapConsumerIfNotNull;
+import static com.android.tools.r8.utils.MapConsumerUtils.wrapExistingInternalMapConsumerIfNotNull;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.dump.DumpOptions;
@@ -15,8 +15,8 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.metadata.D8BuildMetadata;
-import com.android.tools.r8.naming.MapConsumer;
-import com.android.tools.r8.naming.ProguardMapStringConsumer;
+import com.android.tools.r8.naming.InternalMapConsumer;
+import com.android.tools.r8.naming.InternalMapConsumerImpl;
import com.android.tools.r8.origin.ArchiveEntryOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
@@ -614,7 +614,7 @@
private final boolean enableMainDexListCheck;
private final boolean minimalMainDex;
private final ImmutableList<ProguardConfigurationRule> mainDexKeepRules;
- private final StringConsumer proguardMapConsumer;
+ private final MapConsumer proguardMapConsumer;
private final PartitionMapConsumer partitionMapConsumer;
private final boolean enableMissingLibraryApiModeling;
private final boolean enableRewritingOfArtProfilesIsNopCheck;
@@ -691,7 +691,7 @@
int threadCount,
DumpInputFlags dumpInputFlags,
MapIdProvider mapIdProvider,
- StringConsumer proguardMapConsumer,
+ MapConsumer proguardMapConsumer,
PartitionMapConsumer partitionMapConsumer,
boolean enableMissingLibraryApiModeling,
boolean enableRewritingOfArtProfilesIsNopCheck,
@@ -787,15 +787,15 @@
internal.setSyntheticInfoConsumer(syntheticInfoConsumer);
internal.desugarGraphConsumer = desugarGraphConsumer;
internal.mainDexKeepRules = mainDexKeepRules;
- MapConsumer mapConsumer =
- wrapExistingMapConsumerIfNotNull(
+ InternalMapConsumer mapConsumer =
+ wrapExistingInternalMapConsumerIfNotNull(
internal.mapConsumer, partitionMapConsumer, MapConsumerToPartitionMapConsumer::new);
internal.mapConsumer =
- wrapExistingMapConsumerIfNotNull(
+ wrapExistingInternalMapConsumerIfNotNull(
mapConsumer,
proguardMapConsumer,
nonNullStringConsumer ->
- ProguardMapStringConsumer.builder().setStringConsumer(proguardMapConsumer).build());
+ InternalMapConsumerImpl.builder().setMapConsumer(proguardMapConsumer).build());
internal.lineNumberOptimization =
!internal.debug && proguardMapConsumer != null
? LineNumberOptimization.ON
diff --git a/src/main/java/com/android/tools/r8/MapConsumer.java b/src/main/java/com/android/tools/r8/MapConsumer.java
new file mode 100644
index 0000000..7ebadaa
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/MapConsumer.java
@@ -0,0 +1,61 @@
+// Copyright (c) 2025, 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 com.android.tools.r8.keepanno.annotations.KeepForApi;
+import java.nio.file.Path;
+
+/** Interface for retrieving the generated mapping and its id. */
+@KeepForApi
+public interface MapConsumer extends StringConsumer {
+
+ /**
+ * Called by R8 when the mapping id has been generated. This is always called prior to {@link
+ * #finished(DiagnosticsHandler)}.
+ */
+ default void acceptMapId(String mapId) {}
+
+ @KeepForApi
+ class FileConsumer extends StringConsumer.FileConsumer implements MapConsumer {
+
+ private final MapConsumer consumer;
+
+ public FileConsumer(Path outputPath) {
+ this(outputPath, null);
+ }
+
+ public FileConsumer(Path outputPath, MapConsumer consumer) {
+ super(outputPath, consumer);
+ this.consumer = consumer;
+ }
+
+ @Override
+ public void acceptMapId(String mapId) {
+ if (consumer != null) {
+ consumer.acceptMapId(mapId);
+ }
+ }
+ }
+
+ @KeepForApi
+ class ForwardingConsumer extends StringConsumer.ForwardingConsumer implements MapConsumer {
+
+ private final MapConsumer consumer;
+
+ /**
+ * @param consumer Consumer to forward to, if null, nothing will be forwarded.
+ */
+ public ForwardingConsumer(MapConsumer consumer) {
+ super(consumer);
+ this.consumer = consumer;
+ }
+
+ @Override
+ public void acceptMapId(String mapId) {
+ if (consumer != null) {
+ consumer.acceptMapId(mapId);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/MapConsumerToPartitionMapConsumer.java b/src/main/java/com/android/tools/r8/MapConsumerToPartitionMapConsumer.java
index 56a5446..3f8214d 100644
--- a/src/main/java/com/android/tools/r8/MapConsumerToPartitionMapConsumer.java
+++ b/src/main/java/com/android/tools/r8/MapConsumerToPartitionMapConsumer.java
@@ -6,12 +6,12 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.naming.ClassNameMapper;
-import com.android.tools.r8.naming.MapConsumer;
+import com.android.tools.r8.naming.InternalMapConsumer;
import com.android.tools.r8.retrace.ProguardMapPartitioner;
import com.android.tools.r8.retrace.internal.ProguardMapProducerInternal;
import java.io.IOException;
-public class MapConsumerToPartitionMapConsumer implements MapConsumer {
+public class MapConsumerToPartitionMapConsumer implements InternalMapConsumer {
protected final PartitionMapConsumer partitionMapConsumer;
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index cace694..6a49f4d 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -4,7 +4,7 @@
package com.android.tools.r8;
import static com.android.tools.r8.utils.InternalOptions.DETERMINISTIC_DEBUGGING;
-import static com.android.tools.r8.utils.MapConsumerUtils.wrapExistingMapConsumerIfNotNull;
+import static com.android.tools.r8.utils.MapConsumerUtils.wrapExistingInternalMapConsumerIfNotNull;
import com.android.build.shrinker.r8integration.LegacyResourceShrinker;
import com.android.tools.r8.ProgramResource.Kind;
@@ -28,8 +28,8 @@
import com.android.tools.r8.metadata.R8BuildMetadata;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.ClassNamingForNameMapper;
-import com.android.tools.r8.naming.MapConsumer;
-import com.android.tools.r8.naming.ProguardMapStringConsumer;
+import com.android.tools.r8.naming.InternalMapConsumer;
+import com.android.tools.r8.naming.InternalMapConsumerImpl;
import com.android.tools.r8.naming.SourceFileRewriter;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
@@ -61,6 +61,7 @@
import com.android.tools.r8.utils.InternalOptions.MappingComposeOptions;
import com.android.tools.r8.utils.InternalProgramClassProvider;
import com.android.tools.r8.utils.ListUtils;
+import com.android.tools.r8.utils.MapConsumerUtils;
import com.android.tools.r8.utils.ProgramClassCollection;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.SemanticVersion;
@@ -346,6 +347,9 @@
/**
* Set a consumer for receiving the proguard-map content.
*
+ * <p>It is possible to also retrieve the map id by passing an instance of {@link
+ * com.android.tools.r8.MapConsumer}.
+ *
* <p>Note that any subsequent call to this method or {@link #setProguardMapOutputPath} will
* override the previous setting.
*
@@ -1155,7 +1159,7 @@
private final boolean forceProguardCompatibility;
private final boolean protectApiSurface;
private final Optional<Boolean> includeDataResources;
- private final StringConsumer proguardMapConsumer;
+ private final MapConsumer proguardMapConsumer;
private final PartitionMapConsumer partitionMapConsumer;
private final StringConsumer proguardUsageConsumer;
private final StringConsumer proguardSeedsConsumer;
@@ -1242,7 +1246,7 @@
boolean forceProguardCompatibility,
boolean protectApiSurface,
Optional<Boolean> includeDataResources,
- StringConsumer proguardMapConsumer,
+ MapConsumer proguardMapConsumer,
PartitionMapConsumer partitionMapConsumer,
StringConsumer proguardUsageConsumer,
StringConsumer proguardSeedsConsumer,
@@ -1423,24 +1427,24 @@
}
// Amend the proguard-map consumer with options from the proguard configuration.
- StringConsumer stringConsumer =
- wrapStringConsumer(
+ MapConsumer mapConsumer =
+ wrapMapConsumer(
proguardMapConsumer,
proguardConfiguration.isPrintMapping(),
proguardConfiguration.getPrintMappingFile());
- MapConsumer mapConsumer =
- wrapExistingMapConsumerIfNotNull(
+ InternalMapConsumer internalMapConsumer =
+ wrapExistingInternalMapConsumerIfNotNull(
internal.mapConsumer, partitionMapConsumer, MapConsumerToPartitionMapConsumer::new);
- mapConsumer =
- wrapExistingMapConsumerIfNotNull(
+ internalMapConsumer =
+ wrapExistingInternalMapConsumerIfNotNull(
+ internalMapConsumer,
mapConsumer,
- stringConsumer,
nonNullStringConsumer ->
- ProguardMapStringConsumer.builder().setStringConsumer(stringConsumer).build());
+ InternalMapConsumerImpl.builder().setMapConsumer(mapConsumer).build());
internal.mapConsumer =
- wrapExistingMapConsumerIfNotNull(
- mapConsumer,
+ wrapExistingInternalMapConsumerIfNotNull(
+ internalMapConsumer,
androidResourceConsumer,
nonNulStringConsumer -> new ResourceShrinkerMapStringConsumer(internal));
// Amend the usage information consumer with options from the proguard configuration.
@@ -1563,6 +1567,18 @@
return internal;
}
+ private static MapConsumer wrapMapConsumer(
+ MapConsumer consumer, boolean optionsFlag, Path optionFile) {
+ if (optionsFlag) {
+ if (optionFile != null) {
+ return new MapConsumer.FileConsumer(optionFile, consumer);
+ } else {
+ return MapConsumerUtils.createStandardOutConsumer(consumer);
+ }
+ }
+ return consumer;
+ }
+
private static StringConsumer wrapStringConsumer(
StringConsumer optionConsumer, boolean optionsFlag, Path optionFile) {
if (optionsFlag) {
@@ -1575,7 +1591,7 @@
return optionConsumer;
}
- private static class ResourceShrinkerMapStringConsumer implements MapConsumer {
+ private static class ResourceShrinkerMapStringConsumer implements InternalMapConsumer {
private final InternalOptions internal;
private final Predicate<String> classNamePredicate;
diff --git a/src/main/java/com/android/tools/r8/bisect/Bisect.java b/src/main/java/com/android/tools/r8/bisect/Bisect.java
index 226ba81..396e0ed 100644
--- a/src/main/java/com/android/tools/r8/bisect/Bisect.java
+++ b/src/main/java/com/android/tools/r8/bisect/Bisect.java
@@ -13,7 +13,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.naming.MapConsumer;
+import com.android.tools.r8.naming.InternalMapConsumer;
import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
@@ -183,7 +183,7 @@
InternalOptions options = app.options;
// Save the original consumers, so they can be unwrapped after write.
ProgramConsumer programConsumer = options.programConsumer;
- MapConsumer mapConsumer = options.mapConsumer;
+ InternalMapConsumer mapConsumer = options.mapConsumer;
AndroidAppConsumers compatSink = new AndroidAppConsumers(options);
ApplicationWriter writer =
ApplicationWriter.create(
diff --git a/src/main/java/com/android/tools/r8/naming/MapConsumer.java b/src/main/java/com/android/tools/r8/naming/InternalMapConsumer.java
similarity index 71%
rename from src/main/java/com/android/tools/r8/naming/MapConsumer.java
rename to src/main/java/com/android/tools/r8/naming/InternalMapConsumer.java
index 01c497f..97cc5b5 100644
--- a/src/main/java/com/android/tools/r8/naming/MapConsumer.java
+++ b/src/main/java/com/android/tools/r8/naming/InternalMapConsumer.java
@@ -11,9 +11,9 @@
* This is an internal consumer that can accept our internal representation of a mapping format.
* This should not be exposed.
*/
-public interface MapConsumer extends Finishable {
+public interface InternalMapConsumer extends Finishable {
- void accept(
- DiagnosticsHandler diagnosticsHandler,
- ClassNameMapper classNameMapper);
+ void accept(DiagnosticsHandler diagnosticsHandler, ClassNameMapper classNameMapper);
+
+ default void acceptMapId(String mapId) {}
}
diff --git a/src/main/java/com/android/tools/r8/naming/InternalMapConsumerImpl.java b/src/main/java/com/android/tools/r8/naming/InternalMapConsumerImpl.java
new file mode 100644
index 0000000..83b5edb
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/naming/InternalMapConsumerImpl.java
@@ -0,0 +1,71 @@
+// Copyright (c) 2023, 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.naming;
+
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.MapConsumer;
+import com.android.tools.r8.utils.ChainableStringConsumer;
+import com.android.tools.r8.utils.StringUtils;
+
+/***
+ * Default implementation of an {@link InternalMapConsumer} that wraps around a {@link
+ * com.android.tools.r8.MapConsumer} for streamed string output.
+ */
+public class InternalMapConsumerImpl implements InternalMapConsumer, ChainableStringConsumer {
+
+ private final MapConsumer mapConsumer;
+ private DiagnosticsHandler diagnosticsHandler;
+
+ private InternalMapConsumerImpl(MapConsumer mapConsumer) {
+ assert mapConsumer != null;
+ this.mapConsumer = mapConsumer;
+ }
+
+ @Override
+ public void accept(DiagnosticsHandler diagnosticsHandler, ClassNameMapper classNameMapper) {
+ this.diagnosticsHandler = diagnosticsHandler;
+ accept(StringUtils.unixLines(classNameMapper.getPreamble()));
+ classNameMapper.write(this);
+ }
+
+ @Override
+ public void acceptMapId(String mapId) {
+ mapConsumer.acceptMapId(mapId);
+ }
+
+ @Override
+ public ChainableStringConsumer accept(String string) {
+ assert diagnosticsHandler != null;
+ mapConsumer.accept(string, diagnosticsHandler);
+ return this;
+ }
+
+ public MapConsumer getMapConsumer() {
+ return mapConsumer;
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ mapConsumer.finished(handler);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+
+ private MapConsumer mapConsumer;
+
+ public Builder setMapConsumer(MapConsumer mapConsumer) {
+ this.mapConsumer = mapConsumer;
+ return this;
+ }
+
+ public InternalMapConsumerImpl build() {
+ return new InternalMapConsumerImpl(mapConsumer);
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapStringConsumer.java b/src/main/java/com/android/tools/r8/naming/ProguardMapStringConsumer.java
deleted file mode 100644
index 6f2091c..0000000
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapStringConsumer.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2023, 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.naming;
-
-import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.StringConsumer;
-import com.android.tools.r8.utils.ChainableStringConsumer;
-import com.android.tools.r8.utils.StringUtils;
-
-/***
- * Default implementation of a MapConsumer that wraps around a string consumer for streamed string
- * output.
- */
-public class ProguardMapStringConsumer implements MapConsumer, ChainableStringConsumer {
-
- private final StringConsumer stringConsumer;
- private DiagnosticsHandler diagnosticsHandler;
-
- private ProguardMapStringConsumer(StringConsumer stringConsumer) {
- assert stringConsumer != null;
- this.stringConsumer = stringConsumer;
- }
-
- @Override
- public void accept(
- DiagnosticsHandler diagnosticsHandler,
- ClassNameMapper classNameMapper) {
- this.diagnosticsHandler = diagnosticsHandler;
- accept(StringUtils.unixLines(classNameMapper.getPreamble()));
- classNameMapper.write(this);
- }
-
- @Override
- public ChainableStringConsumer accept(String string) {
- assert diagnosticsHandler != null;
- stringConsumer.accept(string, diagnosticsHandler);
- return this;
- }
-
- public StringConsumer getStringConsumer() {
- return stringConsumer;
- }
-
- @Override
- public void finished(DiagnosticsHandler handler) {
- stringConsumer.finished(handler);
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
-
- private StringConsumer stringConsumer;
-
- public Builder setStringConsumer(StringConsumer stringConsumer) {
- this.stringConsumer = stringConsumer;
- return this;
- }
-
- public ProguardMapStringConsumer build() {
- return new ProguardMapStringConsumer(stringConsumer);
- }
- }
-}
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 3c7fad9..f8da2d6 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapSupplier.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapSupplier.java
@@ -83,7 +83,7 @@
private final ClassNameMapper classNameMapper;
private final InternalOptions options;
- private final MapConsumer consumer;
+ private final InternalMapConsumer consumer;
private final Reporter reporter;
private final Tool compiler;
@@ -110,7 +110,7 @@
try (Timing t0 = timing.begin("Prepare write")) {
classNameMapper.prepareWrite(appView, executorService);
}
- AwaitableFutureValue<ProguardMapId> proguardMapId =
+ AwaitableFutureValue<ProguardMapId> proguardMapIdSupplier =
computeProguardMapId(appView, executorService, timing);
AwaitableFuture mapWritten;
mapWritten =
@@ -118,10 +118,11 @@
() -> {
try (Timing threadTiming =
timing.createThreadTiming("Write proguard map to consumer", appView.options())) {
+ ProguardMapId proguardMapId = proguardMapIdSupplier.awaitValue();
ProguardMapMarkerInfo markerInfo =
ProguardMapMarkerInfo.builder()
.setCompilerName(compiler.name())
- .setProguardMapId(proguardMapId.awaitValue())
+ .setProguardMapId(proguardMapId)
.setGeneratingDex(options.isGeneratingDex())
.setApiLevel(options.getMinApiLevel())
.setMapVersion(options.getMapFileVersion())
@@ -132,13 +133,14 @@
ListUtils.concat(markerInfo.toPreamble(), classNameMapper.getPreamble()));
consumer.accept(reporter, classNameMapper);
+ consumer.acceptMapId(proguardMapId.id);
ExceptionUtils.withConsumeResourceHandler(reporter, this.consumer::finished);
}
return null;
},
appView.options().getThreadingModule(),
executorService);
- return new ProguardMapSupplierResult(proguardMapId, mapWritten);
+ return new ProguardMapSupplierResult(proguardMapIdSupplier, mapWritten);
}
private AwaitableFutureValue<ProguardMapId> computeProguardMapId(
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidAppConsumers.java b/src/main/java/com/android/tools/r8/utils/AndroidAppConsumers.java
index 8142f7b..8a49577 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidAppConsumers.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidAppConsumers.java
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.utils;
-import static com.android.tools.r8.utils.MapConsumerUtils.wrapExistingMapConsumer;
+import static com.android.tools.r8.utils.MapConsumerUtils.wrapExistingInternalMapConsumer;
import com.android.tools.r8.BaseCompilerCommand;
import com.android.tools.r8.ByteDataView;
@@ -15,11 +15,11 @@
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DexIndexedConsumer.ForwardingConsumer;
import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.MapConsumer;
import com.android.tools.r8.ProgramConsumer;
import com.android.tools.r8.ResourceException;
-import com.android.tools.r8.StringConsumer;
-import com.android.tools.r8.naming.MapConsumer;
-import com.android.tools.r8.naming.ProguardMapStringConsumer;
+import com.android.tools.r8.naming.InternalMapConsumer;
+import com.android.tools.r8.naming.InternalMapConsumerImpl;
import com.android.tools.r8.origin.Origin;
import com.google.common.io.ByteStreams;
import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
@@ -37,7 +37,7 @@
private boolean closed = false;
private ProgramConsumer programConsumer = null;
- private MapConsumer mapConsumer = null;
+ private InternalMapConsumer mapConsumer = null;
public AndroidAppConsumers() {
// Nothing to do.
@@ -69,15 +69,15 @@
return programConsumer;
}
- public MapConsumer wrapProguardMapConsumer(MapConsumer consumer) {
+ public InternalMapConsumer wrapProguardMapConsumer(InternalMapConsumer consumer) {
assert mapConsumer == null;
if (consumer != null) {
mapConsumer =
- wrapExistingMapConsumer(
+ wrapExistingInternalMapConsumer(
consumer,
- ProguardMapStringConsumer.builder()
- .setStringConsumer(
- new StringConsumer() {
+ InternalMapConsumerImpl.builder()
+ .setMapConsumer(
+ new MapConsumer() {
StringBuilder stringBuilder = null;
@Override
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 6614fb8..227b00b 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -77,7 +77,7 @@
import com.android.tools.r8.metadata.D8BuildMetadata;
import com.android.tools.r8.metadata.R8BuildMetadata;
import com.android.tools.r8.naming.ClassNameMapper;
-import com.android.tools.r8.naming.MapConsumer;
+import com.android.tools.r8.naming.InternalMapConsumer;
import com.android.tools.r8.naming.MapVersion;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.optimize.accessmodification.AccessModifierOptions;
@@ -1319,7 +1319,7 @@
// If null, no proguard map needs to be computed.
// If non null it must be and passed to the consumer.
- public MapConsumer mapConsumer = null;
+ public InternalMapConsumer mapConsumer = null;
public boolean hasMappingFileSupport() {
return mapConsumer != null;
diff --git a/src/main/java/com/android/tools/r8/utils/MapConsumerUtils.java b/src/main/java/com/android/tools/r8/utils/MapConsumerUtils.java
index c6056ea..d99f96c 100644
--- a/src/main/java/com/android/tools/r8/utils/MapConsumerUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/MapConsumerUtils.java
@@ -5,18 +5,52 @@
package com.android.tools.r8.utils;
import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.MapConsumer;
+import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.naming.ClassNameMapper;
-import com.android.tools.r8.naming.MapConsumer;
+import com.android.tools.r8.naming.InternalMapConsumer;
import java.util.function.Function;
public class MapConsumerUtils {
- public static MapConsumer wrapExistingMapConsumer(
- MapConsumer existingMapConsumer, MapConsumer newConsumer) {
+ public static MapConsumer createFromStringConsumer(StringConsumer consumer) {
+ if (consumer == null) {
+ return null;
+ }
+ if (consumer instanceof MapConsumer) {
+ return (MapConsumer) consumer;
+ }
+ return new MapConsumer() {
+
+ @Override
+ public void accept(String string, DiagnosticsHandler handler) {
+ consumer.accept(string, handler);
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ consumer.finished(handler);
+ }
+ };
+ }
+
+ public static MapConsumer createStandardOutConsumer(MapConsumer consumer) {
+ return new MapConsumer.ForwardingConsumer(consumer) {
+
+ @Override
+ public void accept(String string, DiagnosticsHandler handler) {
+ super.accept(string, handler);
+ System.out.print(string);
+ }
+ };
+ }
+
+ public static InternalMapConsumer wrapExistingInternalMapConsumer(
+ InternalMapConsumer existingMapConsumer, InternalMapConsumer newConsumer) {
if (existingMapConsumer == null) {
return newConsumer;
}
- return new MapConsumer() {
+ return new InternalMapConsumer() {
@Override
public void accept(DiagnosticsHandler diagnosticsHandler, ClassNameMapper classNameMapper) {
existingMapConsumer.accept(diagnosticsHandler, classNameMapper);
@@ -31,11 +65,13 @@
};
}
- public static <T> MapConsumer wrapExistingMapConsumerIfNotNull(
- MapConsumer existingMapConsumer, T object, Function<T, MapConsumer> producer) {
+ public static <T> InternalMapConsumer wrapExistingInternalMapConsumerIfNotNull(
+ InternalMapConsumer existingMapConsumer,
+ T object,
+ Function<T, InternalMapConsumer> producer) {
if (object == null) {
return existingMapConsumer;
}
- return wrapExistingMapConsumer(existingMapConsumer, producer.apply(object));
+ return wrapExistingInternalMapConsumer(existingMapConsumer, producer.apply(object));
}
}
diff --git a/src/test/java/com/android/tools/r8/L8CommandTest.java b/src/test/java/com/android/tools/r8/L8CommandTest.java
index 8a9c360..5272775 100644
--- a/src/test/java/com/android/tools/r8/L8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/L8CommandTest.java
@@ -18,7 +18,7 @@
import com.android.tools.r8.StringConsumer.FileConsumer;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.dex.Marker.Tool;
-import com.android.tools.r8.naming.ProguardMapStringConsumer;
+import com.android.tools.r8.naming.InternalMapConsumerImpl;
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.Reference;
@@ -192,10 +192,10 @@
assertNotNull(parsedCommand.getR8Command());
InternalOptions internalOptions = parsedCommand.getR8Command().getInternalOptions();
assertNotNull(internalOptions);
- assertTrue(internalOptions.mapConsumer instanceof ProguardMapStringConsumer);
- ProguardMapStringConsumer mapStringConsumer =
- (ProguardMapStringConsumer) internalOptions.mapConsumer;
- FileConsumer proguardMapConsumer = (FileConsumer) mapStringConsumer.getStringConsumer();
+ assertTrue(internalOptions.mapConsumer instanceof InternalMapConsumerImpl);
+ InternalMapConsumerImpl mapStringConsumer =
+ (InternalMapConsumerImpl) internalOptions.mapConsumer;
+ FileConsumer proguardMapConsumer = (FileConsumer) mapStringConsumer.getMapConsumer();
assertEquals(pgMap, proguardMapConsumer.getOutputPath());
}
diff --git a/src/test/java/com/android/tools/r8/compilerapi/mapid/CustomMapIdTest.java b/src/test/java/com/android/tools/r8/compilerapi/mapid/CustomMapIdTest.java
index d1d4330..df63857 100644
--- a/src/test/java/com/android/tools/r8/compilerapi/mapid/CustomMapIdTest.java
+++ b/src/test/java/com/android/tools/r8/compilerapi/mapid/CustomMapIdTest.java
@@ -10,6 +10,8 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.MapConsumer;
import com.android.tools.r8.MapIdEnvironment;
import com.android.tools.r8.MarkerMatcher;
import com.android.tools.r8.ProgramConsumer;
@@ -22,10 +24,13 @@
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.BooleanBox;
+import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.ThrowingBiConsumer;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.Collection;
+import java.util.List;
import java.util.function.Function;
import org.junit.Test;
@@ -47,6 +52,12 @@
}
@Test
+ public void testDefaultMapIdWithPrintConfiguration() throws Exception {
+ ApiTest test = new ApiTest(ApiTest.PARAMETERS);
+ runTest(test::runDefaultMapIdWithPrintConfiguration, hash -> hash);
+ }
+
+ @Test
public void testCustomMapId() throws Exception {
ApiTest test = new ApiTest(ApiTest.PARAMETERS);
runTest(test::runCustomMapId, hash -> hash);
@@ -68,13 +79,34 @@
Path output = temp.newFolder().toPath().resolve("out.jar");
StringBuilder mappingBuilder = new StringBuilder();
BooleanBox didGetMappingContent = new BooleanBox(false);
+ BooleanBox finished = new BooleanBox();
+ Box<String> consumedMapId = new Box<>();
test.accept(
new DexIndexedConsumer.ArchiveConsumer(output),
- (mappingContent, handler) -> {
- mappingBuilder.append(mappingContent);
- didGetMappingContent.set(true);
+ new MapConsumer() {
+ @Override
+ public void accept(String string, DiagnosticsHandler handler) {
+ assertTrue(finished.isFalse());
+ mappingBuilder.append(string);
+ didGetMappingContent.set(true);
+ }
+
+ @Override
+ public void acceptMapId(String mapId) {
+ assertTrue(finished.isFalse());
+ consumedMapId.set(mapId);
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ assertTrue(finished.isFalse());
+ MapConsumer.super.finished(handler);
+ finished.set();
+ }
});
- assertTrue(didGetMappingContent.get());
+ assertTrue(didGetMappingContent.isTrue());
+ assertTrue(consumedMapId.isSet());
+ assertTrue(finished.isTrue());
// Extract the map hash from the file. This is always set by R8 to a SHA 256 hash.
String mappingContent = mappingBuilder.toString();
@@ -83,6 +115,7 @@
// Check the map id is also defined in the map file.
String mapId = hashToId.apply(mapHash);
+ assertEquals(mapId, consumedMapId.get());
assertThat(mappingContent, containsString("pg_map_id: " + mapId + "\n"));
// Check that the map id is also present in the markers.
@@ -100,10 +133,26 @@
public void runDefaultMapId(ProgramConsumer programConsumer, StringConsumer mappingConsumer)
throws Exception {
+ internalRunDefaultMapId(programConsumer, mappingConsumer, false);
+ }
+
+ public void runDefaultMapIdWithPrintConfiguration(
+ ProgramConsumer programConsumer, StringConsumer mappingConsumer) throws Exception {
+ internalRunDefaultMapId(programConsumer, mappingConsumer, true);
+ }
+
+ private void internalRunDefaultMapId(
+ ProgramConsumer programConsumer, StringConsumer mappingConsumer, boolean printConfiguration)
+ throws Exception {
+ List<String> keepRules = getKeepMainRules(getMockClass());
+ if (printConfiguration) {
+ keepRules =
+ ImmutableList.<String>builder().addAll(keepRules).add("-printconfiguration").build();
+ }
R8.run(
R8Command.builder()
.addClassProgramData(getBytesForClass(getMockClass()), Origin.unknown())
- .addProguardConfiguration(getKeepMainRules(getMockClass()), Origin.unknown())
+ .addProguardConfiguration(keepRules, Origin.unknown())
.addLibraryFiles(getJava8RuntimeJar())
.setProgramConsumer(programConsumer)
.setProguardMapConsumer(mappingConsumer)
diff --git a/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1 b/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
index 707acf0..709686c 100644
--- a/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
+++ b/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
@@ -1 +1 @@
-481d303c480e2ac2a6dc71518a28846fc79fc76e
\ No newline at end of file
+c3f45ad6bf68e9f396bdf331b38f512582add212
\ No newline at end of file