[JS IR] Move fir to klib serialization code in separate class

This commit is contained in:
Alexander Korepanov
2023-05-02 18:07:19 +02:00
committed by Space Team
parent effe902c69
commit 28b781f60a
2 changed files with 57 additions and 71 deletions
@@ -528,7 +528,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
val fir2IrActualizedResult = transformFirToIr(moduleStructure, outputs, diagnosticsReporter) val fir2IrActualizedResult = transformFirToIr(moduleStructure, outputs, diagnosticsReporter)
if (configuration.getBoolean(CommonConfigurationKeys.INCREMENTAL_COMPILATION)) { if (configuration.getBoolean(CommonConfigurationKeys.INCREMENTAL_COMPILATION)) {
if (shouldGoToNextIcRound(moduleStructure, outputs, fir2IrActualizedResult, configuration)) { if (shouldGoToNextIcRound(moduleStructure, outputs, fir2IrActualizedResult)) {
throw IncrementalNextRoundException() throw IncrementalNextRoundException()
} }
} }
@@ -25,11 +25,9 @@ import org.jetbrains.kotlin.fir.DependencyListForCliModule
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler 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.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.pipeline.* 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.FirKLibSerializerExtension
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
import org.jetbrains.kotlin.fir.session.KlibIcData 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.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.unresolvedDependencies import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -215,6 +214,48 @@ fun transformFirToIr(
) )
} }
private class Fir2KlibSerializer(
moduleStructure: ModulesStructure,
private val firOutputs: List<ModuleCompilerAnalyzedOutput>,
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<KtSourceFile> = 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( fun serializeFirKlib(
moduleStructure: ModulesStructure, moduleStructure: ModulesStructure,
firOutputs: List<ModuleCompilerAnalyzedOutput>, firOutputs: List<ModuleCompilerAnalyzedOutput>,
@@ -224,94 +265,39 @@ fun serializeFirKlib(
diagnosticsReporter: BaseDiagnosticsCollector, diagnosticsReporter: BaseDiagnosticsCollector,
jsOutputName: String? jsOutputName: String?
) { ) {
val sourceFiles = mutableListOf<KtSourceFile>() val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult)
val firFilesAndSessionsBySourceFile = mutableMapOf<KtSourceFile, Triple<FirFile, FirSession, ScopeSession>>() val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibSerializer.sourceFiles)
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()
serializeModuleIntoKlib( serializeModuleIntoKlib(
moduleStructure.compilerConfiguration[CommonConfigurationKeys.MODULE_NAME]!!, moduleStructure.compilerConfiguration[CommonConfigurationKeys.MODULE_NAME]!!,
moduleStructure.compilerConfiguration, moduleStructure.compilerConfiguration,
moduleStructure.compilerConfiguration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None, moduleStructure.compilerConfiguration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None,
sourceFiles, fir2KlibSerializer.sourceFiles,
klibPath = outputKlibPath, klibPath = outputKlibPath,
moduleStructure.allDependencies, moduleStructure.allDependencies,
fir2IrActualizedResult.irModuleFragment, fir2IrActualizedResult.irModuleFragment,
expectDescriptorToSymbol = mutableMapOf(), expectDescriptorToSymbol = mutableMapOf(),
cleanFiles = icData, cleanFiles = icData ?: emptyList(),
nopack = true, nopack = true,
perFile = false, perFile = false,
containsErrorCode = messageCollector.hasErrors() || diagnosticsReporter.hasErrors, containsErrorCode = messageCollector.hasErrors() || diagnosticsReporter.hasErrors,
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = jsOutputName jsOutputName = jsOutputName,
) { file -> serializeSingleFile = fir2KlibSerializer::serializeSingleFirFile
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,
)
}
} }
fun shouldGoToNextIcRound( fun shouldGoToNextIcRound(
moduleStructure: ModulesStructure, moduleStructure: ModulesStructure,
firOutputs: List<ModuleCompilerAnalyzedOutput>, firOutputs: List<ModuleCompilerAnalyzedOutput>,
fir2IrActualizedResult: Fir2IrActualizedResult, fir2IrActualizedResult: Fir2IrActualizedResult
config: CompilerConfiguration,
): Boolean { ): Boolean {
val sourceFiles = mutableListOf<KtSourceFile>() val nextRoundChecker = moduleStructure.compilerConfiguration.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return false
val firFilesAndSessionsBySourceFile = mutableMapOf<KtSourceFile, Triple<FirFile, FirSession, ScopeSession>>()
for (output in firOutputs) { val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult)
output.fir.forEach {
sourceFiles.add(it.sourceFile!!)
firFilesAndSessionsBySourceFile[it.sourceFile!!] = Triple(it, output.session, output.scopeSession)
}
}
val metadataVersion = moduleStructure.compilerConfiguration.metadataVersion() for (ktFile in fir2KlibSerializer.sourceFiles) {
val packageFragment = fir2KlibSerializer.serializeSingleFirFile(ktFile)
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,
)
// to minimize a number of IC rounds, we should inspect all proto for changes first, // 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 // then go to a next round if needed, with all new dirty files
@@ -319,4 +305,4 @@ fun shouldGoToNextIcRound(
} }
return nextRoundChecker.shouldGoToNextRound() return nextRoundChecker.shouldGoToNextRound()
} }