Don't report missing classes in LibraryAnalyzer to stdout
Fixes: b/491245572
Change-Id: Iedd9b01f989cf9c00b614ae5c5c08f79fc213423
diff --git a/src/libanalyzer/java/com/android/tools/r8/libanalyzer/LibraryAnalyzer.java b/src/libanalyzer/java/com/android/tools/r8/libanalyzer/LibraryAnalyzer.java
index eb448da..029e47f 100644
--- a/src/libanalyzer/java/com/android/tools/r8/libanalyzer/LibraryAnalyzer.java
+++ b/src/libanalyzer/java/com/android/tools/r8/libanalyzer/LibraryAnalyzer.java
@@ -8,6 +8,9 @@
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
+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.ResourceException;
@@ -15,6 +18,7 @@
import com.android.tools.r8.blastradius.BlastRadiusKeepRuleClassifier;
import com.android.tools.r8.blastradius.RootSetBlastRadius;
import com.android.tools.r8.blastradius.RootSetBlastRadiusForRule;
+import com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
@@ -28,7 +32,6 @@
import com.android.tools.r8.libanalyzer.utils.DexIndexedSizeConsumer;
import com.android.tools.r8.libanalyzer.utils.LibraryAnalyzerOptions;
import com.android.tools.r8.origin.CommandLineOrigin;
-import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
import com.android.tools.r8.processkeeprules.ValidateLibraryConsumerRulesKeepRuleProcessor;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -39,6 +42,7 @@
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.ExceptionUtils;
+import com.android.tools.r8.utils.ForwardingDiagnosticsHandler;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.ListUtils;
@@ -139,8 +143,7 @@
private R8CompileResult runR8(ExecutorService executorService) {
DexIndexedSizeConsumer sizeConsumer = new DexIndexedSizeConsumer();
R8Command.Builder commandBuilder =
- R8Command.builder(reporter)
- .addProguardConfiguration(List.of("-ignorewarnings"), Origin.unknown())
+ R8Command.builder(new R8DiagnosticsHandler(reporter))
.setClassConflictResolver((reference, origins, handler) -> origins.iterator().next())
.setProgramConsumer(sizeConsumer);
configure(commandBuilder);
@@ -347,4 +350,20 @@
app.getClasspathResourceProviders().forEach(commandBuilder::addClasspathResourceProvider);
app.getLibraryResourceProviders().forEach(commandBuilder::addLibraryResourceProvider);
}
+
+ private static class R8DiagnosticsHandler extends ForwardingDiagnosticsHandler {
+
+ R8DiagnosticsHandler(DiagnosticsHandler diagnosticsHandler) {
+ super(diagnosticsHandler);
+ }
+
+ @Override
+ public DiagnosticsLevel modifyDiagnosticsLevel(DiagnosticsLevel level, Diagnostic diagnostic) {
+ if (diagnostic instanceof MissingDefinitionsDiagnostic) {
+ // Intentionally drop missing classes diagnostics in LibraryAnalyzer.
+ return DiagnosticsLevel.NONE;
+ }
+ return super.modifyDiagnosticsLevel(level, diagnostic);
+ }
+ }
}
diff --git a/src/test/java/com/android/tools/r8/libanalyzer/LibraryAnalyzerSupressMissingClassesTest.java b/src/test/java/com/android/tools/r8/libanalyzer/LibraryAnalyzerSupressMissingClassesTest.java
new file mode 100644
index 0000000..5ef9fef
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/libanalyzer/LibraryAnalyzerSupressMissingClassesTest.java
@@ -0,0 +1,55 @@
+// Copyright (c) 2026, 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.libanalyzer;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessages;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class LibraryAnalyzerSupressMissingClassesTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ @Test
+ public void test() throws Exception {
+ testForLibraryAnalyzer()
+ .addProgramClasses(Main.class)
+ .addDefaultLibrary()
+ .addKeepRules(
+ "-keep class " + Main.class.getTypeName() + " {",
+ " public static void main(java.lang.String[]);",
+ "}")
+ .setAar()
+ .setMinApi(AndroidApiLevel.getDefault())
+ .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoMessages);
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {
+ A.m();
+ }
+ }
+
+ public static class A {
+
+ public static void m() {
+ System.out.println("Hello, world!");
+ }
+ }
+}
diff --git a/src/test/testbase/java/com/android/tools/r8/libanalyzer/LibraryAnalyzerTestBuilder.java b/src/test/testbase/java/com/android/tools/r8/libanalyzer/LibraryAnalyzerTestBuilder.java
index 12f1ead..525e0b9 100644
--- a/src/test/testbase/java/com/android/tools/r8/libanalyzer/LibraryAnalyzerTestBuilder.java
+++ b/src/test/testbase/java/com/android/tools/r8/libanalyzer/LibraryAnalyzerTestBuilder.java
@@ -10,6 +10,8 @@
import com.android.tools.r8.ByteArrayConsumer;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.TestCompilerBuilder.DiagnosticsConsumer;
+import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestDiagnosticMessagesImpl;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.libanalyzer.proto.LibraryAnalyzerResult;
@@ -101,6 +103,11 @@
}
public LibraryAnalyzerCompileResult compile() throws CompilationFailedException {
+ return compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoMessages);
+ }
+
+ public <E extends Exception> LibraryAnalyzerCompileResult compileWithExpectedDiagnostics(
+ DiagnosticsConsumer<E> diagnosticsConsumer) throws CompilationFailedException, E {
assertNotNull("Must call setAar() or setJar() to specify input type.", aarOrJar);
Box<LibraryAnalyzerResult> LibraryAnalyzerResult = new Box<>();
if (aarOrJar == AarOrJar.AAR) {
@@ -111,7 +118,7 @@
LibraryAnalyzerCommand command =
commandBuilder.setInternalOutputConsumer(LibraryAnalyzerResult::set).build();
LibraryAnalyzer.run(command);
- diagnostics.assertNoMessages();
+ diagnosticsConsumer.accept(diagnostics);
return new LibraryAnalyzerCompileResult(LibraryAnalyzerResult.get());
}