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!");
+ }
+ }
+}