Revert "Update global synthetics API to support per-file global output."
This reverts commit 3b666fa39bc6420dcbfafcfbc0540be9d4663d20.
Failures on the bots.
Bug: b/230445931
Change-Id: Icce28596d39146314e9385ab883e332014311c3a
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 7cb5133..61aea99 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -185,9 +185,9 @@
() ->
AppInfo.createInitialAppInfo(
app,
- options.isGeneratingDexIndexed()
- ? GlobalSyntheticsStrategy.forSingleOutputMode()
- : GlobalSyntheticsStrategy.forPerFileMode(),
+ options.isGeneratingDexFilePerClassFile()
+ ? GlobalSyntheticsStrategy.forPerFileMode()
+ : GlobalSyntheticsStrategy.forSingleOutputMode(),
applicationReader.readMainDexClasses(app)));
return timing.time("Create app-view", () -> AppView.createForD8(appInfo, typeRewriter, timing));
}
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
index 1f982ce..ea8ad11 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
@@ -3,8 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
-import com.android.tools.r8.references.ClassReference;
-
/**
* Consumer receiving the data representing global synthetics for the program.
*
@@ -27,23 +25,7 @@
* <p>The encoding of the global synthetics is compiler internal and may vary between compiler
* versions. The data received here is thus only valid as inputs to the same compiler version.
*
- * <p>The context class is the class for which the global synthetic data is needed. If compiling
- * in DexIndexed mode, the context class will be null.
- *
- * <p>The accept method will be called at most once for a given context class (any only once at
- * all for a DexIndexed mode compilation). The global data for that class may be the same as for
- * other context classes, but it will be provided for each context.
- *
- * @param data Opaque encoding of the global synthetics for the program.
- * @param context The class giving rise to the global synthetics. Null in DexIndexed mode.
- * @param handler Diagnostics handler for reporting.
+ * @param bytes Opaque encoding of the global synthetics for the program.
*/
- void accept(ByteDataView data, ClassReference context, DiagnosticsHandler handler);
-
- /**
- * Callback indicating that no more global synthetics will be reported for the compilation unit.
- *
- * @param handler Diagnostics handler for reporting.
- */
- default void finished(DiagnosticsHandler handler) {}
+ void accept(byte[] bytes);
}
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 0016655..1e62a10 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -52,8 +52,7 @@
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.ExceptionUtils;
-import com.android.tools.r8.utils.InternalGlobalSyntheticsProgramConsumer.InternalGlobalSyntheticsDexIndexedConsumer;
-import com.android.tools.r8.utils.InternalGlobalSyntheticsProgramConsumer.InternalGlobalSyntheticsDexPerFileConsumer;
+import com.android.tools.r8.utils.InternalGlobalSyntheticsProgramConsumer.InternalGlobalSyntheticsDexConsumer;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.OriginalSourceFiles;
import com.android.tools.r8.utils.PredicateUtils;
@@ -91,7 +90,7 @@
public Set<VirtualFile> globalSyntheticFiles;
public DexIndexedConsumer programConsumer;
- public DexFilePerClassFileConsumer globalsSyntheticsConsumer;
+ public InternalGlobalSyntheticsDexConsumer globalsSyntheticsConsumer;
private static class SortAnnotations extends MixedSectionCollection {
@@ -222,11 +221,7 @@
globalSyntheticFiles = new HashSet<>(files);
virtualFiles.addAll(globalSyntheticFiles);
globalsSyntheticsConsumer =
- options.isGeneratingDexFilePerClassFile()
- ? new InternalGlobalSyntheticsDexPerFileConsumer(
- options.getGlobalSyntheticsConsumer(), appView)
- : new InternalGlobalSyntheticsDexIndexedConsumer(
- options.getGlobalSyntheticsConsumer());
+ new InternalGlobalSyntheticsDexConsumer(options.getGlobalSyntheticsConsumer());
}
return virtualFiles;
}
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 d3632ab..7f8d075 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -169,7 +169,7 @@
}
if (!globalSyntheticClasses.isEmpty()) {
InternalGlobalSyntheticsCfConsumer globalsConsumer =
- new InternalGlobalSyntheticsCfConsumer(options.getGlobalSyntheticsConsumer(), appView);
+ new InternalGlobalSyntheticsCfConsumer(options.getGlobalSyntheticsConsumer());
for (DexProgramClass clazz : globalSyntheticClasses) {
writeClassCatchingErrors(
clazz, globalsConsumer, rewriter, markerString, sourceFileEnvironment);
diff --git a/src/main/java/com/android/tools/r8/utils/InternalGlobalSyntheticsProgramConsumer.java b/src/main/java/com/android/tools/r8/utils/InternalGlobalSyntheticsProgramConsumer.java
index 3be0d57..3945a6e 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalGlobalSyntheticsProgramConsumer.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalGlobalSyntheticsProgramConsumer.java
@@ -12,18 +12,12 @@
import com.android.tools.r8.GlobalSyntheticsConsumer;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.Version;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.references.Reference;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.IdentityHashMap;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -32,110 +26,67 @@
public static final String COMPILER_INFO_ENTRY_NAME = "compilerinfo";
public static final String OUTPUT_KIND_ENTRY_NAME = "kind";
- // Builder for constructing a valid "globals" data payload.
- private static class GlobalsFileBuilder {
+ private final GlobalSyntheticsConsumer consumer;
+ private final List<Pair<String, byte[]>> content = new ArrayList<>();
- private final Kind kind;
- private final List<Pair<String, byte[]>> content = new ArrayList<>();
+ public InternalGlobalSyntheticsProgramConsumer(GlobalSyntheticsConsumer consumer) {
+ this.consumer = consumer;
+ }
- public GlobalsFileBuilder(Kind kind) {
- this.kind = kind;
+ public abstract Kind getKind();
+
+ synchronized void addGlobalSynthetic(String descriptor, byte[] data) {
+ add(getGlobalSyntheticFileName(descriptor), data);
+ }
+
+ private void add(String entryName, byte[] data) {
+ content.add(new Pair<>(entryName, data));
+ }
+
+ public void finished(DiagnosticsHandler handler) {
+ // Add meta information.
+ add(COMPILER_INFO_ENTRY_NAME, Version.getVersionString().getBytes(StandardCharsets.UTF_8));
+ add(OUTPUT_KIND_ENTRY_NAME, getKind().toString().getBytes(StandardCharsets.UTF_8));
+
+ // Size estimate to avoid reallocation of the byte output array.
+ final int zipHeaderOverhead = 500;
+ final int zipEntryOverhead = 200;
+ int estimatedZipSize =
+ zipHeaderOverhead
+ + ListUtils.fold(
+ content,
+ 0,
+ (acc, pair) ->
+ acc + pair.getFirst().length() + pair.getSecond().length + zipEntryOverhead);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(estimatedZipSize);
+ try (ZipOutputStream stream = new ZipOutputStream(baos)) {
+ for (Pair<String, byte[]> pair : content) {
+ ZipUtils.writeToZipStream(stream, pair.getFirst(), pair.getSecond(), ZipEntry.STORED);
+ // Clear out the bytes to avoid three copies when converting the boas.
+ pair.setSecond(null);
+ }
+ } catch (IOException e) {
+ handler.error(new ExceptionDiagnostic(e));
+ }
+ byte[] bytes = baos.toByteArray();
+ consumer.accept(bytes);
+ }
+
+ private static String getGlobalSyntheticFileName(String descriptor) {
+ assert descriptor != null && DescriptorUtils.isClassDescriptor(descriptor);
+ return DescriptorUtils.getClassBinaryNameFromDescriptor(descriptor)
+ + GLOBAL_SYNTHETIC_EXTENSION;
+ }
+
+ public static class InternalGlobalSyntheticsDexConsumer
+ extends InternalGlobalSyntheticsProgramConsumer implements DexFilePerClassFileConsumer {
+
+ public InternalGlobalSyntheticsDexConsumer(GlobalSyntheticsConsumer consumer) {
+ super(consumer);
}
+ @Override
public Kind getKind() {
- return kind;
- }
-
- void addGlobalSynthetic(String descriptor, byte[] data) {
- add(getGlobalSyntheticFileName(descriptor), data);
- }
-
- private void add(String entryName, byte[] data) {
- content.add(new Pair<>(entryName, data));
- }
-
- public byte[] build() throws IOException {
- // Add meta information.
- add(COMPILER_INFO_ENTRY_NAME, Version.getVersionString().getBytes(StandardCharsets.UTF_8));
- add(OUTPUT_KIND_ENTRY_NAME, getKind().toString().getBytes(StandardCharsets.UTF_8));
-
- // Size estimate to avoid reallocation of the byte output array.
- final int zipHeaderOverhead = 500;
- final int zipEntryOverhead = 200;
- int estimatedZipSize =
- zipHeaderOverhead
- + ListUtils.fold(
- content,
- 0,
- (acc, pair) ->
- acc + pair.getFirst().length() + pair.getSecond().length + zipEntryOverhead);
- ByteArrayOutputStream baos = new ByteArrayOutputStream(estimatedZipSize);
- try (ZipOutputStream stream = new ZipOutputStream(baos)) {
- for (Pair<String, byte[]> pair : content) {
- ZipUtils.writeToZipStream(stream, pair.getFirst(), pair.getSecond(), ZipEntry.STORED);
- // Clear out the bytes to avoid three copies when converting the boas.
- pair.setSecond(null);
- }
- }
- return baos.toByteArray();
- }
-
- private static String getGlobalSyntheticFileName(String descriptor) {
- assert descriptor != null && DescriptorUtils.isClassDescriptor(descriptor);
- return DescriptorUtils.getClassBinaryNameFromDescriptor(descriptor)
- + GLOBAL_SYNTHETIC_EXTENSION;
- }
- }
-
- public static class InternalGlobalSyntheticsDexIndexedConsumer
- implements DexFilePerClassFileConsumer {
-
- private final GlobalSyntheticsConsumer clientConsumer;
- private final GlobalsFileBuilder builder = new GlobalsFileBuilder(Kind.DEX);
-
- public InternalGlobalSyntheticsDexIndexedConsumer(GlobalSyntheticsConsumer clientConsumer) {
- this.clientConsumer = clientConsumer;
- }
-
- @Override
- public synchronized void accept(
- String primaryClassDescriptor,
- ByteDataView data,
- Set<String> descriptors,
- DiagnosticsHandler handler) {
- builder.addGlobalSynthetic(primaryClassDescriptor, data.copyByteData());
- }
-
- @Override
- public void finished(DiagnosticsHandler handler) {
- byte[] bytes = null;
- try {
- bytes = builder.build();
- } catch (IOException e) {
- handler.error(new ExceptionDiagnostic(e));
- }
- if (bytes != null) {
- clientConsumer.accept(ByteDataView.of(bytes), null, handler);
- }
- clientConsumer.finished(handler);
- }
-
- @Override
- public boolean combineSyntheticClassesWithPrimaryClass() {
- return false;
- }
- }
-
- public static class InternalGlobalSyntheticsDexPerFileConsumer extends PerFileBase
- implements DexFilePerClassFileConsumer {
-
- public InternalGlobalSyntheticsDexPerFileConsumer(
- GlobalSyntheticsConsumer consumer, AppView appView) {
- super(consumer, appView);
- }
-
- @Override
- Kind getKind() {
return Kind.DEX;
}
@@ -145,7 +96,7 @@
ByteDataView data,
Set<String> descriptors,
DiagnosticsHandler handler) {
- addGlobal(primaryClassDescriptor, data);
+ addGlobalSynthetic(primaryClassDescriptor, data.copyByteData());
}
@Override
@@ -154,73 +105,21 @@
}
}
- public static class InternalGlobalSyntheticsCfConsumer extends PerFileBase
- implements ClassFileConsumer {
+ public static class InternalGlobalSyntheticsCfConsumer
+ extends InternalGlobalSyntheticsProgramConsumer implements ClassFileConsumer {
- public InternalGlobalSyntheticsCfConsumer(GlobalSyntheticsConsumer consumer, AppView appView) {
- super(consumer, appView);
+ public InternalGlobalSyntheticsCfConsumer(GlobalSyntheticsConsumer consumer) {
+ super(consumer);
}
@Override
- Kind getKind() {
+ public Kind getKind() {
return Kind.CF;
}
@Override
public void accept(ByteDataView data, String descriptor, DiagnosticsHandler handler) {
- addGlobal(descriptor, data);
- }
- }
-
- private abstract static class PerFileBase {
-
- private final AppView appView;
- private final GlobalSyntheticsConsumer clientConsumer;
- private final Map<DexType, byte[]> globalToBytes = new ConcurrentHashMap<>();
-
- public PerFileBase(GlobalSyntheticsConsumer consumer, AppView appView) {
- this.appView = appView;
- this.clientConsumer = consumer;
- }
-
- abstract Kind getKind();
-
- public void finished(DiagnosticsHandler handler) {
- Map<DexType, Set<DexType>> contextToGlobals = new IdentityHashMap<>();
- for (DexType globalType : globalToBytes.keySet()) {
- for (DexType contextType :
- appView.getSyntheticItems().getFinalGlobalSyntheticContexts(globalType)) {
- contextToGlobals
- .computeIfAbsent(contextType, k -> SetUtils.newIdentityHashSet())
- .add(globalType);
- }
- }
- contextToGlobals.forEach(
- (context, globals) -> {
- GlobalsFileBuilder builder = new GlobalsFileBuilder(getKind());
- globals.forEach(
- global ->
- builder.addGlobalSynthetic(
- global.toDescriptorString(), globalToBytes.get(global)));
- byte[] bytes = null;
- try {
- bytes = builder.build();
- } catch (IOException e) {
- handler.error(new ExceptionDiagnostic(e));
- }
- if (bytes != null) {
- clientConsumer.accept(
- ByteDataView.of(bytes),
- Reference.classFromDescriptor(context.toDescriptorString()),
- handler);
- }
- });
- clientConsumer.finished(handler);
- }
-
- void addGlobal(String descriptor, ByteDataView data) {
- DexType type = appView.dexItemFactory().createType(descriptor);
- globalToBytes.put(type, data.copyByteData());
+ addGlobalSynthetic(descriptor, data.copyByteData());
}
}
}
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
index 184e984..b999875 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
@@ -7,26 +7,18 @@
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.verifyThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.OutputMode;
import com.android.tools.r8.SingleTestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.synthesis.globals.GlobalSyntheticsTestingConsumer;
import com.android.tools.r8.testing.AndroidBuildVersion;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import java.nio.file.Path;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -49,26 +41,18 @@
return parameters.isDexRuntime() && parameters.getApiLevel().isGreaterThanOrEqualTo(mockLevel);
}
- private void setupTestCompileBuilder(TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder) {
+ private void setupTestBuilder(TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder) {
testBuilder
.addProgramClasses(Main.class, TestClass.class)
.addLibraryClasses(LibraryClass.class)
.addDefaultRuntimeLibrary(parameters)
.setMinApi(parameters.getApiLevel())
+ .addAndroidBuildVersion()
.apply(ApiModelingTestHelper::enableStubbingOfClasses)
.apply(setMockApiLevelForClass(LibraryClass.class, mockLevel))
.apply(setMockApiLevelForDefaultInstanceInitializer(LibraryClass.class, mockLevel));
}
- private void setupTestRuntimeBuilder(TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder) {
- testBuilder.setMinApi(parameters.getApiLevel()).addAndroidBuildVersion();
- }
-
- private void setupTestBuilder(TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder) {
- setupTestCompileBuilder(testBuilder);
- setupTestRuntimeBuilder(testBuilder);
- }
-
private boolean addToBootClasspath() {
return parameters.isDexRuntime()
&& parameters.getRuntime().maxSupportedApiLevel().isGreaterThanOrEqualTo(mockLevel);
@@ -103,63 +87,6 @@
}
@Test
- public void testD8MergeIndexed() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testD8Merge(OutputMode.DexIndexed);
- }
-
- @Test
- public void testD8MergeFilePerClass() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testD8Merge(OutputMode.DexFilePerClass);
- }
-
- @Test
- public void testD8MergeFilePerClassFile() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testD8Merge(OutputMode.DexFilePerClassFile);
- }
-
- public void testD8Merge(OutputMode outputMode) throws Exception {
- GlobalSyntheticsTestingConsumer globals = new GlobalSyntheticsTestingConsumer();
- Path incrementalOut =
- testForD8()
- .debug()
- .setOutputMode(outputMode)
- .setIntermediate(true)
- .apply(b -> b.getBuilder().setGlobalSyntheticsConsumer(globals))
- // TODO(b/213552119): Remove when enabled by default.
- .apply(ApiModelingTestHelper::enableApiCallerIdentification)
- .apply(this::setupTestCompileBuilder)
- .compile()
- .writeToZip();
-
- if (isGreaterOrEqualToMockLevel()) {
- assertFalse(globals.hasGlobals());
- } else if (outputMode == OutputMode.DexIndexed) {
- assertTrue(globals.hasGlobals());
- assertTrue(globals.isSingleGlobal());
- } else {
- assertTrue(globals.hasGlobals());
- // The TestClass does reference the mock and should have globals.
- assertNotNull(globals.getProvider(Reference.classFromClass(TestClass.class)));
- // The Main class does not have references to the mock and should have no globals.
- assertNull(globals.getProvider(Reference.classFromClass(Main.class)));
- }
-
- testForD8()
- .debug()
- .addProgramFiles(incrementalOut)
- .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals.getProviders()))
- .apply(this::setupTestRuntimeBuilder)
- .compile()
- .applyIf(addToBootClasspath(), b -> b.addBootClasspathClasses(LibraryClass.class))
- .run(parameters.getRuntime(), Main.class)
- .apply(this::checkOutput)
- .inspect(this::inspect);
- }
-
- @Test
public void testR8() throws Exception {
testForR8(parameters.getBackend())
.apply(this::setupTestBuilder)
diff --git a/src/test/java/com/android/tools/r8/compilerapi/globalsynthetics/GlobalSyntheticsTest.java b/src/test/java/com/android/tools/r8/compilerapi/globalsynthetics/GlobalSyntheticsTest.java
index e711b40..edc42c2 100644
--- a/src/test/java/com/android/tools/r8/compilerapi/globalsynthetics/GlobalSyntheticsTest.java
+++ b/src/test/java/com/android/tools/r8/compilerapi/globalsynthetics/GlobalSyntheticsTest.java
@@ -3,11 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.compilerapi.globalsynthetics;
-import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.DexIndexedConsumer;
-import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.GlobalSyntheticsConsumer;
import com.android.tools.r8.GlobalSyntheticsResourceProvider;
import com.android.tools.r8.ResourceException;
@@ -15,7 +13,6 @@
import com.android.tools.r8.compilerapi.CompilerApiTest;
import com.android.tools.r8.compilerapi.CompilerApiTestRunner;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.references.ClassReference;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
@@ -74,16 +71,10 @@
.setGlobalSyntheticsConsumer(
new GlobalSyntheticsConsumer() {
@Override
- public void accept(
- ByteDataView data, ClassReference context, DiagnosticsHandler handler) {
+ public void accept(byte[] bytes) {
// Nothing is actually received here as MockClass does not give rise to
// globals.
}
-
- @Override
- public void finished(DiagnosticsHandler handler) {
- // Nothing to do, just checking we can override finished.
- }
})
.build());
}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
index 596f50f..d3816f8 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
@@ -10,7 +10,6 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.D8TestCompileResult;
@@ -19,7 +18,7 @@
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.errors.DuplicateTypesDiagnostic;
import com.android.tools.r8.errors.MissingGlobalSyntheticsConsumerDiagnostic;
-import com.android.tools.r8.synthesis.globals.GlobalSyntheticsTestingConsumer;
+import com.android.tools.r8.synthesis.globals.GlobalSyntheticsConsumerAndProvider;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.nio.file.Path;
@@ -73,10 +72,7 @@
@Test
public void testMergeDesugaredInputs() throws Exception {
- // TODO(b/230445931): Records do not yet have contexts so per-file modes fail.
- // This test should be extended or duplicated to also test the pre-file-dex modes.
- assumeTrue("b/230445931", parameters.isDexRuntime());
- GlobalSyntheticsTestingConsumer globals1 = new GlobalSyntheticsTestingConsumer();
+ GlobalSyntheticsConsumerAndProvider globals1 = new GlobalSyntheticsConsumerAndProvider();
Path output1 =
testForD8(parameters.getBackend())
.addProgramClassFileData(PROGRAM_DATA_1)
@@ -87,7 +83,7 @@
.inspect(this::assertDoesNotHaveRecordTag)
.writeToZip();
- GlobalSyntheticsTestingConsumer globals2 = new GlobalSyntheticsTestingConsumer();
+ GlobalSyntheticsConsumerAndProvider globals2 = new GlobalSyntheticsConsumerAndProvider();
Path output2 =
testForD8(parameters.getBackend())
.addProgramClassFileData(PROGRAM_DATA_2)
@@ -98,17 +94,13 @@
.inspect(this::assertDoesNotHaveRecordTag)
.writeToZip();
- assertTrue(globals1.hasGlobals());
- assertTrue(globals2.hasGlobals());
+ assertTrue(globals1.hasBytes());
+ assertTrue(globals2.hasBytes());
D8TestCompileResult result =
testForD8(parameters.getBackend())
.addProgramFiles(output1, output2)
- .apply(
- b ->
- b.getBuilder()
- .addGlobalSyntheticsResourceProviders(
- globals1.getIndexedModeProvider(), globals2.getIndexedModeProvider()))
+ .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals1, globals2))
.setMinApi(parameters.getApiLevel())
.compile()
.inspect(this::assertHasRecordTag);
@@ -119,7 +111,7 @@
@Test
public void testMergeDesugaredAndNonDesugaredInputs() throws Exception {
- GlobalSyntheticsTestingConsumer globals1 = new GlobalSyntheticsTestingConsumer();
+ GlobalSyntheticsConsumerAndProvider globals1 = new GlobalSyntheticsConsumerAndProvider();
Path output1 =
testForD8(parameters.getBackend())
.addProgramClassFileData(PROGRAM_DATA_1)
@@ -132,10 +124,7 @@
D8TestCompileResult result =
testForD8(parameters.getBackend())
.addProgramFiles(output1)
- .apply(
- b ->
- b.getBuilder()
- .addGlobalSyntheticsResourceProviders(globals1.getIndexedModeProvider()))
+ .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals1))
.addProgramClassFileData(PROGRAM_DATA_2)
.setMinApi(parameters.getApiLevel())
.compile();
diff --git a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
index 9a74bb5..e94b6b6 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
@@ -11,7 +11,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.synthesis.globals.GlobalSyntheticsTestingConsumer;
+import com.android.tools.r8.synthesis.globals.GlobalSyntheticsConsumerAndProvider;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import java.nio.file.Path;
@@ -75,14 +75,11 @@
@Test
public void testD8Intermediate() throws Exception {
assumeTrue(parameters.isDexRuntime());
- GlobalSyntheticsTestingConsumer globals = new GlobalSyntheticsTestingConsumer();
+ GlobalSyntheticsConsumerAndProvider globals = new GlobalSyntheticsConsumerAndProvider();
Path path = compileIntermediate(globals);
testForD8()
.addProgramFiles(path)
- .apply(
- b ->
- b.getBuilder()
- .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
+ .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals))
.setMinApi(parameters.getApiLevel())
.setIncludeClassesChecksum(true)
.run(parameters.getRuntime(), MAIN_TYPE)
@@ -92,15 +89,12 @@
@Test
public void testD8IntermediateNoDesugaringInStep2() throws Exception {
assumeTrue(parameters.isDexRuntime());
- GlobalSyntheticsTestingConsumer globals = new GlobalSyntheticsTestingConsumer();
+ GlobalSyntheticsConsumerAndProvider globals = new GlobalSyntheticsConsumerAndProvider();
Path path = compileIntermediate(globals);
// In Android Studio they disable desugaring at this point to improve build speed.
testForD8()
.addProgramFiles(path)
- .apply(
- b ->
- b.getBuilder()
- .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
+ .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals))
.setMinApi(parameters.getApiLevel())
.setIncludeClassesChecksum(true)
.disableDesugaring()
diff --git a/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsConsumerAndProvider.java b/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsConsumerAndProvider.java
new file mode 100644
index 0000000..57f5622
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsConsumerAndProvider.java
@@ -0,0 +1,41 @@
+// Copyright (c) 2022, 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.synthesis.globals;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import com.android.tools.r8.GlobalSyntheticsConsumer;
+import com.android.tools.r8.GlobalSyntheticsResourceProvider;
+import com.android.tools.r8.ResourceException;
+import com.android.tools.r8.origin.Origin;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+public class GlobalSyntheticsConsumerAndProvider
+ implements GlobalSyntheticsConsumer, GlobalSyntheticsResourceProvider {
+
+ private byte[] bytes;
+
+ @Override
+ public void accept(byte[] bytes) {
+ assertNull(this.bytes);
+ assertNotNull(bytes);
+ this.bytes = bytes;
+ }
+
+ @Override
+ public Origin getOrigin() {
+ return Origin.unknown();
+ }
+
+ @Override
+ public InputStream getByteStream() throws ResourceException {
+ return new ByteArrayInputStream(bytes);
+ }
+
+ public boolean hasBytes() {
+ return true;
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsTestingConsumer.java b/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsTestingConsumer.java
deleted file mode 100644
index 51897e6..0000000
--- a/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsTestingConsumer.java
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2022, 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.synthesis.globals;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.ByteDataView;
-import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.GlobalSyntheticsConsumer;
-import com.android.tools.r8.GlobalSyntheticsResourceProvider;
-import com.android.tools.r8.ResourceException;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.references.ClassReference;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class GlobalSyntheticsTestingConsumer implements GlobalSyntheticsConsumer {
-
- private final Map<ClassReference, GlobalSyntheticsResourceProvider> globals = new HashMap<>();
- private boolean finished = false;
-
- @Override
- public void accept(ByteDataView data, ClassReference context, DiagnosticsHandler handler) {
- assertFalse(finished);
- assertNotNull(data);
- Origin origin =
- context == null
- ? Origin.unknown()
- : new Origin(Origin.root()) {
- @Override
- public String part() {
- return "globals(" + context.getTypeName() + ")";
- }
- };
- TestingProvider provider = new TestingProvider(origin, data.copyByteData());
- GlobalSyntheticsResourceProvider old = globals.put(context, provider);
- assertNull(old);
- }
-
- @Override
- public void finished(DiagnosticsHandler handler) {
- assertFalse(finished);
- finished = true;
- }
-
- public boolean hasGlobals() {
- return !globals.isEmpty();
- }
-
- public boolean isSingleGlobal() {
- return globals.size() == 1 && globals.get(null) != null;
- }
-
- public GlobalSyntheticsResourceProvider getIndexedModeProvider() {
- assertTrue(isSingleGlobal());
- return globals.get(null);
- }
-
- public GlobalSyntheticsResourceProvider getProvider(ClassReference clazz) {
- assertNotNull("Use getIndexedModeProvider to get single outputs", clazz);
- assertFalse(isSingleGlobal());
- return globals.get(clazz);
- }
-
- public Collection<GlobalSyntheticsResourceProvider> getProviders() {
- return globals.values();
- }
-
- private static class TestingProvider implements GlobalSyntheticsResourceProvider {
-
- private final Origin origin;
- private final byte[] bytes;
-
- public TestingProvider(Origin origin, byte[] bytes) {
- this.origin = origin;
- this.bytes = bytes;
- }
-
- @Override
- public Origin getOrigin() {
- return origin;
- }
-
- @Override
- public InputStream getByteStream() throws ResourceException {
- return new ByteArrayInputStream(bytes);
- }
- }
-}