From 28b781f60a71728386728a68dccba1085c95ecbb Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Tue, 2 May 2023 18:07:19 +0200 Subject: [PATCH] [JS IR] Move fir to klib serialization code in separate class --- .../jetbrains/kotlin/cli/js/K2JsIrCompiler.kt | 2 +- .../kotlin/cli/js/klib/compilerPipeline.kt | 126 ++++++++---------- 2 files changed, 57 insertions(+), 71 deletions(-) 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 f91da92931e..1d7dc3fce27 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 @@ -528,7 +528,7 @@ class K2JsIrCompiler : CLICompiler() { val fir2IrActualizedResult = transformFirToIr(moduleStructure, outputs, diagnosticsReporter) if (configuration.getBoolean(CommonConfigurationKeys.INCREMENTAL_COMPILATION)) { - if (shouldGoToNextIcRound(moduleStructure, outputs, fir2IrActualizedResult, configuration)) { + if (shouldGoToNextIcRound(moduleStructure, outputs, fir2IrActualizedResult)) { 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 49bf7682bde..217ee51c62f 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 @@ -25,11 +25,9 @@ import org.jetbrains.kotlin.fir.DependencyListForCliModule import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler -import org.jetbrains.kotlin.fir.declarations.FirFile 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.resolve.ScopeSession import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile import org.jetbrains.kotlin.fir.session.KlibIcData @@ -43,6 +41,7 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.library.KotlinAbiVersion 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.psi.KtFile @@ -215,6 +214,48 @@ 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!!, Triple(it, output.session, output.scopeSession)) + } + } + } + + private val actualizedExpectDeclarations by lazy { + fir2IrActualizedResult.irActualizedResult.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, session, scopeSession) = firFilesAndSessionsBySourceFile[file] + ?: error("cannot find FIR file by source file ${file.name} (${file.path})") + + return serializeSingleFirFile( + firFile, + session, + scopeSession, + actualizedExpectDeclarations, + FirKLibSerializerExtension( + session, metadataVersion, + ConstValueProviderImpl(fir2IrActualizedResult.components), + allowErrorTypes = false, exportKDoc = false + ), + languageVersionSettings, + ) + } +} + fun serializeFirKlib( moduleStructure: ModulesStructure, firOutputs: List, @@ -224,94 +265,39 @@ fun serializeFirKlib( diagnosticsReporter: BaseDiagnosticsCollector, jsOutputName: String? ) { - val sourceFiles = mutableListOf() - val firFilesAndSessionsBySourceFile = mutableMapOf>() - - for (output in firOutputs) { - output.fir.forEach { - sourceFiles.add(it.sourceFile!!) - firFilesAndSessionsBySourceFile[it.sourceFile!!] = Triple(it, output.session, output.scopeSession) - } - } - - val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList() - - val metadataVersion = moduleStructure.compilerConfiguration.metadataVersion() - - val actualizedExpectDeclarations = fir2IrActualizedResult.irActualizedResult.extractFirDeclarations() + val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult) + val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibSerializer.sourceFiles) serializeModuleIntoKlib( moduleStructure.compilerConfiguration[CommonConfigurationKeys.MODULE_NAME]!!, moduleStructure.compilerConfiguration, moduleStructure.compilerConfiguration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None, - sourceFiles, + fir2KlibSerializer.sourceFiles, klibPath = outputKlibPath, moduleStructure.allDependencies, fir2IrActualizedResult.irModuleFragment, expectDescriptorToSymbol = mutableMapOf(), - cleanFiles = icData, + cleanFiles = icData ?: emptyList(), nopack = true, perFile = false, containsErrorCode = messageCollector.hasErrors() || diagnosticsReporter.hasErrors, abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data - jsOutputName = jsOutputName - ) { file -> - val (firFile, session, scopeSession) = firFilesAndSessionsBySourceFile[file] - ?: error("cannot find FIR file by source file ${file.name} (${file.path})") - serializeSingleFirFile( - firFile, - session, - scopeSession, - actualizedExpectDeclarations, - FirKLibSerializerExtension( - session, metadataVersion, - ConstValueProviderImpl(fir2IrActualizedResult.components), - allowErrorTypes = false, exportKDoc = false - ), - moduleStructure.compilerConfiguration.languageVersionSettings, - ) - } + jsOutputName = jsOutputName, + serializeSingleFile = fir2KlibSerializer::serializeSingleFirFile + ) } fun shouldGoToNextIcRound( moduleStructure: ModulesStructure, firOutputs: List, - fir2IrActualizedResult: Fir2IrActualizedResult, - config: CompilerConfiguration, + fir2IrActualizedResult: Fir2IrActualizedResult ): Boolean { - val sourceFiles = mutableListOf() - val firFilesAndSessionsBySourceFile = mutableMapOf>() + val nextRoundChecker = moduleStructure.compilerConfiguration.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return false - for (output in firOutputs) { - output.fir.forEach { - sourceFiles.add(it.sourceFile!!) - firFilesAndSessionsBySourceFile[it.sourceFile!!] = Triple(it, output.session, output.scopeSession) - } - } + val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult) - val metadataVersion = moduleStructure.compilerConfiguration.metadataVersion() - - val actualizedExpectDeclarations = fir2IrActualizedResult.irActualizedResult.extractFirDeclarations() - - val nextRoundChecker = config.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return false - - for (ktFile in sourceFiles) { - - val (firFile, session, scopeSession) = firFilesAndSessionsBySourceFile[ktFile] - ?: error("cannot find FIR file by source file ${ktFile.name} (${ktFile.path})") - - val packageFragment = serializeSingleFirFile( - firFile, - session, - scopeSession, - actualizedExpectDeclarations, - FirKLibSerializerExtension( - session, metadataVersion, - ConstValueProviderImpl(fir2IrActualizedResult.components), - allowErrorTypes = false, exportKDoc = false - ), - moduleStructure.compilerConfiguration.languageVersionSettings, - ) + 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 @@ -319,4 +305,4 @@ fun shouldGoToNextIcRound( } return nextRoundChecker.shouldGoToNextRound() -} \ No newline at end of file +}