Fix inadequate keep rule generating in trace references Bug: b/397904338 Change-Id: I3d613d57f8de37a3c5670b6d843e1edc402591e7
diff --git a/src/main/java/com/android/tools/r8/tracereferences/Formatter.java b/src/main/java/com/android/tools/r8/tracereferences/Formatter.java index 2f19681..e3978f3 100644 --- a/src/main/java/com/android/tools/r8/tracereferences/Formatter.java +++ b/src/main/java/com/android/tools/r8/tracereferences/Formatter.java
@@ -10,10 +10,14 @@ import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedClass; import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedField; import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedMethod; +import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedReference; import com.android.tools.r8.tracereferences.internal.TraceReferencesResult; +import com.android.tools.r8.utils.IterableUtils; import com.android.tools.r8.utils.ListUtils; +import com.android.tools.r8.utils.MapUtils; import com.android.tools.r8.utils.StringUtils; import com.android.tools.r8.utils.StringUtils.BraceType; +import com.google.common.collect.Streams; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -89,13 +93,14 @@ Set<PackageReference> keepPackageNames, Map<ClassReference, Set<TracedField>> fields, Map<ClassReference, Set<TracedMethod>> methods) { - List<TracedClass> sortedTypes = new ArrayList<>(types); - sortedTypes.sort(Comparator.comparing(tracedClass -> tracedClass.getReference().getTypeName())); + List<TracedClass> sortedTypes = + ListUtils.sort( + types, Comparator.comparing(tracedClass -> tracedClass.getReference().getDescriptor())); for (TracedClass type : sortedTypes) { Set<TracedMethod> methodsForClass = - methods.getOrDefault(type.getReference(), Collections.emptySet()); + MapUtils.removeOrDefault(methods, type.getReference(), Collections.emptySet()); Set<TracedField> fieldsForClass = - fields.getOrDefault(type.getReference(), Collections.emptySet()); + MapUtils.removeOrDefault(fields, type.getReference(), Collections.emptySet()); if (type.isMissingDefinition()) { continue; } @@ -123,6 +128,10 @@ } printTypeFooter(); } + assert Streams.stream(IterableUtils.flatten(fields.values())) + .allMatch(TracedReference::isMissingDefinition); + assert Streams.stream(IterableUtils.flatten(methods.values())) + .allMatch(TracedReference::isMissingDefinition); List<String> packageNamesToKeep = keepPackageNames.stream() .map(PackageReference::getPackageName)
diff --git a/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java b/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java index 22ec0d0..6bcaf98 100644 --- a/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java +++ b/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java
@@ -123,6 +123,12 @@ consumer.acceptMethod(tracedMethod, diagnostics); } + protected void notifyPresentMethod( + DexClassAndMethod method, DefinitionContext referencedFrom, DexMethod reference) { + TracedMethodImpl tracedMethod = new TracedMethodImpl(method, referencedFrom, reference); + consumer.acceptMethod(tracedMethod, diagnostics); + } + protected void notifyPackageOf(Definition definition) { consumer.acceptPackage( Reference.packageFromString(definition.getContextType().getPackageName()), diagnostics); @@ -212,19 +218,6 @@ } } - private void addSuperMethodFromTarget( - DexClassAndMethod method, ProgramMethod context, DefinitionContext referencedFrom) { - assert !method.isProgramMethod(); - assert isTargetType(method.getHolderType()); - // There should be no need to register the types referenced from the method signature: - // - The return type and the parameter types are registered when visiting the source method - // that overrides this target method, - // - The holder type is registered from visiting the extends/implements clause of the sub - // class. - notifyPresentMethod(method, referencedFrom); - ensurePackageAccessToMember(method, context.getHolder()); - } - private <R, T extends TracedReference<R, ?>> void collectMissing( T tracedReference, Set<R> missingCollection) { if (tracedReference.isMissingDefinition()) { @@ -291,7 +284,23 @@ if (resolvedMethod != null && !resolvedMethod.isProgramMethod() && isTargetType(resolvedMethod.getHolderType())) { - addSuperMethodFromTarget(resolvedMethod, method, referencedFrom); + // There should be no need to register the types referenced from the method signature: + // - The return type and the parameter types are registered when visiting the source + // method that overrides this target method, + // - The holder type is registered from visiting the extends/implements clause of the + // sub class. + if (resolvedMethod.getHolderType().isIdenticalTo(superType)) { + notifyPresentMethod(resolvedMethod, referencedFrom); + } else if (isTargetType(superType)) { + notifyPresentMethod( + resolvedMethod, + referencedFrom, + resolvedMethod.getReference().withHolder(superType, factory)); + } else { + notifyPresentMethod(resolvedMethod, referencedFrom); + addClass(resolvedMethod.getHolder(), referencedFrom); + } + ensurePackageAccessToMember(resolvedMethod, method.getHolder()); } }); }
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/TracedMethodImpl.java b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedMethodImpl.java index 2e315df..22f7671 100644 --- a/src/main/java/com/android/tools/r8/tracereferences/internal/TracedMethodImpl.java +++ b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedMethodImpl.java
@@ -26,6 +26,14 @@ } public TracedMethodImpl( + DexClassAndMethod method, DefinitionContext referencedFrom, DexMethod reference) { + this( + reference.asMethodReference(), + referencedFrom, + new MethodAccessFlagsImpl(method.getAccessFlags())); + } + + public TracedMethodImpl( MethodReference methodReference, DefinitionContext referencedFrom, MethodAccessFlags accessFlags) {
diff --git a/src/test/java/com/android/tools/r8/tracereferences/TraceReferencesIndirectOverrideTest.java b/src/test/java/com/android/tools/r8/tracereferences/TraceReferencesIndirectOverrideTest.java index cc255ed..771e4e3 100644 --- a/src/test/java/com/android/tools/r8/tracereferences/TraceReferencesIndirectOverrideTest.java +++ b/src/test/java/com/android/tools/r8/tracereferences/TraceReferencesIndirectOverrideTest.java
@@ -4,7 +4,6 @@ package com.android.tools.r8.tracereferences; import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; import com.android.tools.r8.TestBase; @@ -57,8 +56,7 @@ .setOutputConsumer(testingKeepRuleConsumer) .build()) .build()); - // TODO(b/397904338): shouldBeKept() should be kept. - assertThat(testingKeepRuleConsumer.get(), not(containsString("shouldBeKept"))); + assertThat(testingKeepRuleConsumer.get(), containsString("shouldBeKept")); } static class A {