Add empty implementation of ReflectiveOperationReceiver

This allows easy embedding and testing, while retaining the ability to
guarantee full implementation of the interface when required


Bug: b/400878112
Change-Id: Ic0e5d6e53c6cd9b8243d50066f807f579819b4dd
Fixes: 400878112
diff --git a/src/assistant/java/com/android/tools/r8/assistant/runtime/EmptyReflectiveOperationReceiver.java b/src/assistant/java/com/android/tools/r8/assistant/runtime/EmptyReflectiveOperationReceiver.java
new file mode 100644
index 0000000..6f57eeb
--- /dev/null
+++ b/src/assistant/java/com/android/tools/r8/assistant/runtime/EmptyReflectiveOperationReceiver.java
@@ -0,0 +1,30 @@
+// Copyright (c) 2025, 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.assistant.runtime;
+
+import com.android.tools.r8.assistant.runtime.ReflectiveOracle.Stack;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+@KeepForApi
+public class EmptyReflectiveOperationReceiver implements ReflectiveOperationReceiver {
+
+  @Override
+  public void onClassForName(Stack stack, String className) {}
+
+  @Override
+  public void onClassNewInstance(Stack stack, Class<?> clazz) {}
+
+  @Override
+  public void onClassGetDeclaredMethod(
+      Stack stack, Class<?> clazz, String method, Class<?>... parameters) {}
+
+  @Override
+  public void onClassGetDeclaredField(Stack stack, Class<?> clazz, String fieldName) {}
+
+  @Override
+  public void onClassGetDeclaredMethods(Stack stack, Class<?> clazz) {}
+
+  @Override
+  public void onClassGetName(Stack stack, Class<?> clazz, NameLookupType lookupType) {}
+}
diff --git a/src/main/java/com/android/tools/r8/R8AssistantCommand.java b/src/main/java/com/android/tools/r8/R8AssistantCommand.java
index fb5bfac..b319253 100644
--- a/src/main/java/com/android/tools/r8/R8AssistantCommand.java
+++ b/src/main/java/com/android/tools/r8/R8AssistantCommand.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import com.android.tools.r8.assistant.ClassInjectionHelper;
+import com.android.tools.r8.assistant.runtime.EmptyReflectiveOperationReceiver;
 import com.android.tools.r8.assistant.runtime.ReflectiveOperationReceiver;
 import com.android.tools.r8.assistant.runtime.ReflectiveOracle;
 import com.android.tools.r8.assistant.runtime.ReflectiveOracle.ReflectiveOperationLogger;
@@ -146,6 +147,7 @@
     @Override
     R8AssistantCommand makeCommand() {
       injectClasses(
+          EmptyReflectiveOperationReceiver.class,
           ReflectiveOperationLogger.class,
           ReflectiveOperationReceiver.NameLookupType.class,
           ReflectiveOperationReceiver.class,
diff --git a/src/test/java/com/android/tools/r8/assistant/JavaLangClassTest.java b/src/test/java/com/android/tools/r8/assistant/JavaLangClassTest.java
index 3ef728c..029f71a 100644
--- a/src/test/java/com/android/tools/r8/assistant/JavaLangClassTest.java
+++ b/src/test/java/com/android/tools/r8/assistant/JavaLangClassTest.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.assistant.JavaLangClassTestClass.Foo;
-import com.android.tools.r8.assistant.runtime.ReflectiveOracle.ReflectiveOperationLogger;
+import com.android.tools.r8.assistant.runtime.EmptyReflectiveOperationReceiver;
 import com.android.tools.r8.assistant.runtime.ReflectiveOracle.Stack;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,7 +38,7 @@
         .assertSuccessWithOutputLines("5", "1", "2", "3", "3", "4", "5", "6", "7", "8");
   }
 
-  public static class Instrumentation extends ReflectiveOperationLogger {
+  public static class Instrumentation extends EmptyReflectiveOperationReceiver {
 
     private void printNumIfTrue(boolean correct, int num) {
       if (correct) {
diff --git a/src/test/java/com/android/tools/r8/assistant/R8AssistentReflectiveInstrumentationTest.java b/src/test/java/com/android/tools/r8/assistant/R8AssistentReflectiveInstrumentationTest.java
index cec0774..e62da59 100644
--- a/src/test/java/com/android/tools/r8/assistant/R8AssistentReflectiveInstrumentationTest.java
+++ b/src/test/java/com/android/tools/r8/assistant/R8AssistentReflectiveInstrumentationTest.java
@@ -13,7 +13,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.assistant.runtime.ReflectiveOperationReceiver;
+import com.android.tools.r8.assistant.runtime.EmptyReflectiveOperationReceiver;
 import com.android.tools.r8.assistant.runtime.ReflectiveOracle.Stack;
 import com.android.tools.r8.utils.ZipUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -109,7 +109,7 @@
 
   // Injected into the app by the R8Assistant.
   public static class TestReflectiveOperationReceiverStackHandler
-      implements ReflectiveOperationReceiver {
+      extends EmptyReflectiveOperationReceiver {
 
     int lineNumberOfNewInstance = -1;
 
@@ -169,16 +169,6 @@
       ensureCorrectStack(stack);
     }
 
-    // TODO(b/400878112): remove + below
-    @Override
-    public void onClassGetDeclaredField(Stack stack, Class<?> clazz, String fieldName) {}
-
-    @Override
-    public void onClassGetDeclaredMethods(Stack stack, Class<?> clazz) {}
-
-    @Override
-    public void onClassGetName(Stack stack, Class<?> clazz, NameLookupType lookupType) {}
-
     @Override
     public boolean requiresStackInformation() {
       return true;
@@ -195,13 +185,7 @@
     assertEquals(count, codeCount);
   }
 
-  public static class InstrumentationClass implements ReflectiveOperationReceiver {
-
-    @Override
-    public boolean requiresStackInformation() {
-      return true;
-    }
-
+  public static class InstrumentationClass extends EmptyReflectiveOperationReceiver {
     @Override
     public void onClassForName(Stack stack, String className) {
       System.out.println("Custom receiver classForName " + className);
@@ -217,16 +201,6 @@
         Stack stack, Class<?> clazz, String method, Class<?>... parameters) {
       System.out.println("Custom receiver method " + method);
     }
-
-    // TODO(b/400878112): remove + below
-    @Override
-    public void onClassGetDeclaredField(Stack stack, Class<?> clazz, String fieldName) {}
-
-    @Override
-    public void onClassGetDeclaredMethods(Stack stack, Class<?> clazz) {}
-
-    @Override
-    public void onClassGetName(Stack stack, Class<?> clazz, NameLookupType lookupType) {}
   }
 
   static class TestClass {