Relanding "Add finished callback to StringConsumer."
This cherry-picks 197c2292f84b11632e3c5c8e9db34dc5da842231
with fixed conflicts.
The change was reverted as part of 523ef9455bab0bd029227982f0ade905d710feeb.
Bug: 140141590
Change-Id: Ie987353e02a25ad9a14bea2710f4de965247a3c3
diff --git a/build.gradle b/build.gradle
index 09f6368..a68c7a9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -517,7 +517,7 @@
options.fork = true
// Javac often runs out of stack space when compiling the tests.
// Increase the stack size for the javac process.
- options.forkOptions.jvmArgs << "-Xss4m"
+ options.forkOptions.jvmArgs << "-Xss256m"
// Test compilation is sometimes hitting the default limit at 1g, increase it.
options.forkOptions.jvmArgs << "-Xmx2g"
// Set the bootclass path so compilation is consistent with 1.8 target compatibility.
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index ea3472f..2aa0ac5 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -75,6 +75,7 @@
if (options.mainDexListConsumer != null) {
options.mainDexListConsumer.accept(String.join("\n", result), options.reporter);
+ options.mainDexListConsumer.finished(options.reporter);
}
R8.processWhyAreYouKeepingAndCheckDiscarded(
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 53faa52..235882e 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.ir.desugar.DesugaredLibraryConfiguration;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
-import com.android.tools.r8.origin.StandardOutOrigin;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.ProguardConfigurationParser;
import com.android.tools.r8.shaking.ProguardConfigurationRule;
@@ -882,10 +881,22 @@
if (optionFile != null) {
return new StringConsumer.FileConsumer(optionFile, optionConsumer);
} else {
- return new StringConsumer.StreamConsumer(
- StandardOutOrigin.instance(), System.out, optionConsumer);
+ return new StandardOutConsumer(optionConsumer);
}
}
return optionConsumer;
}
+
+ private static class StandardOutConsumer extends StringConsumer.ForwardingConsumer {
+
+ public StandardOutConsumer(StringConsumer consumer) {
+ super(consumer);
+ }
+
+ @Override
+ public void accept(String string, DiagnosticsHandler handler) {
+ super.accept(string, handler);
+ System.out.print(string);
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/StringConsumer.java b/src/main/java/com/android/tools/r8/StringConsumer.java
index 2037cda..5d02846 100644
--- a/src/main/java/com/android/tools/r8/StringConsumer.java
+++ b/src/main/java/com/android/tools/r8/StringConsumer.java
@@ -6,10 +6,8 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.ExceptionDiagnostic;
-import java.io.BufferedWriter;
import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
+import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -20,17 +18,31 @@
public interface StringConsumer {
/**
- * Callback to receive a String resource.
+ * Callback to receive part of a string resource.
*
* <p>The consumer is expected not to throw, but instead report any errors via the diagnostics
* {@param handler}. If an error is reported via {@param handler} and no exceptions are thrown,
* then the compiler guaranties to exit with an error.
*
- * @param string String resource.
+ * <p>Note: prior to the addition of 'finished' consumers could expect all content to be reported
+ * in one call to accept. That is no longer guaranteed.
+ *
+ * @param string Part of the string resource.
* @param handler Diagnostics handler for reporting.
*/
void accept(String string, DiagnosticsHandler handler);
+ /**
+ * Callback when no further content will be provided for the string resource.
+ *
+ * <p>The consumer is expected not to throw, but instead report any errors via the diagnostics
+ * {@param handler}. If an error is reported via {@param handler} and no exceptions are thrown,
+ * then the compiler guaranties to exit with an error.
+ *
+ * @param handler Diagnostics handler for reporting.
+ */
+ void finished(DiagnosticsHandler handler);
+
static EmptyConsumer emptyConsumer() {
return EmptyConsumer.EMPTY_CONSUMER;
}
@@ -44,6 +56,11 @@
public void accept(String string, DiagnosticsHandler handler) {
// Ignore content.
}
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ // No content so, nothing to do.
+ }
}
/** Forwarding consumer to delegate to an optional existing consumer. */
@@ -62,14 +79,22 @@
consumer.accept(string, handler);
}
}
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ if (consumer != null) {
+ consumer.finished(handler);
+ }
+ }
}
/** File consumer to write contents to a file-system file. */
- @Keep // TODO(b/121121779) Extend keep-annotation to public inner classes and remove this.
+ @Keep // TODO(b/121121779) Consider deprecating the R8 provided file writing.
class FileConsumer extends ForwardingConsumer {
private final Path outputPath;
private Charset encoding = StandardCharsets.UTF_8;
+ private WriterConsumer delegate = null;
/** Consumer that writes to {@param outputPath}. */
public FileConsumer(Path outputPath) {
@@ -90,6 +115,9 @@
/** Set the output encoding. Defaults to UTF8. */
public void setEncoding(Charset encoding) {
assert encoding != null;
+ if (delegate != null) {
+ throw new IllegalStateException("Invalid call to set encoding after file stream is opened");
+ }
this.encoding = encoding;
}
@@ -101,57 +129,61 @@
@Override
public void accept(String string, DiagnosticsHandler handler) {
super.accept(string, handler);
+ ensureDelegate(handler);
+ delegate.accept(string, handler);
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ super.finished(handler);
+ if (delegate != null) {
+ delegate.finished(handler);
+ delegate = null;
+ }
+ }
+
+ private void ensureDelegate(DiagnosticsHandler handler) {
+ if (delegate != null) {
+ return;
+ }
+ PathOrigin origin = new PathOrigin(outputPath);
try {
Path parent = outputPath.getParent();
if (parent != null && !parent.toFile().exists()) {
Files.createDirectories(parent);
}
- com.google.common.io.Files.asCharSink(outputPath.toFile(), encoding).write(string);
+ delegate = new WriterConsumer(origin, Files.newBufferedWriter(outputPath, encoding));
} catch (IOException e) {
- Origin origin = new PathOrigin(outputPath);
handler.error(new ExceptionDiagnostic(e, origin));
}
}
}
/**
- * Stream consumer to write contents to an output stream.
+ * String consumer to write contents to a Writer.
*
- * <p>Note: No close events are given to this stream so it should either be a permanent stream or
- * the closing needs to happen outside of the compilation itself. If the stream is not one of the
- * standard streams, i.e., System.out or System.err, you should likely implement yor own consumer.
+ * <p>Note: The writer is closed when the consumer receives its 'finished' callback.
*/
- class StreamConsumer extends ForwardingConsumer {
+ class WriterConsumer extends ForwardingConsumer {
private final Origin origin;
- private final OutputStream outputStream;
- private Charset encoding = StandardCharsets.UTF_8;
+ private Writer writer;
- /** Consumer that writes to {@param outputStream}. */
- public StreamConsumer(Origin origin, OutputStream outputStream) {
- this(origin, outputStream, null);
+ /** Consumer that writes to {@param writer}. */
+ public WriterConsumer(Origin origin, Writer writer) {
+ this(origin, writer, null);
}
- /** Consumer that forwards to {@param consumer} and also writes to {@param outputStream}. */
- public StreamConsumer(Origin origin, OutputStream outputStream, StringConsumer consumer) {
+ /** Consumer that forwards to {@param consumer} and also writes to {@param writer}. */
+ public WriterConsumer(Origin origin, Writer writer, StringConsumer consumer) {
super(consumer);
this.origin = origin;
- this.outputStream = outputStream;
- }
-
- /** Set the encoding. Defaults to UTF8. */
- public void setEncoding(Charset encoding) {
- assert encoding != null;
- this.encoding = encoding;
+ this.writer = writer;
}
@Override
public void accept(String string, DiagnosticsHandler handler) {
super.accept(string, handler);
- // Don't close this writer as it will close the underlying stream, which we specifically do
- // not want.
- BufferedWriter writer =
- new BufferedWriter(new OutputStreamWriter(outputStream, encoding.newEncoder()));
try {
writer.write(string);
writer.flush();
@@ -159,5 +191,15 @@
handler.error(new ExceptionDiagnostic(e, origin));
}
}
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ super.finished(handler);
+ try {
+ writer.close();
+ } catch (IOException e) {
+ handler.error(new ExceptionDiagnostic(e, origin));
+ }
+ }
}
}
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 a3b6888..eb5fa29 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -374,19 +374,24 @@
ExceptionUtils.withConsumeResourceHandler(
options.reporter, options.configurationConsumer,
options.getProguardConfiguration().getParsedConfiguration());
+ ExceptionUtils.withFinishedResourceHandler(options.reporter, options.configurationConsumer);
}
if (options.usageInformationConsumer != null && deadCode != null) {
ExceptionUtils.withConsumeResourceHandler(
options.reporter, options.usageInformationConsumer, deadCode);
+ ExceptionUtils.withFinishedResourceHandler(
+ options.reporter, options.usageInformationConsumer);
}
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));
+ ExceptionUtils.withFinishedResourceHandler(options.reporter, options.mainDexListConsumer);
}
DataResourceConsumer dataResourceConsumer = options.dataResourceConsumer;
if (dataResourceConsumer != null) {
diff --git a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
index 4f3f442..6e44735 100644
--- a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
+++ b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
@@ -145,6 +145,7 @@
sb.append("}").append(cr);
}
options.desugaredLibraryKeepRuleConsumer.accept(sb.toString(), options.reporter);
+ options.desugaredLibraryKeepRuleConsumer.finished(options.reporter);
}
}
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 b7beb82..06fef54 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidAppConsumers.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidAppConsumers.java
@@ -70,10 +70,23 @@
if (consumer != null) {
proguardMapConsumer =
new StringConsumer.ForwardingConsumer(consumer) {
+ StringBuilder stringBuilder = null;
+
@Override
public void accept(String string, DiagnosticsHandler handler) {
super.accept(string, handler);
- builder.setProguardMapOutputData(string);
+ if (stringBuilder == null) {
+ stringBuilder = new StringBuilder();
+ }
+ stringBuilder.append(string);
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ super.finished(handler);
+ if (stringBuilder != null) {
+ builder.setProguardMapOutputData(stringBuilder.toString());
+ }
}
};
}
diff --git a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
index 8b4b602..16bde83 100644
--- a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
@@ -25,6 +25,10 @@
withConsumeResourceHandler(reporter, handler -> consumer.accept(data, handler));
}
+ public static void withFinishedResourceHandler(Reporter reporter, StringConsumer consumer) {
+ withConsumeResourceHandler(reporter, consumer::finished);
+ }
+
public static void withConsumeResourceHandler(
Reporter reporter, Consumer<DiagnosticsHandler> consumer) {
// Unchecked exceptions simply propagate out, aborting the compilation forcefully.
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index ec83a9b..a35a7d7 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -21,7 +21,6 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.ZipUtils;
import com.google.common.collect.ImmutableList;
@@ -87,8 +86,7 @@
@Test
public void desugaredLibraryKeepRuleConsumer() throws Exception {
- Box<String> holder = new Box<>("");
- StringConsumer stringConsumer = (string, handler) -> holder.set(holder.get() + string);
+ StringConsumer stringConsumer = StringConsumer.emptyConsumer();
D8Command command =
D8Command.builder()
.setProgramConsumer(DexIndexedConsumer.emptyConsumer())
diff --git a/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java b/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
index c5961e8..59f6159 100644
--- a/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
@@ -70,11 +70,12 @@
.addLibraryFiles(ToolHelper.getAndroidJar(minApiLevel))
.setMinApiLevel(minApiLevel.getLevel())
.setProguardMapConsumer(
- (proguardMap, handler) -> {
- proguardMapIds.fromMap =
- verifyMarkersGetPgMapId(
- proguardMap, minApiLevel.getLevel(), EXPECTED_NUMBER_OF_KEYS_DEX);
- })
+ ToolHelper.consumeString(
+ proguardMap -> {
+ proguardMapIds.fromMap =
+ verifyMarkersGetPgMapId(
+ proguardMap, minApiLevel.getLevel(), EXPECTED_NUMBER_OF_KEYS_DEX);
+ }))
.build());
verifyProguardMapIds(proguardMapIds);
}
@@ -113,10 +114,11 @@
})
.addLibraryFiles(ToolHelper.getJava8RuntimeJar())
.setProguardMapConsumer(
- (proguardMap, handler) -> {
- buildIds.fromMap =
- verifyMarkersGetPgMapId(proguardMap, null, EXPECTED_NUMBER_OF_KEYS_CF);
- })
+ ToolHelper.consumeString(
+ proguardMap -> {
+ buildIds.fromMap =
+ verifyMarkersGetPgMapId(proguardMap, null, EXPECTED_NUMBER_OF_KEYS_CF);
+ }))
.build());
verifyProguardMapIds(buildIds);
}
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 955e75c..afa408d 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -66,7 +66,18 @@
StringBuilder proguardMapBuilder = new StringBuilder();
builder.setDisableTreeShaking(!enableTreeShaking);
builder.setDisableMinification(!enableMinification);
- builder.setProguardMapConsumer((string, ignore) -> proguardMapBuilder.append(string));
+ builder.setProguardMapConsumer(
+ new StringConsumer() {
+ @Override
+ public void accept(String string, DiagnosticsHandler handler) {
+ proguardMapBuilder.append(string);
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ // Nothing to do.
+ }
+ });
if (!applyMappingMaps.isEmpty()) {
try {
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index f7cca02..f9636bd 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -167,6 +167,28 @@
|| (backend == Backend.DEX && outputMode != OutputMode.ClassFile);
}
+ public static StringConsumer consumeString(Consumer<String> consumer) {
+ return new StringConsumer() {
+
+ private StringBuilder builder;
+
+ @Override
+ public void accept(String string, DiagnosticsHandler handler) {
+ if (builder == null) {
+ builder = new StringBuilder();
+ }
+ builder.append(string);
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ if (builder != null) {
+ consumer.accept(builder.toString());
+ }
+ }
+ };
+ }
+
public enum DexVm {
ART_4_0_4_TARGET(Version.V4_0_4, Kind.TARGET),
ART_4_0_4_HOST(Version.V4_0_4, Kind.HOST),
diff --git a/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java b/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
index d14e230..6b4f17d 100644
--- a/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
@@ -519,8 +519,10 @@
options.enableVerticalClassMerging = false;
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
- (proguardMap, handler) ->
- assertThat(proguardMap, containsString(expectedProguardMapWithoutClassMerging));
+ ToolHelper.consumeString(
+ proguardMap ->
+ assertThat(
+ proguardMap, containsString(expectedProguardMapWithoutClassMerging)));
});
// Try with vertical class merging.
@@ -547,8 +549,9 @@
configure(options);
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
- (proguardMap, handler) ->
- assertThat(proguardMap, containsString(expectedProguardMapWithClassMerging));
+ ToolHelper.consumeString(
+ proguardMap ->
+ assertThat(proguardMap, containsString(expectedProguardMapWithClassMerging)));
});
}
@@ -584,8 +587,10 @@
options.enableVerticalClassMerging = false;
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
- (proguardMap, handler) ->
- assertThat(proguardMap, containsString(expectedProguardMapWithoutClassMerging));
+ ToolHelper.consumeString(
+ proguardMap ->
+ assertThat(
+ proguardMap, containsString(expectedProguardMapWithoutClassMerging)));
});
// Try with vertical class merging.
@@ -615,8 +620,9 @@
configure(options);
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
- (proguardMap, handler) ->
- assertThat(proguardMap, containsString(expectedProguardMapWithClassMerging));
+ ToolHelper.consumeString(
+ proguardMap ->
+ assertThat(proguardMap, containsString(expectedProguardMapWithClassMerging)));
});
}
@@ -655,8 +661,10 @@
options.enableVerticalClassMerging = false;
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
- (proguardMap, handler) ->
- assertThat(proguardMap, containsString(expectedProguardMapWithoutClassMerging));
+ ToolHelper.consumeString(
+ proguardMap ->
+ assertThat(
+ proguardMap, containsString(expectedProguardMapWithoutClassMerging)));
});
// Try with vertical class merging.
@@ -685,8 +693,9 @@
configure(options);
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
- (proguardMap, handler) ->
- assertThat(proguardMap, containsString(expectedProguardMapWithClassMerging));
+ ToolHelper.consumeString(
+ proguardMap ->
+ assertThat(proguardMap, containsString(expectedProguardMapWithClassMerging)));
});
}
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java b/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
index a5f8124..57e3231 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
@@ -134,6 +134,11 @@
public void accept(String string, DiagnosticsHandler handler) {
throw new Unreachable("No desugaring on high API levels");
}
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ throw new Unreachable("No desugaring on high API levels");
+ }
}
public static class PresentKeepRuleConsumer implements KeepRuleConsumer {
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
index 36ea940..a60cbd2 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
@@ -10,12 +10,20 @@
import com.android.tools.r8.D8TestRunResult;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.InstructionSubject.JumboStringMode;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -47,18 +55,22 @@
@Test
public void testCustomCollectionD8() throws Exception {
- KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ Box<String> keepRulesHolder = new Box<>("");
D8TestRunResult d8TestRunResult =
testForD8()
.addInnerClasses(CustomCollectionTest.class)
.setMinApi(parameters.getApiLevel())
- .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .addOptionsModification(
+ options ->
+ options.desugaredLibraryKeepRuleConsumer =
+ ToolHelper.consumeString(keepRulesHolder::set))
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
.compile()
.inspect(inspector -> this.assertCustomCollectionCallsCorrect(inspector, false))
.addDesugaredCoreLibraryRunClassPath(
this::buildDesugaredLibrary,
parameters.getApiLevel(),
- keepRuleConsumer.get(),
+ keepRulesHolder.get(),
shrinkCoreLibrary)
.run(parameters.getRuntime(), EXECUTOR)
.assertSuccess();
@@ -77,7 +89,7 @@
@Test
public void testCustomCollectionR8() throws Exception {
- KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ Box<String> keepRulesHolder = new Box<>("");
R8TestRunResult r8TestRunResult =
testForR8(Backend.DEX)
.addInnerClasses(CustomCollectionTest.class)
@@ -88,13 +100,17 @@
// TODO(b/140233505): Allow devirtualization once fixed.
options.enableDevirtualization = false;
})
- .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .addOptionsModification(
+ options ->
+ options.desugaredLibraryKeepRuleConsumer =
+ ToolHelper.consumeString(keepRulesHolder::set))
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
.compile()
.inspect(inspector -> this.assertCustomCollectionCallsCorrect(inspector, true))
.addDesugaredCoreLibraryRunClassPath(
this::buildDesugaredLibrary,
parameters.getApiLevel(),
- keepRuleConsumer.get(),
+ keepRulesHolder.get(),
shrinkCoreLibrary)
.run(parameters.getRuntime(), EXECUTOR)
.assertSuccess();
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
index 34ab55c..1c4f47a 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
@@ -9,7 +9,9 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -54,17 +56,21 @@
@Test
public void testTimeD8() throws Exception {
- KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ Box<String> keepRulesHolder = new Box<>("");
testForD8()
.addInnerClasses(JavaTimeTest.class)
.setMinApi(parameters.getApiLevel())
- .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
+ .addOptionsModification(
+ options ->
+ options.desugaredLibraryKeepRuleConsumer =
+ ToolHelper.consumeString(keepRulesHolder::set))
.compile()
.inspect(this::checkRewrittenInvokes)
.addDesugaredCoreLibraryRunClassPath(
this::buildDesugaredLibrary,
parameters.getApiLevel(),
- keepRuleConsumer.get(),
+ keepRulesHolder.get(),
shrinkCoreLibrary)
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(expectedOutput);
@@ -72,18 +78,22 @@
@Test
public void testTimeR8() throws Exception {
- KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ Box<String> keepRulesHolder = new Box<>("");
testForR8(parameters.getBackend())
.addInnerClasses(JavaTimeTest.class)
.addKeepMainRule(TestClass.class)
.setMinApi(parameters.getApiLevel())
- .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
+ .addOptionsModification(
+ options ->
+ options.desugaredLibraryKeepRuleConsumer =
+ ToolHelper.consumeString(keepRulesHolder::set))
.compile()
.inspect(this::checkRewrittenInvokes)
.addDesugaredCoreLibraryRunClassPath(
this::buildDesugaredLibrary,
parameters.getApiLevel(),
- keepRuleConsumer.get(),
+ keepRulesHolder.get(),
shrinkCoreLibrary)
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(expectedOutput);
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
index f9778df..deb0bd4 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -56,30 +57,35 @@
@Test
public void testProgramD8() throws Exception {
Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
+
ArrayList<Path> coreLambdaStubs = new ArrayList<>();
coreLambdaStubs.add(ToolHelper.getCoreLambdaStubs());
+ Box<String> keepRulesHolder = new Box<>("");
for (Boolean coreLambdaStubsActive : BooleanUtils.values()) {
- KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
D8TestRunResult d8TestRunResult =
testForD8()
.addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
.setMinApi(parameters.getApiLevel())
- .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
+ .addOptionsModification(
+ options ->
+ options.desugaredLibraryKeepRuleConsumer =
+ ToolHelper.consumeString(keepRulesHolder::set))
.compile()
.inspect(this::checkRewrittenInvokes)
.addRunClasspathFiles(
coreLambdaStubsActive
? buildDesugaredLibrary(
parameters.getApiLevel(),
- keepRuleConsumer.get(),
+ keepRulesHolder.get(),
shrinkCoreLibrary,
coreLambdaStubs)
: buildDesugaredLibrary(
- parameters.getApiLevel(), keepRuleConsumer.get(), shrinkCoreLibrary))
+ parameters.getApiLevel(), keepRulesHolder.get(), shrinkCoreLibrary))
.run(parameters.getRuntime(), TEST_CLASS)
.assertSuccess();
assertLines2By2Correct(d8TestRunResult.getStdOut());
- assertGeneratedKeepRulesAreCorrect(keepRuleConsumer.get());
+ assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
String stdErr = d8TestRunResult.getStdErr();
if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
// Flaky: There might be a missing method on lambda deserialization.
@@ -96,7 +102,7 @@
public void testProgramR8() throws Exception {
Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
for (Boolean minifying : BooleanUtils.values()) {
- KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ Box<String> keepRulesHolder = new Box<>("");
R8TestRunResult r8TestRunResult =
testForR8(parameters.getBackend())
.minification(minifying)
@@ -108,16 +114,20 @@
// TODO(b/140233505): Allow devirtualization once fixed.
options.enableDevirtualization = false;
})
- .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .addOptionsModification(
+ options ->
+ options.desugaredLibraryKeepRuleConsumer =
+ ToolHelper.consumeString(keepRulesHolder::set))
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
.compile()
.inspect(this::checkRewrittenInvokes)
.addRunClasspathFiles(
buildDesugaredLibrary(
- parameters.getApiLevel(), keepRuleConsumer.get(), shrinkCoreLibrary))
+ parameters.getApiLevel(), keepRulesHolder.get(), shrinkCoreLibrary))
.run(parameters.getRuntime(), TEST_CLASS)
.assertSuccess();
assertLines2By2Correct(r8TestRunResult.getStdOut());
- assertGeneratedKeepRulesAreCorrect(keepRuleConsumer.get());
+ assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
// Flaky: There might be a missing method on lambda deserialization.
r8TestRunResult.assertStderrMatches(
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
index 1d0a1ba..a16962d 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
@@ -46,7 +46,7 @@
options.ignoreMissingClasses = true;
// Store the generated Proguard map.
options.proguardMapConsumer =
- (proguardMap, handler) -> result.proguardMap = proguardMap;
+ ToolHelper.consumeString(proguardMap -> result.proguardMap = proguardMap);
});
return result;
}
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreLatestTreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreLatestTreeShakeJarVerificationTest.java
index a8da699..0168988 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreLatestTreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreLatestTreeShakeJarVerificationTest.java
@@ -32,7 +32,7 @@
additionalProguardConfiguration,
options -> {
options.proguardMapConsumer =
- (proguardMap, handler) -> this.proguardMap1 = proguardMap;
+ ToolHelper.consumeString(proguardMap -> this.proguardMap1 = proguardMap);
});
AndroidApp app2 =
buildAndTreeShakeFromDeployJar(
@@ -43,7 +43,7 @@
additionalProguardConfiguration,
options -> {
options.proguardMapConsumer =
- (proguardMap, handler) -> this.proguardMap2 = proguardMap;
+ ToolHelper.consumeString(proguardMap -> this.proguardMap2 = proguardMap);
});
// Verify that the result of the two compilations was the same.
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
index 5803355..be62787 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
@@ -7,12 +7,11 @@
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.CompilationMode;
-import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DexIndexedConsumer.ArchiveConsumer;
import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
+import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.AndroidApp;
import java.io.File;
-import java.util.function.Supplier;
import org.junit.Test;
public class R8GMSCoreV10DeployJarVerificationTest extends GMSCoreDeployJarVerificationTest {
@@ -34,8 +33,8 @@
false,
options ->
options.proguardMapConsumer =
- (proguardMap, handler) -> this.proguardMap1 = proguardMap,
- ()-> new ArchiveConsumer(app1Zip.toPath(), true));
+ ToolHelper.consumeString(proguardMap -> this.proguardMap1 = proguardMap),
+ () -> new ArchiveConsumer(app1Zip.toPath(), true));
AndroidApp app2 =
buildFromDeployJar(
CompilerUnderTest.R8,
@@ -44,10 +43,8 @@
false,
options ->
options.proguardMapConsumer =
- (proguardMap, handler) -> this.proguardMap2 = proguardMap,
- ()-> new ArchiveConsumer(app2Zip.toPath(), true));
-
-
+ ToolHelper.consumeString(proguardMap -> this.proguardMap2 = proguardMap),
+ () -> new ArchiveConsumer(app2Zip.toPath(), true));
// Verify that the result of the two compilations was the same.
assertIdenticalApplications(app1, app2);
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
index 4374d0e..00a751a 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
@@ -6,6 +6,7 @@
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.AndroidApp;
import org.junit.Test;
@@ -26,7 +27,7 @@
GMSCORE_V10_MAX_SIZE,
options ->
options.proguardMapConsumer =
- (proguardMap, handler) -> this.proguardMap1 = proguardMap);
+ ToolHelper.consumeString(proguardMap -> this.proguardMap1 = proguardMap));
AndroidApp app2 =
buildAndTreeShakeFromDeployJar(
CompilationMode.RELEASE,
@@ -35,7 +36,7 @@
GMSCORE_V10_MAX_SIZE,
options ->
options.proguardMapConsumer =
- (proguardMap, handler) -> this.proguardMap2 = proguardMap);
+ ToolHelper.consumeString(proguardMap -> this.proguardMap2 = proguardMap));
// Verify that the result of the two compilations was the same.
assertIdenticalApplications(app1, app2);
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListOutputTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListOutputTest.java
index 33a8bf3..123744d 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListOutputTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListOutputTest.java
@@ -51,10 +51,17 @@
private static class TestMainDexListConsumer implements StringConsumer {
public boolean called = false;
+ public StringBuilder builder = new StringBuilder();
@Override
public void accept(String string, DiagnosticsHandler handler) {
called = true;
+ builder.append(string);
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ String string = builder.toString();
assertTrue(string.contains(testClassMainDexName));
assertTrue(string.contains("Lambda"));
}
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
index c23e3fe..3806c05 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -311,7 +311,7 @@
.addProgramFiles(inputJar)
.addProgramFiles(Paths.get(EXAMPLE_BUILD_DIR, "multidexfakeframeworks" + JAR_EXTENSION))
.addMainDexRulesFiles(mainDexRules)
- .setMainDexListConsumer((string, handler) -> mainDexListOutput.set(string))
+ .setMainDexListConsumer(ToolHelper.consumeString(mainDexListOutput::set))
.build();
GenerateMainDexList.run(mdlCommand);
List<String> mainDexGeneratorMainDexListFromConsumer =
@@ -332,7 +332,7 @@
.setMinApi(minSdk)
.noMinification()
.noTreeShaking()
- .setMainDexListConsumer((string, handler) -> r8MainDexListOutput.set(string))
+ .setMainDexListConsumer(ToolHelper.consumeString(r8MainDexListOutput::set))
.compile()
.writeToZip(out);
diff --git a/src/test/java/com/android/tools/r8/maindexlist/b72312389/B72312389.java b/src/test/java/com/android/tools/r8/maindexlist/b72312389/B72312389.java
index b1c93c1..1978867 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/b72312389/B72312389.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/b72312389/B72312389.java
@@ -84,7 +84,7 @@
.addProguardConfiguration(ImmutableList.of("-dontobfuscate"), Origin.unknown())
.addMainDexRules(keepInstrumentationTestCaseRules, Origin.unknown())
.setProgramConsumer(DexIndexedConsumer.emptyConsumer())
- .setMainDexListConsumer((string, handler) -> mainDexList.set(string))
+ .setMainDexListConsumer(ToolHelper.consumeString(mainDexList::set))
.build();
CodeInspector inspector = new CodeInspector(ToolHelper.runR8(command));
assertTrue(inspector.clazz("instrumentationtest.InstrumentationTest").isPresent());
diff --git a/src/test/java/com/android/tools/r8/naming/AdaptResourceFileNamesTest.java b/src/test/java/com/android/tools/r8/naming/AdaptResourceFileNamesTest.java
index 3ae9fbf..188e58d 100644
--- a/src/test/java/com/android/tools/r8/naming/AdaptResourceFileNamesTest.java
+++ b/src/test/java/com/android/tools/r8/naming/AdaptResourceFileNamesTest.java
@@ -16,7 +16,6 @@
import com.android.tools.r8.DataEntryResource;
import com.android.tools.r8.DataResourceConsumer;
import com.android.tools.r8.DataResourceProvider.Visitor;
-import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.ToolHelper;
@@ -115,7 +114,9 @@
public void testEnabled() throws Exception {
DataResourceConsumerForTesting dataResourceConsumer = new DataResourceConsumerForTesting();
compileWithR8(
- getProguardConfigWithNeverInline(true, null), dataResourceConsumer, this::checkR8Renamings);
+ getProguardConfigWithNeverInline(true, null),
+ dataResourceConsumer,
+ ToolHelper.consumeString(this::checkR8Renamings));
// Check that the generated resources have the expected names.
for (DataEntryResource dataResource : getOriginalDataResources()) {
assertNotNull(
@@ -130,7 +131,7 @@
compileWithR8(
getProguardConfigWithNeverInline(true, "**.md"),
dataResourceConsumer,
- this::checkR8Renamings);
+ ToolHelper.consumeString(this::checkR8Renamings));
// Check that the generated resources have the expected names.
Map<String, String> expectedRenamings =
ImmutableMap.of("adaptresourcefilenames/B.md", "adaptresourcefilenames/b.md");
@@ -160,7 +161,7 @@
compileWithR8(
getProguardConfigWithNeverInline(true, null),
dataResourceConsumer,
- this::checkR8Renamings,
+ ToolHelper.consumeString(this::checkR8Renamings),
ImmutableList.<DataEntryResource>builder()
.addAll(getOriginalDataResources())
.add(
@@ -274,7 +275,7 @@
});
}
- private void checkR8Renamings(String proguardMap, DiagnosticsHandler handler) {
+ private void checkR8Renamings(String proguardMap) {
try {
// Check that the renamings are as expected. These exact renamings are not important as
// such, but the test expectations rely on them.
diff --git a/src/test/java/com/android/tools/r8/shaking/UsageInformationConsumerTest.java b/src/test/java/com/android/tools/r8/shaking/UsageInformationConsumerTest.java
index 341d696..4c9b057 100644
--- a/src/test/java/com/android/tools/r8/shaking/UsageInformationConsumerTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/UsageInformationConsumerTest.java
@@ -5,11 +5,11 @@
import static org.junit.Assert.assertEquals;
-import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
@@ -33,26 +33,18 @@
this.parameters = parameters;
}
- public static class UsageConsumer implements StringConsumer {
- String data = null;
-
- @Override
- public void accept(String string, DiagnosticsHandler handler) {
- data = string;
- }
- };
-
@Test
public void testConsumer() throws Exception {
- UsageConsumer usageConsumer = new UsageConsumer();
+ Box<String> usageData = new Box<>();
testForR8(parameters.getBackend())
.addProgramClasses(TestClass.class, UnusedClass.class)
.addKeepClassAndMembersRules(TestClass.class)
- .apply(b -> b.getBuilder().setProguardUsageConsumer(usageConsumer))
+ .apply(
+ b -> b.getBuilder().setProguardUsageConsumer(ToolHelper.consumeString(usageData::set)))
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED);
- assertEquals(StringUtils.lines(UnusedClass.class.getTypeName()), usageConsumer.data);
+ assertEquals(StringUtils.lines(UnusedClass.class.getTypeName()), usageData.get());
}
@Test