[FIR] Implement support for MPP in Native
^KT-56071
This commit is contained in:
committed by
Space Team
parent
cf4934f539
commit
d8bae5a6f8
+8
-28
@@ -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<ModuleDescriptorImpl>()
|
||||
@@ -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(
|
||||
|
||||
+44
-28
@@ -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<FirModuleData>,
|
||||
ktFiles: List<KtFile>
|
||||
): 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)
|
||||
}
|
||||
}
|
||||
|
||||
+17
-6
@@ -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<KtSourceFile>()
|
||||
val firFilesAndSessionsBySourceFile = mutableMapOf<KtSourceFile, Triple<FirFile, FirSession, ScopeSession>>()
|
||||
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
+2
-6
@@ -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<FirFile>,
|
||||
val firResult: FirResult,
|
||||
val fir2irResult: Fir2IrResult,
|
||||
val symbols: KonanSymbols
|
||||
)
|
||||
|
||||
+2
-8
@@ -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<FirFile>,
|
||||
) : FirOutput()
|
||||
data class Full(val firResult: FirResult) : FirOutput()
|
||||
}
|
||||
|
||||
internal val FIRPhase = createSimpleNamedCompilerPhase(
|
||||
|
||||
Reference in New Issue
Block a user