Add a test of class initialzation of an interface from implementor

This is a variant of b/379241435. Also update the original test for
b/379241435 with more clarity of the order of class initialization.

Bug: b/379241435
Change-Id: I949482969e4c822468151a5c459a794e08b40548
diff --git a/src/test/java/com/android/tools/r8/B379241435Test.java b/src/test/java/com/android/tools/r8/B379241435InterfaceInitializedAftertInstantiatingImplementorTest.java
similarity index 83%
rename from src/test/java/com/android/tools/r8/B379241435Test.java
rename to src/test/java/com/android/tools/r8/B379241435InterfaceInitializedAftertInstantiatingImplementorTest.java
index 3647f0a..9fb3f4f 100644
--- a/src/test/java/com/android/tools/r8/B379241435Test.java
+++ b/src/test/java/com/android/tools/r8/B379241435InterfaceInitializedAftertInstantiatingImplementorTest.java
@@ -12,7 +12,7 @@
 
 // Regression test for b/379241435.
 @RunWith(Parameterized.class)
-public class B379241435Test extends TestBase {
+public class B379241435InterfaceInitializedAftertInstantiatingImplementorTest extends TestBase {
 
   @Parameter(0)
   public TestParameters parameters;
@@ -22,7 +22,7 @@
     return getTestParameters().withAllRuntimesAndApiLevels().build();
   }
 
-  private static final String EXPECTED_OUTPUT = StringUtils.lines("A.A()", "I.f()");
+  private static final String EXPECTED_OUTPUT = StringUtils.lines("B.B()", "A.A()", "I.f()");
 
   @Test
   public void testJvm() throws Exception {
@@ -56,12 +56,14 @@
                     .getApiLevel()
                     .isLessThan(apiLevelWithDefaultInterfaceMethodsSupport()),
             r -> r.assertSuccessWithOutput(EXPECTED_OUTPUT),
-            r -> r.assertSuccessWithOutputLines("I.f()"));
+            r -> r.assertSuccessWithOutputLines("B.B()", "I.f()"));
   }
 
   public static class TestClass {
     public static void main(String[] args) {
+      // Instantiating B does not trigger class initialization of I.
       I b = new B();
+      // Invoking the static method on I trigger class initialization of I.
       I.f();
     }
   }
@@ -80,5 +82,9 @@
     }
   }
 
-  static class B implements I {}
+  static class B implements I {
+    B() {
+      System.out.println("B.B()");
+    }
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/B379241435Test.java b/src/test/java/com/android/tools/r8/B379241435InterfaceInitializedFromImplementorStaticMethodTest.java
similarity index 75%
copy from src/test/java/com/android/tools/r8/B379241435Test.java
copy to src/test/java/com/android/tools/r8/B379241435InterfaceInitializedFromImplementorStaticMethodTest.java
index 3647f0a..bb43551 100644
--- a/src/test/java/com/android/tools/r8/B379241435Test.java
+++ b/src/test/java/com/android/tools/r8/B379241435InterfaceInitializedFromImplementorStaticMethodTest.java
@@ -10,9 +10,9 @@
 import org.junit.runners.Parameterized.Parameter;
 import org.junit.runners.Parameterized.Parameters;
 
-// Regression test for b/379241435.
+// Regression test for a variant of b/379241435.
 @RunWith(Parameterized.class)
-public class B379241435Test extends TestBase {
+public class B379241435InterfaceInitializedFromImplementorStaticMethodTest extends TestBase {
 
   @Parameter(0)
   public TestParameters parameters;
@@ -22,7 +22,7 @@
     return getTestParameters().withAllRuntimesAndApiLevels().build();
   }
 
-  private static final String EXPECTED_OUTPUT = StringUtils.lines("A.A()", "I.f()");
+  private static final String EXPECTED_OUTPUT = StringUtils.lines("B.B()", "A.A()", "I.f()");
 
   @Test
   public void testJvm() throws Exception {
@@ -49,6 +49,8 @@
         .addInnerClasses(getClass())
         .addKeepMainRule(TestClass.class)
         .setMinApi(parameters)
+        .enableInliningAnnotations()
+        .enableNeverClassInliningAnnotations()
         .run(parameters.getRuntime(), TestClass.class)
         .applyIf(
             parameters.isDexRuntime()
@@ -56,13 +58,15 @@
                     .getApiLevel()
                     .isLessThan(apiLevelWithDefaultInterfaceMethodsSupport()),
             r -> r.assertSuccessWithOutput(EXPECTED_OUTPUT),
-            r -> r.assertSuccessWithOutputLines("I.f()"));
+            r -> r.assertSuccessWithOutputLines("B.B()", "I.f()"));
   }
 
   public static class TestClass {
     public static void main(String[] args) {
-      I b = new B();
-      I.f();
+      // Instantiating B does not trigger class initialization of I.
+      B b = new B();
+      // Invoking m indirectly trigger class initialization of I as it calls a static method on I.
+      B.m();
     }
   }
 
@@ -80,5 +84,15 @@
     }
   }
 
-  static class B implements I {}
+  @NeverClassInline
+  static class B implements I {
+    B() {
+      System.out.println("B.B()");
+    }
+
+    @NeverInline
+    static void m() {
+      I.f();
+    }
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/B379241435Test.java b/src/test/java/com/android/tools/r8/B379241435InterfaceInitializedFromImplementorVirtualMethodTest.java
similarity index 74%
copy from src/test/java/com/android/tools/r8/B379241435Test.java
copy to src/test/java/com/android/tools/r8/B379241435InterfaceInitializedFromImplementorVirtualMethodTest.java
index 3647f0a..bdb3b3b 100644
--- a/src/test/java/com/android/tools/r8/B379241435Test.java
+++ b/src/test/java/com/android/tools/r8/B379241435InterfaceInitializedFromImplementorVirtualMethodTest.java
@@ -10,9 +10,9 @@
 import org.junit.runners.Parameterized.Parameter;
 import org.junit.runners.Parameterized.Parameters;
 
-// Regression test for b/379241435.
+// Regression test for a variant of b/379241435.
 @RunWith(Parameterized.class)
-public class B379241435Test extends TestBase {
+public class B379241435InterfaceInitializedFromImplementorVirtualMethodTest extends TestBase {
 
   @Parameter(0)
   public TestParameters parameters;
@@ -22,7 +22,7 @@
     return getTestParameters().withAllRuntimesAndApiLevels().build();
   }
 
-  private static final String EXPECTED_OUTPUT = StringUtils.lines("A.A()", "I.f()");
+  private static final String EXPECTED_OUTPUT = StringUtils.lines("B.B()", "A.A()", "I.f()");
 
   @Test
   public void testJvm() throws Exception {
@@ -49,6 +49,9 @@
         .addInnerClasses(getClass())
         .addKeepMainRule(TestClass.class)
         .setMinApi(parameters)
+        .enableInliningAnnotations()
+        .enableNeverClassInliningAnnotations()
+        .enableNoMethodStaticizingAnnotations()
         .run(parameters.getRuntime(), TestClass.class)
         .applyIf(
             parameters.isDexRuntime()
@@ -56,13 +59,15 @@
                     .getApiLevel()
                     .isLessThan(apiLevelWithDefaultInterfaceMethodsSupport()),
             r -> r.assertSuccessWithOutput(EXPECTED_OUTPUT),
-            r -> r.assertSuccessWithOutputLines("I.f()"));
+            r -> r.assertSuccessWithOutputLines("B.B()", "I.f()"));
   }
 
   public static class TestClass {
     public static void main(String[] args) {
-      I b = new B();
-      I.f();
+      // Instantiating B does not trigger class initialization of I.
+      B b = new B();
+      // Invoking m indirectly trigger class initialization of I as it calls a static method on I.
+      b.m();
     }
   }
 
@@ -80,5 +85,16 @@
     }
   }
 
-  static class B implements I {}
+  @NeverClassInline
+  static class B implements I {
+    B() {
+      System.out.println("B.B()");
+    }
+
+    @NeverInline
+    @NoMethodStaticizing
+    void m() {
+      I.f();
+    }
+  }
 }