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 9571ce05605..766087c3815 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 @@ -16,16 +16,10 @@ import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib -import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.* -import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider -import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor -import org.jetbrains.kotlin.fir.moduleData -import org.jetbrains.kotlin.fir.resolve.providers.firProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl +import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories import org.jetbrains.kotlin.storage.LockBasedStorageManager @@ -36,10 +30,6 @@ internal fun PhaseContext.fir2Ir( input: FirOutput.Full, ): Fir2IrOutput { val fir2IrExtensions = Fir2IrExtensions.Default - val commonFirFiles = input.session.moduleData.dependsOnDependencies - .map { it.session } - .filter { it.kind == FirSession.Kind.Source } - .flatMap { (it.firProvider as FirProviderImpl).getAllFirFiles() } var builtInsModule: KotlinBuiltIns? = null val dependencies = mutableListOf() @@ -70,31 +60,21 @@ internal fun PhaseContext.fir2Ir( moduleDescriptor.setDependencies(ArrayList(dependencies)) } - val commonMemberStorage = Fir2IrCommonMemberStorage( - generateSignatures = false, - signatureComposerCreator = null, - manglerCreator = { FirJvmKotlinMangler() } // TODO: replace with potentially simpler JS version - ) - - val fir2irResult = Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded( - input.session, input.scopeSession, input.firFiles + commonFirFiles, - configuration.languageVersionSettings, + val fir2irResult = input.firResult.convertToIrAndActualize( fir2IrExtensions, - KonanManglerIr, IrFactoryImpl, - Fir2IrVisibilityConverter.Default, - Fir2IrJvmSpecialAnnotationSymbolProvider(), // TODO: replace with appropriate (probably empty) implementation IrGenerationExtension.getInstances(config.project), - generateSignatures = false, - kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance, // TODO: consider passing externally - commonMemberStorage = commonMemberStorage, - initializedIrBuiltIns = null + linkViaSignatures = false, + signatureComposerCreator = null, + irMangler = KonanManglerIr, + visibilityConverter = Fir2IrVisibilityConverter.Default, + kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance, ).also { (it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors } } val symbols = createKonanSymbols(fir2irResult) // TODO KT-55580 Invoke CopyDefaultValuesToActualPhase, same as PsiToir phase does. - return Fir2IrOutput(input.session, input.scopeSession, input.firFiles, fir2irResult, symbols) + return Fir2IrOutput(input.firResult, fir2irResult, symbols) } private fun PhaseContext.createKonanSymbols( diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirFrontend.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirFrontend.kt index bf875400534..49176c23aa7 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirFrontend.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirFrontend.kt @@ -7,24 +7,22 @@ import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.config.AnalysisFlags +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory -import org.jetbrains.kotlin.fir.BinaryModuleData -import org.jetbrains.kotlin.fir.DependencyListForCliModule -import org.jetbrains.kotlin.fir.FirModuleDataImpl +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider -import org.jetbrains.kotlin.fir.pipeline.buildFirFromKtFiles -import org.jetbrains.kotlin.fir.pipeline.runCheckers -import org.jetbrains.kotlin.fir.pipeline.runResolution -import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.pipeline.* import org.jetbrains.kotlin.fir.session.FirNativeSessionFactory import org.jetbrains.kotlin.fir.session.FirSessionConfigurator import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.CommonPlatforms +import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices +import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource internal fun PhaseContext.firFrontend( input: KotlinCoreEnvironment @@ -61,31 +59,49 @@ internal fun PhaseContext.firFrontend( configuration.languageVersionSettings, registerExtraComponents = {}, ) - val mainModuleData = FirModuleDataImpl( - mainModuleName, - dependencyList.regularDependencies, - dependencyList.dependsOnDependencies, - dependencyList.friendsDependencies, - CommonPlatforms.defaultCommonPlatform, - NativePlatformAnalyzerServices - ) - val session = FirNativeSessionFactory.createModuleBasedSession( - mainModuleData, - sessionProvider, - extensionRegistrars, - configuration.languageVersionSettings, - sessionConfigurator, - ) - val rawFirFiles = session.buildFirFromKtFiles(ktFiles) - val (scopeSession, firFiles) = session.runResolution(rawFirFiles) - if (shouldPrintFiles()) - firFiles.forEach { println(it.render()) } - session.runCheckers(scopeSession, firFiles, diagnosticsReporter) + + fun runFrontend( + moduleName: Name, + dependsOn: List, + ktFiles: List + ): ModuleCompilerAnalyzedOutput { + val moduleData = FirModuleDataImpl( + moduleName, + dependencyList.regularDependencies, + dependsOn, + dependencyList.friendsDependencies, + CommonPlatforms.defaultCommonPlatform, + NativePlatformAnalyzerServices + ) + val session = FirNativeSessionFactory.createModuleBasedSession( + moduleData, + sessionProvider, + extensionRegistrars, + configuration.languageVersionSettings, + sessionConfigurator, + ) + val output = buildResolveAndCheckFir(session, ktFiles, diagnosticsReporter) + if (shouldPrintFiles()) + output.fir.forEach { println(it.render()) } + + return output + } + + val isMppEnabled = configuration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) + + val firResult = if (isMppEnabled) { + val (commonKtFiles, platformKtFiles) = ktFiles.partition { it.isCommonSource == true } + val commonOutput = runFrontend(Name.identifier("${mainModuleName}-common"), emptyList(), commonKtFiles) + val platformOutput = runFrontend(mainModuleName, listOf(commonOutput.session.moduleData), platformKtFiles) + FirResult(platformOutput, commonOutput) + } else { + FirResult(runFrontend(mainModuleName, emptyList(), ktFiles), null) + } return if (syntaxErrors || diagnosticsReporter.hasErrors) { FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames) FirOutput.ShouldNotGenerateCode } else { - FirOutput.Full(session, scopeSession, firFiles) + FirOutput.Full(firResult) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt index 8e32a2d7999..d126257a03f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.serialization.* import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -29,13 +30,22 @@ import org.jetbrains.kotlin.utils.toMetadataVersion import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable import org.jetbrains.kotlin.psi +import org.jetbrains.kotlin.utils.addIfNotNull internal fun PhaseContext.firSerializer( input: Fir2IrOutput ): SerializerOutput { val configuration = config.configuration - val sourceFiles = input.firFiles.mapNotNull { it.sourceFile } - val firFilesBySourceFile = input.firFiles.associateBy { it.sourceFile } + val sourceFiles = mutableListOf() + val firFilesAndSessionsBySourceFile = mutableMapOf>() + + for (firOutput in listOfNotNull(input.firResult.commonOutput, input.firResult.platformOutput)) { + 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() @@ -49,12 +59,13 @@ internal fun PhaseContext.firSerializer( input.fir2irResult.irModuleFragment, expectDescriptorToSymbol = mutableMapOf() // TODO: expect -> actual mapping ) { file -> - val firFile = firFilesBySourceFile[file] ?: error("cannot find FIR file by source file ${file.name} (${file.path})") + val (firFile, session, scopeSession) = firFilesAndSessionsBySourceFile[file] + ?: error("cannot find FIR file by source file ${file.name} (${file.path})") serializeSingleFirFile( firFile, - input.session, - input.scopeSession, - FirNativeKLibSerializerExtension(input.session, metadataVersion, FirElementAwareSerializableStringTable()), + session, + scopeSession, + FirNativeKLibSerializerExtension(session, metadataVersion, FirElementAwareSerializableStringTable()), configuration.languageVersionSettings, ) } 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 ae0d3adbda6..026e881e90d 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 @@ -9,15 +9,11 @@ import org.jetbrains.kotlin.backend.konan.driver.PhaseContext import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine import org.jetbrains.kotlin.backend.konan.fir2Ir import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols -import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.Fir2IrResult -import org.jetbrains.kotlin.fir.declarations.FirFile -import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.pipeline.FirResult internal data class Fir2IrOutput( - val session: FirSession, - val scopeSession: ScopeSession, - val firFiles: List, + val firResult: FirResult, val fir2irResult: Fir2IrResult, val symbols: KonanSymbols ) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/FirFrontend.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/FirFrontend.kt index 0134d280495..6c56e864fac 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/FirFrontend.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/FirFrontend.kt @@ -9,18 +9,12 @@ import org.jetbrains.kotlin.backend.konan.driver.PhaseContext import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine import org.jetbrains.kotlin.backend.konan.firFrontend import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirFile -import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.pipeline.FirResult sealed class FirOutput { object ShouldNotGenerateCode : FirOutput() - data class Full( - val session: FirSession, - val scopeSession: ScopeSession, - val firFiles: List, - ) : FirOutput() + data class Full(val firResult: FirResult) : FirOutput() } internal val FIRPhase = createSimpleNamedCompilerPhase(