Add a test for inlining of methods with nullable receivers

Bug: 130202534
Change-Id: I398fd65b837fef835f8ac0b744442d282063bd7c
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index 106cfac..2137c84 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -78,6 +78,11 @@
     return run(runtime, mainClass.getTypeName());
   }
 
+  public RR run(TestRuntime runtime, Class<?> mainClass, String... args)
+      throws ExecutionException, IOException {
+    return run(runtime, mainClass.getTypeName(), args);
+  }
+
   public RR run(TestRuntime runtime, String mainClass) throws ExecutionException, IOException {
     return run(runtime, mainClass, new String[] {});
   }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineInvokeWithNullableReceiverTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineInvokeWithNullableReceiverTest.java
new file mode 100644
index 0000000..fa613a7
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineInvokeWithNullableReceiverTest.java
@@ -0,0 +1,90 @@
+// Copyright (c) 2019, 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.ir.optimize.inliner;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.R8TestCompileResult;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/** Test for b/130202534. */
+@RunWith(Parameterized.class)
+public class InlineInvokeWithNullableReceiverTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection params() {
+    return getTestParameters().withAllRuntimes().build();
+  }
+
+  public InlineInvokeWithNullableReceiverTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    R8TestCompileResult result =
+        testForR8(parameters.getBackend())
+            .addInnerClasses(InlineInvokeWithNullableReceiverTest.class)
+            .addKeepMainRule(TestClass.class)
+            .setMinApi(parameters.getRuntime())
+            .compile()
+            .inspect(this::verifyMethodHasBeenInlined);
+
+    result
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(StringUtils.lines("Hello world!"));
+
+    // Invoking main() with a non-zero argument list should cause the program to throw.
+    result
+        .run(parameters.getRuntime(), TestClass.class, "42")
+        .assertFailureWithErrorThatMatches(containsString("NullPointerException"));
+  }
+
+  private void verifyMethodHasBeenInlined(CodeInspector inspector) {
+    ClassSubject classSubject = inspector.clazz(TestClass.class);
+    assertThat(classSubject, isPresent());
+
+    MethodSubject methodSubject = classSubject.mainMethod();
+    assertThat(methodSubject, isPresent());
+
+    // TODO(b/130202534): A `throw` instruction should have been synthesized into main().
+    assertTrue(methodSubject.streamInstructions().noneMatch(InstructionSubject::isThrow));
+
+    // TODO(b/130202534): Class A should be absent.
+    ClassSubject otherClassSubject = inspector.clazz(A.class);
+    assertThat(otherClassSubject, isPresent());
+  }
+
+  static class TestClass {
+
+    public static void main(String[] args) {
+      A obj = args.length == 0 ? new A() : null;
+      obj.m();
+    }
+  }
+
+  static class A {
+
+    public void m() {
+      System.out.println("Hello world!");
+    }
+  }
+}