[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.deserialization.PlatformDependentTypeTransformer
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
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.*
|
||||||
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.descriptors.FirModuleDescriptor
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
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.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
@@ -36,10 +30,6 @@ internal fun PhaseContext.fir2Ir(
|
|||||||
input: FirOutput.Full,
|
input: FirOutput.Full,
|
||||||
): Fir2IrOutput {
|
): Fir2IrOutput {
|
||||||
val fir2IrExtensions = Fir2IrExtensions.Default
|
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
|
var builtInsModule: KotlinBuiltIns? = null
|
||||||
val dependencies = mutableListOf<ModuleDescriptorImpl>()
|
val dependencies = mutableListOf<ModuleDescriptorImpl>()
|
||||||
@@ -70,31 +60,21 @@ internal fun PhaseContext.fir2Ir(
|
|||||||
moduleDescriptor.setDependencies(ArrayList(dependencies))
|
moduleDescriptor.setDependencies(ArrayList(dependencies))
|
||||||
}
|
}
|
||||||
|
|
||||||
val commonMemberStorage = Fir2IrCommonMemberStorage(
|
val fir2irResult = input.firResult.convertToIrAndActualize(
|
||||||
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,
|
|
||||||
fir2IrExtensions,
|
fir2IrExtensions,
|
||||||
KonanManglerIr, IrFactoryImpl,
|
|
||||||
Fir2IrVisibilityConverter.Default,
|
|
||||||
Fir2IrJvmSpecialAnnotationSymbolProvider(), // TODO: replace with appropriate (probably empty) implementation
|
|
||||||
IrGenerationExtension.getInstances(config.project),
|
IrGenerationExtension.getInstances(config.project),
|
||||||
generateSignatures = false,
|
linkViaSignatures = false,
|
||||||
kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance, // TODO: consider passing externally
|
signatureComposerCreator = null,
|
||||||
commonMemberStorage = commonMemberStorage,
|
irMangler = KonanManglerIr,
|
||||||
initializedIrBuiltIns = null
|
visibilityConverter = Fir2IrVisibilityConverter.Default,
|
||||||
|
kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance,
|
||||||
).also {
|
).also {
|
||||||
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors }
|
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors }
|
||||||
}
|
}
|
||||||
|
|
||||||
val symbols = createKonanSymbols(fir2irResult)
|
val symbols = createKonanSymbols(fir2irResult)
|
||||||
// TODO KT-55580 Invoke CopyDefaultValuesToActualPhase, same as PsiToir phase does.
|
// 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(
|
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.common.messages.AnalyzerWithCompilerReport
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
import org.jetbrains.kotlin.fir.BinaryModuleData
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
|
||||||
import org.jetbrains.kotlin.fir.FirModuleDataImpl
|
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.pipeline.buildFirFromKtFiles
|
import org.jetbrains.kotlin.fir.pipeline.*
|
||||||
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.session.FirNativeSessionFactory
|
import org.jetbrains.kotlin.fir.session.FirNativeSessionFactory
|
||||||
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
|
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
|
||||||
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
|
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
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.konan.platform.NativePlatformAnalyzerServices
|
||||||
|
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
||||||
|
|
||||||
internal fun PhaseContext.firFrontend(
|
internal fun PhaseContext.firFrontend(
|
||||||
input: KotlinCoreEnvironment
|
input: KotlinCoreEnvironment
|
||||||
@@ -61,31 +59,49 @@ internal fun PhaseContext.firFrontend(
|
|||||||
configuration.languageVersionSettings,
|
configuration.languageVersionSettings,
|
||||||
registerExtraComponents = {},
|
registerExtraComponents = {},
|
||||||
)
|
)
|
||||||
val mainModuleData = FirModuleDataImpl(
|
|
||||||
mainModuleName,
|
fun runFrontend(
|
||||||
dependencyList.regularDependencies,
|
moduleName: Name,
|
||||||
dependencyList.dependsOnDependencies,
|
dependsOn: List<FirModuleData>,
|
||||||
dependencyList.friendsDependencies,
|
ktFiles: List<KtFile>
|
||||||
CommonPlatforms.defaultCommonPlatform,
|
): ModuleCompilerAnalyzedOutput {
|
||||||
NativePlatformAnalyzerServices
|
val moduleData = FirModuleDataImpl(
|
||||||
)
|
moduleName,
|
||||||
val session = FirNativeSessionFactory.createModuleBasedSession(
|
dependencyList.regularDependencies,
|
||||||
mainModuleData,
|
dependsOn,
|
||||||
sessionProvider,
|
dependencyList.friendsDependencies,
|
||||||
extensionRegistrars,
|
CommonPlatforms.defaultCommonPlatform,
|
||||||
configuration.languageVersionSettings,
|
NativePlatformAnalyzerServices
|
||||||
sessionConfigurator,
|
)
|
||||||
)
|
val session = FirNativeSessionFactory.createModuleBasedSession(
|
||||||
val rawFirFiles = session.buildFirFromKtFiles(ktFiles)
|
moduleData,
|
||||||
val (scopeSession, firFiles) = session.runResolution(rawFirFiles)
|
sessionProvider,
|
||||||
if (shouldPrintFiles())
|
extensionRegistrars,
|
||||||
firFiles.forEach { println(it.render()) }
|
configuration.languageVersionSettings,
|
||||||
session.runCheckers(scopeSession, firFiles, diagnosticsReporter)
|
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) {
|
return if (syntaxErrors || diagnosticsReporter.hasErrors) {
|
||||||
FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames)
|
FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames)
|
||||||
FirOutput.ShouldNotGenerateCode
|
FirOutput.ShouldNotGenerateCode
|
||||||
} else {
|
} 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.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.serialization.*
|
import org.jetbrains.kotlin.fir.serialization.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
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.deserialization.BinaryVersion
|
||||||
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.psi
|
import org.jetbrains.kotlin.psi
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
internal fun PhaseContext.firSerializer(
|
internal fun PhaseContext.firSerializer(
|
||||||
input: Fir2IrOutput
|
input: Fir2IrOutput
|
||||||
): SerializerOutput {
|
): SerializerOutput {
|
||||||
val configuration = config.configuration
|
val configuration = config.configuration
|
||||||
val sourceFiles = input.firFiles.mapNotNull { it.sourceFile }
|
val sourceFiles = mutableListOf<KtSourceFile>()
|
||||||
val firFilesBySourceFile = input.firFiles.associateBy { it.sourceFile }
|
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 =
|
val metadataVersion =
|
||||||
configuration.get(CommonConfigurationKeys.METADATA_VERSION)
|
configuration.get(CommonConfigurationKeys.METADATA_VERSION)
|
||||||
?: configuration.languageVersionSettings.languageVersion.toMetadataVersion()
|
?: configuration.languageVersionSettings.languageVersion.toMetadataVersion()
|
||||||
@@ -49,12 +59,13 @@ internal fun PhaseContext.firSerializer(
|
|||||||
input.fir2irResult.irModuleFragment,
|
input.fir2irResult.irModuleFragment,
|
||||||
expectDescriptorToSymbol = mutableMapOf() // TODO: expect -> actual mapping
|
expectDescriptorToSymbol = mutableMapOf() // TODO: expect -> actual mapping
|
||||||
) { file ->
|
) { 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(
|
serializeSingleFirFile(
|
||||||
firFile,
|
firFile,
|
||||||
input.session,
|
session,
|
||||||
input.scopeSession,
|
scopeSession,
|
||||||
FirNativeKLibSerializerExtension(input.session, metadataVersion, FirElementAwareSerializableStringTable()),
|
FirNativeKLibSerializerExtension(session, metadataVersion, FirElementAwareSerializableStringTable()),
|
||||||
configuration.languageVersionSettings,
|
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.driver.PhaseEngine
|
||||||
import org.jetbrains.kotlin.backend.konan.fir2Ir
|
import org.jetbrains.kotlin.backend.konan.fir2Ir
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
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.backend.Fir2IrResult
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.pipeline.FirResult
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
|
||||||
|
|
||||||
internal data class Fir2IrOutput(
|
internal data class Fir2IrOutput(
|
||||||
val session: FirSession,
|
val firResult: FirResult,
|
||||||
val scopeSession: ScopeSession,
|
|
||||||
val firFiles: List<FirFile>,
|
|
||||||
val fir2irResult: Fir2IrResult,
|
val fir2irResult: Fir2IrResult,
|
||||||
val symbols: KonanSymbols
|
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.driver.PhaseEngine
|
||||||
import org.jetbrains.kotlin.backend.konan.firFrontend
|
import org.jetbrains.kotlin.backend.konan.firFrontend
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.pipeline.FirResult
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
|
||||||
|
|
||||||
sealed class FirOutput {
|
sealed class FirOutput {
|
||||||
object ShouldNotGenerateCode : FirOutput()
|
object ShouldNotGenerateCode : FirOutput()
|
||||||
|
|
||||||
data class Full(
|
data class Full(val firResult: FirResult) : FirOutput()
|
||||||
val session: FirSession,
|
|
||||||
val scopeSession: ScopeSession,
|
|
||||||
val firFiles: List<FirFile>,
|
|
||||||
) : FirOutput()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val FIRPhase = createSimpleNamedCompilerPhase(
|
internal val FIRPhase = createSimpleNamedCompilerPhase(
|
||||||
|
|||||||
Reference in New Issue
Block a user