Generate Record class based on AppReader flag
Bug: 197081367
Change-Id: Ic29b332eaa5949e32a6922df886fb95049c4436d
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index 4e999be..4050961 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -331,6 +331,7 @@
// as there was a dex resource.
private boolean hasReadProgramResourceFromCf = false;
private boolean hasReadProgramResourceFromDex = false;
+ private boolean hasReadProgramRecord = false;
ClassReader(ExecutorService executorService, List<Future<?>> futures) {
this.executorService = executorService;
@@ -339,7 +340,7 @@
public DexApplicationReadFlags getDexApplicationReadFlags() {
return new DexApplicationReadFlags(
- hasReadProgramResourceFromDex, hasReadProgramResourceFromCf);
+ hasReadProgramResourceFromDex, hasReadProgramResourceFromCf, hasReadProgramRecord);
}
private void readDexSources(List<ProgramResource> dexSources, Queue<DexProgramClass> classes)
@@ -381,7 +382,15 @@
}
hasReadProgramResourceFromCf = true;
JarClassFileReader<DexProgramClass> reader =
- new JarClassFileReader<>(application, classes::add, PROGRAM);
+ new JarClassFileReader<>(
+ application,
+ clazz -> {
+ classes.add(clazz);
+ if (clazz.isRecord()) {
+ hasReadProgramRecord = true;
+ }
+ },
+ PROGRAM);
// Read classes in parallel.
for (ProgramResource input : classSources) {
futures.add(
diff --git a/src/main/java/com/android/tools/r8/graph/DexApplicationReadFlags.java b/src/main/java/com/android/tools/r8/graph/DexApplicationReadFlags.java
index 525bd9a..d5089a7 100644
--- a/src/main/java/com/android/tools/r8/graph/DexApplicationReadFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/DexApplicationReadFlags.java
@@ -9,11 +9,15 @@
private final boolean hasReadProgramClassFromDex;
private final boolean hasReadProgramClassFromCf;
+ private final boolean hasReadProgramRecord;
public DexApplicationReadFlags(
- boolean hasReadProgramClassFromDex, boolean hasReadProgramClassFromCf) {
+ boolean hasReadProgramClassFromDex,
+ boolean hasReadProgramClassFromCf,
+ boolean hasReadProgramRecord) {
this.hasReadProgramClassFromDex = hasReadProgramClassFromDex;
this.hasReadProgramClassFromCf = hasReadProgramClassFromCf;
+ this.hasReadProgramRecord = hasReadProgramRecord;
}
public boolean hasReadProgramClassFromCf() {
@@ -23,4 +27,8 @@
public boolean hasReadProgramClassFromDex() {
return hasReadProgramClassFromDex;
}
+
+ public boolean hasReadProgramRecord() {
+ return hasReadProgramRecord;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
index 38d9d56..5d49406 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
@@ -9,8 +9,6 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.desugar.CfClassDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfClassDesugaringEventConsumer.D8CfClassDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer;
@@ -55,10 +53,10 @@
throws ExecutionException {
List<DexProgramClass> classes = appView.appInfo().classes();
- if (appView.options().isDesugaredLibraryCompilation()) {
CfClassSynthesizerDesugaringEventConsumer classSynthesizerEventConsumer =
new CfClassSynthesizerDesugaringEventConsumer();
converter.classSynthesisDesugaring(executorService, classSynthesizerEventConsumer);
+ if (!classSynthesizerEventConsumer.getSynthesizedClasses().isEmpty()) {
classes =
ImmutableList.<DexProgramClass>builder()
.addAll(classes)
@@ -66,9 +64,6 @@
.build();
}
- D8CfClassDesugaringEventConsumer classDesugaringEventConsumer =
- CfClassDesugaringEventConsumer.createForD8(methodProcessor);
- converter.desugarClassesForD8(classes, classDesugaringEventConsumer, executorService);
converter.prepareDesugaringForD8(executorService);
while (!classes.isEmpty()) {
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 c6f7d4a..a1d1e2a 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
@@ -44,8 +44,6 @@
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.conversion.MethodConversionOptions.DefaultMethodConversionOptions;
import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
-import com.android.tools.r8.ir.desugar.CfClassDesugaringCollection;
-import com.android.tools.r8.ir.desugar.CfClassDesugaringEventConsumer.D8CfClassDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection;
@@ -134,7 +132,6 @@
private final Timing timing;
private final Outliner outliner;
private final ClassInitializerDefaultsOptimization classInitializerDefaultsOptimization;
- private final CfClassDesugaringCollection classDesugaring;
private final CfInstructionDesugaringCollection instructionDesugaring;
private final FieldAccessAnalysis fieldAccessAnalysis;
private final LibraryMethodOverrideAnalysis libraryMethodOverrideAnalysis;
@@ -225,7 +222,6 @@
// - invoke-special desugaring.
assert options.desugarState.isOn();
this.instructionDesugaring = CfInstructionDesugaringCollection.create(appView);
- this.classDesugaring = CfClassDesugaringCollection.create(appView);
this.interfaceMethodRewriter = null;
this.covariantReturnTypeAnnotationTransformer = null;
this.dynamicTypeOptimization = null;
@@ -252,10 +248,6 @@
appView.enableWholeProgramOptimizations()
? CfInstructionDesugaringCollection.empty()
: CfInstructionDesugaringCollection.create(appView);
- this.classDesugaring =
- appView.enableWholeProgramOptimizations()
- ? CfClassDesugaringCollection.empty()
- : CfClassDesugaringCollection.create(appView);
this.interfaceMethodRewriter =
options.isInterfaceMethodDesugaringEnabled() && appView.enableWholeProgramOptimizations()
? new InterfaceMethodRewriter(appView, this)
@@ -456,7 +448,8 @@
ExecutorService executorService,
CfClassSynthesizerDesugaringEventConsumer classSynthesizerEventConsumer)
throws ExecutionException {
- new CfClassSynthesizerDesugaringCollection(appView, instructionDesugaring.getRetargetingInfo())
+ CfClassSynthesizerDesugaringCollection.create(
+ appView, instructionDesugaring.getRetargetingInfo())
.synthesizeClasses(executorService, classSynthesizerEventConsumer);
}
@@ -494,26 +487,6 @@
DesugaredLibraryAPIConverter::generateTrackingWarnings);
}
- public void desugarClassesForD8(
- List<DexProgramClass> classes,
- D8CfClassDesugaringEventConsumer desugaringEventConsumer,
- ExecutorService executorService)
- throws ExecutionException {
- if (classDesugaring.isEmpty()) {
- return;
- }
- // Currently the classes can be processed in any order and do not require to be sorted.
- ThreadUtils.processItems(
- classes, clazz -> desugarClassForD8(clazz, desugaringEventConsumer), executorService);
- }
-
- private void desugarClassForD8(
- DexProgramClass clazz, D8CfClassDesugaringEventConsumer desugaringEventConsumer) {
- if (classDesugaring.needsDesugaring(clazz)) {
- classDesugaring.desugar(clazz, desugaringEventConsumer);
- }
- }
-
public void prepareDesugaringForD8(ExecutorService executorService) throws ExecutionException {
// Prepare desugaring by collecting all the synthetic methods required on program classes.
ProgramAdditions programAdditions = new ProgramAdditions();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaring.java
deleted file mode 100644
index a885344..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaring.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.ir.desugar;
-
-import com.android.tools.r8.graph.DexProgramClass;
-
-/** Interface for desugaring a class. */
-public interface CfClassDesugaring {
-
- void desugar(DexProgramClass clazz, CfClassDesugaringEventConsumer eventConsumer);
-
- /** Returns true if the given class needs desugaring. */
- boolean needsDesugaring(DexProgramClass clazz);
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaringCollection.java
deleted file mode 100644
index 1ddeb09..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaringCollection.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.ir.desugar;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.ir.desugar.records.RecordRewriter;
-import com.google.common.collect.Iterables;
-import java.util.ArrayList;
-import java.util.List;
-
-/** Interface for desugaring a class. */
-public abstract class CfClassDesugaringCollection {
-
- public abstract void desugar(DexProgramClass clazz, CfClassDesugaringEventConsumer eventConsumer);
-
- /** Returns true if the given class needs desugaring. */
- public abstract boolean needsDesugaring(DexProgramClass clazz);
-
- public abstract boolean isEmpty();
-
- public static CfClassDesugaringCollection empty() {
- return EmptyCfClassDesugaringCollection.getInstance();
- }
-
- public static CfClassDesugaringCollection create(AppView<?> appView) {
- List<CfClassDesugaring> desugarings = new ArrayList<>();
- RecordRewriter recordRewriter = RecordRewriter.create(appView);
- if (recordRewriter != null) {
- desugarings.add(recordRewriter);
- }
- if (desugarings.isEmpty()) {
- return empty();
- }
- return new NonEmptyCfClassDesugaringCollection(desugarings);
- }
-
- public static class NonEmptyCfClassDesugaringCollection extends CfClassDesugaringCollection {
- private final List<CfClassDesugaring> desugarings;
-
- NonEmptyCfClassDesugaringCollection(List<CfClassDesugaring> desugarings) {
- this.desugarings = desugarings;
- }
-
- @Override
- public void desugar(DexProgramClass clazz, CfClassDesugaringEventConsumer eventConsumer) {
- for (CfClassDesugaring desugaring : desugarings) {
- desugaring.desugar(clazz, eventConsumer);
- }
- }
-
- @Override
- public boolean needsDesugaring(DexProgramClass clazz) {
- return Iterables.any(desugarings, desugaring -> desugaring.needsDesugaring(clazz));
- }
-
- @Override
- public boolean isEmpty() {
- return false;
- }
- }
-
- public static class EmptyCfClassDesugaringCollection extends CfClassDesugaringCollection {
-
- private static final EmptyCfClassDesugaringCollection INSTANCE =
- new EmptyCfClassDesugaringCollection();
-
- public static EmptyCfClassDesugaringCollection getInstance() {
- return INSTANCE;
- }
-
- @Override
- public void desugar(DexProgramClass clazz, CfClassDesugaringEventConsumer eventConsumer) {
- // Intentionally empty.
- }
-
- @Override
- public boolean needsDesugaring(DexProgramClass clazz) {
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return true;
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaringEventConsumer.java
deleted file mode 100644
index ef09aba..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfClassDesugaringEventConsumer.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.ir.desugar;
-
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.conversion.D8MethodProcessor;
-import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer;
-
-public abstract class CfClassDesugaringEventConsumer implements RecordDesugaringEventConsumer {
-
- public static D8CfClassDesugaringEventConsumer createForD8(D8MethodProcessor methodProcessor) {
- return new D8CfClassDesugaringEventConsumer(methodProcessor);
- }
-
- public static class D8CfClassDesugaringEventConsumer extends CfClassDesugaringEventConsumer {
-
- private final D8MethodProcessor methodProcessor;
-
- public D8CfClassDesugaringEventConsumer(D8MethodProcessor methodProcessor) {
- this.methodProcessor = methodProcessor;
- }
-
- @Override
- public void acceptRecordClass(DexProgramClass recordClass) {
- methodProcessor.scheduleDesugaredMethodsForProcessing(recordClass.programMethods());
- }
-
- @Override
- public void acceptRecordMethod(ProgramMethod method) {
- assert false;
- }
- }
-
- // TODO(b/): Implement R8CfClassDesugaringEventConsumer
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringCollection.java
index 4bca24a..b0ea9ef 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringCollection.java
@@ -1,7 +1,6 @@
// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-
package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.graph.AppView;
@@ -9,36 +8,73 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.RetargetingInfo;
import com.android.tools.r8.ir.desugar.itf.ProgramEmulatedInterfaceSynthesizer;
+import com.android.tools.r8.ir.desugar.records.RecordRewriter;
import com.android.tools.r8.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-public class CfClassSynthesizerDesugaringCollection {
+public abstract class CfClassSynthesizerDesugaringCollection {
- private Collection<CfClassSynthesizerDesugaring> synthesizers = new ArrayList<>();
-
- public CfClassSynthesizerDesugaringCollection(
+ public static CfClassSynthesizerDesugaringCollection create(
AppView<?> appView, RetargetingInfo retargetingInfo) {
- assert appView.options().isDesugaredLibraryCompilation();
- ProgramEmulatedInterfaceSynthesizer emulatedInterfaceSynthesizer =
- ProgramEmulatedInterfaceSynthesizer.create(appView);
- if (emulatedInterfaceSynthesizer != null) {
- synthesizers.add(emulatedInterfaceSynthesizer);
+ Collection<CfClassSynthesizerDesugaring> synthesizers = new ArrayList<>();
+ if (appView.options().isDesugaredLibraryCompilation()) {
+ ProgramEmulatedInterfaceSynthesizer emulatedInterfaceSynthesizer =
+ ProgramEmulatedInterfaceSynthesizer.create(appView);
+ if (emulatedInterfaceSynthesizer != null) {
+ synthesizers.add(emulatedInterfaceSynthesizer);
+ }
+ DesugaredLibraryRetargeterL8Synthesizer retargeterL8Synthesizer =
+ DesugaredLibraryRetargeterL8Synthesizer.create(appView, retargetingInfo);
+ if (retargeterL8Synthesizer != null) {
+ synthesizers.add(retargeterL8Synthesizer);
+ }
+ synthesizers.add(new DesugaredLibraryWrapperSynthesizer(appView));
}
- DesugaredLibraryRetargeterL8Synthesizer retargeterL8Synthesizer =
- DesugaredLibraryRetargeterL8Synthesizer.create(appView, retargetingInfo);
- if (retargeterL8Synthesizer != null) {
- synthesizers.add(retargeterL8Synthesizer);
+ RecordRewriter recordRewriter = RecordRewriter.create(appView);
+ if (recordRewriter != null) {
+ synthesizers.add(recordRewriter);
}
- synthesizers.add(new DesugaredLibraryWrapperSynthesizer(appView));
+ if (synthesizers.isEmpty()) {
+ return new EmptyCfClassSynthesizerCollection();
+ }
+ return new NonEmptyCfClassSynthesizerCollection(synthesizers);
}
- public void synthesizeClasses(
+ public abstract void synthesizeClasses(
ExecutorService executorService, CfClassSynthesizerDesugaringEventConsumer eventConsumer)
- throws ExecutionException {
- ThreadUtils.processItems(
- synthesizers, synthesizer -> synthesizer.synthesizeClasses(eventConsumer), executorService);
+ throws ExecutionException;
+
+ static class NonEmptyCfClassSynthesizerCollection extends CfClassSynthesizerDesugaringCollection {
+
+ private final Collection<CfClassSynthesizerDesugaring> synthesizers;
+
+ public NonEmptyCfClassSynthesizerCollection(
+ Collection<CfClassSynthesizerDesugaring> synthesizers) {
+ assert !synthesizers.isEmpty();
+ this.synthesizers = synthesizers;
+ }
+
+ @Override
+ public void synthesizeClasses(
+ ExecutorService executorService, CfClassSynthesizerDesugaringEventConsumer eventConsumer)
+ throws ExecutionException {
+ ThreadUtils.processItems(
+ synthesizers,
+ synthesizer -> synthesizer.synthesizeClasses(eventConsumer),
+ executorService);
+ }
+ }
+
+ static class EmptyCfClassSynthesizerCollection extends CfClassSynthesizerDesugaringCollection {
+
+ @Override
+ public void synthesizeClasses(
+ ExecutorService executorService, CfClassSynthesizerDesugaringEventConsumer eventConsumer)
+ throws ExecutionException {
+ // Intentionally empty.
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
index 6ff6ec9..3f60ffe 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
@@ -8,13 +8,15 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterL8SynthesizerEventConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer;
import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceSynthesizerEventConsumer.L8ProgramEmulatedInterfaceSynthesizerEventConsumer;
+import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer;
import com.google.common.collect.Sets;
import java.util.Set;
public class CfClassSynthesizerDesugaringEventConsumer
implements L8ProgramEmulatedInterfaceSynthesizerEventConsumer,
DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer,
- DesugaredLibraryRetargeterL8SynthesizerEventConsumer {
+ DesugaredLibraryRetargeterL8SynthesizerEventConsumer,
+ RecordDesugaringEventConsumer {
private Set<DexProgramClass> synthesizedClasses = Sets.newConcurrentHashSet();
@@ -33,6 +35,11 @@
synthesizedClasses.add(clazz);
}
+ @Override
+ public void acceptRecordClass(DexProgramClass clazz) {
+ synthesizedClasses.add(clazz);
+ }
+
public Set<DexProgramClass> getSynthesizedClasses() {
return synthesizedClasses;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
index 9c90fd7..afd0856 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
@@ -23,7 +23,7 @@
import com.android.tools.r8.ir.desugar.lambda.LambdaDeserializationMethodRemover;
import com.android.tools.r8.ir.desugar.lambda.LambdaDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer.RecordInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.twr.TwrCloseResourceDesugaringEventConsumer;
import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
import com.google.common.collect.Sets;
@@ -46,7 +46,7 @@
InvokeSpecialToSelfDesugaringEventConsumer,
LambdaDesugaringEventConsumer,
NestBasedAccessDesugaringEventConsumer,
- RecordDesugaringEventConsumer,
+ RecordInstructionDesugaringEventConsumer,
TwrCloseResourceDesugaringEventConsumer,
InterfaceMethodDesugaringEventConsumer,
DesugaredLibraryRetargeterInstructionEventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
index 2d99720..dbba296 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterPostProcessor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.RetargetingInfo;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
+import com.android.tools.r8.ir.desugar.records.RecordRewriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -69,6 +70,10 @@
if (apiCallbackSynthesizor != null) {
desugarings.add(apiCallbackSynthesizor);
}
+ RecordRewriter recordRewriter = RecordRewriter.create(appView);
+ if (recordRewriter != null) {
+ desugarings.add(recordRewriter);
+ }
if (desugarings.isEmpty()) {
return empty();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaringEventConsumer.java
index 5affc2b..f81b5d6 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaringEventConsumer.java
@@ -1,7 +1,6 @@
// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-
package com.android.tools.r8.ir.desugar.records;
import com.android.tools.r8.graph.DexProgramClass;
@@ -11,5 +10,8 @@
void acceptRecordClass(DexProgramClass recordClass);
- void acceptRecordMethod(ProgramMethod method);
+ interface RecordInstructionDesugaringEventConsumer extends RecordDesugaringEventConsumer {
+
+ void acceptRecordMethod(ProgramMethod method);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java
index 3f5eccc..3bce77c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordRewriter.java
@@ -35,12 +35,15 @@
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.desugar.CfClassDesugaring;
-import com.android.tools.r8.ir.desugar.CfClassDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaring;
+import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaring;
+import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.FreshLocalProvider;
import com.android.tools.r8.ir.desugar.LocalStackAllocator;
+import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer.RecordInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.synthetic.CallObjectInitCfCodeProvider;
import com.android.tools.r8.ir.synthetic.RecordGetFieldsAsObjectsCfCodeProvider;
import com.android.tools.r8.naming.dexitembasedstring.ClassNameComputationInfo;
@@ -51,10 +54,13 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
import java.util.function.BiFunction;
import org.objectweb.asm.Opcodes;
-public class RecordRewriter implements CfInstructionDesugaring, CfClassDesugaring {
+public class RecordRewriter
+ implements CfInstructionDesugaring, CfClassSynthesizerDesugaring, CfPostProcessingDesugaring {
private final AppView<?> appView;
private final DexItemFactory factory;
@@ -134,7 +140,10 @@
MethodProcessingContext methodProcessingContext,
DexItemFactory dexItemFactory) {
assert !instruction.isInitClass();
- if (instruction.isInvokeDynamic() && needsDesugaring(instruction.asInvokeDynamic(), context)) {
+ if (!needsDesugaring(instruction, context)) {
+ return null;
+ }
+ if (instruction.isInvokeDynamic()) {
return desugarInvokeDynamicOnRecord(
instruction.asInvokeDynamic(),
localStackAllocator,
@@ -142,16 +151,13 @@
eventConsumer,
methodProcessingContext);
}
- if (instruction.isInvoke()) {
- CfInvoke cfInvoke = instruction.asInvoke();
- DexMethod newMethod =
- rewriteMethod(cfInvoke.getMethod(), cfInvoke.isInvokeSuper(context.getHolderType()));
- if (newMethod != cfInvoke.getMethod()) {
- return Collections.singletonList(
- new CfInvoke(cfInvoke.getOpcode(), newMethod, cfInvoke.isInterface()));
- }
- }
- return null;
+ assert instruction.isInvoke();
+ CfInvoke cfInvoke = instruction.asInvoke();
+ DexMethod newMethod =
+ rewriteMethod(cfInvoke.getMethod(), cfInvoke.isInvokeSuper(context.getHolderType()));
+ assert newMethod != cfInvoke.getMethod();
+ return Collections.singletonList(
+ new CfInvoke(cfInvoke.getOpcode(), newMethod, cfInvoke.isInterface()));
}
public List<CfInstruction> desugarInvokeDynamicOnRecord(
@@ -217,7 +223,9 @@
}
private void ensureGetFieldsAsObjects(
- DexProgramClass clazz, DexField[] fields, RecordDesugaringEventConsumer eventConsumer) {
+ DexProgramClass clazz,
+ DexField[] fields,
+ RecordInstructionDesugaringEventConsumer eventConsumer) {
DexMethod method = getFieldsAsObjectsMethod(clazz.type);
synchronized (clazz.getMethodCollection()) {
ProgramMethod getFieldsAsObjects = clazz.lookupProgramMethod(method);
@@ -256,7 +264,7 @@
private List<CfInstruction> desugarInvokeRecordHashCode(
DexProgramClass recordClass,
DexField[] fields,
- CfInstructionDesugaringEventConsumer eventConsumer,
+ RecordInstructionDesugaringEventConsumer eventConsumer,
MethodProcessingContext methodProcessingContext) {
ensureGetFieldsAsObjects(recordClass, fields, eventConsumer);
ProgramMethod programMethod =
@@ -272,7 +280,7 @@
private List<CfInstruction> desugarInvokeRecordEquals(
DexProgramClass recordClass,
DexField[] fields,
- CfInstructionDesugaringEventConsumer eventConsumer,
+ RecordInstructionDesugaringEventConsumer eventConsumer,
MethodProcessingContext methodProcessingContext) {
ensureGetFieldsAsObjects(recordClass, fields, eventConsumer);
ProgramMethod programMethod =
@@ -291,7 +299,7 @@
DexField[] fields,
DexString simpleName,
LocalStackAllocator localStackAllocator,
- CfInstructionDesugaringEventConsumer eventConsumer,
+ RecordInstructionDesugaringEventConsumer eventConsumer,
MethodProcessingContext methodProcessingContext) {
ensureGetFieldsAsObjects(recordClass, fields, eventConsumer);
ArrayList<CfInstruction> instructions = new ArrayList<>();
@@ -356,20 +364,6 @@
}
}
- @Override
- public boolean needsDesugaring(DexProgramClass clazz) {
- return clazz.isRecord();
- }
-
- @Override
- public void desugar(DexProgramClass clazz, CfClassDesugaringEventConsumer eventConsumer) {
- if (clazz.isRecord()) {
- assert clazz.superType == factory.recordType;
- ensureRecordClass(eventConsumer);
- clazz.accessFlags.unsetRecord();
- }
- }
-
private boolean refersToRecord(DexField field) {
assert !refersToRecord(field.holder) : "The java.lang.Record class has no fields.";
return refersToRecord(field.type);
@@ -531,4 +525,25 @@
new CallObjectInitCfCodeProvider(appView, factory.recordTagType).generateCfCode(), appView);
return init;
}
+
+ @Override
+ public void synthesizeClasses(CfClassSynthesizerDesugaringEventConsumer eventConsumer) {
+ if (appView.appInfo().app().getFlags().hasReadProgramRecord()) {
+ ensureRecordClass(eventConsumer);
+ }
+ }
+
+ @Override
+ public void postProcessingDesugaring(
+ Collection<DexProgramClass> programClasses,
+ CfPostProcessingDesugaringEventConsumer eventConsumer,
+ ExecutorService executorService)
+ throws ExecutionException {
+ for (DexProgramClass clazz : programClasses) {
+ if (clazz.isRecord()) {
+ assert clazz.superType == factory.recordType;
+ clazz.accessFlags.unsetRecord();
+ }
+ }
+ }
}