Trace method-overrides-edge in repackaging

Bug: 165783399
Change-Id: I613e59e49dedfee300a08a98f0f3c889ae8c8255
diff --git a/src/main/java/com/android/tools/r8/repackaging/RepackagingConstraintGraph.java b/src/main/java/com/android/tools/r8/repackaging/RepackagingConstraintGraph.java
index fbaf1b8..5c521b5 100644
--- a/src/main/java/com/android/tools/r8/repackaging/RepackagingConstraintGraph.java
+++ b/src/main/java/com/android/tools/r8/repackaging/RepackagingConstraintGraph.java
@@ -136,6 +136,14 @@
     // Trace the type references in the method signature.
     definition.getProto().forEachType(registry::registerTypeReference);
 
+    // Check if this overrides a package-private method.
+    DexProgramClass superClass =
+        appView.programDefinitionFor(method.getHolder().getSuperType(), method.getHolder());
+    if (superClass != null) {
+      registry.registerMemberAccess(
+          appView.appInfo().resolveMethodOn(superClass, method.getReference()));
+    }
+
     // Trace the references in the method and method parameter annotations.
     RepackagingAnnotationTracer annotationTracer =
         new RepackagingAnnotationTracer(appView, registry);
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageWithOverridesOfPackagePrivateMethodsTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageWithOverridesOfPackagePrivateMethodsTest.java
new file mode 100644
index 0000000..951a2b6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageWithOverridesOfPackagePrivateMethodsTest.java
@@ -0,0 +1,96 @@
+// Copyright (c) 2020, 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.repackage;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NoVerticalClassMerging;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class RepackageWithOverridesOfPackagePrivateMethodsTest extends RepackageTestBase {
+
+  public RepackageWithOverridesOfPackagePrivateMethodsTest(
+      String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
+    super(flattenPackageHierarchyOrRepackageClasses, parameters);
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(TestClass.class)
+        .apply(this::configureRepackaging)
+        .enableInliningAnnotations()
+        .enableNeverClassInliningAnnotations()
+        .enableNoVerticalClassMergingAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(this::inspect)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutputLines("Hello world!");
+  }
+
+  private void inspect(CodeInspector inspector) {
+    assertThat(HelloGreeter.class, isNotRepackaged(inspector));
+    assertThat(WorldGreeter.class, isNotRepackaged(inspector));
+  }
+
+  public static class TestClass {
+
+    public static void main(String[] args) {
+      greet(new HelloGreeter());
+      greet(new WorldGreeter());
+    }
+
+    @NeverInline
+    static void greet(HelloGreeterBase greeter) {
+      greeter.greet();
+    }
+
+    @NeverInline
+    static void greet(WorldGreeterBase greeter) {
+      greeter.greet();
+    }
+  }
+
+  @NoVerticalClassMerging
+  public abstract static class HelloGreeterBase {
+
+    abstract void greet();
+  }
+
+  @NeverClassInline
+  public static class HelloGreeter extends HelloGreeterBase {
+
+    @NeverInline
+    @Override
+    void greet() {
+      System.out.print("Hello");
+    }
+  }
+
+  @NoVerticalClassMerging
+  public abstract static class WorldGreeterBase {
+
+    abstract void greet();
+  }
+
+  @NeverClassInline
+  public static class WorldGreeter extends WorldGreeterBase {
+
+    @NeverInline
+    @Override
+    public void greet() {
+      System.out.println(" world!");
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageWithOverridesOfProtectedMethodsTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageWithOverridesOfProtectedMethodsTest.java
new file mode 100644
index 0000000..7747cbd
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageWithOverridesOfProtectedMethodsTest.java
@@ -0,0 +1,96 @@
+// Copyright (c) 2020, 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.repackage;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NoVerticalClassMerging;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class RepackageWithOverridesOfProtectedMethodsTest extends RepackageTestBase {
+
+  public RepackageWithOverridesOfProtectedMethodsTest(
+      String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
+    super(flattenPackageHierarchyOrRepackageClasses, parameters);
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(TestClass.class)
+        .apply(this::configureRepackaging)
+        .enableInliningAnnotations()
+        .enableNeverClassInliningAnnotations()
+        .enableNoVerticalClassMergingAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(this::inspect)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutputLines("Hello world!");
+  }
+
+  private void inspect(CodeInspector inspector) {
+    assertThat(HelloGreeter.class, isRepackaged(inspector));
+    assertThat(WorldGreeter.class, isRepackaged(inspector));
+  }
+
+  public static class TestClass {
+
+    public static void main(String[] args) {
+      greet(new HelloGreeter());
+      greet(new WorldGreeter());
+    }
+
+    @NeverInline
+    static void greet(HelloGreeterBase greeter) {
+      greeter.greet();
+    }
+
+    @NeverInline
+    static void greet(WorldGreeterBase greeter) {
+      greeter.greet();
+    }
+  }
+
+  @NoVerticalClassMerging
+  public abstract static class HelloGreeterBase {
+
+    protected abstract void greet();
+  }
+
+  @NeverClassInline
+  public static class HelloGreeter extends HelloGreeterBase {
+
+    @NeverInline
+    @Override
+    protected void greet() {
+      System.out.print("Hello");
+    }
+  }
+
+  @NoVerticalClassMerging
+  public abstract static class WorldGreeterBase {
+
+    protected abstract void greet();
+  }
+
+  @NeverClassInline
+  public static class WorldGreeter extends WorldGreeterBase {
+
+    @NeverInline
+    @Override
+    public void greet() {
+      System.out.println(" world!");
+    }
+  }
+}