blob: 2e9591789775307f70e58bcd3fe87f501984c924 [file] [log] [blame]
// 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.contexts.CompilationContext.ClassSynthesisDesugaringContext;
import com.android.tools.r8.contexts.CompilationContext.ProcessorContext;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryWrapperSynthesizer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterL8Synthesizer;
import com.android.tools.r8.ir.desugar.itf.ProgramEmulatedInterfaceSynthesizer;
import com.android.tools.r8.ir.desugar.records.RecordDesugaring;
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;
import java.util.stream.Collectors;
public abstract class CfClassSynthesizerDesugaringCollection {
public static CfClassSynthesizerDesugaringCollection create(AppView<?> appView) {
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);
if (retargeterL8Synthesizer != null) {
synthesizers.add(retargeterL8Synthesizer);
}
synthesizers.add(new DesugaredLibraryWrapperSynthesizer(appView));
}
RecordDesugaring recordRewriter = RecordDesugaring.create(appView);
if (recordRewriter != null) {
synthesizers.add(recordRewriter);
}
if (synthesizers.isEmpty()) {
return new EmptyCfClassSynthesizerCollection();
}
return new NonEmptyCfClassSynthesizerCollection(appView, synthesizers);
}
public abstract void synthesizeClasses(
ExecutorService executorService, CfClassSynthesizerDesugaringEventConsumer eventConsumer)
throws ExecutionException;
static class NonEmptyCfClassSynthesizerCollection extends CfClassSynthesizerDesugaringCollection {
private final AppView<?> appView;
private final Collection<CfClassSynthesizerDesugaring> synthesizers;
public NonEmptyCfClassSynthesizerCollection(
AppView<?> appView, Collection<CfClassSynthesizerDesugaring> synthesizers) {
assert !synthesizers.isEmpty();
this.appView = appView;
this.synthesizers = synthesizers;
}
@Override
public void synthesizeClasses(
ExecutorService executorService, CfClassSynthesizerDesugaringEventConsumer eventConsumer)
throws ExecutionException {
assert synthesizers.stream()
.map(CfClassSynthesizerDesugaring::uniqueIdentifier)
.collect(Collectors.toSet())
.size()
== synthesizers.size();
ProcessorContext processorContext = appView.createProcessorContext();
ThreadUtils.processItems(
synthesizers,
synthesizer -> {
ClassSynthesisDesugaringContext classSynthesisDesugaringContext =
processorContext.createClassSynthesisDesugaringContext(synthesizer);
synthesizer.synthesizeClasses(classSynthesisDesugaringContext, eventConsumer);
},
executorService);
}
}
static class EmptyCfClassSynthesizerCollection extends CfClassSynthesizerDesugaringCollection {
@Override
public void synthesizeClasses(
ExecutorService executorService, CfClassSynthesizerDesugaringEventConsumer eventConsumer)
throws ExecutionException {
// Intentionally empty.
}
}
}