Add API test for keep rule diagnostics.

Bug: b/143432055
Bug: b/248371950
Change-Id: I4be26b4cd3abab915dbcdcf05d23e8abb5d31c9a
diff --git a/src/main/java/com/android/tools/r8/errors/ProguardKeepRuleDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ProguardKeepRuleDiagnostic.java
index dcb6bb9..10d8c1f 100644
--- a/src/main/java/com/android/tools/r8/errors/ProguardKeepRuleDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/ProguardKeepRuleDiagnostic.java
@@ -4,6 +4,8 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.Keep;
 
-/** Base class for diagnostics related to proguard keep rules. */
-public abstract class ProguardKeepRuleDiagnostic implements Diagnostic {}
+/** Base interface for diagnostics related to proguard keep rules. */
+@Keep
+public interface ProguardKeepRuleDiagnostic extends Diagnostic {}
diff --git a/src/main/java/com/android/tools/r8/errors/UnusedProguardKeepRuleDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnusedProguardKeepRuleDiagnostic.java
index 396f88b..2d2b326 100644
--- a/src/main/java/com/android/tools/r8/errors/UnusedProguardKeepRuleDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnusedProguardKeepRuleDiagnostic.java
@@ -9,7 +9,7 @@
 import com.android.tools.r8.shaking.ProguardConfigurationRule;
 
 @Keep
-public class UnusedProguardKeepRuleDiagnostic extends ProguardKeepRuleDiagnostic {
+public class UnusedProguardKeepRuleDiagnostic implements ProguardKeepRuleDiagnostic {
 
   private final ProguardConfigurationRule rule;
 
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index f07a328..6bf0a8f 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1988,8 +1988,7 @@
     public boolean allowInvokeErrors = false;
     public boolean allowUnnecessaryDontWarnWildcards = true;
     public boolean allowUnusedDontWarnRules = true;
-    public boolean reportUnusedProguardConfigurationRules =
-        System.getProperty("com.android.tools.r8.reportUnusedProguardConfigurationRules") != null;
+    public boolean reportUnusedProguardConfigurationRules = true;
     public boolean alwaysUseExistingAccessInfoCollectionsInMemberRebinding = true;
     public boolean alwaysUsePessimisticRegisterAllocation = false;
     public boolean enableCheckCastAndInstanceOfRemoval = true;
diff --git a/src/test/java/com/android/tools/r8/L8TestBuilder.java b/src/test/java/com/android/tools/r8/L8TestBuilder.java
index 4a22769..f5a808a 100644
--- a/src/test/java/com/android/tools/r8/L8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/L8TestBuilder.java
@@ -6,8 +6,10 @@
 
 import static junit.framework.Assert.assertNull;
 import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.fail;
 
 import com.android.tools.r8.TestBase.Backend;
+import com.android.tools.r8.errors.UnusedProguardKeepRuleDiagnostic;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
 import com.android.tools.r8.origin.Origin;
@@ -249,14 +251,20 @@
             || warnings.stream()
                 .allMatch(warn -> warn.getDiagnosticMessage().contains("org.testng.Assert")));
     List<Diagnostic> infos = diagnosticsMessages.getInfos();
-    // The rewriting confuses the generic signatures in some methods. Such signatures are never
-    // used by tools (they use the non library desugared version) and are stripped when compiling
-    // with R8 anyway.
-    // TODO(b/243483320): Investigate the Invalid signature.
-    assertTrue(
-        infos.isEmpty()
-            || infos.stream()
-                .allMatch(info -> info.getDiagnosticMessage().contains("Invalid signature ")));
+    for (Diagnostic info : infos) {
+      // The rewriting confuses the generic signatures in some methods. Such signatures are never
+      // used by tools (they use the non library desugared version) and are stripped when compiling
+      // with R8 anyway.
+      // TODO(b/243483320): Investigate the Invalid signature.
+      if (info.getDiagnosticMessage().contains("Invalid signature ")) {
+        continue;
+      }
+      // TODO(b/248371950): Should we have L8 shinking builds with these?
+      if (info instanceof UnusedProguardKeepRuleDiagnostic) {
+        continue;
+      }
+      fail("Unexpected info diagnostic: " + info);
+    }
   }
 
   private L8Command.Builder addProgramClassFileData(L8Command.Builder builder) {
diff --git a/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java b/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
index 73dbba2..fd3e16d 100644
--- a/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
+++ b/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.compilerapi.assertionconfiguration.AssertionConfigurationTest;
 import com.android.tools.r8.compilerapi.classconflictresolver.ClassConflictResolverTest;
 import com.android.tools.r8.compilerapi.desugardependencies.DesugarDependenciesTest;
+import com.android.tools.r8.compilerapi.diagnostics.ProguardKeepRuleDiagnosticsApiTest;
 import com.android.tools.r8.compilerapi.diagnostics.UnsupportedFeaturesDiagnosticApiTest;
 import com.android.tools.r8.compilerapi.globalsynthetics.GlobalSyntheticsTest;
 import com.android.tools.r8.compilerapi.inputdependencies.InputDependenciesTest;
@@ -56,7 +57,8 @@
       ImmutableList.of(
           ArtProfilesForRewritingApiTest.ApiTest.class,
           StartupProfileApiTest.ApiTest.class,
-          ClassConflictResolverTest.ApiTest.class);
+          ClassConflictResolverTest.ApiTest.class,
+          ProguardKeepRuleDiagnosticsApiTest.ApiTest.class);
 
   private final TemporaryFolder temp;
 
diff --git a/src/test/java/com/android/tools/r8/compilerapi/diagnostics/ProguardKeepRuleDiagnosticsApiTest.java b/src/test/java/com/android/tools/r8/compilerapi/diagnostics/ProguardKeepRuleDiagnosticsApiTest.java
new file mode 100644
index 0000000..fedb449
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/compilerapi/diagnostics/ProguardKeepRuleDiagnosticsApiTest.java
@@ -0,0 +1,117 @@
+// 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.compilerapi.diagnostics;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
+
+import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.DiagnosticsLevel;
+import com.android.tools.r8.R8;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.TestDiagnosticMessagesImpl;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.compilerapi.CompilerApiTest;
+import com.android.tools.r8.compilerapi.CompilerApiTestRunner;
+import com.android.tools.r8.errors.ProguardKeepRuleDiagnostic;
+import com.android.tools.r8.errors.UnusedProguardKeepRuleDiagnostic;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import java.util.Collections;
+import org.junit.Test;
+
+public class ProguardKeepRuleDiagnosticsApiTest extends CompilerApiTestRunner {
+
+  public ProguardKeepRuleDiagnosticsApiTest(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<? extends CompilerApiTest> binaryTestClass() {
+    return ApiTest.class;
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    ApiTest test = new ApiTest(ApiTest.PARAMETERS);
+    runTest(test::runR8);
+  }
+
+  private void runTest(ThrowingConsumer<DiagnosticsHandler, Exception> test) throws Exception {
+    TestDiagnosticMessagesImpl diagnostics = new TestDiagnosticMessagesImpl();
+    test.accept(diagnostics);
+    diagnostics
+        .assertOnlyWarnings()
+        // Check the diagnostic is an instance of both types.
+        .assertWarningsMatch(
+            allOf(
+                diagnosticType(UnusedProguardKeepRuleDiagnostic.class),
+                diagnosticMessage(containsString("does not match anything"))))
+        .assertWarningsMatch(
+            allOf(
+                diagnosticType(ProguardKeepRuleDiagnostic.class),
+                diagnosticMessage(containsString("does not match anything"))));
+  }
+
+  public static class ApiTest extends CompilerApiTest {
+
+    public ApiTest(Object parameters) {
+      super(parameters);
+    }
+
+    public void runR8(DiagnosticsHandler handler) throws Exception {
+      R8.run(
+          R8Command.builder(
+                  new DiagnosticsHandler() {
+                    @Override
+                    public DiagnosticsLevel modifyDiagnosticsLevel(
+                        DiagnosticsLevel level, Diagnostic diagnostic) {
+                      if (diagnostic instanceof ProguardKeepRuleDiagnostic
+                          || diagnostic instanceof UnusedProguardKeepRuleDiagnostic) {
+                        return handler.modifyDiagnosticsLevel(DiagnosticsLevel.WARNING, diagnostic);
+                      }
+                      return handler.modifyDiagnosticsLevel(level, diagnostic);
+                    }
+
+                    @Override
+                    public void error(Diagnostic error) {
+                      handler.error(error);
+                    }
+
+                    @Override
+                    public void warning(Diagnostic warning) {
+                      handler.warning(warning);
+                    }
+
+                    @Override
+                    public void info(Diagnostic info) {
+                      handler.info(info);
+                    }
+                  })
+              .addClassProgramData(getBytesForClass(getMockClass()), Origin.unknown())
+              .addProguardConfiguration(getKeepMainRules(getMockClass()), Origin.unknown())
+              .addProguardConfiguration(
+                  Collections.singletonList("-keep class NotPresent {}"), Origin.unknown())
+              .addLibraryFiles(getJava8RuntimeJar())
+              .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+              .setMinApiLevel(1)
+              .build());
+    }
+
+    @Test
+    public void testR8() throws Exception {
+      runR8(
+          new DiagnosticsHandler() {
+            @Override
+            public void warning(Diagnostic warning) {
+              // ignore the warnings.
+            }
+          });
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryWarningTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryWarningTest.java
index 2bd0f31..9d0d78e 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryWarningTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryWarningTest.java
@@ -5,6 +5,7 @@
 package com.android.tools.r8.desugar.desugaredlibrary;
 
 import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.D8_L8DEBUG;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.D8_L8SHRINK;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK8;
@@ -14,6 +15,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
 import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import com.android.tools.r8.errors.UnusedProguardKeepRuleDiagnostic;
 import com.google.common.collect.ImmutableList;
 import java.util.List;
 import org.junit.Test;
@@ -64,14 +66,16 @@
         .compile()
         .inspectDiagnosticMessages(
             diagnosticsHandler -> {
+              diagnosticsHandler.assertNoErrors();
               if (libraryDesugaringSpecification != JDK8) {
-                diagnosticsHandler.assertNoErrors();
                 diagnosticsHandler.assertAllWarningsMatch(
                     diagnosticMessage(containsString("Specification conversion")));
               } else {
-
-                diagnosticsHandler.assertNoMessages();
+                diagnosticsHandler.assertNoWarnings();
               }
+              // TODO(b/248371950): Should we have L8 shinking builds with these?
+              diagnosticsHandler.assertAllInfosMatch(
+                  diagnosticType(UnusedProguardKeepRuleDiagnostic.class));
             });
   }
 }