[GlobalSynthetics] Add record tag to output
Bug: b/280016114
Change-Id: I27703f41170f5215dce48651bb305ea163262245
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
index 12df474..827931b 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
@@ -30,8 +30,13 @@
import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.MethodCollection.MethodCollectionFactory;
import com.android.tools.r8.graph.NestHostClassAttribute;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ThrowExceptionCode;
+import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.desugar.TypeRewriter;
+import com.android.tools.r8.ir.desugar.records.RecordDesugaring;
+import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.naming.RecordRewritingNamingLens;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.MainDexInfo;
@@ -47,7 +52,9 @@
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -154,11 +161,22 @@
Set<DexProgramClass> synthesizingContext =
ImmutableSet.of(createSynthesizingContext(appView.dexItemFactory()));
- // TODO(b/280016114): Create record tag
+ List<ProgramMethod> methodsToProcess = new ArrayList<>();
+ RecordDesugaring.ensureRecordClassHelper(
+ appView,
+ synthesizingContext,
+ recordTagClass -> recordTagClass.programMethods().forEach(methodsToProcess::add));
+ NamingLens namingLens = RecordRewritingNamingLens.createRecordRewritingNamingLens(appView);
+
// TODO(b/280016114): Create Var Handle
// TODO(b/280016114): Create MethodHandlesLookup
+
createAllApiStubs(appView, synthesizingContext, executorService);
+ appView.setNamingLens(namingLens);
+ IRConverter converter = new IRConverter(appView);
+ converter.processSimpleSynthesizeMethods(methodsToProcess, executorService);
+
appView
.withoutClassHierarchy()
.setAppInfo(
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index a5417c6..7b531fb 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -349,14 +349,13 @@
return onWaveDoneActions != null;
}
- protected void processSimpleSynthesizeMethods(
- List<ProgramMethod> serviceLoadMethods, ExecutorService executorService)
- throws ExecutionException {
+ public void processSimpleSynthesizeMethods(
+ List<ProgramMethod> methods, ExecutorService executorService) throws ExecutionException {
ThreadUtils.processItems(
- serviceLoadMethods, this::processAndFinalizeSimpleSynthesiedMethod, executorService);
+ methods, this::processAndFinalizeSimpleSynthesizedMethod, executorService);
}
- private void processAndFinalizeSimpleSynthesiedMethod(ProgramMethod method) {
+ private void processAndFinalizeSimpleSynthesizedMethod(ProgramMethod method) {
IRCode code = method.buildIR(appView);
assert code != null;
codeRewriter.rewriteMoveResult(code);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
index 4e982d8..5cd5230 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
@@ -442,16 +442,23 @@
Collection<? extends ProgramDefinition> contexts) {
DexItemFactory factory = appView.dexItemFactory();
checkRecordTagNotPresent(factory);
+ return ensureRecordClassHelper(appView, contexts, eventConsumer);
+ }
+
+ public static DexProgramClass ensureRecordClassHelper(
+ AppView<?> appView,
+ Collection<? extends ProgramDefinition> contexts,
+ RecordDesugaringEventConsumer eventConsumer) {
return appView
.getSyntheticItems()
.ensureGlobalClass(
() -> new MissingGlobalSyntheticsConsumerDiagnostic("Record desugaring"),
kinds -> kinds.RECORD_TAG,
- factory.recordType,
+ appView.dexItemFactory().recordType,
contexts,
appView,
builder -> {
- DexEncodedMethod init = synthesizeRecordInitMethod();
+ DexEncodedMethod init = synthesizeRecordInitMethod(appView);
builder.setAbstract().setDirectMethods(ImmutableList.of(init));
},
eventConsumer::acceptRecordClass);
@@ -532,14 +539,16 @@
return factory.objectMembers.toString;
}
- private DexEncodedMethod synthesizeRecordInitMethod() {
+ private static DexEncodedMethod synthesizeRecordInitMethod(AppView<?> appView) {
MethodAccessFlags methodAccessFlags =
MethodAccessFlags.fromSharedAccessFlags(
Constants.ACC_SYNTHETIC | Constants.ACC_PROTECTED, true);
return DexEncodedMethod.syntheticBuilder()
- .setMethod(factory.recordMembers.constructor)
+ .setMethod(appView.dexItemFactory().recordMembers.constructor)
.setAccessFlags(methodAccessFlags)
- .setCode(new CallObjectInitCfCodeProvider(appView, factory.recordTagType).generateCfCode())
+ .setCode(
+ new CallObjectInitCfCodeProvider(appView, appView.dexItemFactory().recordTagType)
+ .generateCfCode())
// Will be traced by the enqueuer.
.disableAndroidApiLevelCheck()
.build();
diff --git a/src/test/java/com/android/tools/r8/globalsynthetics/GlobalSyntheticsEnsureClassesOutputTest.java b/src/test/java/com/android/tools/r8/globalsynthetics/GlobalSyntheticsEnsureClassesOutputTest.java
index fd26662..13e2f29 100644
--- a/src/test/java/com/android/tools/r8/globalsynthetics/GlobalSyntheticsEnsureClassesOutputTest.java
+++ b/src/test/java/com/android/tools/r8/globalsynthetics/GlobalSyntheticsEnsureClassesOutputTest.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
import com.google.common.collect.Sets;
import java.nio.file.Path;
+import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Test;
@@ -47,7 +48,7 @@
.setProgramConsumer(new DexIndexedConsumer.ArchiveConsumer(output))
.build());
CodeInspector inspector = new CodeInspector(output);
- assertEquals(1023, inspector.allClasses().size());
+ assertEquals(1024, inspector.allClasses().size());
}
@Test
@@ -59,9 +60,16 @@
.setMinApiLevel(AndroidApiLevel.LATEST.getLevel())
.setProgramConsumer(new DexIndexedConsumer.ArchiveConsumer(output))
.build());
- CodeInspector inspector = new CodeInspector(output);
- // TODO(b/280016114): This will change when we have record tag.
- assertEquals(0, inspector.allClasses().size());
+ Set<String> expectedInOutput = new HashSet<>();
+ // The output contains a RecordTag type that is mapped back to the original java.lang.Record by
+ // our codeinspector.
+ expectedInOutput.add("Ljava/lang/Record;");
+ assertEquals(
+ expectedInOutput,
+ new CodeInspector(output)
+ .allClasses().stream()
+ .map(FoundClassSubject::getFinalDescriptor)
+ .collect(Collectors.toSet()));
}
@Test