Reproduce b/123730538: method rebinding missed calling context.

Bug: 111622837, 123730538
Change-Id: Icd9fb10fd781cb28b7ca3627cdbc03fc698e1273
diff --git a/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java b/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
index 6908fda..4cedaea 100644
--- a/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
@@ -18,8 +18,8 @@
 import com.android.tools.r8.utils.codeinspector.FieldSubject;
 import com.android.tools.r8.utils.codeinspector.InstructionSubject;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
 import java.nio.file.Path;
-import java.util.LinkedList;
 import java.util.List;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -46,9 +46,10 @@
 
   @BeforeClass
   public static void setUpClass() throws Exception {
-    CLASSES = new LinkedList<>();
-    CLASSES.addAll(ToolHelper.getClassFilesForTestPackage(MAIN.getPackage()));
-    CLASSES.addAll(ToolHelper.getClassFilesForTestPackage(CONCRETE1.getPackage()));
+    CLASSES = ImmutableList.<Path>builder()
+        .addAll(ToolHelper.getClassFilesForTestPackage(MAIN.getPackage()))
+        .addAll(ToolHelper.getClassFilesForTestPackage(CONCRETE1.getPackage()))
+        .build();
   }
 
   @Test
@@ -58,10 +59,9 @@
     testForProguard()
         .addProgramFiles(inJar)
         .addKeepMainRule(MAIN)
-        .compile()
-        .inspect(this::inspect)
         .run(MAIN)
-        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+        .assertSuccessWithOutput(EXPECTED_OUTPUT)
+        .inspect(this::inspect);
   }
 
   @Test
@@ -69,15 +69,15 @@
     testForR8(backend)
         .addProgramFiles(CLASSES)
         .addKeepMainRule(MAIN)
-        .compile()
-        .inspect(this::inspect)
         .run(MAIN)
-        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+        .assertSuccessWithOutput(EXPECTED_OUTPUT)
+        .inspect(this::inspect);
   }
 
   private void inspect(CodeInspector inspector) {
     FieldSubject fld = inspector.clazz(CONCRETE1.getTypeName().replace("Concrete1", "Abs"))
         .uniqueFieldWithName("strField");
+    assertThat(fld, isPresent());
 
     ClassSubject main = inspector.clazz(MAIN);
     assertThat(main, isPresent());
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/B123730538.java b/src/test/java/com/android/tools/r8/resolution/b123730538/B123730538.java
new file mode 100644
index 0000000..e298c9d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/B123730538.java
@@ -0,0 +1,99 @@
+// 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.resolution.b123730538;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.resolution.b123730538.runner.PublicClassExtender;
+import com.android.tools.r8.resolution.b123730538.runner.Runner;
+import com.android.tools.r8.resolution.b123730538.sub.PublicClass;
+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 com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.util.List;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class B123730538 extends TestBase {
+  private static final Class MAIN = Runner.class;
+  private static List<Path> CLASSES;
+  private static final String EXPECTED_OUTPUT = StringUtils.lines("pkg.AbstractClass::foo");
+
+  private final Backend backend;
+
+  @Parameterized.Parameters(name = "Backend: {0}")
+  public static Object[] data() {
+    return Backend.values();
+  }
+
+  public B123730538(Backend backend) {
+    this.backend = backend;
+  }
+
+  @BeforeClass
+  public static void setUpClass() throws Exception {
+    CLASSES = ImmutableList.<Path>builder()
+        .addAll(ToolHelper.getClassFilesForTestPackage(MAIN.getPackage()))
+        .addAll(ToolHelper.getClassFilesForTestPackage(PublicClass.class.getPackage()))
+        .build();
+  }
+
+  @Test
+  public void testProguard() throws Exception {
+    Path inJar = temp.newFile("input.jar").toPath().toAbsolutePath();
+    writeToJar(inJar, CLASSES);
+    testForProguard()
+        .addProgramFiles(inJar)
+        .addKeepMainRule(MAIN)
+        .run(MAIN)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT)
+        .inspect(this::inspect);
+  }
+
+  @Ignore("b/123730538")
+  @Test
+  public void testR8() throws Exception {
+    testForR8(backend)
+        .addProgramFiles(CLASSES)
+        .addKeepMainRule(MAIN)
+        .run(MAIN)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT)
+        .inspect(this::inspect);
+  }
+
+  private void inspect(CodeInspector inspector) {
+    MethodSubject foo = inspector.clazz(
+        PublicClass.class.getTypeName().replace("PublicClass", "AbstractClass"))
+        .uniqueMethodWithName("foo");
+    assertThat(foo, isPresent());
+
+    ClassSubject main = inspector.clazz(PublicClassExtender.class);
+    assertThat(main, isPresent());
+    MethodSubject methodSubject = main.uniqueMethodWithName("delegate");
+    assertThat(methodSubject, isPresent());
+
+    methodSubject
+        .iterateInstructions(InstructionSubject::isInvokeVirtual)
+        .forEachRemaining(instructionSubject -> {
+          String methodName = instructionSubject.getMethod().name.toString();
+          // Method references will be renamed.
+          assertNotEquals("foo", methodName);
+          assertEquals(foo.getFinalName(), methodName);
+        });
+  }
+
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/runner/AnotherPublicClassExtender.java b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/AnotherPublicClassExtender.java
new file mode 100644
index 0000000..8377885
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/AnotherPublicClassExtender.java
@@ -0,0 +1,13 @@
+// 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.resolution.b123730538.runner;
+
+import com.android.tools.r8.resolution.b123730538.sub.AnotherPublicClass;
+
+// To make AbstractPublicClass not mergeable for both R8 and Proguard.
+class AnotherPublicClassExtender extends AnotherPublicClass {
+  void delegate() {
+    foo();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/runner/PublicClassExtender.java b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/PublicClassExtender.java
new file mode 100644
index 0000000..b866eea
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/PublicClassExtender.java
@@ -0,0 +1,15 @@
+// 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.resolution.b123730538.runner;
+
+import com.android.tools.r8.resolution.b123730538.sub.PublicClass;
+
+public class PublicClassExtender extends PublicClass {
+  void delegate() {
+    // Method reference should be PublicClassExtender#foo, not the definition AbstractClass#foo
+    // because package-private AbstractClass is not visible from this calling context.
+    // Otherwise, we will see java.lang.IllegalAccessError.
+    foo();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/runner/Runner.java b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/Runner.java
new file mode 100644
index 0000000..54e0c6e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/Runner.java
@@ -0,0 +1,26 @@
+// 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.resolution.b123730538.runner;
+
+public class Runner {
+
+  static int counter = 0;
+
+  static Object create() {
+    if (counter++ % 2 == 0) {
+      return new PublicClassExtender();
+    } else {
+      return new AnotherPublicClassExtender();
+    }
+  }
+
+  public static void main(String[] args) {
+    Object instance = create();
+    if (instance instanceof PublicClassExtender) {
+      ((PublicClassExtender) instance).delegate();
+    } else {
+      ((AnotherPublicClassExtender) instance).delegate();
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AbstractClass.java b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AbstractClass.java
new file mode 100644
index 0000000..a99e9c5
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AbstractClass.java
@@ -0,0 +1,10 @@
+// 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.resolution.b123730538.sub;
+
+abstract class AbstractClass {
+  protected void foo() {
+    System.out.println("pkg.AbstractClass::foo");
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AnotherPublicClass.java b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AnotherPublicClass.java
new file mode 100644
index 0000000..b9433a1
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AnotherPublicClass.java
@@ -0,0 +1,8 @@
+// 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.resolution.b123730538.sub;
+
+// To make AbstractClass not mergeable for both R8 and Proguard.
+public class AnotherPublicClass extends AbstractClass {
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/sub/PublicClass.java b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/PublicClass.java
new file mode 100644
index 0000000..c3afbfc
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/PublicClass.java
@@ -0,0 +1,7 @@
+// 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.resolution.b123730538.sub;
+
+public class PublicClass extends AbstractClass {
+}