Enable minimizeSyntheticNames in TwrCloseResourceDuplicationProfileRewritingTest
This implements robust detection of synthetics in the output in a way that is not based on the naming.
Change-Id: I81184477e20c4545940eb279909885e9e4a89258
diff --git a/src/main/java/com/android/tools/r8/ir/code/NumberGenerator.java b/src/main/java/com/android/tools/r8/ir/code/NumberGenerator.java
index e1ecde4..ddaf5de 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NumberGenerator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NumberGenerator.java
@@ -10,6 +10,10 @@
private int nextValueNumber = 0;
+ public int peekPrevious() {
+ return nextValueNumber - 1;
+ }
+
public int next() {
return nextValueNumber++;
}
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
index e0a0ee9..def2cc5 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -38,6 +38,7 @@
import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.OptionalBool;
+import com.android.tools.r8.utils.QuadConsumer;
import com.android.tools.r8.utils.SetUtils;
import com.android.tools.r8.utils.collections.BidirectionalManyToOneRepresentativeHashMap;
import com.android.tools.r8.utils.collections.BidirectionalManyToOneRepresentativeMap;
@@ -650,14 +651,13 @@
// Two equivalence groups in same context type must be distinct otherwise the assignment
// of the synthetic name will be non-deterministic between the two.
assert i == 0 || checkGroupsAreDistinct(groups.get(i - 1), group, comparator);
- SyntheticKind kind = group.getRepresentative().getKind();
DexType representativeType =
intermediate
&& synthetics.isSyntheticInput(
group.getRepresentative().getHolder().asProgramClass())
? group.getRepresentative().getHolder().getType()
: createExternalType(
- kind,
+ group,
externalSyntheticTypePrefix,
generators,
appView,
@@ -871,15 +871,17 @@
}
private DexType createExternalType(
- SyntheticKind kind,
+ EquivalenceGroup<?> group,
String externalSyntheticTypePrefix,
Map<String, NumberGenerator> generators,
AppView<?> appView,
Predicate<DexType> reserved) {
DexItemFactory factory = appView.dexItemFactory();
+ SyntheticKind kind = group.getRepresentative().getKind();
+ InternalOptions options = appView.options();
if (kind.isFixedSuffixSynthetic()) {
return SyntheticNaming.createExternalType(
- kind, externalSyntheticTypePrefix, "", factory, appView.options());
+ kind, externalSyntheticTypePrefix, "", factory, options);
}
NumberGenerator generator =
generators.computeIfAbsent(externalSyntheticTypePrefix, k -> new NumberGenerator());
@@ -903,6 +905,17 @@
externalType = null;
}
} while (externalType == null);
+ QuadConsumer<SyntheticKind, Integer, DexType, DexType> syntheticItemsConsumer =
+ options.getTestingOptions().syntheticItemsConsumer;
+ if (syntheticItemsConsumer != null) {
+ for (SyntheticDefinition<?, ?, ?> member : group.getRepresentativeAndMembers()) {
+ syntheticItemsConsumer.accept(
+ kind,
+ generator.peekPrevious(),
+ member.getContext().getSynthesizingContextType(),
+ externalType);
+ }
+ }
return externalType;
}
@@ -1012,6 +1025,10 @@
this.pinned = pinned;
}
+ public Iterable<T> getRepresentativeAndMembers() {
+ return IterableUtils.append(members, representative);
+ }
+
public boolean isPinned(AppView<?> appView) {
if (pinned.isTrue()) {
return true;
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 64eabc6..017d4a1 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -107,6 +107,7 @@
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.ProguardConfigurationRule;
import com.android.tools.r8.synthesis.SyntheticItemsOptions;
+import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.threading.ThreadingModule;
import com.android.tools.r8.tracereferences.TraceReferencesOptions;
import com.android.tools.r8.utils.IROrdering.IdentityIROrdering;
@@ -2331,6 +2332,8 @@
public BiConsumer<DexItemFactory, RepackagingLens> repackagingLensConsumer =
ConsumerUtils.emptyBiConsumer();
+ public QuadConsumer<SyntheticKind, Integer, DexType, DexType> syntheticItemsConsumer = null;
+
public BiConsumer<DexItemFactory, EnumDataMap> unboxedEnumsConsumer =
ConsumerUtils.emptyBiConsumer();
diff --git a/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationProfileRewritingTest.java b/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationProfileRewritingTest.java
index 76f002f..dd68df9 100644
--- a/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationProfileRewritingTest.java
+++ b/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationProfileRewritingTest.java
@@ -17,7 +17,9 @@
import com.android.tools.r8.profile.art.utils.ArtProfileInspector;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.InlinerOptions;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -59,6 +61,7 @@
@Test
public void testR8ProfileRewriting() throws Exception {
parameters.assumeR8TestParameters();
+ Box<SyntheticItemsTestUtils> syntheticItems = new Box<>();
testForR8(parameters.getBackend())
.addProgramClassFileData(TwrCloseResourceDuplicationTest.getProgramInputs())
.addKeepMainRule(MAIN)
@@ -67,9 +70,7 @@
.addOptionsModification(InlinerOptions::disableInlining)
.addOptionsModification(
options -> {
- // Explicitly disable minimal synthetic names to enable robust detection of
- // synthetics.
- options.desugarSpecificOptions().minimizeSyntheticNames = false;
+ options.desugarSpecificOptions().minimizeSyntheticNames = true;
options.testing.enableSyntheticSharing = false;
})
.applyIf(
@@ -83,10 +84,14 @@
options.getOpenClosedInterfacesOptions().suppressAllOpenInterfaces()),
testBuilder ->
testBuilder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST)))
+ .collectSyntheticItems()
.noHorizontalClassMergingOfSynthetics()
.setMinApi(parameters)
.compile()
- .inspectResidualArtProfile(this::inspectR8)
+ .inspectSyntheticItems(syntheticItems::set)
+ .inspectResidualArtProfile(
+ (profileInspector, inspector) ->
+ inspectR8(profileInspector, inspector, syntheticItems.get()))
.run(parameters.getRuntime(), MAIN, getZipFile())
.assertSuccessWithOutput(TwrCloseResourceDuplicationTest.EXPECTED);
}
@@ -127,19 +132,29 @@
}
private void inspectD8(ArtProfileInspector profileInspector, CodeInspector inspector) {
- inspect(profileInspector, inspector, hasTwrCloseResourceSupport(true), false);
+ inspect(
+ profileInspector,
+ inspector,
+ hasTwrCloseResourceSupport(true),
+ getDefaultSyntheticItemsTestUtils());
}
- private void inspectR8(ArtProfileInspector profileInspector, CodeInspector inspector) {
+ private void inspectR8(
+ ArtProfileInspector profileInspector,
+ CodeInspector inspector,
+ SyntheticItemsTestUtils syntheticItems) {
inspect(
- profileInspector, inspector, hasTwrCloseResourceSupport(parameters.isDexRuntime()), true);
+ profileInspector,
+ inspector,
+ hasTwrCloseResourceSupport(parameters.isDexRuntime()),
+ syntheticItems);
}
private void inspect(
ArtProfileInspector profileInspector,
CodeInspector inspector,
boolean hasTwrCloseResourceSupport,
- boolean isR8) {
+ SyntheticItemsTestUtils syntheticItems) {
int expectedClassCount = 3;
if (!hasTwrCloseResourceSupport) {
expectedClassCount += 8;
@@ -191,46 +206,41 @@
// There is 1 backport, 2 synthetic API outlines, and 3 twr classes for both Foo and Bar.
for (String clazz : ImmutableList.of(FOO, BAR)) {
ClassSubject syntheticApiOutlineClassSubject0 =
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticApiOutlineClass(Reference.classFromTypeName(clazz), 0));
+ inspector.syntheticClass(
+ syntheticItems.syntheticApiOutlineClass(Reference.classFromTypeName(clazz), 0));
assertThat(syntheticApiOutlineClassSubject0, isPresentIf(hasTwrCloseResourceApiOutlines()));
ClassSubject syntheticApiOutlineClassSubject1 =
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticApiOutlineClass(Reference.classFromTypeName(clazz), 1));
+ inspector.syntheticClass(
+ syntheticItems.syntheticApiOutlineClass(Reference.classFromTypeName(clazz), 1));
assertThat(syntheticApiOutlineClassSubject1, isPresentIf(hasTwrCloseResourceApiOutlines()));
int initialSyntheticId = hasTwrCloseResourceApiOutlines() ? 2 : 0;
ClassSubject syntheticBackportClassSubject =
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticBackportClass(Reference.classFromTypeName(clazz), initialSyntheticId));
+ inspector.syntheticClass(
+ syntheticItems.syntheticBackportClass(
+ Reference.classFromTypeName(clazz), initialSyntheticId));
assertThat(syntheticBackportClassSubject, notIf(isPresent(), hasTwrCloseResourceSupport));
ClassSubject syntheticTwrCloseResourceClassSubject3 =
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticTwrCloseResourceClass(
- Reference.classFromTypeName(clazz), initialSyntheticId + 1));
+ inspector.syntheticClass(
+ syntheticItems.syntheticTwrCloseResourceClass(
+ Reference.classFromTypeName(clazz), initialSyntheticId + 1));
assertThat(
syntheticTwrCloseResourceClassSubject3, notIf(isPresent(), hasTwrCloseResourceSupport));
ClassSubject syntheticTwrCloseResourceClassSubject4 =
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticTwrCloseResourceClass(
- Reference.classFromTypeName(clazz), initialSyntheticId + 2));
+ inspector.syntheticClass(
+ syntheticItems.syntheticTwrCloseResourceClass(
+ Reference.classFromTypeName(clazz), initialSyntheticId + 2));
assertThat(
syntheticTwrCloseResourceClassSubject4, notIf(isPresent(), hasTwrCloseResourceSupport));
ClassSubject syntheticTwrCloseResourceClassSubject5 =
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticTwrCloseResourceClass(
- Reference.classFromTypeName(clazz), initialSyntheticId + 3));
+ inspector.syntheticClass(
+ syntheticItems.syntheticTwrCloseResourceClass(
+ Reference.classFromTypeName(clazz), initialSyntheticId + 3));
assertThat(
syntheticTwrCloseResourceClassSubject5, notIf(isPresent(), hasTwrCloseResourceSupport));
@@ -261,9 +271,10 @@
profileInspector.applyIf(
options.shouldDesugarAutoCloseable(),
i ->
- i.assertContainsClassRules(getCloseDispatcherSyntheticClasses(inspector, isR8))
+ i.assertContainsClassRules(
+ getCloseDispatcherSyntheticClasses(inspector, syntheticItems))
.assertContainsMethodRules(
- Arrays.stream(getCloseDispatcherSyntheticClasses(inspector, isR8))
+ Arrays.stream(getCloseDispatcherSyntheticClasses(inspector, syntheticItems))
.map(ClassSubject::uniqueMethod)
.toArray(MethodSubject[]::new)));
@@ -271,44 +282,36 @@
}
private static ClassSubject[] getCloseDispatcherSyntheticClasses(
- CodeInspector inspector, boolean isR8) {
+ CodeInspector inspector, SyntheticItemsTestUtils syntheticItems) {
return new ClassSubject[] {
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticAutoCloseableDispatcherClass(Reference.classFromTypeName(FOO), 0)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticAutoCloseableDispatcherClass(Reference.classFromTypeName(FOO), 1)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticAutoCloseableDispatcherClass(Reference.classFromTypeName(BAR), 0)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticAutoCloseableDispatcherClass(Reference.classFromTypeName(BAR), 1)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticAutoCloseableForwarderClass(Reference.classFromTypeName(FOO), 2)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticAutoCloseableForwarderClass(Reference.classFromTypeName(FOO), 3)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticAutoCloseableForwarderClass(Reference.classFromTypeName(BAR), 2)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticAutoCloseableForwarderClass(Reference.classFromTypeName(BAR), 3)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticThrowIAEClass(Reference.classFromTypeName(FOO), 4)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticThrowIAEClass(Reference.classFromTypeName(FOO), 5)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticThrowIAEClass(Reference.classFromTypeName(BAR), 4)),
- inspector.clazz(
- getDefaultSyntheticItemsTestUtils()
- .syntheticThrowIAEClass(Reference.classFromTypeName(BAR), 5))
+ inspector.syntheticClass(
+ syntheticItems.syntheticAutoCloseableDispatcherClass(
+ Reference.classFromTypeName(FOO), 0)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticAutoCloseableDispatcherClass(
+ Reference.classFromTypeName(FOO), 1)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticAutoCloseableDispatcherClass(
+ Reference.classFromTypeName(BAR), 0)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticAutoCloseableDispatcherClass(
+ Reference.classFromTypeName(BAR), 1)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticAutoCloseableForwarderClass(Reference.classFromTypeName(FOO), 2)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticAutoCloseableForwarderClass(Reference.classFromTypeName(FOO), 3)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticAutoCloseableForwarderClass(Reference.classFromTypeName(BAR), 2)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticAutoCloseableForwarderClass(Reference.classFromTypeName(BAR), 3)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticThrowIAEClass(Reference.classFromTypeName(FOO), 4)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticThrowIAEClass(Reference.classFromTypeName(FOO), 5)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticThrowIAEClass(Reference.classFromTypeName(BAR), 4)),
+ inspector.syntheticClass(
+ syntheticItems.syntheticThrowIAEClass(Reference.classFromTypeName(BAR), 5))
};
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/b149971007/B149971007.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/b149971007/B149971007.java
index 5b38c12..c261571 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/b149971007/B149971007.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/b149971007/B149971007.java
@@ -5,19 +5,19 @@
package com.android.tools.r8.ir.optimize.outliner.b149971007;
import static com.android.tools.r8.synthesis.SyntheticItemsTestUtils.getMinimalSyntheticItemsTestUtils;
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.notIf;
import static junit.framework.TestCase.assertEquals;
-import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
+import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.dexsplitter.SplitterTestBase;
-import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
@@ -30,21 +30,20 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class B149971007 extends SplitterTestBase {
- private final TestParameters parameters;
+ @Parameter(0)
+ public TestParameters parameters;
- @Parameterized.Parameters(name = "{0}")
+ @Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withDexRuntimes().withAllApiLevels().build();
}
- public B149971007(TestParameters parameters) {
- this.parameters = parameters;
- }
-
private boolean invokesOutline(MethodSubject method, String outlineClassName) {
assertThat(method, isPresent());
for (InstructionSubject instruction : method.asFoundMethodSubject().instructions()) {
@@ -150,6 +149,7 @@
.addProgramClasses(TestClass.class, FeatureAPI.class)
.addKeepClassAndMembersRules(TestClass.class)
.addKeepClassAndMembersRules(FeatureClass.class)
+ .collectSyntheticItems()
.setMinApi(parameters)
.addFeatureSplit(
builder -> simpleSplitProvider(builder, featureCode, temp, FeatureClass.class))
@@ -161,30 +161,25 @@
.compile()
.inspect(this::checkNoOutlineFromFeature);
+ MethodSubject outlineMethod =
+ compileResult
+ .inspector()
+ .clazz(compileResult.getSyntheticItems().syntheticOutlineClass(TestClass.class, 1))
+ .uniqueMethod();
+ assertThat(outlineMethod, isPresent());
+
// Check that parts of method1, ..., method4 in FeatureClass was not outlined.
CodeInspector featureInspector = new CodeInspector(featureCode);
ClassSubject featureClass = featureInspector.clazz(FeatureClass.class);
-
- // Note, this code does not really check a valid property now as the name of the outline is not
- // known.
assertThat(featureClass, isPresent());
- String outlineClassName =
- ClassNameMapper.mapperFromString(compileResult.getProguardMap())
- .getObfuscatedToOriginalMapping()
- .inverse
- .get(
- getMinimalSyntheticItemsTestUtils()
- .syntheticOutlineClass(TestClass.class, 0)
- .getTypeName());
-
- assertFalse(
- invokesOutline(featureClass.uniqueMethodWithOriginalName("method1"), outlineClassName));
- assertFalse(
- invokesOutline(featureClass.uniqueMethodWithOriginalName("method2"), outlineClassName));
- assertFalse(
- invokesOutline(featureClass.uniqueMethodWithOriginalName("method3"), outlineClassName));
- assertFalse(
- invokesOutline(featureClass.uniqueMethodWithOriginalName("method4"), outlineClassName));
+ assertThat(
+ featureClass.uniqueMethodWithOriginalName("method1"), not(invokesMethod(outlineMethod)));
+ assertThat(
+ featureClass.uniqueMethodWithOriginalName("method2"), not(invokesMethod(outlineMethod)));
+ assertThat(
+ featureClass.uniqueMethodWithOriginalName("method3"), not(invokesMethod(outlineMethod)));
+ assertThat(
+ featureClass.uniqueMethodWithOriginalName("method4"), not(invokesMethod(outlineMethod)));
// Run the code without the feature code present.
compileResult.run(parameters.getRuntime(), TestClass.class).assertSuccessWithOutput("12");
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
index 7d1fabd..52d0ba8 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
@@ -99,7 +99,7 @@
"class_inliner_lambda_j_style.MainKt$$ExternalSyntheticLambda7")
.assertIsCompleteMergeGroup(
"class_inliner_lambda_j_style.MainKt$$ExternalSyntheticLambda2",
- "class_inliner_lambda_j_style.MainKt$$ExternalSyntheticThrowBlockOutline0");
+ "class_inliner_lambda_j_style.MainKt$$ExternalSyntheticBUOutline0");
}
inspector.assertNoOtherClassesMerged();
})
diff --git a/src/test/testbase/java/com/android/tools/r8/R8TestCompileResultBase.java b/src/test/testbase/java/com/android/tools/r8/R8TestCompileResultBase.java
index 083a743..e22b978 100644
--- a/src/test/testbase/java/com/android/tools/r8/R8TestCompileResultBase.java
+++ b/src/test/testbase/java/com/android/tools/r8/R8TestCompileResultBase.java
@@ -27,6 +27,7 @@
import com.android.tools.r8.profile.art.utils.ArtProfileInspector;
import com.android.tools.r8.shaking.CollectingGraphConsumer;
import com.android.tools.r8.shaking.ProguardConfigurationRule;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
@@ -214,6 +215,16 @@
return self();
}
+ public SyntheticItemsTestUtils getSyntheticItems() {
+ return state.getSyntheticItems();
+ }
+
+ public <E extends Throwable> CR inspectSyntheticItems(
+ ThrowingConsumer<SyntheticItemsTestUtils, E> consumer) throws E {
+ consumer.accept(state.getSyntheticItems());
+ return self();
+ }
+
public <E extends Throwable> CR assertResourceFile(String name, boolean present)
throws IOException {
assertNotNull(resourceShrinkerOutput);
diff --git a/src/test/testbase/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/testbase/java/com/android/tools/r8/TestCompilerBuilder.java
index 49007f8..5806896 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.optimize.argumentpropagation.ArgumentPropagatorEventConsumer;
import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodStateCollectionByReference;
import com.android.tools.r8.profile.art.model.ExternalArtProfile;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.testing.AndroidBuildVersion;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
@@ -115,6 +116,7 @@
private PrintStream oldStderr = null;
protected OutputMode outputMode = OutputMode.DexIndexed;
private boolean isBenchmarkRunner = false;
+ private SyntheticItemsTestUtils.Builder syntheticItemsBuilder;
private Optional<Integer> isAndroidBuildVersionAdded = null;
@@ -296,6 +298,13 @@
return self();
}
+ public T collectSyntheticItems() {
+ assert syntheticItemsBuilder == null;
+ this.syntheticItemsBuilder = new SyntheticItemsTestUtils.Builder();
+ return addOptionsModification(
+ options -> options.testing.syntheticItemsConsumer = syntheticItemsBuilder::add);
+ }
+
public CR benchmarkCompile(BenchmarkResults results) throws CompilationFailedException {
if (System.getProperty("com.android.tools.r8.printtimes") != null) {
allowStdoutMessages();
@@ -433,6 +442,9 @@
getState().setStderr(stderr.toString());
}
System.setErr(oldStderr);
+ if (syntheticItemsBuilder != null) {
+ getState().setSyntheticItems(syntheticItemsBuilder);
+ }
}
}
diff --git a/src/test/testbase/java/com/android/tools/r8/TestState.java b/src/test/testbase/java/com/android/tools/r8/TestState.java
index 77d4a0b..0cd7d32 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestState.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestState.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
@@ -20,6 +21,8 @@
private String stdout;
private String stderr;
+ private SyntheticItemsTestUtils syntheticItems;
+
public TestState(TemporaryFolder temp) {
this(temp, new TestDiagnosticMessagesImpl());
}
@@ -81,6 +84,14 @@
this.stderr = stderr;
}
+ public SyntheticItemsTestUtils getSyntheticItems() {
+ return syntheticItems;
+ }
+
+ void setSyntheticItems(SyntheticItemsTestUtils syntheticItems) {
+ this.syntheticItems = syntheticItems;
+ }
+
void setDiagnosticsLevelModifier(
BiFunction<DiagnosticsLevel, Diagnostic, DiagnosticsLevel> modifier) {
messages.setDiagnosticsLevelModifier(modifier);
diff --git a/src/test/testbase/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java b/src/test/testbase/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
index bcb3ce2..605183e 100644
--- a/src/test/testbase/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
+++ b/src/test/testbase/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
@@ -11,9 +11,12 @@
import static com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaring.NEST_ACCESS_STATIC_METHOD_NAME_PREFIX;
import static com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaring.NEST_ACCESS_STATIC_PUT_FIELD_NAME_PREFIX;
import static com.android.tools.r8.synthesis.SyntheticNaming.EXTERNAL_SYNTHETIC_CLASS_SEPARATOR;
+import static com.android.tools.r8.utils.MapUtils.ignoreKey;
import static org.hamcrest.CoreMatchers.containsString;
+import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.desugar.invokespecial.InvokeSpecialToSelfDesugaring;
import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringForTesting;
import com.android.tools.r8.references.ClassReference;
@@ -25,9 +28,14 @@
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceMaps;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import org.hamcrest.Matcher;
// TODO(b/454846973): Instantiate this based on an output from D8/R8 so that this is completely
@@ -130,25 +138,19 @@
return syntheticBottomUpOutlineClass(Reference.classFromClass(clazz), id);
}
- public ClassReference syntheticBottomUpOutlineClass(ClassReference clazz, int id) {
- return syntheticClass(clazz, naming.BOTTOM_UP_OUTLINE, id);
- }
+ public abstract ClassReference syntheticBottomUpOutlineClass(ClassReference clazz, int id);
public final ClassReference syntheticOutlineClass(Class<?> clazz, int id) {
return syntheticOutlineClass(Reference.classFromClass(clazz), id);
}
- public ClassReference syntheticOutlineClass(ClassReference clazz, int id) {
- return syntheticClass(clazz, naming.OUTLINE, id);
- }
+ public abstract ClassReference syntheticOutlineClass(ClassReference clazz, int id);
public final ClassReference syntheticLambdaClass(Class<?> clazz, int id) {
return syntheticLambdaClass(Reference.classFromClass(clazz), id);
}
- public ClassReference syntheticLambdaClass(ClassReference clazz, int id) {
- return syntheticClass(clazz, naming.LAMBDA, id);
- }
+ public abstract ClassReference syntheticLambdaClass(ClassReference clazz, int id);
public static ClassReference syntheticApiConversionClass(Class<?> clazz, int id) {
return syntheticClass(clazz, naming.API_CONVERSION, id);
@@ -158,23 +160,15 @@
return syntheticApiOutlineClass(Reference.classFromClass(clazz), id);
}
- public ClassReference syntheticApiOutlineClass(ClassReference classReference, int id) {
- return syntheticClass(classReference, naming.API_MODEL_OUTLINE, id);
- }
+ public abstract ClassReference syntheticApiOutlineClass(ClassReference classReference, int id);
- public String syntheticApiOutlineClassPrefix(Class<?> clazz) {
- return clazz.getTypeName()
- + EXTERNAL_SYNTHETIC_CLASS_SEPARATOR
- + naming.API_MODEL_OUTLINE.getDescriptor();
- }
+ public abstract String syntheticApiOutlineClassPrefix(Class<?> clazz);
public final ClassReference syntheticBackportClass(Class<?> clazz, int id) {
return syntheticBackportClass(Reference.classFromClass(clazz), id);
}
- public ClassReference syntheticBackportClass(ClassReference classReference, int id) {
- return syntheticClass(classReference, naming.BACKPORT, id);
- }
+ public abstract ClassReference syntheticBackportClass(ClassReference classReference, int id);
public static ClassReference syntheticBackportWithForwardingClass(Class<?> clazz, int id) {
return syntheticClass(clazz, naming.BACKPORT_WITH_FORWARDING, id);
@@ -193,23 +187,15 @@
return syntheticClass(reference, naming.RECORD_HELPER, id);
}
- public ClassReference syntheticTwrCloseResourceClass(ClassReference reference, int id) {
- return syntheticClass(reference, naming.TWR_CLOSE_RESOURCE, id);
- }
+ public abstract ClassReference syntheticTwrCloseResourceClass(ClassReference reference, int id);
- public ClassReference syntheticAutoCloseableDispatcherClass(
- ClassReference classReference, int id) {
- return syntheticClass(classReference, naming.AUTOCLOSEABLE_DISPATCHER, id);
- }
+ public abstract ClassReference syntheticAutoCloseableDispatcherClass(
+ ClassReference classReference, int id);
- public ClassReference syntheticAutoCloseableForwarderClass(
- ClassReference classReference, int id) {
- return syntheticClass(classReference, naming.AUTOCLOSEABLE_FORWARDER, id);
- }
+ public abstract ClassReference syntheticAutoCloseableForwarderClass(
+ ClassReference classReference, int id);
- public ClassReference syntheticThrowIAEClass(ClassReference classReference, int id) {
- return syntheticClass(classReference, naming.THROW_IAE, id);
- }
+ public abstract ClassReference syntheticThrowIAEClass(ClassReference classReference, int id);
public final MethodReference syntheticLambdaMethod(Class<?> clazz, int id, Method method) {
ClassReference syntheticHolder = syntheticLambdaClass(clazz, id);
@@ -396,7 +382,62 @@
return SyntheticNaming.isSynthetic(method.getHolderClass(), Phase.INTERNAL, naming.THROW_NSME);
}
- private static class DefaultSyntheticItemsTestUtils extends SyntheticItemsTestUtils {}
+ private static class DefaultSyntheticItemsTestUtils extends SyntheticItemsTestUtils {
+
+ @Override
+ public ClassReference syntheticApiOutlineClass(ClassReference classReference, int id) {
+ return syntheticClass(classReference, naming.API_MODEL_OUTLINE, id);
+ }
+
+ @Override
+ public String syntheticApiOutlineClassPrefix(Class<?> clazz) {
+ return clazz.getTypeName()
+ + EXTERNAL_SYNTHETIC_CLASS_SEPARATOR
+ + naming.API_MODEL_OUTLINE.getDescriptor();
+ }
+
+ @Override
+ public ClassReference syntheticAutoCloseableDispatcherClass(
+ ClassReference classReference, int id) {
+ return syntheticClass(classReference, naming.AUTOCLOSEABLE_DISPATCHER, id);
+ }
+
+ @Override
+ public ClassReference syntheticAutoCloseableForwarderClass(
+ ClassReference classReference, int id) {
+ return syntheticClass(classReference, naming.AUTOCLOSEABLE_FORWARDER, id);
+ }
+
+ @Override
+ public ClassReference syntheticBackportClass(ClassReference classReference, int id) {
+ return syntheticClass(classReference, naming.BACKPORT, id);
+ }
+
+ @Override
+ public ClassReference syntheticBottomUpOutlineClass(ClassReference clazz, int id) {
+ return syntheticClass(clazz, naming.BOTTOM_UP_OUTLINE, id);
+ }
+
+ @Override
+ public ClassReference syntheticLambdaClass(ClassReference clazz, int id) {
+ return syntheticClass(clazz, naming.LAMBDA, id);
+ }
+
+ @Override
+ public ClassReference syntheticOutlineClass(ClassReference clazz, int id) {
+ return syntheticClass(clazz, naming.OUTLINE, id);
+ }
+
+ @Override
+ public ClassReference syntheticThrowIAEClass(ClassReference classReference, int id) {
+ return syntheticClass(classReference, naming.THROW_IAE, id);
+ }
+
+ @Override
+ public ClassReference syntheticTwrCloseResourceClass(ClassReference reference, int id) {
+ return syntheticClass(reference, naming.TWR_CLOSE_RESOURCE, id);
+ }
+ }
private static class MinimalSyntheticItemsTestUtils extends SyntheticItemsTestUtils {
@@ -428,6 +469,11 @@
}
@Override
+ public ClassReference syntheticBottomUpOutlineClass(ClassReference classReference, int id) {
+ return syntheticClassWithMinimalName(classReference, id);
+ }
+
+ @Override
public ClassReference syntheticLambdaClass(ClassReference classReference, int id) {
return syntheticClassWithMinimalName(classReference, id);
}
@@ -438,11 +484,6 @@
}
@Override
- public ClassReference syntheticBottomUpOutlineClass(ClassReference classReference, int id) {
- return syntheticClassWithMinimalName(classReference, id);
- }
-
- @Override
public ClassReference syntheticThrowIAEClass(ClassReference classReference, int id) {
return syntheticClassWithMinimalName(classReference, id);
}
@@ -452,4 +493,78 @@
return syntheticClassWithMinimalName(classReference, id);
}
}
+
+ public static class Builder extends SyntheticItemsTestUtils {
+
+ private final Map<ClassReference, Map<SyntheticKind, Int2ReferenceMap<ClassReference>>>
+ synthetics = new HashMap<>();
+
+ public void add(SyntheticKind kind, int id, DexType syntheticContext, DexType externalType) {
+ Map<SyntheticKind, Int2ReferenceMap<ClassReference>> syntheticsForContextMap =
+ synthetics.computeIfAbsent(syntheticContext.asClassReference(), ignoreKey(HashMap::new));
+ Int2ReferenceMap<ClassReference> idToExternalTypeMap =
+ syntheticsForContextMap.computeIfAbsent(kind, ignoreKey(Int2ReferenceOpenHashMap::new));
+ ClassReference previousValue = idToExternalTypeMap.put(id, externalType.asClassReference());
+ assert previousValue == null;
+ }
+
+ private ClassReference lookup(ClassReference classReference, int id, SyntheticKind kind) {
+ return synthetics
+ .getOrDefault(classReference, Collections.emptyMap())
+ .getOrDefault(kind, Int2ReferenceMaps.emptyMap())
+ .get(id);
+ }
+
+ @Override
+ public ClassReference syntheticApiOutlineClass(ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.API_MODEL_OUTLINE);
+ }
+
+ @Override
+ public String syntheticApiOutlineClassPrefix(Class<?> clazz) {
+ throw new Unimplemented();
+ }
+
+ @Override
+ public ClassReference syntheticAutoCloseableDispatcherClass(
+ ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.AUTOCLOSEABLE_DISPATCHER);
+ }
+
+ @Override
+ public ClassReference syntheticAutoCloseableForwarderClass(
+ ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.AUTOCLOSEABLE_FORWARDER);
+ }
+
+ @Override
+ public ClassReference syntheticBackportClass(ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.BACKPORT);
+ }
+
+ @Override
+ public ClassReference syntheticBottomUpOutlineClass(ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.BOTTOM_UP_OUTLINE);
+ }
+
+ @Override
+ public ClassReference syntheticLambdaClass(ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.LAMBDA);
+ }
+
+ @Override
+ public ClassReference syntheticOutlineClass(ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.OUTLINE);
+ }
+
+ @Override
+ public ClassReference syntheticThrowIAEClass(ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.THROW_IAE);
+ }
+
+ @Override
+ public ClassReference syntheticTwrCloseResourceClass(ClassReference classReference, int id) {
+ return lookup(classReference, id, naming.TWR_CLOSE_RESOURCE);
+ }
+ }
}
diff --git a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/AbsentClassSubject.java b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/AbsentClassSubject.java
index 629ad82..3d337bb 100644
--- a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/AbsentClassSubject.java
+++ b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/AbsentClassSubject.java
@@ -20,6 +20,10 @@
public class AbsentClassSubject extends ClassSubject {
+ public AbsentClassSubject() {
+ super(null, null);
+ }
+
public AbsentClassSubject(CodeInspector codeInspector, ClassReference reference) {
super(codeInspector, reference);
}
diff --git a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index 521664a..bdb96d0 100644
--- a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -416,6 +416,10 @@
return clazz(SyntheticItemsTestUtils.syntheticCompanionClass(clazz));
}
+ public ClassSubject syntheticClass(ClassReference classReference) {
+ return classReference != null ? clazz(classReference) : new AbsentClassSubject();
+ }
+
public void forAllClasses(Consumer<FoundClassSubject> inspection) {
forAll(
application.classes(),