diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 313f9a570cd..7cceda92faf 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory +import org.jetbrains.kotlin.fir.pipeline.Fir2KlibMetadataSerializer import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider @@ -470,13 +471,6 @@ class K2JsIrCompiler : CLICompiler() { sourceModule.getModuleDescriptor(it) } - val metadataSerializer = - KlibMetadataIncrementalSerializer( - environmentForJS.configuration, - sourceModule.project, - sourceModule.jsFrontEndResult.hasErrors - ) - val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter() generateKLib( sourceModule, @@ -486,10 +480,8 @@ class K2JsIrCompiler : CLICompiler() { icData = icData, moduleFragment = moduleFragment, diagnosticReporter = diagnosticsReporter, - builtInsPlatform = if (arguments.wasm) BuiltInsPlatform.WASM else BuiltInsPlatform.JS - ) { file -> - metadataSerializer.serializeScope(file, sourceModule.jsFrontEndResult.bindingContext, moduleFragment.descriptor) - } + builtInsPlatform = if (arguments.wasm) BuiltInsPlatform.WASM else BuiltInsPlatform.JS, + ) val messageCollector = environmentForJS.configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) reportCollectedDiagnostics(environmentForJS.configuration, diagnosticsReporter, messageCollector) @@ -562,7 +554,16 @@ class K2JsIrCompiler : CLICompiler() { // This happens because we check the next round before compilation errors. // Test reproducer: testFileWithConstantRemoved // Issue: https://youtrack.jetbrains.com/issue/KT-58824/ - if (shouldGoToNextIcRound(moduleStructure, analyzedOutput.output, fir2IrActualizedResult)) { + val shouldGoToNextIcRound = shouldGoToNextIcRound(moduleStructure.compilerConfiguration) { + Fir2KlibMetadataSerializer( + moduleStructure.compilerConfiguration, + analyzedOutput.output, + fir2IrActualizedResult, + exportKDoc = false, + produceHeaderKlib = false, + ) + } + if (shouldGoToNextIcRound) { throw IncrementalNextRoundException() } } diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt index 5ad22e6fcac..1aeebfc356a 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt @@ -22,13 +22,13 @@ import org.jetbrains.kotlin.diagnostics.impl.PendingDiagnosticsCollectorWithSupp import org.jetbrains.kotlin.fir.BinaryModuleData import org.jetbrains.kotlin.fir.DependencyListForCliModule import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.backend.* +import org.jetbrains.kotlin.fir.backend.Fir2IrConfiguration +import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions +import org.jetbrains.kotlin.fir.backend.Fir2IrVisibilityConverter import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar import org.jetbrains.kotlin.fir.pipeline.* -import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension -import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile import org.jetbrains.kotlin.fir.session.KlibIcData import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider @@ -41,16 +41,13 @@ import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.impl.BuiltInsPlatform import org.jetbrains.kotlin.library.unresolvedDependencies -import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.platform.wasm.WasmPlatforms import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.storage.LockBasedStorageManager -import org.jetbrains.kotlin.utils.metadataVersion import org.jetbrains.kotlin.wasm.resolve.WasmJsPlatformAnalyzerServices import org.jetbrains.kotlin.wasm.resolve.WasmWasiPlatformAnalyzerServices -import java.io.File import java.nio.file.Paths inline fun compileModuleToAnalyzedFir( @@ -253,50 +250,6 @@ fun transformFirToIr( } } -private class Fir2KlibSerializer( - moduleStructure: ModulesStructure, - private val firOutputs: List, - private val fir2IrActualizedResult: Fir2IrActualizedResult -) { - private val firFilesAndSessionsBySourceFile = buildMap { - for (output in firOutputs) { - output.fir.forEach { - put(it.sourceFile!!, it) - } - } - } - - private val actualizedExpectDeclarations by lazy { - fir2IrActualizedResult.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations() - } - - private val metadataVersion = moduleStructure.compilerConfiguration.metadataVersion() - - private val languageVersionSettings = moduleStructure.compilerConfiguration.languageVersionSettings - - val sourceFiles: List = firFilesAndSessionsBySourceFile.keys.toList() - - fun serializeSingleFirFile(file: KtSourceFile): ProtoBuf.PackageFragment { - val firFile = firFilesAndSessionsBySourceFile[file] - ?: error("cannot find FIR file by source file ${file.name} (${file.path})") - - val components = fir2IrActualizedResult.components - return serializeSingleFirFile( - firFile, - components.session, - components.scopeSession, - actualizedExpectDeclarations, - FirKLibSerializerExtension( - components.session, components.firProvider, metadataVersion, - ConstValueProviderImpl(components), - allowErrorTypes = false, exportKDoc = false, - components.annotationsFromPluginRegistrar.createAdditionalMetadataProvider() - ), - languageVersionSettings, - ) - } -} - fun serializeFirKlib( moduleStructure: ModulesStructure, firOutputs: List, @@ -308,14 +261,20 @@ fun serializeFirKlib( jsOutputName: String?, useWasmPlatform: Boolean, ) { - val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult) - val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibSerializer.sourceFiles) + val fir2KlibMetadataSerializer = Fir2KlibMetadataSerializer( + moduleStructure.compilerConfiguration, + firOutputs, + fir2IrActualizedResult, + exportKDoc = false, + produceHeaderKlib = false, + ) + val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibMetadataSerializer.sourceFiles) serializeModuleIntoKlib( moduleStructure.compilerConfiguration[CommonConfigurationKeys.MODULE_NAME]!!, moduleStructure.compilerConfiguration, diagnosticsReporter, - fir2KlibSerializer.sourceFiles, + fir2KlibMetadataSerializer, klibPath = outputKlibPath, moduleStructure.allDependencies, fir2IrActualizedResult.irModuleFragment, @@ -325,27 +284,6 @@ fun serializeFirKlib( containsErrorCode = messageCollector.hasErrors() || diagnosticsReporter.hasErrors, abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data jsOutputName = jsOutputName, - serializeSingleFile = fir2KlibSerializer::serializeSingleFirFile, builtInsPlatform = if (useWasmPlatform) BuiltInsPlatform.WASM else BuiltInsPlatform.JS, ) } - -fun shouldGoToNextIcRound( - moduleStructure: ModulesStructure, - firOutputs: List, - fir2IrActualizedResult: Fir2IrActualizedResult -): Boolean { - val nextRoundChecker = moduleStructure.compilerConfiguration.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return false - - val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult) - - for (ktFile in fir2KlibSerializer.sourceFiles) { - val packageFragment = fir2KlibSerializer.serializeSingleFirFile(ktFile) - - // to minimize a number of IC rounds, we should inspect all proto for changes first, - // then go to a next round if needed, with all new dirty files - nextRoundChecker.checkProtoChanges(File(ktFile.path!!), packageFragment.toByteArray()) - } - - return nextRoundChecker.shouldGoToNextRound() -} diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/Fir2KlibMetadataSerializer.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/Fir2KlibMetadataSerializer.kt new file mode 100644 index 00000000000..d167af88fc5 --- /dev/null +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/Fir2KlibMetadataSerializer.kt @@ -0,0 +1,103 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.pipeline + +import org.jetbrains.kotlin.KtSourceFile +import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.languageVersionSettings +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.backend.ConstValueProviderImpl +import org.jetbrains.kotlin.fir.backend.extractFirDeclarations +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.packageFqName +import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.providers.FirProvider +import org.jetbrains.kotlin.fir.resolve.providers.firProvider +import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension +import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile +import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion +import org.jetbrains.kotlin.metadata.ProtoBuf +import org.jetbrains.kotlin.name.FqName + +/** + * Responsible for serializing a FIR file metadata into a protobuf to be later written to a KLIB. + */ +class Fir2KlibMetadataSerializer( + compilerConfiguration: CompilerConfiguration, + private val firOutputs: List, + private val fir2IrActualizedResult: Fir2IrActualizedResult?, + private val exportKDoc: Boolean, + private val produceHeaderKlib: Boolean, +) : KlibSingleFileMetadataSerializer { + + private val firFilesAndSessions: Map> = + buildMap { + for (firOutput in firOutputs) { + for (firFile in firOutput.fir) { + put(firFile, firOutput.session to firOutput.scopeSession) + } + } + } + + private val actualizedExpectDeclarations by lazy { + fir2IrActualizedResult?.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations() + } + + private val languageVersionSettings = compilerConfiguration.languageVersionSettings + + private val metadataVersion = compilerConfiguration.get(CommonConfigurationKeys.METADATA_VERSION) as? KlibMetadataVersion + ?: KlibMetadataVersion.INSTANCE + + /** + * The list of source files whose metadata is to be serialized. + */ + val sourceFiles: List = firFilesAndSessions.keys.map { it.sourceFile!! } + + override val numberOfSourceFiles: Int + get() = firFilesAndSessions.size + + override fun serializeSingleFileMetadata(file: FirFile): ProtoBuf.PackageFragment { + val session: FirSession + val scopeSession: ScopeSession + val firProvider: FirProvider + val components = fir2IrActualizedResult?.components + if (components != null) { + session = components.session + scopeSession = components.scopeSession + firProvider = components.firProvider + } else { + val sessionAndScopeSession = firFilesAndSessions[file] ?: error("Missing FirSession and ScopeSession") + session = sessionAndScopeSession.first + scopeSession = sessionAndScopeSession.second + firProvider = session.firProvider + } + return serializeSingleFirFile( + file, + session, + scopeSession, + actualizedExpectDeclarations, + FirKLibSerializerExtension( + session, + firProvider, + metadataVersion, + components?.let(::ConstValueProviderImpl), + allowErrorTypes = false, + exportKDoc, + components?.annotationsFromPluginRegistrar?.createAdditionalMetadataProvider(), + ), + languageVersionSettings, + produceHeaderKlib, + ) + } + + override fun forEachFile(block: (Int, FirFile, KtSourceFile, FqName) -> Unit) { + firFilesAndSessions.keys.forEachIndexed { i, firFile -> + block(i, firFile, firFile.sourceFile!!, firFile.packageFqName) + } + } +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibSingleFileMetadataSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibSingleFileMetadataSerializer.kt new file mode 100644 index 00000000000..7aa06ff2643 --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibSingleFileMetadataSerializer.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.common.serialization.metadata + +import org.jetbrains.kotlin.KtSourceFile +import org.jetbrains.kotlin.metadata.ProtoBuf +import org.jetbrains.kotlin.name.FqName + +/** + * Something capable of serializing the metadata of a source file to a protobuf message, one file at a time. + */ +interface KlibSingleFileMetadataSerializer { + + /** + * The number of source files whose metadata is to be serialized. + */ + val numberOfSourceFiles: Int + + /** + * Serializes the metadata of a single source file to a protobuf message and returns the message. + */ + fun serializeSingleFileMetadata(file: SourceFile): ProtoBuf.PackageFragment + + /** + * Iterates through each file whose metadata is to be serialized, providing an opportunity to call [serializeSingleFileMetadata] + * and perform additional processing of the serialized data. + * + * @param block A closure that accepts the index of the file in the list of source files, the source file, its corresponding + * [KtSourceFile], and the fully qualified name of the package containing the file. + */ + fun forEachFile(block: (Int, SourceFile, KtSourceFile, FqName) -> Unit) +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/serializeModuleIntoKlib.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/serializeModuleIntoKlib.kt index 09cd253fe3a..2af77b389da 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/serializeModuleIntoKlib.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/serializeModuleIntoKlib.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.KtIoFileSourceFile import org.jetbrains.kotlin.KtPsiSourceFile import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.KtVirtualFileSourceFile +import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer import org.jetbrains.kotlin.backend.common.serialization.metadata.serializeKlibHeader import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration @@ -24,8 +25,6 @@ import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.SerializedIrFile import org.jetbrains.kotlin.library.SerializedIrModule import org.jetbrains.kotlin.library.SerializedMetadata -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.name.FqName import java.io.File /** @@ -86,24 +85,22 @@ fun KtSourceFile.toIoFileOrNull(): File? = when (this) { * @param irModuleFragment The IR to be serialized into the KLIB being produced, or `null` if this is going to be a metadata-only KLIB. * @param configuration Used to determine certain serialization parameters and enable/disable serialization diagnostics. * @param diagnosticReporter Used for reporting serialization-time diagnostics, for example, about clashing IR signatures. - * @param sourceFiles The source files from which the KLIB is being compiled. Used for serializing file metadata. * @param compatibilityMode The information about KLIB ABI. * @param cleanFiles In the case of incremental compilation, the list of files that were not changed and therefore don't need to be * serialized again. * @param dependencies The list of KLIBs that the KLIB being produced depends on. * @param createModuleSerializer Used for creating a backend-specific instance of [IrModuleSerializer]. - * @param serializeFileMetadata The name of this argument kind of speaks for itself. + * @param metadataSerializer Something capable of serializing the metadata of the source files. See the corresponding interface KDoc. * @param runKlibCheckers Additional checks to be run before serializing [irModuleFragment]. Can be used to report serialization-time * diagnostics. * @param processCompiledFileData Called for each newly serialized file. Useful for incremental compilation. * @param processKlibHeader Called after serializing the KLIB header. Useful for incremental compilation. */ -fun serializeModuleIntoKlib( +fun serializeModuleIntoKlib( moduleName: String, irModuleFragment: IrModuleFragment?, configuration: CompilerConfiguration, diagnosticReporter: DiagnosticReporter, - sourceFiles: List, compatibilityMode: CompatibilityMode, cleanFiles: List, dependencies: List, @@ -116,14 +113,14 @@ fun serializeModuleIntoKlib( languageVersionSettings: LanguageVersionSettings, shouldCheckSignaturesOnUniqueness: Boolean, ) -> IrModuleSerializer<*>, - serializeFileMetadata: (KtSourceFile) -> Pair, + metadataSerializer: KlibSingleFileMetadataSerializer, runKlibCheckers: (IrModuleFragment, IrDiagnosticReporter, CompilerConfiguration) -> Unit = { _, _, _ -> }, processCompiledFileData: ((File, KotlinFileSerializedData) -> Unit)? = null, processKlibHeader: (ByteArray) -> Unit = {}, ): SerializerOutput { if (irModuleFragment != null) { - assert(sourceFiles.size == irModuleFragment.files.size) { - "The number of source files (${sourceFiles.size}) does not match the number of IrFiles (${irModuleFragment.files.size})" + assert(metadataSerializer.numberOfSourceFiles == irModuleFragment.files.size) { + "The number of source files (${metadataSerializer.numberOfSourceFiles}) does not match the number of IrFiles (${irModuleFragment.files.size})" } } @@ -147,28 +144,31 @@ fun serializeModuleIntoKlib( val serializedFiles = serializedIr?.files?.toList() - val compiledKotlinFiles = sourceFiles.mapIndexedTo(cleanFiles.toMutableList()) { i, ktSourceFile -> - val binaryFile = serializedFiles?.get(i)?.also { - assert(ktSourceFile.path == it.path) { - """The Kt and Ir files are put in different order - Kt: ${ktSourceFile.path} - Ir: ${it.path} - """.trimMargin() + val compiledKotlinFiles = buildList { + addAll(cleanFiles) + metadataSerializer.forEachFile { i, sourceFile, ktSourceFile, packageFqName -> + val binaryFile = serializedFiles?.get(i)?.also { + assert(ktSourceFile.path == it.path) { + """The Kt and Ir files are put in different order + Kt: ${ktSourceFile.path} + Ir: ${it.path} + """.trimMargin() + } } - } - val (packageFragment, fqName) = serializeFileMetadata(ktSourceFile) - val metadata = packageFragment.toByteArray() - val compiledKotlinFile = if (binaryFile == null) - KotlinFileSerializedData(metadata, ktSourceFile.path, fqName.asString()) - else - KotlinFileSerializedData(metadata, binaryFile) + val protoBuf = metadataSerializer.serializeSingleFileMetadata(sourceFile) + val metadata = protoBuf.toByteArray() + val compiledKotlinFile = if (binaryFile == null) + KotlinFileSerializedData(metadata, ktSourceFile.path, packageFqName.asString()) + else + KotlinFileSerializedData(metadata, binaryFile) - if (processCompiledFileData != null) { - val ioFile = ktSourceFile.toIoFileOrNull() ?: error("No file found for source ${ktSourceFile.path}") - processCompiledFileData(ioFile, compiledKotlinFile) - } + if (processCompiledFileData != null) { + val ioFile = ktSourceFile.toIoFileOrNull() ?: error("No file found for source ${ktSourceFile.path}") + processCompiledFileData(ioFile, compiledKotlinFile) + } - compiledKotlinFile + add(compiledKotlinFile) + } } val header = serializeKlibHeader( diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/KlibMetadataIncrementalSerializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/KlibMetadataIncrementalSerializer.kt index 96e70847ba0..ea2ad074df3 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/KlibMetadataIncrementalSerializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/KlibMetadataIncrementalSerializer.kt @@ -6,21 +6,35 @@ package org.jetbrains.kotlin.ir.backend.js import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.KtPsiSourceFile +import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataSerializer +import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.serialization.DescriptorSerializer // TODO: need a refactoring between IncrementalSerializer and MonolithicSerializer. class KlibMetadataIncrementalSerializer( + private val ktFiles: List, + private val bindingContext: BindingContext, + private val moduleDescriptor: ModuleDescriptor, languageVersionSettings: LanguageVersionSettings, metadataVersion: KlibMetadataVersion, project: Project, @@ -33,9 +47,54 @@ class KlibMetadataIncrementalSerializer( exportKDoc = exportKDoc, skipExpects = true, // Incremental compilation is not supposed to work when producing pure metadata (IR-less) KLIBs. allowErrorTypes = allowErrorTypes -) { +), KlibSingleFileMetadataSerializer { - fun serializePackageFragment( + constructor( + files: List, + configuration: CompilerConfiguration, + project: Project, + bindingContext: BindingContext, + moduleDescriptor: ModuleDescriptor, + allowErrorTypes: Boolean, + ) : this( + ktFiles = files, + bindingContext = bindingContext, + moduleDescriptor = moduleDescriptor, + languageVersionSettings = configuration.languageVersionSettings, + metadataVersion = configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? KlibMetadataVersion + ?: KlibMetadataVersion.INSTANCE, + project = project, + exportKDoc = false, + allowErrorTypes = allowErrorTypes, + ) + + constructor(modulesStructure: ModulesStructure, moduleFragment: IrModuleFragment) : this( + (modulesStructure.mainModule as MainModule.SourceFiles).files, + modulesStructure.compilerConfiguration, + modulesStructure.project, + modulesStructure.jsFrontEndResult.bindingContext, + moduleFragment.descriptor, + modulesStructure.jsFrontEndResult.hasErrors, + ) + + override fun serializeSingleFileMetadata(file: KtFile): ProtoBuf.PackageFragment { + val memberScope = file.declarations.map { getDescriptorForElement(bindingContext, it) } + return serializePackageFragment(moduleDescriptor, memberScope, file.packageFqName) + } + + override val numberOfSourceFiles: Int + get() = ktFiles.size + + override fun forEachFile(block: (Int, KtFile, KtSourceFile, FqName) -> Unit) { + ktFiles.forEachIndexed { i, ktFile -> + block(i, ktFile, KtPsiSourceFile(ktFile), ktFile.packageFqName) + } + } + + private fun getDescriptorForElement(context: BindingContext, element: PsiElement): DeclarationDescriptor = + BindingContextUtils.getNotNull(context, BindingContext.DECLARATION_TO_DESCRIPTOR, element) + + private fun serializePackageFragment( module: ModuleDescriptor, scope: Collection, fqName: FqName diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 65f160d0c95..a42c51cd0e0 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -6,9 +6,8 @@ package org.jetbrains.kotlin.ir.backend.js import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VfsUtilCore -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.* +import org.jetbrains.kotlin.KtPsiSourceFile +import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.analyzer.AbstractAnalyzerWithCompilerReport import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.CompilationErrorException @@ -22,12 +21,12 @@ import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter -import org.jetbrains.kotlin.backend.common.serialization.metadata.* +import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer +import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.common.toLogger import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.diagnostics.DiagnosticReporter @@ -55,8 +54,6 @@ import org.jetbrains.kotlin.library.impl.BuiltInsPlatform import org.jetbrains.kotlin.library.impl.buildKotlinLibrary import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.progress.IncrementalNextRoundException import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.psi.KtFile @@ -66,7 +63,6 @@ import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.utils.DFS @@ -94,9 +90,6 @@ val KotlinLibrary.serializedIrFileFingerprints: List ProtoBuf.PackageFragment ) { - val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files.map(::KtPsiSourceFile) val configuration = depsDescriptors.compilerConfiguration val allDependencies = depsDescriptors.allDependencies @@ -120,7 +111,7 @@ fun generateKLib( configuration[CommonConfigurationKeys.MODULE_NAME]!!, configuration, diagnosticReporter, - files, + KlibMetadataIncrementalSerializer(depsDescriptors, moduleFragment), outputKlibPath, allDependencies, moduleFragment, @@ -131,7 +122,6 @@ fun generateKLib( abiVersion, jsOutputName, builtInsPlatform, - serializeSingleFile ) } @@ -521,8 +511,19 @@ class ModulesStructure( val analysisResult = analyzer.analysisResult if (compilerConfiguration.getBoolean(CommonConfigurationKeys.INCREMENTAL_COMPILATION)) { - /** can throw [IncrementalNextRoundException] */ - compareMetadataAndGoToNextICRoundIfNeeded(analysisResult, compilerConfiguration, project, files, errorPolicy.allowErrors) + val shouldGoToNextIcRound = shouldGoToNextIcRound(compilerConfiguration) { + KlibMetadataIncrementalSerializer( + files, + compilerConfiguration, + project, + analysisResult.bindingContext, + analysisResult.moduleDescriptor, + errorPolicy.allowErrors, + ) + } + if (shouldGoToNextIcRound) { + throw IncrementalNextRoundException() + } } var hasErrors = false @@ -589,12 +590,6 @@ class ModulesStructure( null // null in case compiling builtInModule itself } -private fun getDescriptorForElement( - context: BindingContext, - element: PsiElement -): DeclarationDescriptor = BindingContextUtils.getNotNull(context, BindingContext.DECLARATION_TO_DESCRIPTOR, element) - - private const val FILE_FINGERPRINTS_SEPARATOR = " " private fun List.joinIrFileFingerprints(): String { @@ -609,7 +604,7 @@ fun serializeModuleIntoKlib( moduleName: String, configuration: CompilerConfiguration, diagnosticReporter: DiagnosticReporter, - files: List, + metadataSerializer: KlibSingleFileMetadataSerializer<*>, klibPath: String, dependencies: List, moduleFragment: IrModuleFragment, @@ -620,7 +615,6 @@ fun serializeModuleIntoKlib( abiVersion: KotlinAbiVersion, jsOutputName: String?, builtInsPlatform: BuiltInsPlatform = BuiltInsPlatform.JS, - serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment ) { val moduleExportedNames = moduleFragment.collectExportedNames() val incrementalResultsConsumer = configuration.get(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER) @@ -630,7 +624,6 @@ fun serializeModuleIntoKlib( irModuleFragment = moduleFragment, configuration = configuration, diagnosticReporter = diagnosticReporter, - sourceFiles = files, compatibilityMode = CompatibilityMode(abiVersion), cleanFiles = cleanFiles, dependencies = dependencies, @@ -653,7 +646,7 @@ fun serializeModuleIntoKlib( shouldCheckSignaturesOnUniqueness, ) { JsIrFileMetadata(moduleExportedNames[it]?.values?.toSmartList() ?: emptyList()) } }, - serializeFileMetadata = { serializeSingleFile(it) to FqName.ROOT }, + metadataSerializer = metadataSerializer, runKlibCheckers = { irModuleFragment, irDiagnosticReporter, compilerConfiguration -> if (builtInsPlatform == BuiltInsPlatform.JS) { val cleanFilesIrData = cleanFiles.map { it.irData ?: error("Metadata-only KLIBs are not supported in Kotlin/JS") } @@ -725,54 +718,22 @@ const val KLIB_PROPERTY_JS_OUTPUT_NAME = "jsOutputName" const val KLIB_PROPERTY_SERIALIZED_IR_FILE_FINGERPRINTS = "serializedIrFileFingerprints" const val KLIB_PROPERTY_SERIALIZED_KLIB_FINGERPRINT = "serializedKlibFingerprint" -fun KlibMetadataIncrementalSerializer.serializeScope( - ktFile: KtFile, - bindingContext: BindingContext, - moduleDescriptor: ModuleDescriptor -): ProtoBuf.PackageFragment { - val memberScope = ktFile.declarations.map { getDescriptorForElement(bindingContext, it) } - return serializePackageFragment(moduleDescriptor, memberScope, ktFile.packageFqName) -} - -fun KlibMetadataIncrementalSerializer.serializeScope( - ktSourceFile: KtSourceFile, - bindingContext: BindingContext, - moduleDescriptor: ModuleDescriptor -): ProtoBuf.PackageFragment { - val ktFile = (ktSourceFile as KtPsiSourceFile).psiFile as KtFile - val memberScope = ktFile.declarations.map { getDescriptorForElement(bindingContext, it) } - return serializePackageFragment(moduleDescriptor, memberScope, ktFile.packageFqName) -} - -private fun compareMetadataAndGoToNextICRoundIfNeeded( - analysisResult: AnalysisResult, - config: CompilerConfiguration, - project: Project, - files: List, - allowErrors: Boolean -) { - val nextRoundChecker = config.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return - val bindingContext = analysisResult.bindingContext - val serializer = KlibMetadataIncrementalSerializer(config, project, allowErrors) - for (ktFile in files) { - val packageFragment = serializer.serializeScope(ktFile, bindingContext, analysisResult.moduleDescriptor) - // to minimize a number of IC rounds, we should inspect all proto for changes first, - // then go to a next round if needed, with all new dirty files - nextRoundChecker.checkProtoChanges(VfsUtilCore.virtualToIoFile(ktFile.virtualFile), packageFragment.toByteArray()) +fun shouldGoToNextIcRound( + compilerConfiguration: CompilerConfiguration, + createMetadataSerializer: () -> KlibSingleFileMetadataSerializer, +): Boolean { + val nextRoundChecker = compilerConfiguration.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return false + createMetadataSerializer().run { + forEachFile { _, sourceFile, ktSourceFile, _ -> + val protoBuf = serializeSingleFileMetadata(sourceFile) + // to minimize the number of IC rounds, we should inspect all proto for changes first, + // then go to the next round if needed, with all new dirty files + nextRoundChecker.checkProtoChanges(ktSourceFile.toIoFileOrNull()!!, protoBuf.toByteArray()) + } } - - if (nextRoundChecker.shouldGoToNextRound()) throw IncrementalNextRoundException() + return nextRoundChecker.shouldGoToNextRound() } -fun KlibMetadataIncrementalSerializer(configuration: CompilerConfiguration, project: Project, allowErrors: Boolean) = - KlibMetadataIncrementalSerializer( - languageVersionSettings = configuration.languageVersionSettings, - metadataVersion = configuration.metadataVersion, - project = project, - exportKDoc = false, - allowErrorTypes = allowErrors - ) - private fun Map.getUniqueNameForEachFragment(): Map { return this.entries.mapNotNull { (moduleFragment, klib) -> klib.jsOutputName?.let { moduleFragment to it } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/IrBackendInput.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/IrBackendInput.kt index 7c8cd3e525f..ecd23bd2a3a 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/IrBackendInput.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/ir/IrBackendInput.kt @@ -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() { class JsIrBackendInput( override val irModuleFragment: IrModuleFragment, override val irPluginContext: IrPluginContext, - val sourceFiles: List, val icData: List, 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() { class WasmBackendInput( override val irModuleFragment: IrModuleFragment, override val irPluginContext: IrPluginContext, - val sourceFiles: List, val icData: List, 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( diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontend2IrConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontend2IrConverter.kt index 130aaceb290..2f23f46898f 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontend2IrConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontend2IrConverter.kt @@ -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, + ) } } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/AbstractFir2IrNonJvmResultsConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/AbstractFir2IrNonJvmResultsConverter.kt index 5eb7fac247f..4ba70c979d9 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/AbstractFir2IrNonJvmResultsConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/AbstractFir2IrNonJvmResultsConverter.kt @@ -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() - val firFilesAndComponentsBySourceFile = mutableMapOf>() 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>, - sourceFiles: List + fir2KlibMetadataSerializer: Fir2KlibMetadataSerializer, ): IrBackendInput private fun loadResolvedLibraries( diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJsWasmResultsConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJsWasmResultsConverter.kt index 73cdf2f6afb..416deaedd40 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJsWasmResultsConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJsWasmResultsConverter.kt @@ -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, List, 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>, - sourceFiles: List, + 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, List, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, (KtSourceFile) -> ProtoBuf.PackageFragment) -> IrBackendInput + override val artifactFactory: (IrModuleFragment, IrPluginContext, List, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, KlibSingleFileMetadataSerializer<*>) -> IrBackendInput get() = IrBackendInput::JsIrBackendInput override fun resolveLibraries(module: TestModule, compilerConfiguration: CompilerConfiguration): List { @@ -114,7 +84,7 @@ class Fir2IrJsResultsConverter(testServices: TestServices) : Fir2IrJsWasmResults class Fir2IrWasmResultsConverter(testServices: TestServices) : Fir2IrJsWasmResultsConverter(testServices) { - override val artifactFactory: (IrModuleFragment, IrPluginContext, List, List, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, (KtSourceFile) -> ProtoBuf.PackageFragment) -> IrBackendInput + override val artifactFactory: (IrModuleFragment, IrPluginContext, List, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, KlibSingleFileMetadataSerializer<*>) -> IrBackendInput get() = IrBackendInput::WasmBackendInput override fun resolveLibraries(module: TestModule, compilerConfiguration: CompilerConfiguration): List { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibIrTextTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibIrTextTestCase.kt index 870e7c7932d..118322a12d2 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibIrTextTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibIrTextTestCase.kt @@ -5,10 +5,7 @@ package org.jetbrains.kotlin.klib -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import junit.framework.TestCase -import org.jetbrains.kotlin.KtPsiSourceFile import org.jetbrains.kotlin.backend.common.CommonKLibResolver import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker @@ -18,11 +15,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.CodegenTestCase import org.jetbrains.kotlin.config.CommonConfigurationKeys -import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.languageVersionSettings -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.incremental.components.LookupTracker @@ -34,7 +28,6 @@ import org.jetbrains.kotlin.ir.backend.js.KlibMetadataIncrementalSerializer import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.serializeModuleIntoKlib -import org.jetbrains.kotlin.ir.backend.js.serializeScope import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.util.* @@ -45,17 +38,13 @@ import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.impl.BuiltInsPlatform -import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl import org.jetbrains.kotlin.resolve.AnalyzingUtils import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.resolve.CompilerEnvironment import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.test.ConfigurationKind @@ -119,42 +108,25 @@ abstract class AbstractKlibIrTextTestCase : CodegenTestCase() { } } - private fun klibMetadataIncrementalSerializer(configuration: CompilerConfiguration, project: Project, allowErrors: Boolean) = - KlibMetadataIncrementalSerializer( - languageVersionSettings = configuration.languageVersionSettings, - metadataVersion = KlibMetadataVersion.INSTANCE, - project = project, - exportKDoc = false, - allowErrorTypes = allowErrors - ) - - private fun getDescriptorForElement( - context: BindingContext, - element: PsiElement - ): DeclarationDescriptor = BindingContextUtils.getNotNull(context, BindingContext.DECLARATION_TO_DESCRIPTOR, element) - - private fun KlibMetadataIncrementalSerializer.serializeScope( - ktFile: KtFile, - bindingContext: BindingContext, - moduleDescriptor: ModuleDescriptor - ): ProtoBuf.PackageFragment { - val memberScope = ktFile.declarations.map { getDescriptorForElement(bindingContext, it) } - return serializePackageFragment(moduleDescriptor, memberScope, ktFile.packageFqName) - } - private fun serializeModule( irModuleFragment: IrModuleFragment, bindingContext: BindingContext, stdlib: KotlinLibrary, containsErrorCode: Boolean, ): String { - val metadataSerializer = klibMetadataIncrementalSerializer(myEnvironment.configuration, myEnvironment.project, containsErrorCode) val klibDir = org.jetbrains.kotlin.konan.file.createTempDir("testKlib") serializeModuleIntoKlib( moduleName = MODULE_NAME, configuration = myEnvironment.configuration, diagnosticReporter = DiagnosticReporterFactory.createPendingReporter(), - files = myFiles.psiFiles.map(::KtPsiSourceFile), + metadataSerializer = KlibMetadataIncrementalSerializer( + files = myFiles.psiFiles, + configuration = myEnvironment.configuration, + project = myEnvironment.project, + bindingContext = bindingContext, + moduleDescriptor = irModuleFragment.descriptor, + allowErrorTypes = containsErrorCode + ), klibPath = klibDir.canonicalPath, dependencies = listOf(stdlib), moduleFragment = irModuleFragment, @@ -165,7 +137,6 @@ abstract class AbstractKlibIrTextTestCase : CodegenTestCase() { abiVersion = KotlinAbiVersion.CURRENT, jsOutputName = null, builtInsPlatform = BuiltInsPlatform.JS, - serializeSingleFile = { metadataSerializer.serializeScope(it, bindingContext, irModuleFragment.descriptor) } ) return klibDir.canonicalPath } diff --git a/compiler/tests/org/jetbrains/kotlin/klib/FilePathsInKlibTest.kt b/compiler/tests/org/jetbrains/kotlin/klib/FilePathsInKlibTest.kt index 08ae9c69a00..278dfcaecb6 100644 --- a/compiler/tests/org/jetbrains/kotlin/klib/FilePathsInKlibTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/klib/FilePathsInKlibTest.kt @@ -74,9 +74,6 @@ class FilePathsInKlibTest : CodegenTestCase() { module.getModuleDescriptor(it) } - val metadataSerializer = - KlibMetadataIncrementalSerializer(module.compilerConfiguration, module.project, module.jsFrontEndResult.hasErrors) - val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter() generateKLib( module, @@ -85,10 +82,8 @@ class FilePathsInKlibTest : CodegenTestCase() { jsOutputName = MODULE_NAME, icData = icData, moduleFragment = moduleFragment, - diagnosticReporter = diagnosticReporter - ) { file -> - metadataSerializer.serializeScope(file, module.jsFrontEndResult.bindingContext, moduleFragment.descriptor) - } + diagnosticReporter = diagnosticReporter, + ) } private fun setupEnvironment(): CompilerConfiguration { diff --git a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt index 847b634e4e4..4fb440990fd 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt @@ -12,7 +12,6 @@ import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.PsiManager import org.jetbrains.kotlin.ir.KtDiagnosticReporterWithImplicitIrBasedContext -import org.jetbrains.kotlin.KtPsiSourceFile import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker @@ -485,7 +484,6 @@ class GenerateIrRuntime { return psi2IrTranslator.generateModuleFragment(psi2IrContext, files, irProviders, emptyList()) } - @OptIn(ExperimentalPathApi::class) private fun doSerializeModule( moduleFragment: IrModuleFragment, bindingContext: BindingContext, @@ -494,12 +492,19 @@ class GenerateIrRuntime { ): String { val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter() val tmpKlibDir = createTempDirectory().also { it.toFile().deleteOnExit() }.toString() - val metadataSerializer = KlibMetadataIncrementalSerializer(configuration, project, false) + val metadataSerializer = KlibMetadataIncrementalSerializer( + files, + configuration, + project, + bindingContext, + moduleFragment.descriptor, + allowErrorTypes = false, + ) serializeModuleIntoKlib( moduleName, configuration, diagnosticReporter, - files.map(::KtPsiSourceFile), + metadataSerializer, tmpKlibDir, emptyList(), moduleFragment, @@ -507,10 +512,8 @@ class GenerateIrRuntime { true, perFile, abiVersion = KotlinAbiVersion.CURRENT, - jsOutputName = null - ) { file -> - metadataSerializer.serializeScope(file, bindingContext, moduleFragment.descriptor) - } + jsOutputName = null, + ) return tmpKlibDir } diff --git a/js/js.tests/test/org/jetbrains/kotlin/incremental/IrAbstractInvalidationTest.kt b/js/js.tests/test/org/jetbrains/kotlin/incremental/IrAbstractInvalidationTest.kt index fe7e8eb57f2..a8eae81c990 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/incremental/IrAbstractInvalidationTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/incremental/IrAbstractInvalidationTest.kt @@ -106,10 +106,6 @@ abstract class IrAbstractInvalidationTest( ) { sourceModule.getModuleDescriptor(it) } - val metadataSerializer = - KlibMetadataIncrementalSerializer(configuration, sourceModule.project, sourceModule.jsFrontEndResult.hasErrors) - - val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter() generateKLib( sourceModule, outputKlibFile.canonicalPath, @@ -117,9 +113,7 @@ abstract class IrAbstractInvalidationTest( jsOutputName = moduleName, icData = icData, moduleFragment = moduleFragment, - diagnosticReporter = diagnosticReporter - ) { file -> - metadataSerializer.serializeScope(file, sourceModule.jsFrontEndResult.bindingContext, moduleFragment.descriptor) - } + diagnosticReporter = DiagnosticReporterFactory.createPendingReporter(), + ) } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/FirJsKlibBackendFacade.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/FirJsKlibBackendFacade.kt index cbe8e2c31b8..fb9f051349c 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/FirJsKlibBackendFacade.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/FirJsKlibBackendFacade.kt @@ -61,7 +61,7 @@ class FirJsKlibBackendFacade( configuration[CommonConfigurationKeys.MODULE_NAME]!!, configuration, inputArtifact.diagnosticReporter, - inputArtifact.sourceFiles, + inputArtifact.metadataSerializer, klibPath = outputFile, libraries.map { it.library }, inputArtifact.irModuleFragment, @@ -71,9 +71,7 @@ class FirJsKlibBackendFacade( containsErrorCode = inputArtifact.hasErrors, abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data jsOutputName = null - ) { - inputArtifact.serializeSingleFile(it) - } + ) } // TODO: consider avoiding repeated libraries resolution diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsKlibBackendFacade.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsKlibBackendFacade.kt index 0412a0e7fad..65d59ab789b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsKlibBackendFacade.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsKlibBackendFacade.kt @@ -51,7 +51,7 @@ class JsKlibBackendFacade( configuration[CommonConfigurationKeys.MODULE_NAME]!!, configuration, inputArtifact.diagnosticReporter, - inputArtifact.sourceFiles, + inputArtifact.metadataSerializer, klibPath = outputFile, JsEnvironmentConfigurator.getAllRecursiveLibrariesFor(module, testServices).keys.toList(), inputArtifact.irModuleFragment, @@ -61,9 +61,7 @@ class JsKlibBackendFacade( containsErrorCode = inputArtifact.hasErrors, abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data jsOutputName = null - ) { - inputArtifact.serializeSingleFile(it) - } + ) } val dependencies = JsEnvironmentConfigurator.getAllRecursiveDependenciesFor(module, testServices).toList() diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt index 0be9975cd17..100fb39687b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt @@ -92,7 +92,7 @@ internal fun PhaseContext.fir2Ir( val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter() val fir2IrConfiguration = Fir2IrConfiguration.forKlibCompilation(configuration, diagnosticsReporter) - val (irModuleFragment, components, pluginContext, irActualizedResult) = input.firResult.convertToIrAndActualize( + val actualizedResult = input.firResult.convertToIrAndActualize( NativeFir2IrExtensions, fir2IrConfiguration, IrGenerationExtension.getInstances(config.project), @@ -104,8 +104,8 @@ internal fun PhaseContext.fir2Ir( ).also { (it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors } } - assert(irModuleFragment.name.isSpecial) { - "`${irModuleFragment.name}` must be Name.special, since it's required by KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns()" + assert(actualizedResult.irModuleFragment.name.isSpecial) { + "`${actualizedResult.irModuleFragment.name}` must be Name.special, since it's required by KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns()" } @OptIn(DelicateDeclarationStorageApi::class) @@ -116,8 +116,8 @@ internal fun PhaseContext.fir2Ir( val fragment = (p.getPackageFragment() as? IrExternalPackageFragment) ?: return add(fragment.packageFqName) } - components.declarationStorage.forEachCachedDeclarationSymbol(::addExternalPackage) - components.classifierStorage.forEachCachedDeclarationSymbol(::addExternalPackage) + actualizedResult.components.declarationStorage.forEachCachedDeclarationSymbol(::addExternalPackage) + actualizedResult.components.classifierStorage.forEachCachedDeclarationSymbol(::addExternalPackage) // These packages exist in all platform libraries, but can contain only synthetic declarations. // These declarations are not really located in klib, so we don't need to depend on klib to use them. @@ -135,7 +135,7 @@ internal fun PhaseContext.fir2Ir( } } - val symbols = createKonanSymbols(components, pluginContext) + val symbols = createKonanSymbols(actualizedResult.components, actualizedResult.pluginContext) val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames) @@ -144,7 +144,7 @@ internal fun PhaseContext.fir2Ir( throw KonanCompilationException("Compilation failed: there were some diagnostics during fir2ir") } - return Fir2IrOutput(input.firResult, symbols, irModuleFragment, components, pluginContext, irActualizedResult, usedLibraries) + return Fir2IrOutput(input.firResult, symbols, actualizedResult, usedLibraries) } private fun PhaseContext.createKonanSymbols( diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirNativeSerializer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirNativeSerializer.kt index 5e93bfc7ce7..dac634c61f5 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirNativeSerializer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirNativeSerializer.kt @@ -11,23 +11,12 @@ import org.jetbrains.kotlin.backend.konan.driver.phases.SerializerOutput import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleSerializer import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.fir.reportToMessageCollector -import org.jetbrains.kotlin.config.CommonConfigurationKeys -import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.backend.ConstValueProviderImpl -import org.jetbrains.kotlin.fir.backend.extractFirDeclarations -import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.moduleData -import org.jetbrains.kotlin.fir.packageFqName +import org.jetbrains.kotlin.fir.pipeline.Fir2KlibMetadataSerializer import org.jetbrains.kotlin.fir.pipeline.FirResult -import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.providers.firProvider -import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension -import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder -import org.jetbrains.kotlin.utils.toMetadataVersion internal fun PhaseContext.firSerializer(input: FirOutput): SerializerOutput? = when (input) { !is FirOutput.Full -> null @@ -44,35 +33,26 @@ internal fun PhaseContext.firSerializerBase( produceHeaderKlib: Boolean = false, ): SerializerOutput { val configuration = config.configuration - val sourceFiles = mutableListOf() - val firFilesAndSessionsBySourceFile = mutableMapOf>() - - for (firOutput in firResult.outputs) { - for (firFile in firOutput.fir) { - sourceFiles.add(firFile.sourceFile!!) - firFilesAndSessionsBySourceFile[firFile.sourceFile!!] = Triple(firFile, firOutput.session, firOutput.scopeSession) - } - } - - val metadataVersion = - configuration.get(CommonConfigurationKeys.METADATA_VERSION) - ?: configuration.languageVersionSettings.languageVersion.toMetadataVersion() - val usedResolvedLibraries = fir2IrOutput?.let { config.resolvedLibraries.getFullResolvedList(TopologicalLibraryOrder).filter { (!it.isDefault && !configuration.getBoolean(KonanConfigKeys.PURGE_USER_LIBS)) || it in fir2IrOutput.usedLibraries } } - val actualizedFirDeclarations = fir2IrOutput?.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations() + val irModuleFragment = fir2IrOutput?.fir2irActualizedResult?.irModuleFragment val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter() val serializerOutput = serializeModuleIntoKlib( - moduleName = fir2IrOutput?.irModuleFragment?.descriptor?.name?.asString() - ?: firResult.outputs.last().session.moduleData.name.asString(), - irModuleFragment = fir2IrOutput?.irModuleFragment, + moduleName = irModuleFragment?.name?.asString() ?: firResult.outputs.last().session.moduleData.name.asString(), + irModuleFragment = irModuleFragment, configuration = configuration, diagnosticReporter = diagnosticReporter, - sourceFiles = sourceFiles, + metadataSerializer = Fir2KlibMetadataSerializer( + configuration, + firResult.outputs, + fir2IrOutput?.fir2irActualizedResult, + exportKDoc = shouldExportKDoc(), + produceHeaderKlib = produceHeaderKlib, + ), compatibilityMode = CompatibilityMode.CURRENT, cleanFiles = emptyList(), dependencies = usedResolvedLibraries?.map { it.library as KonanLibrary }.orEmpty(), @@ -95,30 +75,6 @@ internal fun PhaseContext.firSerializerBase( shouldCheckSignaturesOnUniqueness = shouldCheckSignaturesOnUniqueness, ) }, - serializeFileMetadata = { ktSourceFile -> - val (firFile, originalSession, originalScopeSession) = firFilesAndSessionsBySourceFile[ktSourceFile] - ?: error("cannot find FIR file by source file ${ktSourceFile.name} (${ktSourceFile.path})") - val session = fir2IrOutput?.components?.session ?: originalSession - val scopeSession = fir2IrOutput?.components?.scopeSession ?: originalScopeSession - val firProvider = fir2IrOutput?.components?.firProvider ?: originalSession.firProvider - serializeSingleFirFile( - firFile, - session, - scopeSession, - actualizedFirDeclarations, - FirKLibSerializerExtension( - session, firProvider, metadataVersion, - fir2IrOutput?.let { - ConstValueProviderImpl(fir2IrOutput.components) - }, - allowErrorTypes = false, - exportKDoc = shouldExportKDoc(), - additionalMetadataProvider = fir2IrOutput?.components?.annotationsFromPluginRegistrar?.createAdditionalMetadataProvider() - ), - configuration.languageVersionSettings, - produceHeaderKlib, - ) to firFile.packageFqName - }, ) val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) diagnosticReporter.reportToMessageCollector(messageCollector, renderDiagnosticNames) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/BackendPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/BackendPhases.kt index 4834a16f20b..292aba5d980 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/BackendPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/BackendPhases.kt @@ -51,7 +51,7 @@ internal val K2SpecialBackendChecksPhase = createSimpleNamedCompilerPhase - val moduleFragment = input.irModuleFragment + val moduleFragment = input.fir2irActualizedResult.irModuleFragment SpecialBackendChecksTraversal( context, input.symbols, diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Fir2Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Fir2Ir.kt index 71a3dd63d6f..6a4fe8b131e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Fir2Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Fir2Ir.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.konan.fir2Ir import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.fir.backend.Fir2IrComponents import org.jetbrains.kotlin.fir.backend.Fir2IrPluginContext +import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult import org.jetbrains.kotlin.fir.pipeline.FirResult import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary @@ -20,10 +21,7 @@ import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary internal data class Fir2IrOutput( val firResult: FirResult, val symbols: KonanSymbols, - val irModuleFragment: IrModuleFragment, - val components: Fir2IrComponents, - val pluginContext: Fir2IrPluginContext, - val irActualizedResult: IrActualizedResult?, + val fir2irActualizedResult: Fir2IrActualizedResult, val usedLibraries: Set ) diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/test/Fir2IrNativeResultsConverter.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/test/Fir2IrNativeResultsConverter.kt index 7154d1589d6..5e8e0fde416 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/test/Fir2IrNativeResultsConverter.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/test/Fir2IrNativeResultsConverter.kt @@ -5,17 +5,15 @@ package org.jetbrains.kotlin.konan.test -import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector -import org.jetbrains.kotlin.fir.backend.Fir2IrComponents import org.jetbrains.kotlin.fir.backend.FirMangler import org.jetbrains.kotlin.fir.backend.native.FirNativeKotlinMangler -import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult +import org.jetbrains.kotlin.fir.pipeline.Fir2KlibMetadataSerializer import org.jetbrains.kotlin.ir.util.KotlinMangler import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary @@ -48,8 +46,7 @@ class Fir2IrNativeResultsConverter(testServices: TestServices) : AbstractFir2IrN diagnosticReporter: BaseDiagnosticsCollector, inputArtifact: FirOutputArtifact, fir2IrResult: Fir2IrActualizedResult, - firFilesAndComponentsBySourceFile: Map>, - sourceFiles: List, + fir2KlibMetadataSerializer: Fir2KlibMetadataSerializer, ): IrBackendInput { val fir2IrComponents = fir2IrResult.components val manglers = fir2IrComponents.manglers diff --git a/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/converters/FirWasmKlibBackendFacade.kt b/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/converters/FirWasmKlibBackendFacade.kt index 72778c227bf..cc37c31f3dc 100644 --- a/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/converters/FirWasmKlibBackendFacade.kt +++ b/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/converters/FirWasmKlibBackendFacade.kt @@ -61,7 +61,7 @@ class FirWasmKlibBackendFacade( configuration[CommonConfigurationKeys.MODULE_NAME]!!, configuration, inputArtifact.diagnosticReporter, - inputArtifact.sourceFiles, + inputArtifact.metadataSerializer, klibPath = outputFile, libraries.map { it.library }, inputArtifact.irModuleFragment, @@ -71,9 +71,7 @@ class FirWasmKlibBackendFacade( containsErrorCode = inputArtifact.hasErrors, abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data jsOutputName = null - ) { - inputArtifact.serializeSingleFile(it) - } + ) } // TODO: consider avoiding repeated libraries resolution