[klib] Don't pass around metadata serialization closure

Pass the metadata serializer instance instead. This allows to further
reduce code duplication by introducing the common interface
`KlibSingleFileMetadataSerializer` for abstracting away K1 and K2
representation of a source file, as well as reusing
`Fir2KlibMetadataSerializer` across different backends.

KT-64392
This commit is contained in:
Sergej Jaskiewicz
2024-01-22 14:21:20 +01:00
committed by Space Team
parent 5a6f51e474
commit f39335b3f7
23 changed files with 388 additions and 406 deletions
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.test.backend.ir
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.serialization.KotlinFileSerializedData
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.backend.FirMangler
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.test.model.BackendKind
import org.jetbrains.kotlin.test.model.BackendKinds
import org.jetbrains.kotlin.test.model.ResultingArtifact
@@ -66,14 +66,13 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
class JsIrBackendInput(
override val irModuleFragment: IrModuleFragment,
override val irPluginContext: IrPluginContext,
val sourceFiles: List<KtSourceFile>,
val icData: List<KotlinFileSerializedData>,
override val diagnosticReporter: BaseDiagnosticsCollector,
val hasErrors: Boolean,
override val descriptorMangler: KotlinMangler.DescriptorMangler?,
override val irMangler: KotlinMangler.IrMangler,
override val firMangler: FirMangler?,
val serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment,
val metadataSerializer: KlibSingleFileMetadataSerializer<*>,
) : IrBackendInput()
data class JsIrDeserializedFromKlibBackendInput(
@@ -92,14 +91,13 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
class WasmBackendInput(
override val irModuleFragment: IrModuleFragment,
override val irPluginContext: IrPluginContext,
val sourceFiles: List<KtSourceFile>,
val icData: List<KotlinFileSerializedData>,
override val diagnosticReporter: BaseDiagnosticsCollector,
val hasErrors: Boolean,
override val descriptorMangler: KotlinMangler.DescriptorMangler?,
override val irMangler: KotlinMangler.IrMangler,
override val firMangler: FirMangler?,
val serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment,
val metadataSerializer: KlibSingleFileMetadataSerializer<*>,
) : IrBackendInput()
class JvmIrBackendInput(
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.test.frontend.classic
import org.jetbrains.kotlin.KtPsiSourceFile
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForJSIR
@@ -105,21 +104,26 @@ class ClassicFrontend2IrConverter(
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val hasErrors = TopDownAnalyzerFacadeForJSIR.checkForErrors(sourceFiles, analysisResult.bindingContext, errorPolicy)
val metadataSerializer = KlibMetadataIncrementalSerializer(configuration, project, hasErrors)
val metadataSerializer = KlibMetadataIncrementalSerializer(
sourceFiles,
configuration,
project,
analysisResult.bindingContext,
moduleFragment.descriptor,
hasErrors,
)
return IrBackendInput.JsIrBackendInput(
moduleFragment,
pluginContext,
sourceFiles.map(::KtPsiSourceFile),
icData,
diagnosticReporter = DiagnosticReporterFactory.createReporter(),
hasErrors,
descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer!!.mangler,
irMangler = JsManglerIr,
firMangler = null,
) { file ->
metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor)
}
metadataSerializer = metadataSerializer,
)
}
private fun transformToWasmIr(module: TestModule, inputArtifact: ClassicFrontendOutputArtifact): IrBackendInput {
@@ -147,20 +151,25 @@ class ClassicFrontend2IrConverter(
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val analyzerFacade = TopDownAnalyzerFacadeForWasm.facadeFor(configuration.get(JSConfigurationKeys.WASM_TARGET))
val hasErrors = analyzerFacade.checkForErrors(sourceFiles, analysisResult.bindingContext, errorPolicy)
val metadataSerializer = KlibMetadataIncrementalSerializer(configuration, project, hasErrors)
val metadataSerializer = KlibMetadataIncrementalSerializer(
sourceFiles,
configuration,
project,
analysisResult.bindingContext,
moduleFragment.descriptor,
hasErrors,
)
return IrBackendInput.WasmBackendInput(
moduleFragment,
pluginContext,
sourceFiles.map(::KtPsiSourceFile),
icData,
diagnosticReporter = DiagnosticReporterFactory.createReporter(),
hasErrors,
descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer!!.mangler,
irMangler = JsManglerIr,
firMangler = null,
) { file ->
metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor)
}
metadataSerializer = metadataSerializer,
)
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -17,12 +16,8 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult
import org.jetbrains.kotlin.fir.pipeline.FirResult
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
import org.jetbrains.kotlin.fir.pipeline.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.KotlinMangler
@@ -74,8 +69,6 @@ abstract class AbstractFir2IrNonJvmResultsConverter(
inputArtifact: FirOutputArtifact
): IrBackendInput {
val compilerConfiguration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
val sourceFiles = mutableListOf<KtSourceFile>()
val firFilesAndComponentsBySourceFile = mutableMapOf<KtSourceFile, Pair<FirFile, Fir2IrComponents>>()
val irMangler = createIrMangler()
val diagnosticReporter = DiagnosticReporterFactory.createReporter()
@@ -87,7 +80,8 @@ abstract class AbstractFir2IrNonJvmResultsConverter(
compilerConfiguration,
diagnosticReporter,
)
val fir2irResult = inputArtifact.toFirResult().convertToIrAndActualize(
val firResult = inputArtifact.toFirResult()
val fir2irResult = firResult.convertToIrAndActualize(
Fir2IrExtensions.Default,
fir2IrConfiguration,
module.irGenerationExtensions(testServices),
@@ -96,16 +90,23 @@ abstract class AbstractFir2IrNonJvmResultsConverter(
Fir2IrVisibilityConverter.Default,
builtIns ?: DefaultBuiltIns.Instance, // TODO: consider passing externally,
::IrTypeSystemContextImpl
) { firPart, irPart ->
sourceFiles.addAll(firPart.fir.mapNotNull { it.sourceFile })
for (firFile in firPart.fir) {
firFilesAndComponentsBySourceFile[firFile.sourceFile!!] = firFile to irPart.components
}
}.also {
).also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
}
return createBackendInput(compilerConfiguration, diagnosticReporter, inputArtifact, fir2irResult, firFilesAndComponentsBySourceFile, sourceFiles)
return createBackendInput(
compilerConfiguration,
diagnosticReporter,
inputArtifact,
fir2irResult,
Fir2KlibMetadataSerializer(
compilerConfiguration,
firResult.outputs,
fir2irResult,
exportKDoc = false,
produceHeaderKlib = false,
),
)
}
protected abstract fun createBackendInput(
@@ -113,8 +114,7 @@ abstract class AbstractFir2IrNonJvmResultsConverter(
diagnosticReporter: BaseDiagnosticsCollector,
inputArtifact: FirOutputArtifact,
fir2IrResult: Fir2IrActualizedResult,
firFilesAndComponentsBySourceFile: Map<KtSourceFile, Pair<FirFile, Fir2IrComponents>>,
sourceFiles: List<KtSourceFile>
fir2KlibMetadataSerializer: Fir2KlibMetadataSerializer,
): IrBackendInput
private fun loadResolvedLibraries(
@@ -5,21 +5,15 @@
package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.serialization.KotlinFileSerializedData
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.backend.ConstValueProviderImpl
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.FirMangler
import org.jetbrains.kotlin.fir.backend.extractFirDeclarations
import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult
import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
import org.jetbrains.kotlin.fir.pipeline.Fir2KlibMetadataSerializer
import org.jetbrains.kotlin.ir.backend.js.JsFactories
import org.jetbrains.kotlin.ir.backend.js.getSerializedData
import org.jetbrains.kotlin.ir.backend.js.incrementalDataProvider
@@ -28,25 +22,22 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.frontend.fir.handlers.firDiagnosticCollectorService
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.utils.metadataVersion
abstract class Fir2IrJsWasmResultsConverter(testServices: TestServices) : AbstractFir2IrNonJvmResultsConverter(testServices) {
protected abstract val artifactFactory: (
IrModuleFragment,
IrPluginContext,
List<KtSourceFile>,
List<KotlinFileSerializedData>,
BaseDiagnosticsCollector,
Boolean,
KotlinMangler.DescriptorMangler?,
KotlinMangler.IrMangler,
FirMangler?,
(KtSourceFile) -> ProtoBuf.PackageFragment
KlibSingleFileMetadataSerializer<*>,
) -> IrBackendInput
override fun createIrMangler(): KotlinMangler.IrMangler {
@@ -65,46 +56,25 @@ abstract class Fir2IrJsWasmResultsConverter(testServices: TestServices) : Abstra
diagnosticReporter: BaseDiagnosticsCollector,
inputArtifact: FirOutputArtifact,
fir2IrResult: Fir2IrActualizedResult,
firFilesAndComponentsBySourceFile: Map<KtSourceFile, Pair<FirFile, Fir2IrComponents>>,
sourceFiles: List<KtSourceFile>,
fir2KlibMetadataSerializer: Fir2KlibMetadataSerializer,
): IrBackendInput {
val languageVersionSettings = compilerConfiguration.languageVersionSettings
val metadataVersion = compilerConfiguration.metadataVersion(languageVersionSettings.languageVersion)
val fir2IrComponents = fir2IrResult.components
val manglers = fir2IrComponents.manglers
val manglers = fir2IrResult.components.manglers
return artifactFactory(
fir2IrResult.irModuleFragment,
fir2IrResult.pluginContext,
sourceFiles,
compilerConfiguration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList(),
compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibMetadataSerializer.sourceFiles) ?: emptyList(),
diagnosticReporter,
testServices.firDiagnosticCollectorService.containsErrors(inputArtifact),
/*descriptorMangler = */null,
manglers.irMangler,
manglers.firMangler,
) { file ->
val (firFile, components) = firFilesAndComponentsBySourceFile[file]
?: error("cannot find FIR file by source file ${file.name} (${file.path})")
val actualizedExpectDeclarations = fir2IrResult.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations()
serializeSingleFirFile(
firFile,
components.session,
components.scopeSession,
actualizedExpectDeclarations,
FirKLibSerializerExtension(
components.session, components.firProvider, metadataVersion,
ConstValueProviderImpl(components),
allowErrorTypes = false, exportKDoc = false,
components.annotationsFromPluginRegistrar.createAdditionalMetadataProvider()
),
languageVersionSettings,
)
}
fir2KlibMetadataSerializer,
)
}
}
class Fir2IrJsResultsConverter(testServices: TestServices) : Fir2IrJsWasmResultsConverter(testServices) {
override val artifactFactory: (IrModuleFragment, IrPluginContext, List<KtSourceFile>, List<KotlinFileSerializedData>, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, (KtSourceFile) -> ProtoBuf.PackageFragment) -> IrBackendInput
override val artifactFactory: (IrModuleFragment, IrPluginContext, List<KotlinFileSerializedData>, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, KlibSingleFileMetadataSerializer<*>) -> IrBackendInput
get() = IrBackendInput::JsIrBackendInput
override fun resolveLibraries(module: TestModule, compilerConfiguration: CompilerConfiguration): List<KotlinResolvedLibrary> {
@@ -114,7 +84,7 @@ class Fir2IrJsResultsConverter(testServices: TestServices) : Fir2IrJsWasmResults
class Fir2IrWasmResultsConverter(testServices: TestServices) : Fir2IrJsWasmResultsConverter(testServices) {
override val artifactFactory: (IrModuleFragment, IrPluginContext, List<KtSourceFile>, List<KotlinFileSerializedData>, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, (KtSourceFile) -> ProtoBuf.PackageFragment) -> IrBackendInput
override val artifactFactory: (IrModuleFragment, IrPluginContext, List<KotlinFileSerializedData>, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, KlibSingleFileMetadataSerializer<*>) -> IrBackendInput
get() = IrBackendInput::WasmBackendInput
override fun resolveLibraries(module: TestModule, compilerConfiguration: CompilerConfiguration): List<KotlinResolvedLibrary> {