[FIR & FIR2IR] Prepare test and CLI infrastructure to support MPP

- Move out getAnalyzerServices from FirFrontendFacade to TestSetupUtils
- Simplify DependencyListForCliModule. Now it takes BinaryModuleData as input
- FirOutArtifact contains several FirOutputArtifactPart
- Simplify FirFrontendFacade
This commit is contained in:
Ivan Kochurkin
2022-11-18 19:51:58 +01:00
committed by Space Team
parent 3029e47609
commit 5d273ce839
44 changed files with 1025 additions and 788 deletions
@@ -7,7 +7,6 @@
package org.jetbrains.kotlin.cli.jvm.compiler
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
@@ -26,24 +25,21 @@ import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
import org.jetbrains.kotlin.codegen.CodegenFactory
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.backend.jvm.*
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.pipeline.*
import org.jetbrains.kotlin.fir.session.FirSessionFactoryHelper
import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext
import org.jetbrains.kotlin.fir.session.*
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
import org.jetbrains.kotlin.fir.types.arrayElementType
@@ -52,18 +48,16 @@ import org.jetbrains.kotlin.fir.types.isArrayType
import org.jetbrains.kotlin.fir.types.isString
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -102,15 +96,8 @@ object FirKotlinToJvmBytecodeCompiler {
)
return false
}
if (projectConfiguration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) {
messageCollector.report(
CompilerMessageSeverity.ERROR,
"K2 compiler does not support multi-platform projects yet, so please remove -Xuse-k2 flag"
)
return false
}
val outputs = ArrayList<Pair<ModuleCompilerAnalyzedOutput, GenerationState>>(chunk.size)
val outputs = ArrayList<Pair<FirResult, GenerationState>>(chunk.size)
val targetIds = projectConfiguration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
val incrementalComponents = projectConfiguration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
val isMultiModuleChunk = chunk.size > 1
@@ -140,14 +127,14 @@ object FirKotlinToJvmBytecodeCompiler {
}
val mainClassFqName: FqName? = runIf(chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
findMainClass(outputs.single().first.fir)
findMainClass(outputs.single().first.platformOutput.fir)
}
return writeOutputsIfNeeded(
project,
projectConfiguration,
chunk,
outputs.map(Pair<ModuleCompilerAnalyzedOutput, GenerationState>::second),
outputs.map(Pair<FirResult, GenerationState>::second),
mainClassFqName
)
}
@@ -160,7 +147,7 @@ object FirKotlinToJvmBytecodeCompiler {
?.mapTo(destination) { it::class.qualifiedName }
}
private fun CompilationContext.compileModule(): Pair<ModuleCompilerAnalyzedOutput, GenerationState>? {
private fun CompilationContext.compileModule(): Pair<FirResult, GenerationState>? {
performanceManager?.notifyAnalysisStarted()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
@@ -181,8 +168,11 @@ object FirKotlinToJvmBytecodeCompiler {
performanceManager?.notifyIRTranslationStarted()
val fir2IrExtensions = JvmFir2IrExtensions(moduleConfiguration, JvmIrDeserializerImpl(), JvmIrMangler)
val linkViaSignatures = moduleConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
val fir2IrResult = firResult.convertToIr(fir2IrExtensions, irGenerationExtensions, linkViaSignatures)
val fir2IrResult = firResult.convertToIrAndActualize(
fir2IrExtensions,
irGenerationExtensions,
linkViaSignatures = moduleConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
)
performanceManager?.notifyIRTranslationFinished()
@@ -190,7 +180,7 @@ object FirKotlinToJvmBytecodeCompiler {
allSources,
fir2IrResult,
fir2IrExtensions,
firResult.session,
firResult.platformOutput.session,
diagnosticsReporter
)
@@ -203,14 +193,12 @@ object FirKotlinToJvmBytecodeCompiler {
return firResult to generationState
}
private fun CompilationContext.runFrontend(ktFiles: List<KtFile>, diagnosticsReporter: BaseDiagnosticsCollector): ModuleCompilerAnalyzedOutput? {
@Suppress("NAME_SHADOWING")
var ktFiles = ktFiles
private fun CompilationContext.runFrontend(ktFiles: List<KtFile>, diagnosticsReporter: BaseDiagnosticsCollector): FirResult? {
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound
}
var sourceScope = (projectEnvironment as VfsBasedProjectEnvironment).getSearchScopeByPsiFiles(ktFiles) +
val sourceScope = (projectEnvironment as VfsBasedProjectEnvironment).getSearchScopeByPsiFiles(ktFiles) +
projectEnvironment.getSearchScopeForProjectJavaSources()
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
@@ -223,85 +211,132 @@ object FirKotlinToJvmBytecodeCompiler {
val languageVersionSettings = moduleConfiguration.languageVersionSettings
val commonKtFiles = ktFiles.filter { it.isCommonSource == true }
val isMppEnabled = languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
val sessionProvider = FirProjectSessionProvider()
fun createSession(
name: String,
platform: TargetPlatform,
analyzerServices: PlatformDependentAnalyzerServices,
sourceScope: AbstractProjectFileSearchScope,
needRegisterJavaElementFinder: Boolean,
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {}
): FirSession {
return FirSessionFactoryHelper.createSessionWithDependencies(
Name.identifier(name),
platform,
analyzerServices,
externalSessionProvider = sessionProvider,
projectEnvironment,
languageVersionSettings,
sourceScope,
librariesScope,
lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER),
providerAndScopeForIncrementalCompilation,
firExtensionRegistrars,
needRegisterJavaElementFinder,
dependenciesConfigurator = {
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
dependenciesConfigurator()
}
) {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
}
val moduleName = module.getModuleName()
val libraryList = createLibraryListAndSession(moduleName, sessionProvider, librariesScope, languageVersionSettings)
val commonSession = runIf(
languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) && commonKtFiles.isNotEmpty()
) {
val commonSourcesScope = projectEnvironment.getSearchScopeByPsiFiles(commonKtFiles)
sourceScope -= commonSourcesScope
ktFiles = ktFiles.filterNot { it.isCommonSource == true }
createSession(
"${module.getModuleName()}-common",
CommonPlatforms.defaultCommonPlatform,
CommonPlatformAnalyzerServices,
commonSourcesScope,
needRegisterJavaElementFinder = false
val commonModuleData = runIf(isMppEnabled) {
FirModuleDataImpl(
Name.identifier("${module.getModuleName()}-common"),
libraryList.regularDependencies,
listOf(),
libraryList.friendsDependencies,
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices
)
}
val session = createSession(
module.getModuleName(),
val platformModuleData = FirModuleDataImpl(
Name.identifier(module.getModuleName()),
libraryList.regularDependencies,
listOfNotNull(commonModuleData),
libraryList.friendsDependencies,
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices,
sourceScope,
needRegisterJavaElementFinder = true
) {
if (commonSession != null) {
sourceDependsOnDependencies(listOf(commonSession.moduleData))
JvmPlatformAnalyzerServices
)
val lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER)
val enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER)
val sessionConfigurator: FirSessionConfigurator.() -> Unit = {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
val commonKtFiles = mutableListOf<KtFile>()
val platformKtFiles = mutableListOf<KtFile>()
val commonSourcesScope: AbstractProjectFileSearchScope?
val platformSourcesScope: AbstractProjectFileSearchScope
if (isMppEnabled) {
for (ktFile in ktFiles) {
(if (ktFile.isCommonSource == true) commonKtFiles else platformKtFiles).add(ktFile)
}
commonSourcesScope = projectEnvironment.getSearchScopeByPsiFiles(commonKtFiles)
platformSourcesScope = sourceScope - commonSourcesScope
} else {
platformKtFiles.addAll(ktFiles)
commonSourcesScope = null
platformSourcesScope = sourceScope
}
val commonSession = runIf(isMppEnabled) {
FirJvmSessionFactory.createModuleBasedSession(
commonModuleData!!,
sessionProvider,
commonSourcesScope!!,
projectEnvironment,
providerAndScopeForIncrementalCompilation,
firExtensionRegistrars,
languageVersionSettings,
lookupTracker,
enumWhenTracker,
needRegisterJavaElementFinder = true,
registerExtraComponents = {},
sessionConfigurator
)
}
val platformSession = FirJvmSessionFactory.createModuleBasedSession(
platformModuleData,
sessionProvider,
platformSourcesScope,
projectEnvironment,
providerAndScopeForIncrementalCompilation,
firExtensionRegistrars,
languageVersionSettings,
lookupTracker,
enumWhenTracker,
needRegisterJavaElementFinder = true,
registerExtraComponents = {},
sessionConfigurator,
)
val commonOutput = commonSession?.let { buildResolveAndCheckFir(it, commonKtFiles, diagnosticsReporter) }
val platformOutput = buildResolveAndCheckFir(platformSession, platformKtFiles, diagnosticsReporter)
return if (syntaxErrors || diagnosticsReporter.hasErrors) null else FirResult(platformOutput, commonOutput)
}
private fun CompilationContext.createLibraryListAndSession(
moduleName: String,
sessionProvider: FirProjectSessionProvider,
librariesScope: AbstractProjectFileSearchScope,
languageVersionSettings: LanguageVersionSettings
): DependencyListForCliModule {
val binaryModuleData = BinaryModuleData.initialize(
Name.identifier(moduleName),
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices
)
val libraryList = DependencyListForCliModule.build(binaryModuleData) {
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
friendDependencies(module.getFriendPaths())
}
FirJvmSessionFactory.createLibrarySession(
Name.identifier(moduleName),
sessionProvider,
libraryList.moduleDataProvider,
projectEnvironment,
librariesScope,
projectEnvironment.getPackagePartProvider(librariesScope),
languageVersionSettings,
registerExtraComponents = {},
)
return libraryList
}
val commonRawFir = commonSession?.buildFirFromKtFiles(commonKtFiles)
private fun buildResolveAndCheckFir(
session: FirSession,
ktFiles: List<KtFile>,
diagnosticsReporter: BaseDiagnosticsCollector
): ModuleCompilerAnalyzedOutput {
val rawFir = session.buildFirFromKtFiles(ktFiles)
commonSession?.apply {
val (commonScopeSession, commonFir) = runResolution(commonRawFir!!)
runCheckers(commonScopeSession, commonFir, diagnosticsReporter)
}
val (scopeSession, fir) = session.runResolution(rawFir)
session.runCheckers(scopeSession, fir, diagnosticsReporter)
return if (syntaxErrors || diagnosticsReporter.hasErrors) null else ModuleCompilerAnalyzedOutput(session, scopeSession, fir)
return ModuleCompilerAnalyzedOutput(session, scopeSession, fir)
}
private fun CompilationContext.createComponentsForIncrementalCompilation(
@@ -19,7 +19,6 @@ import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.io.URLUtil
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.KtVirtualFileSourceFile
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl
@@ -44,7 +43,9 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
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.FirSession
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
@@ -52,10 +53,10 @@ import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
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.moduleData
import org.jetbrains.kotlin.fir.pipeline.*
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.session.FirSessionFactoryHelper
import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
@@ -71,16 +72,14 @@ import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import java.io.File
import java.util.LinkedHashSet
import kotlin.reflect.KFunction2
private const val kotlinFileExtensionWithDot = ".${KotlinFileType.EXTENSION}"
private const val javaFileExtensionWithDot = ".${JavaFileType.DEFAULT_EXTENSION}"
@@ -105,14 +104,6 @@ fun compileModulesUsingFrontendIrAndLightTree(
"ATTENTION!\n This build uses experimental K2 compiler: \n -Xuse-k2"
)
if (compilerConfiguration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) {
messageCollector.report(
CompilerMessageSeverity.ERROR,
"K2 compiler does not support multi-platform projects yet, so please remove -Xuse-k2 flag"
)
return false
}
val outputs = mutableListOf<GenerationState>()
var mainClassFqName: FqName? = null
@@ -148,7 +139,7 @@ fun compileModulesUsingFrontendIrAndLightTree(
// TODO: consider what to do if many modules has main classes
if (mainClassFqName == null && moduleConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
mainClassFqName = findMainClass(analysisResults.fir)
mainClassFqName = findMainClass(analysisResults.platformOutput.fir)
}
if (diagnosticsReporter.hasErrors) {
@@ -225,7 +216,7 @@ fun collectSources(
fun convertAnalyzedFirToIr(
input: ModuleCompilerInput,
analysisResults: ModuleCompilerAnalyzedOutput,
analysisResults: FirResult,
environment: ModuleCompilerEnvironment
): ModuleCompilerIrBackendInput {
val extensions = JvmFir2IrExtensions(input.configuration, JvmIrDeserializerImpl(), JvmIrMangler)
@@ -237,7 +228,7 @@ fun convertAnalyzedFirToIr(
} ?: emptyList()
val linkViaSignatures = input.configuration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
val (irModuleFragment, components, pluginContext) =
analysisResults.convertToIr(extensions, irGenerationExtensions, linkViaSignatures)
analysisResults.convertToIrAndActualize(extensions, irGenerationExtensions, linkViaSignatures)
return ModuleCompilerIrBackendInput(
input.targetId,
@@ -246,7 +237,7 @@ fun convertAnalyzedFirToIr(
irModuleFragment,
components.symbolTable,
components,
analysisResults.session,
analysisResults.platformOutput.session,
pluginContext
)
}
@@ -310,73 +301,158 @@ fun compileModuleToAnalyzedFir(
incrementalExcludesScope: AbstractProjectFileSearchScope?,
diagnosticsReporter: DiagnosticReporter,
performanceManager: CommonCompilerPerformanceManager?
): ModuleCompilerAnalyzedOutput {
var sourcesScope = environment.projectEnvironment.getSearchScopeBySourceFiles(input.platformSources)
val sessionProvider = FirProjectSessionProvider()
val extendedAnalysisMode = input.configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
): FirResult {
val languageVersionSettings = input.configuration.languageVersionSettings
val projectEnvironment = environment.projectEnvironment
val moduleConfiguration = input.configuration
val isMppEnabled = languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
val sourcesScope = environment.projectEnvironment.getSearchScopeBySourceFiles(input.platformSources)
val commonSession = runIf(
input.commonSources.isNotEmpty() && input.configuration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
) {
val commonSourcesScope = environment.projectEnvironment.getSearchScopeBySourceFiles(input.commonSources)
sourcesScope -= commonSourcesScope
createSession(
"${input.targetId.name}-common",
input.commonPlatform,
input.configuration,
environment.projectEnvironment,
commonSourcesScope,
CommonPlatformAnalyzerServices,
sessionProvider,
val commonSourcesScope: AbstractProjectFileSearchScope?
val platformSourcesScope: AbstractProjectFileSearchScope
if (isMppEnabled) {
commonSourcesScope = projectEnvironment.getSearchScopeBySourceFiles(input.commonSources)
platformSourcesScope = sourcesScope - commonSourcesScope
} else {
commonSourcesScope = null
platformSourcesScope = sourcesScope
}
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
val commonProviderAndScopeForIncrementalCompilation = runIf(isMppEnabled) {
createContextForIncrementalCompilation(
moduleConfiguration,
projectEnvironment,
commonSourcesScope!!,
previousStepsSymbolProviders,
incrementalExcludesScope,
extendedAnalysisMode,
needRegisterJavaElementFinder = false
incrementalExcludesScope
)?.also { (_, _, precompiledBinariesFileScope) ->
precompiledBinariesFileScope?.let { librariesScope -= it }
}
}
val platformProviderAndScopeForIncrementalCompilation = createContextForIncrementalCompilation(
moduleConfiguration,
projectEnvironment,
platformSourcesScope,
previousStepsSymbolProviders,
incrementalExcludesScope
)?.also { (_, _, precompiledBinariesFileScope) ->
precompiledBinariesFileScope?.let { librariesScope -= it }
}
val sessionProvider = FirProjectSessionProvider()
val moduleName = input.targetId.name
val libraryList = createLibraryListAndSession(moduleName, input.configuration, projectEnvironment, librariesScope, sessionProvider)
val commonModuleData = runIf(isMppEnabled) {
FirModuleDataImpl(
Name.identifier("${moduleName}-common"),
libraryList.regularDependencies,
listOf(),
libraryList.friendsDependencies,
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices
)
}
val platformModuleData = FirModuleDataImpl(
Name.identifier(moduleName),
libraryList.regularDependencies,
listOfNotNull(commonModuleData),
libraryList.friendsDependencies,
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices
)
val session = createSession(
input.targetId.name,
input.platform,
input.configuration,
environment.projectEnvironment,
sourcesScope,
JvmPlatformAnalyzerServices,
sessionProvider,
previousStepsSymbolProviders,
incrementalExcludesScope,
extendedAnalysisMode,
needRegisterJavaElementFinder = true
) {
if (commonSession != null) {
sourceDependsOnDependencies(listOf(commonSession.moduleData))
val extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) }
?: emptyList()
val lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER)
val enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER)
val extendedAnalysisMode = input.configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
val sessionConfigurator: FirSessionConfigurator.() -> Unit = {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
friendDependencies(input.configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
sourceFriendsDependencies(input.friendFirModules)
}
val javaSourcesScope = projectEnvironment.getSearchScopeForProjectJavaSources()
val commonSession = runIf(isMppEnabled) {
FirJvmSessionFactory.createModuleBasedSession(
commonModuleData!!,
sessionProvider,
javaSourcesScope,
projectEnvironment,
commonProviderAndScopeForIncrementalCompilation,
extensionRegistrars,
languageVersionSettings,
lookupTracker,
enumWhenTracker,
needRegisterJavaElementFinder = true,
registerExtraComponents = {},
sessionConfigurator,
)
}
val platformSession = FirJvmSessionFactory.createModuleBasedSession(
platformModuleData,
sessionProvider,
javaSourcesScope,
projectEnvironment,
platformProviderAndScopeForIncrementalCompilation,
extensionRegistrars,
languageVersionSettings,
lookupTracker,
enumWhenTracker,
needRegisterJavaElementFinder = true,
registerExtraComponents = {},
sessionConfigurator
)
val countFilesAndLines = if (performanceManager == null) null else performanceManager::addSourcesStats
val commonOutput = commonSession?.let { buildResolveAndCheckFir(it, input.commonSources, diagnosticsReporter, countFilesAndLines) }
val platformOutput = buildResolveAndCheckFir(platformSession, input.platformSources, diagnosticsReporter, countFilesAndLines)
// raw fir
val commonRawFir = commonSession?.buildFirViaLightTree(
input.commonSources,
diagnosticsReporter,
countFilesAndLines
return FirResult(platformOutput, commonOutput)
}
fun createLibraryListAndSession(
moduleName: String,
configuration: CompilerConfiguration,
projectEnvironment: AbstractProjectEnvironment,
librariesScope: AbstractProjectFileSearchScope,
sessionProvider: FirProjectSessionProvider
): DependencyListForCliModule {
val binaryModuleData = BinaryModuleData.initialize(
Name.identifier(moduleName),
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices
)
val rawFir =
session.buildFirViaLightTree(input.platformSources, diagnosticsReporter, countFilesAndLines)
// resolution
commonSession?.apply {
val (commonScopeSession, commonFir) = runResolution(commonRawFir!!)
// TODO: find out what to do with commonFir
runCheckers(commonScopeSession, commonFir, environment.diagnosticsReporter)
val libraryList = DependencyListForCliModule.build(binaryModuleData) {
dependencies(configuration.jvmClasspathRoots.map { it.toPath() })
dependencies(configuration.jvmModularRoots.map { it.toPath() })
friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
}
FirJvmSessionFactory.createLibrarySession(
Name.identifier(moduleName),
sessionProvider,
libraryList.moduleDataProvider,
projectEnvironment,
projectEnvironment.getSearchScopeForProjectLibraries(),
projectEnvironment.getPackagePartProvider(librariesScope),
configuration.languageVersionSettings,
registerExtraComponents = {},
)
return libraryList
}
val (scopeSession, fir) = session.runResolution(rawFir)
// checkers
session.runCheckers(scopeSession, fir, environment.diagnosticsReporter)
private fun buildResolveAndCheckFir(
session: FirSession,
ktFiles: Collection<KtSourceFile>,
diagnosticsReporter: DiagnosticReporter,
countFilesAndLines: KFunction2<Int, Int, Unit>?
): ModuleCompilerAnalyzedOutput {
val firFiles = session.buildFirViaLightTree(ktFiles, diagnosticsReporter, countFilesAndLines)
val (scopeSession, fir) = session.runResolution(firFiles)
session.runCheckers(scopeSession, fir, diagnosticsReporter)
return ModuleCompilerAnalyzedOutput(session, scopeSession, fir)
}
@@ -413,63 +489,7 @@ fun writeOutputs(
return true
}
fun createSession(
name: String,
platform: TargetPlatform,
moduleConfiguration: CompilerConfiguration,
projectEnvironment: AbstractProjectEnvironment,
sourceScope: AbstractProjectFileSearchScope,
analyzerServices: PlatformDependentAnalyzerServices,
sessionProvider: FirProjectSessionProvider?,
previousStepsSymbolProviders: List<FirSymbolProvider>,
incrementalExcludesScope: AbstractProjectFileSearchScope?,
extendedAnalysisMode: Boolean,
needRegisterJavaElementFinder: Boolean,
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {},
): FirSession {
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
val providerAndScopeForIncrementalCompilation =
createContextForIncrementalCompilation(
moduleConfiguration,
projectEnvironment,
sourceScope,
previousStepsSymbolProviders,
incrementalExcludesScope
)
?.also { (_, _, precompiledBinariesFileScope) ->
precompiledBinariesFileScope?.let { librariesScope -= it }
}
return FirSessionFactoryHelper.createSessionWithDependencies(
Name.identifier(name),
platform,
analyzerServices,
externalSessionProvider = sessionProvider,
projectEnvironment,
moduleConfiguration.languageVersionSettings,
projectEnvironment.getSearchScopeForProjectJavaSources(),
librariesScope,
lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER),
providerAndScopeForIncrementalCompilation,
extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) }
?: emptyList(),
needRegisterJavaElementFinder = needRegisterJavaElementFinder,
dependenciesConfigurator = {
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
dependenciesConfigurator()
}
) {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
}
private fun createContextForIncrementalCompilation(
fun createContextForIncrementalCompilation(
compilerConfiguration: CompilerConfiguration,
projectEnvironment: AbstractProjectEnvironment,
sourceScope: AbstractProjectFileSearchScope,