Ensure stable insertion of markers when writing DEX
Bug: b/243111584
Change-Id: I5cad64531179b7fe9b16f0ac4bdfc8025aa53d9b
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 8be1456..74a3d20 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -46,19 +46,16 @@
import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.InternalOptions.DesugarState;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
-import com.google.common.collect.ImmutableList;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -278,15 +275,6 @@
boolean hasDexResources = appView.appInfo().app().getFlags().hasReadProgramClassFromDex();
Marker marker = options.getMarker(Tool.D8);
- Set<Marker> markers = new HashSet<>(appView.dexItemFactory().extractMarkers());
- // TODO(b/166617364): Don't add an additional marker when desugaring is turned off.
- if (hasClassResources
- && (options.desugarState != DesugarState.OFF
- || markers.isEmpty()
- || (markers.size() == 1 && markers.iterator().next().isL8()))) {
- markers.add(marker);
- }
- Marker.checkCompatibleDesugaredLibrary(markers, options.reporter);
timing.time(
"Run inspections",
@@ -314,7 +302,7 @@
// without iterating again the IR. We fall-back to writing one app with rewriting and
// merging it with the other app in rewriteNonDexInputs.
timing.begin("Rewrite non-dex inputs");
- DexApplication app = rewriteNonDexInputs(appView, inputApp, executor, timing);
+ DexApplication app = rewriteNonDexInputs(appView, inputApp, executor, marker, timing);
timing.end();
appView.setAppInfo(
new AppInfo(
@@ -345,8 +333,7 @@
if (options.isGeneratingClassFiles()) {
new CfApplicationWriter(appView, marker).write(options.getClassFileConsumer(), inputApp);
} else {
- new ApplicationWriter(appView, marker == null ? null : ImmutableList.copyOf(markers))
- .write(executor, inputApp);
+ new ApplicationWriter(appView, marker).write(executor, inputApp);
}
options.printWarnings();
} catch (ExecutionException e) {
@@ -408,7 +395,11 @@
}
private static DexApplication rewriteNonDexInputs(
- AppView<AppInfo> appView, AndroidApp inputApp, ExecutorService executor, Timing timing)
+ AppView<AppInfo> appView,
+ AndroidApp inputApp,
+ ExecutorService executor,
+ Marker marker,
+ Timing timing)
throws IOException, ExecutionException {
// TODO(b/154575955): Remove the naming lens in D8.
appView
@@ -437,11 +428,7 @@
ConvertedCfFiles convertedCfFiles = new ConvertedCfFiles();
new GenericSignatureRewriter(appView).run(appView.appInfo().classes(), executor);
new KotlinMetadataRewriter(appView).runForD8(executor);
- new ApplicationWriter(
- appView,
- null,
- convertedCfFiles)
- .write(executor);
+ new ApplicationWriter(appView, marker, convertedCfFiles).write(executor);
AndroidApp.Builder builder = AndroidApp.builder(inputApp);
builder.getProgramResourceProviders().clear();
builder.addProgramResourceProvider(convertedCfFiles);
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 0e1eafb..038b821 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -112,7 +112,6 @@
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.io.ByteStreams;
import java.io.ByteArrayOutputStream;
@@ -123,7 +122,6 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -215,18 +213,10 @@
try {
Marker marker = options.getMarker(Tool.R8);
assert marker != null;
- // Get the markers from the input which are different from the one created for this
- // compilation
- Set<Marker> markers = new HashSet<>(appView.dexItemFactory().extractMarkers());
- markers.remove(marker);
if (options.isGeneratingClassFiles()) {
new CfApplicationWriter(appView, marker).write(options.getClassFileConsumer(), inputApp);
} else {
- new ApplicationWriter(
- appView,
- // Ensure that the marker for this compilation is the first in the list.
- ImmutableList.<Marker>builder().add(marker).addAll(markers).build())
- .write(executorService, inputApp);
+ new ApplicationWriter(appView, marker).write(executorService, inputApp);
}
} catch (IOException e) {
throw new RuntimeException("Cannot write application", 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 845ca61..bb281b3 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -37,6 +37,7 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItem;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
@@ -62,6 +63,7 @@
import com.android.tools.r8.utils.InternalGlobalSyntheticsProgramConsumer.InternalGlobalSyntheticsDexIndexedConsumer;
import com.android.tools.r8.utils.InternalGlobalSyntheticsProgramConsumer.InternalGlobalSyntheticsDexPerFileConsumer;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.OriginalSourceFiles;
import com.android.tools.r8.utils.PredicateUtils;
import com.android.tools.r8.utils.Reporter;
@@ -77,10 +79,12 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -93,7 +97,8 @@
public final InternalOptions options;
private final CodeToKeep desugaredLibraryCodeToKeep;
private final Predicate<DexType> isTypeMissing;
- public List<Marker> markers;
+ private final Optional<Marker> currentMarker;
+ public Collection<Marker> previousMarkers;
public List<DexString> markerStrings;
public Set<VirtualFile> globalSyntheticFiles;
@@ -169,21 +174,19 @@
}
}
- public ApplicationWriter(AppView<?> appView, List<Marker> markers) {
- this(appView, markers, null);
+ public ApplicationWriter(AppView<?> appView, Marker marker) {
+ this(appView, marker, null);
}
- public ApplicationWriter(
- AppView<?> appView,
- List<Marker> markers,
- DexIndexedConsumer consumer) {
+ public ApplicationWriter(AppView<?> appView, Marker marker, DexIndexedConsumer consumer) {
this.appView = appView;
this.options = appView.options();
this.desugaredLibraryCodeToKeep = CodeToKeep.createCodeToKeep(appView);
- this.markers = markers;
+ this.currentMarker = Optional.ofNullable(marker);
this.programConsumer = consumer;
this.isTypeMissing =
PredicateUtils.isNull(appView.appInfo()::definitionForWithoutExistenceAssert);
+ this.previousMarkers = appView.dexItemFactory().extractMarkers();
}
private NamingLens getNamingLens() {
@@ -316,8 +319,8 @@
encodeChecksums(virtualFiles);
timing.end();
}
- assert markers == null
- || markers.isEmpty()
+ assert previousMarkers == null
+ || previousMarkers.isEmpty()
|| appView.dexItemFactory().extractMarkers() != null;
assert appView.withProtoShrinker(
shrinker -> virtualFiles.stream().allMatch(shrinker::verifyDeadProtoTypesNotReferenced),
@@ -404,26 +407,29 @@
private void computeMarkerStrings(
Box<ProguardMapId> delayedProguardMapId, List<LazyDexString> lazyDexStrings) {
- if (markers != null && !markers.isEmpty()) {
- int firstNonLazyMarker = 0;
- if (willComputeProguardMap()) {
- firstNonLazyMarker++;
- lazyDexStrings.add(
- new LazyDexString() {
-
- @Override
- public DexString internalCompute() {
- Marker marker = markers.get(0);
- marker.setPgMapId(delayedProguardMapId.get().getId());
- return marker.toDexString(appView.dexItemFactory());
- }
- });
- }
- markerStrings = new ArrayList<>(markers.size() - firstNonLazyMarker);
- for (int i = firstNonLazyMarker; i < markers.size(); i++) {
- markerStrings.add(markers.get(i).toDexString(appView.dexItemFactory()));
- }
+ List<Marker> allMarkers = new ArrayList<>();
+ if (previousMarkers != null) {
+ allMarkers.addAll(previousMarkers);
}
+ DexItemFactory factory = appView.dexItemFactory();
+ currentMarker.ifPresent(
+ marker -> {
+ if (willComputeProguardMap()) {
+ lazyDexStrings.add(
+ new LazyDexString() {
+
+ @Override
+ public DexString internalCompute() {
+ marker.setPgMapId(delayedProguardMapId.get().getId());
+ return marker.toDexString(factory);
+ }
+ });
+ } else {
+ allMarkers.add(marker);
+ }
+ });
+ allMarkers.sort(Comparator.comparing(Marker::toString));
+ markerStrings = ListUtils.map(allMarkers, marker -> marker.toDexString(factory));
}
private OriginalSourceFiles computeSourceFileString(
diff --git a/src/main/java/com/android/tools/r8/dex/Marker.java b/src/main/java/com/android/tools/r8/dex/Marker.java
index f2b1e15..b308d5d 100644
--- a/src/main/java/com/android/tools/r8/dex/Marker.java
+++ b/src/main/java/com/android/tools/r8/dex/Marker.java
@@ -4,20 +4,15 @@
package com.android.tools.r8.dex;
import com.android.tools.r8.CompilationMode;
-import com.android.tools.r8.errors.DesugaredLibraryMismatchDiagnostic;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.utils.Reporter;
-import com.android.tools.r8.utils.StringDiagnostic;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import java.util.Comparator;
-import java.util.HashSet;
import java.util.Map.Entry;
-import java.util.Set;
/** Abstraction for hidden dex marker intended for the main dex file. */
public class Marker {
@@ -68,55 +63,6 @@
this.jsonObject = jsonObject;
}
- public static void checkCompatibleDesugaredLibrary(Set<Marker> markers, Reporter reporter) {
- if (markers.size() <= 1) {
- return;
- }
- // In L8 compilation, the compilation has two markers, a L8 marker, which has a desugared
- // library property, and either a D8 or a R8 marker, which has no desugared library property.
- // In other compilations, the desugared library versions have to be consistent.
- Set<String> desugaredLibraryIdentifiers = new HashSet<>();
- for (Marker marker : markers) {
- if (marker.tool == Tool.L8) {
- assert marker.getDesugaredLibraryIdentifiers().length > 0;
- assert markers.stream()
- .allMatch(m -> m.tool == Tool.L8 || m.getDesugaredLibraryIdentifiers().length == 0);
- } else {
- String[] identifiers = marker.getDesugaredLibraryIdentifiers();
- String identifier = null;
- switch (identifiers.length) {
- case 0:
- // Only add the <no-library-desugaring> identifier for DEX. A marker from CF is
- // assumed to go though desugaring for compiling to DEX, and that will introduce the
- // DEX marker with the final library desugaring identifier.
- if (marker.isDexBackend()) {
- identifier = NO_LIBRARY_DESUGARING;
- } else {
- assert marker.isCfBackend();
- }
- break;
- case 1:
- identifier = identifiers[0];
- break;
- default:
- // To be implemented once D8/R8 compilation supports multiple desugared libraries.
- throw reporter.fatalError(
- new StringDiagnostic(
- "Merging program compiled with multiple desugared libraries."));
- }
- if (marker.isDesugared() && identifier != null) {
- desugaredLibraryIdentifiers.add(identifier);
- } else {
- assert identifier == null || identifier.equals(NO_LIBRARY_DESUGARING);
- }
- }
- }
-
- if (desugaredLibraryIdentifiers.size() > 1) {
- reporter.error(new DesugaredLibraryMismatchDiagnostic(desugaredLibraryIdentifiers, markers));
- }
- }
-
public Tool getTool() {
return tool;
}
diff --git a/src/main/java/com/android/tools/r8/errors/DesugaredLibraryMismatchDiagnostic.java b/src/main/java/com/android/tools/r8/errors/DesugaredLibraryMismatchDiagnostic.java
index 5141753..f23cee7 100644
--- a/src/main/java/com/android/tools/r8/errors/DesugaredLibraryMismatchDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/DesugaredLibraryMismatchDiagnostic.java
@@ -8,16 +8,17 @@
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
+import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
public class DesugaredLibraryMismatchDiagnostic implements Diagnostic {
private final Set<String> desugaredLibraryIdentifiers;
- private final Set<Marker> markers;
+ private final Collection<Marker> markers;
public DesugaredLibraryMismatchDiagnostic(
- Set<String> desugaredLibraryIdentifiers, Set<Marker> markers) {
+ Set<String> desugaredLibraryIdentifiers, Collection<Marker> markers) {
this.desugaredLibraryIdentifiers = desugaredLibraryIdentifiers;
this.markers = markers;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexByteCodeWriter.java b/src/main/java/com/android/tools/r8/graph/DexByteCodeWriter.java
index 3fe50aa..be0c645 100644
--- a/src/main/java/com/android/tools/r8/graph/DexByteCodeWriter.java
+++ b/src/main/java/com/android/tools/r8/graph/DexByteCodeWriter.java
@@ -12,7 +12,7 @@
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.List;
+import java.util.Collection;
import java.util.function.Consumer;
public abstract class DexByteCodeWriter {
@@ -49,7 +49,7 @@
}
public void writeMarkers(PrintStream output) {
- List<Marker> markers = application.dexItemFactory.extractMarkers();
+ Collection<Marker> markers = application.dexItemFactory.extractMarkers();
System.out.println("Number of markers: " + markers.size());
for (Marker marker : markers) {
output.println(marker.toString());
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index bfa111e..b10a4f5 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -52,7 +52,9 @@
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -2598,9 +2600,9 @@
// Debugging support to extract marking string.
// Find all markers.
- public synchronized List<Marker> extractMarkers() {
+ public synchronized Collection<Marker> extractMarkers() {
// This is slow but it is not needed for any production code yet.
- List<Marker> markers = new ArrayList<>();
+ Set<Marker> markers = new HashSet<>();
for (DexString dexString : strings.keySet()) {
Marker marker = Marker.parse(dexString);
if (marker != null) {
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 6586750..461dc2a 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -90,7 +90,7 @@
private final DexApplication application;
private final AppView<?> appView;
private final InternalOptions options;
- private final Marker marker;
+ private final Optional<Marker> marker;
private final Predicate<DexType> isTypeMissing;
private static final CfVersion MIN_VERSION_FOR_COMPILER_GENERATED_CODE = CfVersion.V1_6;
@@ -99,8 +99,7 @@
this.application = appView.appInfo().app();
this.appView = appView;
this.options = appView.options();
- assert marker != null;
- this.marker = marker;
+ this.marker = Optional.ofNullable(marker);
this.isTypeMissing =
PredicateUtils.isNull(appView.appInfo()::definitionForWithoutExistenceAssert);
}
@@ -137,6 +136,7 @@
private void writeApplication(AndroidApp inputApp, ClassFileConsumer consumer) {
ProguardMapId proguardMapId = null;
if (options.proguardMapConsumer != null) {
+ assert marker.isPresent();
proguardMapId =
runAndWriteMap(
inputApp,
@@ -144,10 +144,9 @@
application.timing,
OriginalSourceFiles.fromClasses(),
DebugRepresentation.none(options));
- marker.setPgMapId(proguardMapId.getId());
+ marker.get().setPgMapId(proguardMapId.getId());
}
- Optional<String> markerString =
- includeMarker(marker) ? Optional.of(marker.toString()) : Optional.empty();
+ Optional<String> markerString = marker.filter(this::includeMarker).map(Marker::toString);
SourceFileEnvironment sourceFileEnvironment = null;
if (options.sourceFileProvider != null) {
sourceFileEnvironment = ApplicationWriter.createSourceFileEnvironment(proguardMapId);
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
index be8001a..de28b58 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
@@ -14,14 +14,10 @@
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8TestCompileResult;
-import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.ExtractMarker;
import com.android.tools.r8.LibraryDesugaringTestConfiguration;
import com.android.tools.r8.TestDiagnosticMessages;
@@ -63,35 +59,39 @@
@Test
public void testMergeDesugaredAndNonDesugared() throws Exception {
- D8TestCompileResult compileResult;
- try {
- compileResult =
- testForD8()
- .addLibraryFiles(libraryDesugaringSpecification.getLibraryFiles())
- .addProgramFiles(buildPart1DesugaredLibrary(), buildPart2NoDesugaredLibrary())
- .setMinApi(parameters.getApiLevel())
- .applyIf(
- someLibraryDesugaringRequired(),
- b ->
- b.enableCoreLibraryDesugaring(
- LibraryDesugaringTestConfiguration.forSpecification(
- libraryDesugaringSpecification.getSpecification())))
- .compileWithExpectedDiagnostics(this::assertError)
- .addRunClasspathFiles(
- getNonShrunkDesugaredLib(parameters, libraryDesugaringSpecification));
- assertFalse(expectError());
- } catch (CompilationFailedException e) {
- assertTrue(expectError());
- return;
- }
- assert !expectError();
- assert compileResult != null;
+ D8TestCompileResult compileResult =
+ testForD8()
+ .addLibraryFiles(libraryDesugaringSpecification.getLibraryFiles())
+ .addProgramFiles(buildPart1DesugaredLibrary(), buildPart2NoDesugaredLibrary())
+ .setMinApi(parameters.getApiLevel())
+ .applyIf(
+ someLibraryDesugaringRequired(),
+ b ->
+ b.enableCoreLibraryDesugaring(
+ LibraryDesugaringTestConfiguration.forSpecification(
+ libraryDesugaringSpecification.getSpecification())))
+ .compile()
+ .addRunClasspathFiles(
+ getNonShrunkDesugaredLib(parameters, libraryDesugaringSpecification));
compileResult
.run(parameters.getRuntime(), Part1.class)
- .assertSuccessWithOutputLines(JAVA_RESULT);
+ .assertSuccessWithOutputLines(getExpected());
compileResult
.run(parameters.getRuntime(), Part2.class)
- .assertSuccessWithOutputLines(JAVA_RESULT);
+ .assertFailureWithErrorThatThrowsIf(!isApiAvailable(), NoSuchMethodError.class)
+ .assertSuccessWithOutputLinesIf(isApiAvailable(), JAVA_RESULT);
+ }
+
+ private boolean isApiAvailable() {
+ return parameters.getApiLevel().getLevel() >= AndroidApiLevel.N.getLevel();
+ }
+
+ private String getExpected() {
+ if (isApiAvailable()) {
+ return JAVA_RESULT;
+ } else {
+ return J$_RESULT;
+ }
}
@Test
@@ -169,9 +169,17 @@
.writeToZip();
// D8 dex file output marker has the same marker as the D8 class file output.
- // TODO(b/166617364): They should not be the same after backend is recorded and neither has
- // library desugaring info.
- assertMarkersMatch(ExtractMarker.extractMarkerFromJarFile(desugaredLibDex), markerMatcher);
+ Matcher<Marker> dexMarkerMatcher =
+ allOf(
+ markerTool(Tool.D8),
+ markerCompilationMode(CompilationMode.DEBUG),
+ markerBackend(Backend.DEX),
+ markerIsDesugared(),
+ markerMinApi(parameters.getApiLevel()),
+ not(markerHasDesugaredLibraryIdentifier()));
+ List<Matcher<Marker>> markerMatcherAfterDex = ImmutableList.of(markerMatcher, dexMarkerMatcher);
+ assertMarkersMatch(
+ ExtractMarker.extractMarkerFromJarFile(desugaredLibDex), markerMatcherAfterDex);
// Build an app using library desugaring merging with library not using library desugaring.
Path app;
@@ -183,36 +191,20 @@
.writeToZip();
// When there is no class-file resources we are adding the marker for the last compilation.
- assertMarkersMatch(
- ExtractMarker.extractMarkerFromDexFile(app),
- ImmutableList.of(
- markerMatcher,
- allOf(
- markerTool(Tool.D8),
- markerCompilationMode(CompilationMode.DEBUG),
- markerBackend(Backend.DEX),
- markerIsDesugared(),
- markerMinApi(parameters.getApiLevel()),
- someLibraryDesugaringRequired()
- ? markerHasDesugaredLibraryIdentifier()
- : not(markerHasDesugaredLibraryIdentifier()))));
- }
-
- private void assertError(TestDiagnosticMessages m) {
- List<Diagnostic> errors = m.getErrors();
- if (expectError()) {
- assertEquals(1, errors.size());
- assertTrue(
- errors.stream()
- .anyMatch(
- w ->
- w.getDiagnosticMessage()
- .contains(
- "The compilation is merging inputs with different"
- + " desugared library desugaring")));
- } else {
- assertEquals(0, errors.size());
+ List<Matcher<Marker>> expectedMarkers = new ArrayList<>();
+ expectedMarkers.add(markerMatcher);
+ expectedMarkers.add(dexMarkerMatcher);
+ if (someLibraryDesugaringRequired()) {
+ expectedMarkers.add(
+ allOf(
+ markerTool(Tool.D8),
+ markerCompilationMode(CompilationMode.DEBUG),
+ markerBackend(Backend.DEX),
+ markerIsDesugared(),
+ markerMinApi(parameters.getApiLevel()),
+ markerHasDesugaredLibraryIdentifier()));
}
+ assertMarkersMatch(ExtractMarker.extractMarkerFromDexFile(app), expectedMarkers);
}
private boolean expectError() {
@@ -241,21 +233,12 @@
.addRunClasspathFiles(
getNonShrunkDesugaredLib(parameters, libraryDesugaringSpecification))
.inspectDiagnosticMessages(this::assertWarningPresent);
- if (parameters.getApiLevel().getLevel() < AndroidApiLevel.N.getLevel()) {
- compileResult
- .run(parameters.getRuntime(), Part1.class)
- .assertSuccessWithOutputLines(J$_RESULT);
- compileResult
- .run(parameters.getRuntime(), Part2.class)
- .assertSuccessWithOutputLines(J$_RESULT);
- } else {
- compileResult
- .run(parameters.getRuntime(), Part1.class)
- .assertSuccessWithOutputLines(JAVA_RESULT);
- compileResult
- .run(parameters.getRuntime(), Part2.class)
- .assertSuccessWithOutputLines(JAVA_RESULT);
- }
+ compileResult
+ .run(parameters.getRuntime(), Part1.class)
+ .assertSuccessWithOutputLines(getExpected());
+ compileResult
+ .run(parameters.getRuntime(), Part2.class)
+ .assertSuccessWithOutputLines(getExpected());
}
private void assertWarningPresent(TestDiagnosticMessages testDiagnosticMessages) {