Revert "Move syntetic finalization over repackaging"
This reverts commit eacf70bb13b04f6542d457a8866d9b8986e67da5.
Reason for revert: Breaking the bots
Change-Id: Ie70dc8b668b5505c59905ba2b4d8d5693ac4a7f1
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index e237dcc..885ada8 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -70,6 +70,7 @@
import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.optimize.ClassAndMemberPublicizer;
import com.android.tools.r8.optimize.MemberRebindingAnalysis;
+import com.android.tools.r8.optimize.MemberRebindingIdentityLens;
import com.android.tools.r8.optimize.MemberRebindingIdentityLensFactory;
import com.android.tools.r8.optimize.VisibilityBridgeRemover;
import com.android.tools.r8.optimize.bridgehoisting.BridgeHoisting;
@@ -711,15 +712,9 @@
assert !options.isShrinking();
}
- // Insert a member rebinding oracle in the graph to ensure that all subsequent rewritings of
- // the application has an applied oracle for looking up non-rebound references.
- appView.setGraphLens(MemberRebindingIdentityLensFactory.create(appView, executorService));
-
- if (appView.appInfo().hasLiveness()) {
- SyntheticFinalization.finalizeWithLiveness(appView.withLiveness(), executorService);
- } else {
- SyntheticFinalization.finalizeWithClassHierarchy(appView, executorService);
- }
+ MemberRebindingIdentityLens memberRebindingLens =
+ MemberRebindingIdentityLensFactory.create(appView, executorService);
+ appView.setGraphLens(memberRebindingLens);
// Read any -applymapping input to allow for repackaging to not relocate the classes.
timing.begin("read -applymapping file");
@@ -733,13 +728,24 @@
RepackagingLens lens =
new Repackaging(appView.withLiveness()).run(appBuilder, executorService, timing);
if (lens != null) {
- appView.rewriteWithLensAndApplication(lens, appBuilder.build());
+ // Specify to use the member rebinding lens as the parent lens during the rewriting. This
+ // is needed to ensure that the rebound references are available during lens lookups.
+ // TODO(b/168282032): This call-site should not have to think about the parent lens that
+ // is used for the rewriting. Once the new member rebinding lens replaces the old member
+ // rebinding analysis it should be possible to clean this up.
+ appView.rewriteWithLensAndApplication(
+ lens, appBuilder.build(), memberRebindingLens.getPrevious());
}
}
if (appView.appInfo().hasLiveness()) {
assert Repackaging.verifyIdentityRepackaging(appView.withLiveness());
}
+ if (appView.appInfo().hasLiveness()) {
+ SyntheticFinalization.finalizeWithLiveness(appView.withLiveness(), executorService);
+ } else {
+ SyntheticFinalization.finalizeWithClassHierarchy(appView, executorService);
+ }
// Clear the reference type lattice element cache. This is required since class merging may
// need to build IR.
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index c3cbe39..b740f3d 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -795,7 +795,6 @@
while (firstUnappliedLens.getPrevious() != appliedLens) {
GraphLens previousLens = firstUnappliedLens.getPrevious();
assert previousLens.isNonIdentityLens();
- assert previousLens != appView.codeLens();
firstUnappliedLens = previousLens.asNonIdentityLens();
}
@@ -803,24 +802,22 @@
// TODO(b/182129249): Once the member rebinding phase has been removed, the MemberRebindingLens
// should be removed and all uses of FieldRebindingIdentityLens should be replaced by
// MemberRebindingIdentityLens.
- GraphLens newMemberRebindingLens = GraphLens.getIdentityLens();
- if (!firstUnappliedLens.isMemberRebindingLens()
- && !firstUnappliedLens.isMemberRebindingIdentityLens()) {
- NonIdentityGraphLens appliedMemberRebindingLens =
- firstUnappliedLens.findPreviousUntil(
- previous ->
- previous.isMemberRebindingLens() || previous.isMemberRebindingIdentityLens(),
- previous -> previous != appView.codeLens());
- if (appliedMemberRebindingLens != null) {
- newMemberRebindingLens =
- appliedMemberRebindingLens.isMemberRebindingLens()
- ? appliedMemberRebindingLens
- .asMemberRebindingLens()
- .toRewrittenFieldRebindingLens(appView, appliedLens)
- : appliedMemberRebindingLens
- .asMemberRebindingIdentityLens()
- .toRewrittenMemberRebindingIdentityLens(appView, appliedLens);
- }
+ NonIdentityGraphLens appliedMemberRebindingLens =
+ firstUnappliedLens.findPrevious(
+ previous ->
+ previous.isMemberRebindingLens() || previous.isMemberRebindingIdentityLens());
+ GraphLens newMemberRebindingLens;
+ if (appliedMemberRebindingLens != null) {
+ newMemberRebindingLens =
+ appliedMemberRebindingLens.isMemberRebindingLens()
+ ? appliedMemberRebindingLens
+ .asMemberRebindingLens()
+ .toRewrittenFieldRebindingLens(appView, appliedLens)
+ : appliedMemberRebindingLens
+ .asMemberRebindingIdentityLens()
+ .toRewrittenMemberRebindingIdentityLens(appView, appliedLens);
+ } else {
+ newMemberRebindingLens = GraphLens.getIdentityLens();
}
firstUnappliedLens.withAlternativeParentLens(
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLens.java b/src/main/java/com/android/tools/r8/graph/GraphLens.java
index 188211d..952c31d 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLens.java
@@ -400,7 +400,7 @@
public abstract DexType lookupType(DexType type, GraphLens applied);
- @Deprecated
+ // This overload can be used when the graph lens is known to be context insensitive.
public final DexMethod lookupMethod(DexMethod method) {
assert verifyIsContextFreeForMethod(method);
return lookupMethod(method, null, null).getReference();
@@ -410,47 +410,22 @@
return lookupMethod(method, context.getReference(), Type.DIRECT);
}
- public final MethodLookupResult lookupInvokeDirect(
- DexMethod method, ProgramMethod context, GraphLens codeLens) {
- return lookupMethod(method, context.getReference(), Type.DIRECT, codeLens);
- }
-
public final MethodLookupResult lookupInvokeInterface(DexMethod method, ProgramMethod context) {
return lookupMethod(method, context.getReference(), Type.INTERFACE);
}
- public final MethodLookupResult lookupInvokeInterface(
- DexMethod method, ProgramMethod context, GraphLens codeLens) {
- return lookupMethod(method, context.getReference(), Type.INTERFACE, codeLens);
- }
-
public final MethodLookupResult lookupInvokeStatic(DexMethod method, ProgramMethod context) {
return lookupMethod(method, context.getReference(), Type.STATIC);
}
- public final MethodLookupResult lookupInvokeStatic(
- DexMethod method, ProgramMethod context, GraphLens codeLens) {
- return lookupMethod(method, context.getReference(), Type.STATIC, codeLens);
- }
-
public final MethodLookupResult lookupInvokeSuper(DexMethod method, ProgramMethod context) {
return lookupMethod(method, context.getReference(), Type.SUPER);
}
- public final MethodLookupResult lookupInvokeSuper(
- DexMethod method, ProgramMethod context, GraphLens codeLens) {
- return lookupMethod(method, context.getReference(), Type.SUPER, codeLens);
- }
-
public final MethodLookupResult lookupInvokeVirtual(DexMethod method, ProgramMethod context) {
return lookupMethod(method, context.getReference(), Type.VIRTUAL);
}
- public final MethodLookupResult lookupInvokeVirtual(
- DexMethod method, ProgramMethod context, GraphLens codeLens) {
- return lookupMethod(method, context.getReference(), Type.VIRTUAL, codeLens);
- }
-
public final MethodLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
return lookupMethod(method, context, type, null);
}
@@ -841,13 +816,6 @@
return previous.isNonIdentityLens() ? previous.asNonIdentityLens().find(predicate) : null;
}
- public final <T extends NonIdentityGraphLens> T findPreviousUntil(
- Predicate<NonIdentityGraphLens> predicate,
- Predicate<NonIdentityGraphLens> stoppingCriterion) {
- T found = findPrevious(predicate.or(stoppingCriterion));
- return (found == null || stoppingCriterion.test(found)) ? null : found;
- }
-
public final void withAlternativeParentLens(GraphLens lens, Action action) {
GraphLens oldParent = getPrevious();
previousLens = lens;
diff --git a/src/main/java/com/android/tools/r8/repackaging/RepackagingAnnotationTracer.java b/src/main/java/com/android/tools/r8/repackaging/RepackagingAnnotationTracer.java
index d119f1c..f52b8b7 100644
--- a/src/main/java/com/android/tools/r8/repackaging/RepackagingAnnotationTracer.java
+++ b/src/main/java/com/android/tools/r8/repackaging/RepackagingAnnotationTracer.java
@@ -13,19 +13,16 @@
import com.android.tools.r8.graph.DexEncodedAnnotation;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexValue;
-import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ParameterAnnotationsList;
public class RepackagingAnnotationTracer {
private final AppInfoWithClassHierarchy appInfo;
- private final GraphLens graphLens;
private final RepackagingUseRegistry registry;
public RepackagingAnnotationTracer(
AppView<? extends AppInfoWithClassHierarchy> appView, RepackagingUseRegistry registry) {
this.appInfo = appView.appInfo();
- this.graphLens = appView.graphLens();
this.registry = registry;
}
@@ -42,7 +39,7 @@
}
private void traceEncodedAnnotation(DexEncodedAnnotation annotation) {
- registry.registerTypeReference(annotation.type, graphLens);
+ registry.registerTypeReference(annotation.type);
annotation.forEachElement(this::traceAnnotationElement);
}
@@ -97,14 +94,11 @@
break;
case METHOD_TYPE:
- value
- .asDexValueMethodType()
- .getValue()
- .forEachType(type -> registry.registerTypeReference(type, graphLens));
+ value.asDexValueMethodType().getValue().forEachType(registry::registerTypeReference);
break;
case TYPE:
- registry.registerTypeReference(value.asDexValueType().getValue(), graphLens);
+ registry.registerTypeReference(value.asDexValueType().getValue());
break;
default:
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 e17be11..9854d69 100644
--- a/src/main/java/com/android/tools/r8/repackaging/RepackagingConstraintGraph.java
+++ b/src/main/java/com/android/tools/r8/repackaging/RepackagingConstraintGraph.java
@@ -105,8 +105,8 @@
new RepackagingUseRegistry(appView, this, clazz, libraryBoundaryNode);
// Trace the references to the immediate super types.
- registry.registerTypeReference(clazz.getSuperType(), appView.graphLens());
- clazz.interfaces.forEach(type -> registry.registerTypeReference(type, appView.graphLens()));
+ registry.registerTypeReference(clazz.getSuperType());
+ clazz.interfaces.forEach(registry::registerTypeReference);
// Trace the references from the class annotations.
new RepackagingAnnotationTracer(appView, registry).trace(clazz.annotations());
@@ -114,10 +114,10 @@
// Trace the references in the nest host and/or members.
if (clazz.isInANest()) {
if (clazz.isNestHost()) {
- clazz.forEachNestMember(type -> registry.registerTypeReference(type, appView.graphLens()));
+ clazz.forEachNestMember(registry::registerTypeReference);
} else {
assert clazz.isNestMember();
- registry.registerTypeReference(clazz.getNestHost(), appView.graphLens());
+ registry.registerTypeReference(clazz.getNestHost());
}
}
@@ -139,7 +139,7 @@
new RepackagingUseRegistry(appView, this, field, libraryBoundaryNode);
// Trace the type of the field.
- registry.registerTypeReference(field.getReference().getType(), appView.graphLens());
+ registry.registerTypeReference(field.getReference().getType());
// Trace the references in the field annotations.
new RepackagingAnnotationTracer(appView, registry).trace(field.getDefinition().annotations());
@@ -151,9 +151,7 @@
new RepackagingUseRegistry(appView, this, method, libraryBoundaryNode);
// Trace the type references in the method signature.
- definition
- .getProto()
- .forEachType(type -> registry.registerTypeReference(type, appView.graphLens()));
+ definition.getProto().forEachType(registry::registerTypeReference);
// Check if this overrides a package-private method.
DexClass superClass =
diff --git a/src/main/java/com/android/tools/r8/repackaging/RepackagingUseRegistry.java b/src/main/java/com/android/tools/r8/repackaging/RepackagingUseRegistry.java
index 1339cbf..5c5a857 100644
--- a/src/main/java/com/android/tools/r8/repackaging/RepackagingUseRegistry.java
+++ b/src/main/java/com/android/tools/r8/repackaging/RepackagingUseRegistry.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.graph.AccessFlags;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClassAccessFlags;
-import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassAndMember;
import com.android.tools.r8.graph.DexField;
@@ -17,7 +16,6 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.EnclosingMethodAttribute;
-import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.MemberResolutionResult;
@@ -38,13 +36,10 @@
private final AppInfoWithLiveness appInfo;
private final InternalOptions options;
- private final GraphLens graphLens;
private final RepackagingConstraintGraph constraintGraph;
private final InitClassLens initClassLens;
private final RepackagingConstraintGraph.Node node;
private final RepackagingConstraintGraph.Node missingTypeNode;
- private final GraphLens codeLens;
- private final ProgramMethod methodContext;
public RepackagingUseRegistry(
AppView<AppInfoWithLiveness> appView,
@@ -56,18 +51,8 @@
this.options = appView.options();
this.constraintGraph = constraintGraph;
this.initClassLens = appView.initClassLens();
- this.graphLens = appView.graphLens();
this.node = constraintGraph.getNode(context.getDefinition());
this.missingTypeNode = missingTypeNode;
- GraphLens codeLens = appView.graphLens();
- if (context.isMethod()) {
- Code code = context.asMethod().getDefinition().getCode();
- if (code != null) {
- codeLens = code.getCodeLens(appView);
- }
- }
- this.codeLens = codeLens;
- methodContext = context.isMethod() ? context.asMethod() : null;
}
private boolean isOnlyAccessibleFromSamePackage(DexClass referencedClass) {
@@ -75,8 +60,11 @@
if (accessFlags.isPackagePrivate()) {
return true;
}
- return accessFlags.isProtected()
- && !appInfo.isSubtype(getContext().getContextType(), referencedClass.getType());
+ if (accessFlags.isProtected()
+ && !appInfo.isSubtype(getContext().getContextType(), referencedClass.getType())) {
+ return true;
+ }
+ return false;
}
private boolean isOnlyAccessibleFromSamePackage(
@@ -104,7 +92,7 @@
}
public void registerFieldAccess(DexField field) {
- registerMemberAccess(appInfo.resolveField(graphLens.lookupField(field)), false);
+ registerMemberAccess(appInfo.resolveField(field), false);
}
public ProgramMethod registerMethodReference(DexMethod method) {
@@ -201,46 +189,32 @@
@Override
public void registerInitClass(DexType type) {
- registerMemberAccess(
- appInfo.resolveField(initClassLens.getInitClassField(graphLens.lookupClassType(type))),
- false);
+ registerFieldAccess(initClassLens.getInitClassField(type));
}
@Override
public void registerInvokeVirtual(DexMethod invokedMethod) {
- registerMemberAccessForInvoke(
- appInfo.resolveMethod(
- graphLens.lookupInvokeVirtual(invokedMethod, methodContext, codeLens).getReference(),
- false));
+ registerMemberAccessForInvoke(appInfo.resolveMethod(invokedMethod, false));
}
@Override
public void registerInvokeDirect(DexMethod invokedMethod) {
- registerMemberAccessForInvoke(
- appInfo.unsafeResolveMethodDueToDexFormat(
- graphLens.lookupInvokeDirect(invokedMethod, methodContext, codeLens).getReference()));
+ registerMemberAccessForInvoke(appInfo.unsafeResolveMethodDueToDexFormat(invokedMethod));
}
@Override
public void registerInvokeStatic(DexMethod invokedMethod) {
- registerMemberAccessForInvoke(
- appInfo.unsafeResolveMethodDueToDexFormat(
- graphLens.lookupInvokeStatic(invokedMethod, methodContext, codeLens).getReference()));
+ registerMemberAccessForInvoke(appInfo.unsafeResolveMethodDueToDexFormat(invokedMethod));
}
@Override
public void registerInvokeInterface(DexMethod invokedMethod) {
- registerMemberAccessForInvoke(
- appInfo.resolveMethod(
- graphLens.lookupInvokeInterface(invokedMethod, methodContext, codeLens).getReference(),
- true));
+ registerMemberAccessForInvoke(appInfo.resolveMethod(invokedMethod, true));
}
@Override
public void registerInvokeSuper(DexMethod invokedMethod) {
- registerMemberAccessForInvoke(
- appInfo.unsafeResolveMethodDueToDexFormat(
- graphLens.lookupInvokeSuper(invokedMethod, methodContext, codeLens).getReference()));
+ registerMemberAccessForInvoke(appInfo.unsafeResolveMethodDueToDexFormat(invokedMethod));
}
@Override
@@ -255,7 +229,7 @@
@Override
public void registerNewInstance(DexType type) {
- registerTypeAccess(graphLens.lookupClassType(type));
+ registerTypeAccess(type);
}
@Override
@@ -270,16 +244,12 @@
@Override
public void registerTypeReference(DexType type) {
- registerTypeReference(type, codeLens);
- }
-
- public void registerTypeReference(DexType type, GraphLens applied) {
- registerTypeAccess(graphLens.lookupType(type, applied));
+ registerTypeAccess(type);
}
@Override
public void registerInstanceOf(DexType type) {
- registerTypeAccess(graphLens.lookupType(type));
+ registerTypeAccess(type);
}
public void registerEnclosingMethodAttribute(EnclosingMethodAttribute enclosingMethodAttribute) {
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingLambdaRepackageTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingLambdaRepackageTest.java
index 6c799bd..c85c55b 100644
--- a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingLambdaRepackageTest.java
+++ b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingLambdaRepackageTest.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.naming.applymapping;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
@@ -50,8 +50,14 @@
.addApplyMapping(firstRunResult.proguardMap())
.compile()
.run(parameters.getRuntime(), Main.class);
- assertEquals(firstRunResult.proguardMap(), secondRunResult.proguardMap());
- secondRunResult.assertSuccessWithOutputLines("Hello World");
+ if (parameters.isDexRuntime()) {
+ // TODO(b/218793832): Should be the same map.
+ assertNotEquals(firstRunResult.proguardMap(), secondRunResult.proguardMap());
+ }
+ secondRunResult
+ .assertSuccessWithOutputLinesIf(parameters.isCfRuntime(), "Hello World")
+ // TODO(b/218793832): Should not fail with an error.
+ .assertFailureWithErrorThatThrowsIf(parameters.isDexRuntime(), IllegalAccessError.class);
}
@NeverClassInline
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageWithSyntheticItemTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageWithSyntheticItemTest.java
index 7611b1c..1a3bfca 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageWithSyntheticItemTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageWithSyntheticItemTest.java
@@ -64,7 +64,11 @@
.filter(item -> item.getFinalName().startsWith("foo"))
.collect(Collectors.toList());
assertEquals(1, classesStartingWithfoo.size());
- String expectedOriginalNamePrefix = typeName(A.class) + "$$ExternalSyntheticLambda0";
+ // TODO(b/172014416): We should not be able to look this up through the repackage name
+ String expectedOriginalNamePrefix =
+ isFlattenPackageHierarchy()
+ ? "foo.a.RepackageWithSyntheticItemTest$A"
+ : "foo.RepackageWithSyntheticItemTest$A";
assertThat(
classesStartingWithfoo.get(0).getOriginalName(),
containsString(expectedOriginalNamePrefix));
diff --git a/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java b/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java
index 369d584..f85290d 100644
--- a/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java
@@ -10,6 +10,7 @@
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.R8;
@@ -291,7 +292,8 @@
.apply(this::configureHorizontalClassMerging)
.compile()
.graphInspector();
- assertRetainedClassesEqual(referenceInspector, ifHasMemberThenKeepClassInspector);
+ assertRetainedClassesEqual(
+ referenceInspector, ifHasMemberThenKeepClassInspector, true, true, true, true);
}
private void configureHorizontalClassMerging(R8FullTestBuilder testBuilder) {
@@ -311,27 +313,58 @@
private void assertRetainedClassesEqual(
GraphInspector referenceResult, GraphInspector conditionalResult) {
+ assertRetainedClassesEqual(referenceResult, conditionalResult, false, false, false, false);
+ }
+
+ private void assertRetainedClassesEqual(
+ GraphInspector referenceResult,
+ GraphInspector conditionalResult,
+ boolean expectReferenceIsLarger,
+ boolean expectReferenceIsLargerOnlyBySynthetics,
+ boolean expectConditionalIsLarger,
+ boolean expectConditionalIsLargerOnlyBySynthetics) {
Set<String> referenceClasses =
new TreeSet<>(
referenceResult.codeInspector().allClasses().stream()
.map(FoundClassSubject::getOriginalName)
.collect(Collectors.toSet()));
+
Set<String> conditionalClasses =
conditionalResult.codeInspector().allClasses().stream()
.map(FoundClassSubject::getOriginalName)
.collect(Collectors.toSet());
- Set<String> notInReference =
- new TreeSet<>(Sets.difference(conditionalClasses, referenceClasses));
- assertEquals(
- "Classes in -if rule that are not in -keepclassmembers rule",
- Collections.emptySet(),
- notInReference);
- Set<String> notInConditional =
- new TreeSet<>(Sets.difference(referenceClasses, conditionalClasses));
- assertEquals(
- "Classes in -keepclassmembers rule that are not in -if rule",
- Collections.emptySet(),
- notInConditional);
+ {
+ Set<String> notInReference =
+ new TreeSet<>(Sets.difference(conditionalClasses, referenceClasses));
+ if (expectConditionalIsLarger) {
+ assertFalse("Expected classes in -if rule to retain more.", notInReference.isEmpty());
+ if (expectConditionalIsLargerOnlyBySynthetics) {
+ assertAllClassesAreSynthetics(notInReference);
+ }
+ } else {
+ assertEquals(
+ "Classes in -if rule that are not in -keepclassmembers rule",
+ Collections.emptySet(),
+ notInReference);
+ }
+ }
+ {
+ Set<String> notInConditional =
+ new TreeSet<>(Sets.difference(referenceClasses, conditionalClasses));
+ if (expectReferenceIsLarger) {
+ assertFalse(
+ "Expected classes in -keepclassmembers rule to retain more.",
+ notInConditional.isEmpty());
+ if (expectReferenceIsLargerOnlyBySynthetics) {
+ assertAllClassesAreSynthetics(notInConditional);
+ }
+ } else {
+ assertEquals(
+ "Classes in -keepclassmembers rule that are not in -if rule",
+ Collections.emptySet(),
+ notInConditional);
+ }
+ }
}
private void assertAllClassesAreSynthetics(Set<String> classNames) {