[FIR] KT-58065: Support LT in K2Native

This commit is contained in:
Nikolay Lunyak
2023-05-02 17:17:49 +03:00
committed by Space Team
parent d72a50b3f5
commit 90651c5851
2 changed files with 72 additions and 16 deletions
@@ -1,18 +1,17 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.driver.phases.FirOutput
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.fileBelongsToModuleForPsi
import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.cli.common.isCommonSourceForPsi
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.prepareNativeSessions
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.pipeline.FirResult
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput
import org.jetbrains.kotlin.fir.pipeline.buildResolveAndCheckFir
import org.jetbrains.kotlin.fir.resolve.ImplicitIntegerCoercionModuleCapability
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
@@ -23,18 +22,23 @@ import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
@OptIn(SessionConfiguration::class)
internal fun PhaseContext.firFrontend(input: KotlinCoreEnvironment): FirOutput {
internal inline fun <F> PhaseContext.firFrontend(
input: KotlinCoreEnvironment,
files: List<F>,
fileHasSyntaxErrors: (F) -> Boolean,
noinline isCommonSource: (F) -> Boolean,
noinline fileBelongsToModule: (F, String) -> Boolean,
buildResolveAndCheckFir: (FirSession, List<F>) -> ModuleCompilerAnalyzedOutput,
): FirOutput {
val configuration = input.configuration
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter()
val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
// FIR
val extensionRegistrars = FirExtensionRegistrar.getInstances(input.project)
val mainModuleName = Name.special("<${config.moduleId}>")
val ktFiles = input.getSourceFiles()
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound
}
val syntaxErrors = files.fold(false) { errorsFound, file -> fileHasSyntaxErrors(file) or errorsFound }
val binaryModuleData = BinaryModuleData.initialize(mainModuleName, CommonPlatforms.defaultCommonPlatform, NativePlatformAnalyzerServices)
val dependencyList = DependencyListForCliModule.build(binaryModuleData) {
val (interopLibs, regularLibs) = config.resolvedLibraries.getFullList().partition { it.isInterop }
@@ -55,24 +59,24 @@ internal fun PhaseContext.firFrontend(input: KotlinCoreEnvironment): FirOutput {
val resolvedLibraries: List<KotlinResolvedLibrary> = config.resolvedLibraries.getFullResolvedList()
val sessionsWithSources = prepareNativeSessions(
ktFiles,
files,
configuration,
mainModuleName,
resolvedLibraries,
dependencyList,
extensionRegistrars,
metadataCompilationMode = configuration.get(KonanConfigKeys.METADATA_KLIB) ?: false,
isCommonSourceForPsi,
fileBelongsToModuleForPsi,
isCommonSource = isCommonSource,
fileBelongsToModule = fileBelongsToModule,
registerExtraComponents = {
it.register(FirOverrideChecker::class, FirNativeOverrideChecker(it))
},
)
val outputs = sessionsWithSources.map { (session, sources) ->
buildResolveAndCheckFir(session, sources, diagnosticsReporter).also {
buildResolveAndCheckFir(session, sources).also {
if (shouldPrintFiles()) {
it.fir.forEach { println(it.render()) }
it.fir.forEach { file -> println(file.render()) }
}
}
}
@@ -84,3 +88,49 @@ internal fun PhaseContext.firFrontend(input: KotlinCoreEnvironment): FirOutput {
FirOutput.Full(FirResult(outputs))
}
}
internal fun PhaseContext.firFrontendWithPsi(input: KotlinCoreEnvironment): FirOutput {
val configuration = input.configuration
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter()
// FIR
val ktFiles = input.getSourceFiles()
return firFrontend(
input,
ktFiles,
fileHasSyntaxErrors = {
AnalyzerWithCompilerReport.reportSyntaxErrors(it, messageCollector).isHasErrors
},
isCommonSource = isCommonSourceForPsi,
fileBelongsToModule = fileBelongsToModuleForPsi,
buildResolveAndCheckFir = { session, files ->
buildResolveAndCheckFir(session, files, diagnosticsReporter)
},
)
}
internal fun PhaseContext.firFrontendWithLightTree(input: KotlinCoreEnvironment): FirOutput {
val configuration = input.configuration
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter()
// FIR
val groupedSources = collectSources(configuration, input.project, messageCollector)
val ktSourceFiles = mutableListOf<KtSourceFile>().apply {
addAll(groupedSources.commonSources)
addAll(groupedSources.platformSources)
}
return firFrontend(
input,
ktSourceFiles,
fileHasSyntaxErrors = { false },
isCommonSource = { groupedSources.isCommonSourceForLt(it) },
fileBelongsToModule = { file, it -> groupedSources.fileBelongsToModuleForLt(file, it) },
buildResolveAndCheckFir = { session, files ->
buildResolveAndCheckFir(session, files, diagnosticsReporter, null)
},
)
}
@@ -7,8 +7,10 @@ package org.jetbrains.kotlin.backend.konan.driver.phases
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.backend.konan.firFrontendWithPsi
import org.jetbrains.kotlin.backend.konan.firFrontendWithLightTree
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.fir.pipeline.FirResult
sealed class FirOutput {
@@ -21,7 +23,11 @@ internal val FIRPhase = createSimpleNamedCompilerPhase(
"FirFrontend", "Compiler Fir Frontend",
outputIfNotEnabled = { _, _, _, _ -> FirOutput.ShouldNotGenerateCode }
) { context: PhaseContext, input: KotlinCoreEnvironment ->
context.firFrontend(input)
if (input.configuration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE)) {
context.firFrontendWithLightTree(input)
} else {
context.firFrontendWithPsi(input)
}
}
internal fun <T : PhaseContext> PhaseEngine<T>.runFirFrontend(environment: KotlinCoreEnvironment): FirOutput {