Add origin information to errors in the ArchiveResourceProvider

This issue was found looking at b/317330821 but it is not a fix.

Bug: b/317330821
Change-Id: Ic360e2008cef5341a0f1e6761f8d1e655d80009e
diff --git a/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java b/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
index 6532b8f..b73119d 100644
--- a/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
@@ -93,8 +93,10 @@
     }
     if (!dexResources.isEmpty() && !classResources.isEmpty()) {
       throw new CompilationError(
-          "Cannot create android app from an archive '" + archive
-              + "' containing both DEX and Java-bytecode content");
+          "Cannot create android app from an archive '"
+              + archive
+              + "' containing both DEX and Java-bytecode content",
+          origin);
     }
     return !dexResources.isEmpty() ? dexResources : classResources;
   }
diff --git a/src/test/java/com/android/tools/r8/files/ArchiveWithDexTest.java b/src/test/java/com/android/tools/r8/files/ArchiveWithDexTest.java
index 0c3bd18..85b25f3 100644
--- a/src/test/java/com/android/tools/r8/files/ArchiveWithDexTest.java
+++ b/src/test/java/com/android/tools/r8/files/ArchiveWithDexTest.java
@@ -4,6 +4,8 @@
 package com.android.tools.r8.files;
 
 import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticOrigin;
+import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
@@ -11,10 +13,15 @@
 
 import com.android.tools.r8.ArchiveProgramResourceProvider;
 import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.R8;
+import com.android.tools.r8.R8Command;
 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.origin.Origin;
+import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.ArchiveResourceProvider;
 import com.android.tools.r8.utils.BooleanBox;
@@ -33,6 +40,8 @@
 @RunWith(Parameterized.class)
 public class ArchiveWithDexTest extends TestBase {
 
+  static final String MESSAGE = "containing both DEX and Java-bytecode content";
+
   @Parameter() public TestParameters parameters;
 
   @Parameters(name = "{0}")
@@ -41,6 +50,7 @@
   }
 
   private static Path zipWithDexAndClass;
+  private static Origin zipWithDexAndClassOrigin;
 
   @BeforeClass
   public static void createZipWitDexAndClass() throws IOException {
@@ -51,6 +61,7 @@
     Files.createFile(zipContent.resolve("other.dex"));
     zipWithDexAndClass = getStaticTemp().newFolder().toPath().resolve("input.zip");
     ZipUtils.zip(zipWithDexAndClass, zipContent);
+    zipWithDexAndClassOrigin = new PathOrigin(zipWithDexAndClass);
   }
 
   private void checkOneDexFiles(Path archive) throws Exception {
@@ -85,6 +96,41 @@
   }
 
   @Test
+  public void testFileInputD8() {
+    assertThrows(
+        CompilationFailedException.class,
+        () ->
+            testForD8(Backend.DEX)
+                .addProgramFiles(zipWithDexAndClass)
+                .setMinApi(AndroidApiLevel.B)
+                .compileWithExpectedDiagnostics(
+                    diagnostics ->
+                        diagnostics.assertErrorsMatch(
+                            allOf(
+                                diagnosticMessage(containsString("input.zip")),
+                                diagnosticMessage(containsString(MESSAGE)),
+                                diagnosticOrigin(zipWithDexAndClassOrigin)))));
+  }
+
+  @Test
+  public void testProviderInputD8() {
+    assertThrows(
+        CompilationFailedException.class,
+        () ->
+            testForD8(Backend.DEX)
+                .addProgramResourceProviders(
+                    ArchiveProgramResourceProvider.fromArchive(zipWithDexAndClass))
+                .setMinApi(AndroidApiLevel.B)
+                .compileWithExpectedDiagnostics(
+                    diagnostics ->
+                        diagnostics.assertErrorsMatch(
+                            allOf(
+                                // When using providers the file name is not in the message.
+                                diagnosticMessage(containsString(MESSAGE)),
+                                diagnosticOrigin(zipWithDexAndClassOrigin)))));
+  }
+
+  @Test
   public void testR8() {
     assertThrows(
         CompilationFailedException.class,
@@ -97,10 +143,10 @@
                 .compileWithExpectedDiagnostics(
                     diagnostics ->
                         diagnostics.assertErrorsMatch(
-                            diagnosticMessage(
-                                containsString(
-                                    "Cannot create android app from an archive containing both DEX"
-                                        + " and Java-bytecode content.")))));
+                            allOf(
+                                // When using providers the file name is not in the message.
+                                diagnosticMessage(containsString(MESSAGE)),
+                                diagnosticOrigin(zipWithDexAndClassOrigin)))));
   }
 
   @Test
@@ -130,6 +176,19 @@
   }
 
   @Test
+  public void testRawCommandBuilderR8() throws Exception {
+    // Check that the error is wrapped and reported at the point of compiling (not arg building).
+    R8Command command =
+        R8Command.builder()
+            .addProgramResourceProvider(
+                ArchiveProgramResourceProvider.fromArchive(zipWithDexAndClass))
+            .setMinApiLevel(1)
+            .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+            .build();
+    assertThrows(CompilationFailedException.class, () -> R8.run(command));
+  }
+
+  @Test
   public void testR8LegacyProgramResourceProviderDontIgnoreDex() {
     assertThrows(
         CompilationFailedException.class,
@@ -142,8 +201,10 @@
                 .compileWithExpectedDiagnostics(
                     diagnostics ->
                         diagnostics.assertErrorsMatch(
-                            diagnosticMessage(
-                                containsString("containing both DEX and Java-bytecode content")))));
+                            allOf(
+                                // When using providers the file name is not in the message.
+                                diagnosticMessage(containsString(MESSAGE)),
+                                diagnosticOrigin(zipWithDexAndClassOrigin)))));
   }
 
   static class TestClass {