Account for non-public library methods in class merger
Bug: 203446070
Change-Id: Ifabf27e4ef78f727a9635c8421bf04019f58f4c4
diff --git a/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java b/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
index 12044f5..7895b61 100644
--- a/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
@@ -45,6 +45,13 @@
return new ImmediateProgramSubtypingInfo(appView, immediateSubtypes);
}
+ public void forEachImmediateSuperClass(DexClass clazz, Consumer<? super DexClass> consumer) {
+ forEachImmediateSuperClassMatching(
+ clazz,
+ (supertype, superclass) -> superclass != null,
+ (supertype, superclass) -> consumer.accept(superclass));
+ }
+
public void forEachImmediateSuperClass(
DexProgramClass clazz, BiConsumer<? super DexType, ? super DexClass> consumer) {
forEachImmediateSuperClassMatching(clazz, (supertype, superclass) -> true, consumer);
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoWeakerAccessPrivileges.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoWeakerAccessPrivileges.java
index 399e807..600b5a8 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoWeakerAccessPrivileges.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoWeakerAccessPrivileges.java
@@ -31,6 +31,8 @@
new IdentityHashMap<>();
private final Map<Set<DexProgramClass>, DexMethodSignatureSet>
nonPublicVirtualMethodSignaturesCache = new IdentityHashMap<>();
+ private final Map<DexClass, DexMethodSignatureSet> nonPublicVirtualLibraryMethodSignaturesCache =
+ new IdentityHashMap<>();
private final Map<DexProgramClass, Set<DexProgramClass>> stronglyConnectedComponentsCache =
new IdentityHashMap<>();
@@ -152,12 +154,37 @@
clazz.forEachProgramVirtualMethodMatching(
method -> method.getAccessFlags().isPackagePrivateOrProtected(),
nonPublicVirtualMethodSignatures::add);
+ immediateSubtypingInfo.forEachImmediateSuperClassMatching(
+ clazz,
+ superclass -> !superclass.isProgramClass(),
+ superclass ->
+ nonPublicVirtualMethodSignatures.addAll(
+ getOrComputeNonPublicVirtualLibraryMethodSignatures(superclass)));
}
nonPublicVirtualMethodSignaturesCache.put(
stronglyConnectedComponent, nonPublicVirtualMethodSignatures);
return nonPublicVirtualMethodSignatures;
}
+ private DexMethodSignatureSet getOrComputeNonPublicVirtualLibraryMethodSignatures(
+ DexClass clazz) {
+ if (nonPublicVirtualLibraryMethodSignaturesCache.containsKey(clazz)) {
+ return nonPublicVirtualLibraryMethodSignaturesCache.get(clazz);
+ }
+ DexMethodSignatureSet nonPublicVirtualLibraryMethodSignatures = DexMethodSignatureSet.create();
+ clazz.forEachClassMethodMatching(
+ method -> method.getAccessFlags().isPackagePrivateOrProtected(),
+ nonPublicVirtualLibraryMethodSignatures::add);
+ immediateSubtypingInfo.forEachImmediateSuperClass(
+ clazz,
+ superclass ->
+ nonPublicVirtualLibraryMethodSignatures.addAll(
+ getOrComputeNonPublicVirtualLibraryMethodSignatures(superclass)));
+ nonPublicVirtualLibraryMethodSignaturesCache.put(
+ clazz, nonPublicVirtualLibraryMethodSignatures);
+ return nonPublicVirtualLibraryMethodSignatures;
+ }
+
@Override
public void clear() {
inheritedInterfaceMethodsCache.clear();