Add API tests for program-resource providers.
Change-Id: Id7958af556aa6cf3c9c6de28c73a73e1ebe1b909
diff --git a/src/test/apiUsageSample/com/android/tools/apiusagesample/D8ApiUsageSample.java b/src/test/apiUsageSample/com/android/tools/apiusagesample/D8ApiUsageSample.java
index e0a0b5b..363b80c 100644
--- a/src/test/apiUsageSample/com/android/tools/apiusagesample/D8ApiUsageSample.java
+++ b/src/test/apiUsageSample/com/android/tools/apiusagesample/D8ApiUsageSample.java
@@ -4,6 +4,7 @@
package com.android.tools.apiusagesample;
import com.android.tools.r8.ArchiveClassFileProvider;
+import com.android.tools.r8.ArchiveProgramResourceProvider;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
@@ -11,9 +12,14 @@
import com.android.tools.r8.DexFilePerClassFileConsumer;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.ProgramResource;
+import com.android.tools.r8.ProgramResource.Kind;
+import com.android.tools.r8.ProgramResourceProvider;
+import com.android.tools.r8.ResourceException;
import com.android.tools.r8.origin.ArchiveEntryOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
+import com.android.tools.r8.utils.StringDiagnostic;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -22,6 +28,7 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
@@ -93,6 +100,7 @@
useProgramFileBuilder(CompilationMode.DEBUG, minApiLevel, libraries, classpath, inputs);
useProgramFileBuilder(CompilationMode.RELEASE, minApiLevel, libraries, classpath, inputs);
useProgramDataBuilder(minApiLevel, libraries, classpath, inputs);
+ useProgramProvider(minApiLevel, libraries, classpath, inputs);
useLibraryAndClasspathProvider(minApiLevel, libraries, classpath, inputs);
useMainDexListFiles(minApiLevel, libraries, classpath, inputs, mainDexList);
useMainDexClasses(minApiLevel, libraries, classpath, inputs, mainDexList);
@@ -111,7 +119,7 @@
D8Command.builder(handler)
.setMode(mode)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addClasspathFiles(classpath)
.addProgramFiles(inputs)
@@ -131,7 +139,7 @@
D8Command.Builder builder =
D8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addClasspathFiles(classpath);
for (ClassFileContent classfile : readClassFiles(inputs)) {
@@ -145,6 +153,40 @@
}
}
+ // Check API support for compiling Java class-files from a program provider abstraction.
+ private static void useProgramProvider(
+ int minApiLevel,
+ Collection<Path> libraries,
+ Collection<Path> classpath,
+ Collection<Path> inputs) {
+ try {
+ D8Command.Builder builder =
+ D8Command.builder(handler)
+ .setMinApiLevel(minApiLevel)
+ .setProgramConsumer(new EnsureOutputConsumer())
+ .addLibraryFiles(libraries)
+ .addClasspathFiles(classpath);
+ for (Path input : inputs) {
+ if (isArchive(input)) {
+ builder.addProgramResourceProvider(
+ ArchiveProgramResourceProvider.fromArchive(
+ input, ArchiveProgramResourceProvider::includeClassFileEntries));
+ } else {
+ builder.addProgramResourceProvider(
+ new ProgramResourceProvider() {
+ @Override
+ public Collection<ProgramResource> getProgramResources() throws ResourceException {
+ return Collections.singleton(ProgramResource.fromFile(Kind.CF, input));
+ }
+ });
+ }
+ }
+ D8.run(builder.build());
+ } catch (CompilationFailedException e) {
+ throw new RuntimeException("Unexpected compilation exceptions", e);
+ }
+ }
+
private static void useLibraryAndClasspathProvider(
int minApiLevel,
Collection<Path> libraries,
@@ -154,7 +196,7 @@
D8Command.Builder builder =
D8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addProgramFiles(inputs);
for (Path library : libraries) {
builder.addLibraryResourceProvider(new ArchiveClassFileProvider(library));
@@ -180,7 +222,7 @@
D8.run(
D8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addClasspathFiles(classpath)
.addProgramFiles(inputs)
@@ -211,7 +253,7 @@
D8.run(
D8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addClasspathFiles(classpath)
.addProgramFiles(inputs)
@@ -284,7 +326,7 @@
D8Command.Builder builder =
D8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer());
+ .setProgramConsumer(new EnsureOutputConsumer());
for (byte[] intermediate : intermediates) {
builder.addDexProgramData(intermediate, Origin.unknown());
}
@@ -387,4 +429,21 @@
@Override
public void finished(DiagnosticsHandler handler) {}
}
+
+ private static class EnsureOutputConsumer implements DexIndexedConsumer {
+ boolean hasOutput = false;
+
+ @Override
+ public synchronized void accept(
+ int fileIndex, byte[] data, Set<String> descriptors, DiagnosticsHandler handler) {
+ hasOutput = true;
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ if (!hasOutput) {
+ handler.error(new StringDiagnostic("Expected to produce output but had none"));
+ }
+ }
+ }
}
diff --git a/src/test/apiUsageSample/com/android/tools/apiusagesample/R8ApiUsageSample.java b/src/test/apiUsageSample/com/android/tools/apiusagesample/R8ApiUsageSample.java
index be7e207..d069d05 100644
--- a/src/test/apiUsageSample/com/android/tools/apiusagesample/R8ApiUsageSample.java
+++ b/src/test/apiUsageSample/com/android/tools/apiusagesample/R8ApiUsageSample.java
@@ -4,12 +4,17 @@
package com.android.tools.apiusagesample;
import com.android.tools.r8.ArchiveClassFileProvider;
+import com.android.tools.r8.ArchiveProgramResourceProvider;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.ProgramResource;
+import com.android.tools.r8.ProgramResource.Kind;
+import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.R8;
import com.android.tools.r8.R8Command;
+import com.android.tools.r8.ResourceException;
import com.android.tools.r8.origin.ArchiveEntryOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
@@ -22,6 +27,7 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
@@ -98,6 +104,7 @@
useProgramFileBuilder(CompilationMode.DEBUG, minApiLevel, libraries, inputs);
useProgramFileBuilder(CompilationMode.RELEASE, minApiLevel, libraries, inputs);
useProgramDataBuilder(minApiLevel, libraries, inputs);
+ useProgramProvider(minApiLevel, libraries, inputs);
useLibraryProvider(minApiLevel, libraries, inputs);
useMainDexListFiles(minApiLevel, libraries, inputs, mainDexList);
useMainDexClasses(minApiLevel, libraries, inputs, mainDexList);
@@ -115,7 +122,7 @@
R8Command.builder(handler)
.setMode(mode)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addProgramFiles(inputs)
.build());
@@ -131,7 +138,7 @@
R8Command.Builder builder =
R8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries);
for (ClassFileContent classfile : readClassFiles(inputs)) {
builder.addClassProgramData(classfile.data, classfile.origin);
@@ -144,13 +151,43 @@
}
}
+ // Check API support for compiling Java class-files from a program provider abstraction.
+ private static void useProgramProvider(
+ int minApiLevel, Collection<Path> libraries, Collection<Path> inputs) {
+ try {
+ R8Command.Builder builder =
+ R8Command.builder(handler)
+ .setMinApiLevel(minApiLevel)
+ .setProgramConsumer(new EnsureOutputConsumer())
+ .addLibraryFiles(libraries);
+ for (Path input : inputs) {
+ if (isArchive(input)) {
+ builder.addProgramResourceProvider(
+ ArchiveProgramResourceProvider.fromArchive(
+ input, ArchiveProgramResourceProvider::includeClassFileEntries));
+ } else {
+ builder.addProgramResourceProvider(
+ new ProgramResourceProvider() {
+ @Override
+ public Collection<ProgramResource> getProgramResources() throws ResourceException {
+ return Collections.singleton(ProgramResource.fromFile(Kind.CF, input));
+ }
+ });
+ }
+ }
+ R8.run(builder.build());
+ } catch (CompilationFailedException e) {
+ throw new RuntimeException("Unexpected compilation exceptions", e);
+ }
+ }
+
private static void useLibraryProvider(
int minApiLevel, Collection<Path> libraries, Collection<Path> inputs) {
try {
R8Command.Builder builder =
R8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addProgramFiles(inputs);
for (Path library : libraries) {
builder.addLibraryResourceProvider(new ArchiveClassFileProvider(library));
@@ -172,7 +209,7 @@
R8.run(
R8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addProgramFiles(inputs)
.addMainDexListFiles(mainDexList)
@@ -201,7 +238,7 @@
R8.run(
R8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addProgramFiles(inputs)
.addMainDexClasses(mainDexClasses)
@@ -222,7 +259,7 @@
R8.run(
R8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addProgramFiles(inputs)
.addMainDexRulesFiles(mainDexRules)
@@ -241,7 +278,7 @@
R8Command.Builder builder =
R8Command.builder(handler)
.setMinApiLevel(minApiLevel)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .setProgramConsumer(new EnsureOutputConsumer())
.addLibraryFiles(libraries)
.addProgramFiles(inputs);
for (Path mainDexRulesFile : mainDexRulesFiles) {
diff --git a/tests/d8_api_usage_sample.jar b/tests/d8_api_usage_sample.jar
index 5913594..3f78a93 100644
--- a/tests/d8_api_usage_sample.jar
+++ b/tests/d8_api_usage_sample.jar
Binary files differ
diff --git a/tests/r8_api_usage_sample.jar b/tests/r8_api_usage_sample.jar
index 55c5e83..e0456f6 100644
--- a/tests/r8_api_usage_sample.jar
+++ b/tests/r8_api_usage_sample.jar
Binary files differ