diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index bf0a8e965ca..355afe92abe 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -41,25 +41,19 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl 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.Fir2IrExtensions import org.jetbrains.kotlin.fir.backend.Fir2IrVisibilityConverter -import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar -import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider 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.pipeline.convertToIrAndActualize import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.serialization.FirElementAwareSerializableStringTable import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile -import org.jetbrains.kotlin.fir.session.FirJsSessionFactory -import org.jetbrains.kotlin.fir.session.FirSessionConfigurator import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider @@ -91,11 +85,12 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.storage.LockBasedStorageManager -import org.jetbrains.kotlin.utils.* -import org.jetbrains.kotlin.utils.addToStdlib.runIf +import org.jetbrains.kotlin.utils.KotlinPaths +import org.jetbrains.kotlin.utils.PathUtil +import org.jetbrains.kotlin.utils.join +import org.jetbrains.kotlin.utils.metadataVersion import java.io.File import java.io.IOException import java.nio.file.Paths @@ -453,7 +448,11 @@ class K2JsIrCompiler : CLICompiler() { } val metadataSerializer = - KlibMetadataIncrementalSerializer(environmentForJS.configuration, sourceModule.project, sourceModule.jsFrontEndResult.hasErrors) + KlibMetadataIncrementalSerializer( + environmentForJS.configuration, + sourceModule.project, + sourceModule.jsFrontEndResult.hasErrors + ) generateKLib( sourceModule, @@ -483,16 +482,7 @@ class K2JsIrCompiler : CLICompiler() { val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) // FIR - - val isMppEnabled = configuration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) - - val sessionProvider = FirProjectSessionProvider() val extensionRegistrars = FirExtensionRegistrar.getInstances(environmentForJS.project) - val sessionConfigurator: FirSessionConfigurator.() -> Unit = { - if (arguments.extendedCompilerChecks) { - registerExtendedCommonCheckers() - } - } val mainModuleName = configuration.get(CommonConfigurationKeys.MODULE_NAME)!! val escapedMainModuleName = Name.special("<$mainModuleName>") @@ -514,67 +504,14 @@ class K2JsIrCompiler : CLICompiler() { val logger = configuration.resolverLogger val resolvedLibraries = jsResolveLibraries(libraries + friendLibraries, logger).getFullResolvedList() - FirJsSessionFactory.createLibrarySession( - escapedMainModuleName, - resolvedLibraries, - sessionProvider, - dependencyList.moduleDataProvider, - configuration.languageVersionSettings, - registerExtraComponents = {}, + val sessionsWithSources = prepareJsSessions( + ktFiles, configuration, escapedMainModuleName.asString(), resolvedLibraries, dependencyList, + extensionRegistrars, isCommonSourceForPsi, fileBelongsToModuleForPsi ) - val commonModuleData = runIf(isMppEnabled) { - FirModuleDataImpl( - Name.identifier("<$mainModuleName-common>"), - dependencyList.regularDependencies, - listOf(), - dependencyList.friendsDependencies, - JsPlatforms.defaultJsPlatform, - JsPlatformAnalyzerServices - ) + val outputs = sessionsWithSources.map { + buildResolveAndCheckFir(it.session, it.files, diagnosticsReporter) } - val mainModuleData = FirModuleDataImpl( - escapedMainModuleName, - dependencyList.regularDependencies, - listOfNotNull(commonModuleData), - dependencyList.friendsDependencies, - JsPlatforms.defaultJsPlatform, - JsPlatformAnalyzerServices - ) - - val commonKtFiles = mutableListOf() - val platformKtFiles = mutableListOf() - if (isMppEnabled) { - for (ktFile in ktFiles) { - (if (ktFile.isCommonSource == true) commonKtFiles else platformKtFiles).add(ktFile) - } - } else { - platformKtFiles.addAll(ktFiles) - } - - val commonSession = runIf(isMppEnabled) { - FirJsSessionFactory.createModuleBasedSession( - commonModuleData!!, - sessionProvider, - extensionRegistrars, - configuration.languageVersionSettings, - null, - registerExtraComponents = {}, - init = sessionConfigurator, - ) - } - val platformSession = FirJsSessionFactory.createModuleBasedSession( - mainModuleData, - sessionProvider, - extensionRegistrars, - configuration.languageVersionSettings, - null, - registerExtraComponents = {}, - init = sessionConfigurator, - ) - - val commonFirOutput = commonSession?.let { buildResolveAndCheckFir(it, commonKtFiles, diagnosticsReporter) } - val platformFirOutput = buildResolveAndCheckFir(platformSession, platformKtFiles, diagnosticsReporter) if (syntaxErrors || diagnosticsReporter.hasErrors) { FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames) @@ -608,7 +545,7 @@ class K2JsIrCompiler : CLICompiler() { moduleDescriptor } - val firResult = FirResult(platformFirOutput, commonFirOutput) + val firResult = FirResult(outputs) val irResult = firResult.convertToIrAndActualize( fir2IrExtensions, IrGenerationExtension.getInstances(environmentForJS.project), @@ -628,13 +565,11 @@ class K2JsIrCompiler : CLICompiler() { val sourceFiles = mutableListOf() val firFilesAndSessionsBySourceFile = mutableMapOf>() - commonFirOutput?.fir?.forEach { - sourceFiles.add(it.sourceFile!!) - firFilesAndSessionsBySourceFile[it.sourceFile!!] = Triple(it, commonFirOutput.session, commonFirOutput.scopeSession) - } - platformFirOutput.fir.forEach { - sourceFiles.add(it.sourceFile!!) - firFilesAndSessionsBySourceFile[it.sourceFile!!] = Triple(it, platformFirOutput.session, platformFirOutput.scopeSession) + for (output in outputs) { + output.fir.forEach { + sourceFiles.add(it.sourceFile!!) + firFilesAndSessionsBySourceFile[it.sourceFile!!] = Triple(it, output.session, output.scopeSession) + } } val icData = environmentForJS.configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList() diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt new file mode 100644 index 00000000000..1db2f25a283 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt @@ -0,0 +1,411 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.cli.common + +import org.jetbrains.kotlin.KtSourceFile +import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices +import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.GroupedKtSources +import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.fir.DependencyListForCliModule +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.fir.FirModuleDataImpl +import org.jetbrains.kotlin.fir.FirSession +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.session.* +import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment +import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope +import org.jetbrains.kotlin.incremental.components.EnumWhenTracker +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices +import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary +import org.jetbrains.kotlin.load.kotlin.PackageAndMetadataPartProvider +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.CommonPlatforms +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.js.JsPlatforms +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.platform.konan.NativePlatforms +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.konan.platform.NativePlatformAnalyzerServices +import org.jetbrains.kotlin.resolve.multiplatform.hmppModuleName +import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource + +val isCommonSourceForPsi: (KtFile) -> Boolean = { it.isCommonSource == true } +val fileBelongsToModuleForPsi: (KtFile, String) -> Boolean = { file, moduleName -> file.hmppModuleName == moduleName } + +val GroupedKtSources.isCommonSourceForLt: (KtSourceFile) -> Boolean + get() = { it in commonSources } + +val GroupedKtSources.fileBelongsToModuleForLt: (KtSourceFile, String) -> Boolean + get() = { file, moduleName -> sourcesByModuleName[moduleName].orEmpty().contains(file) } + +/** + * Creates library session and sources session for JVM platform + * Number of created session depends on mode of MPP: + * - disabled + * - legacy (one platform and one common module) + * - HMPP (multiple number of modules) + */ +fun prepareJvmSessions( + files: List, + configuration: CompilerConfiguration, + projectEnvironment: AbstractProjectEnvironment, + rootModuleName: String, + extensionRegistrars: List, + librariesScope: AbstractProjectFileSearchScope, + libraryList: DependencyListForCliModule, + isCommonSource: (F) -> Boolean, + fileBelongsToModule: (F, String) -> Boolean, + createProviderAndScopeForIncrementalCompilation: (List) -> IncrementalCompilationContext?, +): List> { + val javaSourcesScope = projectEnvironment.getSearchScopeForProjectJavaSources() + + class Context( + val javaSourcesScope: AbstractProjectFileSearchScope, + val lookupTracker: LookupTracker?, + val enumWhenTracker: EnumWhenTracker? + ) + + return prepareSessions( + files, configuration, rootModuleName, JvmPlatforms.unspecifiedJvmPlatform, + JvmPlatformAnalyzerServices, libraryList, isCommonSource, fileBelongsToModule, + createContext = { + val lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) + val enumWhenTracker = configuration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER) + Context(javaSourcesScope, lookupTracker, enumWhenTracker) + }, + createLibrarySession = { sessionProvider -> + FirJvmSessionFactory.createLibrarySession( + Name.identifier(rootModuleName), + sessionProvider, + libraryList.moduleDataProvider, + projectEnvironment, + librariesScope, + projectEnvironment.getPackagePartProvider(librariesScope), + configuration.languageVersionSettings, + registerExtraComponents = {}, + ) + + } + ) { context, moduleFiles, moduleData, sessionProvider, sessionConfigurator -> + FirJvmSessionFactory.createModuleBasedSession( + moduleData, + sessionProvider, + context.javaSourcesScope, + projectEnvironment, + createProviderAndScopeForIncrementalCompilation(moduleFiles), + extensionRegistrars, + configuration.languageVersionSettings, + context.lookupTracker, + context.enumWhenTracker, + needRegisterJavaElementFinder = true, + registerExtraComponents = {}, + sessionConfigurator, + ) + } +} + +/** + * Creates library session and sources session for JS platform + * Number of created session depends on mode of MPP: + * - disabled + * - legacy (one platform and one common module) + * - HMPP (multiple number of modules) + */ +fun prepareJsSessions( + files: List, + configuration: CompilerConfiguration, + rootModuleName: String, + resolvedLibraries: List, + libraryList: DependencyListForCliModule, + extensionRegistrars: List, + isCommonSource: (F) -> Boolean, + fileBelongsToModule: (F, String) -> Boolean, +): List> { + return prepareSessions( + files, configuration, rootModuleName, JsPlatforms.defaultJsPlatform, JsPlatformAnalyzerServices, + libraryList, isCommonSource, fileBelongsToModule, + createContext = { null }, + createLibrarySession = { sessionProvider -> + FirJsSessionFactory.createLibrarySession( + Name.identifier(rootModuleName), + resolvedLibraries, + sessionProvider, + libraryList.moduleDataProvider, + configuration.languageVersionSettings, + registerExtraComponents = {}, + ) + } + ) { _, _, moduleData, sessionProvider, sessionConfigurator -> + FirJsSessionFactory.createModuleBasedSession( + moduleData, + sessionProvider, + extensionRegistrars, + configuration.languageVersionSettings, + null, + registerExtraComponents = {}, + init = sessionConfigurator, + ) + } +} + +/** + * Creates library session and sources session for Native platform + * Number of created session depends on mode of MPP: + * - disabled + * - legacy (one platform and one common module) + * - HMPP (multiple number of modules) + */ +fun prepareNativeSessions( + files: List, + configuration: CompilerConfiguration, + rootModuleName: String, + resolvedLibraries: List, + libraryList: DependencyListForCliModule, + extensionRegistrars: List, + isCommonSource: (F) -> Boolean, + fileBelongsToModule: (F, String) -> Boolean, +): List> { + return prepareSessions( + files, configuration, rootModuleName, NativePlatforms.unspecifiedNativePlatform, NativePlatformAnalyzerServices, + libraryList, isCommonSource, fileBelongsToModule, createContext = { null }, + createLibrarySession = { sessionProvider -> + FirNativeSessionFactory.createLibrarySession( + Name.identifier(rootModuleName), + resolvedLibraries, + sessionProvider, + libraryList.moduleDataProvider, + configuration.languageVersionSettings, + registerExtraComponents = {}, + ) + } + ) { _, _, moduleData, sessionProvider, sessionConfigurator -> + FirNativeSessionFactory.createModuleBasedSession( + moduleData, + sessionProvider, + extensionRegistrars, + configuration.languageVersionSettings, + sessionConfigurator, + ) + } +} + +/** + * Creates library session and sources session for Common platform (for metadata compilation) + * Number of created session depends on mode of MPP: + * - disabled + * - legacy (one platform and one common module) + * - HMPP (multiple number of modules) + */ +fun prepareCommonSessions( + files: List, + configuration: CompilerConfiguration, + projectEnvironment: AbstractProjectEnvironment, + rootModuleName: String, + extensionRegistrars: List, + librariesScope: AbstractProjectFileSearchScope, + libraryList: DependencyListForCliModule, + isCommonSource: (F) -> Boolean, + fileBelongsToModule: (F, String) -> Boolean, + createProviderAndScopeForIncrementalCompilation: (List) -> IncrementalCompilationContext?, +): List> { + return prepareSessions( + files, configuration, rootModuleName, CommonPlatforms.defaultCommonPlatform, CommonPlatformAnalyzerServices, + libraryList, isCommonSource, fileBelongsToModule, createContext = { null }, + createLibrarySession = { sessionProvider -> + FirCommonSessionFactory.createLibrarySession( + Name.identifier(rootModuleName), + sessionProvider, + libraryList.moduleDataProvider, + projectEnvironment, + librariesScope, + projectEnvironment.getPackagePartProvider(librariesScope) as PackageAndMetadataPartProvider, + configuration.languageVersionSettings, + registerExtraComponents = {}, + ) + } + ) { _, moduleFiles, moduleData, sessionProvider, sessionConfigurator -> + FirCommonSessionFactory.createModuleBasedSession( + moduleData, + sessionProvider, + librariesScope, + projectEnvironment, + incrementalCompilationContext = createProviderAndScopeForIncrementalCompilation(moduleFiles), + extensionRegistrars, + configuration.languageVersionSettings, + lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER), + enumWhenTracker = configuration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER), + needRegisterJavaElementFinder = true, + registerExtraComponents = {}, + init = sessionConfigurator + ) + } +} + +// ---------------------------------------------------- Implementation ---------------------------------------------------- + +private typealias FirSessionProducer = (C, List, FirModuleData, FirProjectSessionProvider, FirSessionConfigurator.() -> Unit) -> FirSession + +private inline fun prepareSessions( + files: List, + configuration: CompilerConfiguration, + rootModuleName: String, + targetPlatform: TargetPlatform, + analyzerServices: PlatformDependentAnalyzerServices, + libraryList: DependencyListForCliModule, + isCommonSource: (F) -> Boolean, + fileBelongsToModule: (F, String) -> Boolean, + createContext: () -> C, + createLibrarySession: (FirProjectSessionProvider) -> FirSession, + createSourceSession: FirSessionProducer, +): List> { + val languageVersionSettings = configuration.languageVersionSettings + + val isMppEnabled = languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) + val hmppModuleStructure = configuration.get(CommonConfigurationKeys.HMPP_MODULE_STRUCTURE) + val sessionProvider = FirProjectSessionProvider() + + val context = createContext() + + createLibrarySession(sessionProvider) + val extendedAnalysisMode = configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS) + val sessionConfigurator: FirSessionConfigurator.() -> Unit = { + if (extendedAnalysisMode) { + registerExtendedCommonCheckers() + } + } + + return when { + !isMppEnabled -> listOf( + createSessionForNonMppProject( + context, files, rootModuleName, libraryList, targetPlatform, analyzerServices, + sessionProvider, sessionConfigurator, createSourceSession + ) + ) + + hmppModuleStructure == null -> createSessionsForLegacyMppProject( + context, files, rootModuleName, libraryList, targetPlatform, analyzerServices, + sessionProvider, sessionConfigurator, isCommonSource, createSourceSession + ) + + else -> createSessionsForHmppProject( + context, files, hmppModuleStructure, libraryList, targetPlatform, analyzerServices, + sessionProvider, sessionConfigurator, fileBelongsToModule, createSourceSession + ) + } +} + +private inline fun createSessionForNonMppProject( + context: C, + files: List, + rootModuleName: String, + libraryList: DependencyListForCliModule, + targetPlatform: TargetPlatform, + analyzerServices: PlatformDependentAnalyzerServices, + sessionProvider: FirProjectSessionProvider, + noinline sessionConfigurator: FirSessionConfigurator.() -> Unit, + createFirSession: FirSessionProducer, +): SessionWithSources { + val platformModuleData = FirModuleDataImpl( + Name.identifier(rootModuleName), + libraryList.regularDependencies, + dependsOnDependencies = emptyList(), + libraryList.friendsDependencies, + targetPlatform, + analyzerServices + ) + + val session = createFirSession(context, files, platformModuleData, sessionProvider, sessionConfigurator) + return SessionWithSources(session, files) +} + +private inline fun createSessionsForLegacyMppProject( + context: C, + files: List, + rootModuleName: String, + libraryList: DependencyListForCliModule, + targetPlatform: TargetPlatform, + analyzerServices: PlatformDependentAnalyzerServices, + sessionProvider: FirProjectSessionProvider, + noinline sessionConfigurator: FirSessionConfigurator.() -> Unit, + isCommonSource: (F) -> Boolean, + createFirSession: FirSessionProducer, +): List> { + val commonModuleData = FirModuleDataImpl( + Name.identifier("${rootModuleName}-common"), + libraryList.regularDependencies, + listOf(), + libraryList.friendsDependencies, + targetPlatform, + analyzerServices + ) + + val platformModuleData = FirModuleDataImpl( + Name.identifier(rootModuleName), + libraryList.regularDependencies, + listOf(commonModuleData), + libraryList.friendsDependencies, + targetPlatform, + analyzerServices + ) + + val commonFiles = mutableListOf() + val platformFiles = mutableListOf() + for (file in files) { + (if (isCommonSource(file)) commonFiles else platformFiles).add(file) + } + + val commonSession = createFirSession(context, commonFiles, commonModuleData, sessionProvider, sessionConfigurator) + val platformSession = createFirSession(context, platformFiles, platformModuleData, sessionProvider, sessionConfigurator) + + return listOf( + SessionWithSources(commonSession, commonFiles), + SessionWithSources(platformSession, platformFiles) + ) +} + +private inline fun createSessionsForHmppProject( + context: C, + files: List, + hmppModuleStructure: HmppCliModuleStructure, + libraryList: DependencyListForCliModule, + targetPlatform: TargetPlatform, + analyzerServices: PlatformDependentAnalyzerServices, + sessionProvider: FirProjectSessionProvider, + noinline sessionConfigurator: FirSessionConfigurator.() -> Unit, + fileBelongsToModule: (F, String) -> Boolean, + createFirSession: FirSessionProducer, +): List> { + val moduleDataForHmppModule = LinkedHashMap() + + for (module in hmppModuleStructure.modules) { + val dependencies = hmppModuleStructure.dependenciesMap[module] + ?.map { moduleDataForHmppModule.getValue(it) } + .orEmpty() + val moduleData = FirModuleDataImpl( + Name.identifier(module.name), + libraryList.regularDependencies, + dependsOnDependencies = dependencies, + libraryList.friendsDependencies, + targetPlatform, + analyzerServices + ) + moduleDataForHmppModule[module] = moduleData + } + + return hmppModuleStructure.modules.map { module -> + val moduleData = moduleDataForHmppModule.getValue(module) + val sources = files.filter { fileBelongsToModule(it, module.name) } + val session = createFirSession(context, sources, moduleData, sessionProvider, sessionConfigurator) + SessionWithSources(session, sources) + } +} + +data class SessionWithSources(val session: FirSession, val files: List) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt index 660dcfd24dd..8a27e53660b 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt @@ -11,10 +11,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl -import org.jetbrains.kotlin.cli.common.CLICompiler -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager -import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage +import org.jetbrains.kotlin.cli.common.* import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity @@ -30,15 +27,12 @@ import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector import org.jetbrains.kotlin.fir.* 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.* import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment -import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope import org.jetbrains.kotlin.fir.types.arrayElementType import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.isArrayType @@ -50,13 +44,12 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompil 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.jvm.JvmPlatforms import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices +import org.jetbrains.kotlin.resolve.multiplatform.hmppModuleName import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource import org.jetbrains.kotlin.utils.addToStdlib.runIf +import org.jetbrains.kotlin.utils.addToStdlib.runUnless import java.io.File object FirKotlinToJvmBytecodeCompiler { @@ -66,14 +59,15 @@ object FirKotlinToJvmBytecodeCompiler { messageCollector: MessageCollector, allSources: List, buildFile: File?, - chunk: List, - extendedAnalysisMode: Boolean + chunk: List ): Boolean { val performanceManager = projectConfiguration.get(CLIConfigurationKeys.PERF_MANAGER) val notSupportedPlugins = mutableListOf().apply { - projectConfiguration.get(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS).collectIncompatiblePluginNamesTo(this, ComponentRegistrar::supportsK2) - projectConfiguration.get(CompilerPluginRegistrar.COMPILER_PLUGIN_REGISTRARS).collectIncompatiblePluginNamesTo(this, CompilerPluginRegistrar::supportsK2) + projectConfiguration.get(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS) + .collectIncompatiblePluginNamesTo(this, ComponentRegistrar::supportsK2) + projectConfiguration.get(CompilerPluginRegistrar.COMPILER_PLUGIN_REGISTRARS) + .collectIncompatiblePluginNamesTo(this, CompilerPluginRegistrar::supportsK2) } if (notSupportedPlugins.isNotEmpty()) { @@ -109,8 +103,7 @@ object FirKotlinToJvmBytecodeCompiler { performanceManager, targetIds, incrementalComponents, - extendedAnalysisMode, - firExtensionRegistrars = project?.let { FirExtensionRegistrar.getInstances(it) } ?: emptyList(), + extensionRegistrars = project?.let { FirExtensionRegistrar.getInstances(it) } ?: emptyList(), irGenerationExtensions = project?.let { IrGenerationExtension.getInstances(it) } ?: emptyList() ) val generationState = context.compileModule() ?: return false @@ -118,7 +111,7 @@ object FirKotlinToJvmBytecodeCompiler { } val mainClassFqName: FqName? = runIf(chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { - findMainClass(outputs.single().first.platformOutput.fir) + findMainClass(outputs.single().first.outputs.last().fir) } return writeOutputsIfNeeded( @@ -204,97 +197,21 @@ object FirKotlinToJvmBytecodeCompiler { providerAndScopeForIncrementalCompilation?.precompiledBinariesFileScope?.let { librariesScope -= it } - - val languageVersionSettings = moduleConfiguration.languageVersionSettings - - val isMppEnabled = languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) - - val sessionProvider = FirProjectSessionProvider() - - val moduleName = module.getModuleName() - val libraryList = createFirLibraryListAndSession( - moduleName, moduleConfiguration, projectEnvironment, - scope = librariesScope, librariesScope = librariesScope, friendPaths = module.getFriendPaths(), sessionProvider + val rootModuleName = module.getModuleName() + val libraryList = createLibraryListForJvm(rootModuleName, moduleConfiguration, module.getFriendPaths()) + val sessionsWithSources = prepareJvmSessions( + ktFiles, moduleConfiguration, projectEnvironment, rootModuleName, + extensionRegistrars, librariesScope, libraryList, + isCommonSource = { it.isCommonSource == true }, + fileBelongsToModule = { file, moduleName -> file.hmppModuleName == moduleName }, + createProviderAndScopeForIncrementalCompilation = { providerAndScopeForIncrementalCompilation } ) - val commonModuleData = runIf(isMppEnabled) { - FirModuleDataImpl( - Name.identifier("${module.getModuleName()}-common"), - libraryList.regularDependencies, - listOf(), - libraryList.friendsDependencies, - JvmPlatforms.unspecifiedJvmPlatform, - JvmPlatformAnalyzerServices - ) - } - val platformModuleData = FirModuleDataImpl( - Name.identifier(module.getModuleName()), - libraryList.regularDependencies, - listOfNotNull(commonModuleData), - libraryList.friendsDependencies, - JvmPlatforms.unspecifiedJvmPlatform, - JvmPlatformAnalyzerServices - ) - - val lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER) - val enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER) - val sessionConfigurator: FirSessionConfigurator.() -> Unit = { - if (extendedAnalysisMode) { - registerExtendedCommonCheckers() - } + val outputs = sessionsWithSources.map { (session, sources) -> + buildResolveAndCheckFir(session, sources, diagnosticsReporter) } - val commonKtFiles = mutableListOf() - val platformKtFiles = mutableListOf() - 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) + return runUnless(syntaxErrors || diagnosticsReporter.hasErrors) { FirResult(outputs) } } private fun CompilationContext.runBackend( @@ -365,8 +282,7 @@ object FirKotlinToJvmBytecodeCompiler { val performanceManager: CommonCompilerPerformanceManager?, val targetIds: List?, val incrementalComponents: IncrementalCompilationComponents?, - val extendedAnalysisMode: Boolean, - val firExtensionRegistrars: List, + val extensionRegistrars: List, val irGenerationExtensions: Collection ) } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 43975929854..aba6e9964a4 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -70,7 +70,6 @@ object KotlinToJVMBytecodeCompiler { val projectConfiguration = environment.configuration if (projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR)) { - val extendedAnalysisMode = projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS) val projectEnvironment = VfsBasedProjectEnvironment( environment.project, @@ -81,7 +80,7 @@ object KotlinToJVMBytecodeCompiler { environment.configuration, environment.messageCollector, environment.getSourceFiles(), - buildFile, chunk, extendedAnalysisMode + buildFile, chunk ) } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/cliCompilerUtils.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/cliCompilerUtils.kt index 34a59acc296..bcdfa4924ca 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/cliCompilerUtils.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/cliCompilerUtils.kt @@ -10,7 +10,6 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileSystem -import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices import org.jetbrains.kotlin.backend.common.output.OutputFileCollection import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys @@ -27,17 +26,12 @@ import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys -import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.fir.BinaryModuleData import org.jetbrains.kotlin.fir.DependencyListForCliModule -import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider -import org.jetbrains.kotlin.fir.session.FirCommonSessionFactory -import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope import org.jetbrains.kotlin.javac.JavacWrapper -import org.jetbrains.kotlin.load.kotlin.PackageAndMetadataPartProvider import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.modules.JavaRootPath @@ -45,7 +39,6 @@ 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.jvm.JvmPlatforms import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.psi.KtFile @@ -226,20 +219,15 @@ fun createContextForIncrementalCompilation( return IncrementalCompilationContext(emptyList(), packagePartProvider, incrementalCompilationScope) } -fun createFirLibraryListAndSession( +fun createLibraryListForJvm( moduleName: String, configuration: CompilerConfiguration, - projectEnvironment: AbstractProjectEnvironment, - scope: AbstractProjectFileSearchScope, - librariesScope: AbstractProjectFileSearchScope, - friendPaths: List, - sessionProvider: FirProjectSessionProvider, - isJvm: Boolean = true + friendPaths: List ): DependencyListForCliModule { val binaryModuleData = BinaryModuleData.initialize( Name.identifier(moduleName), - if (isJvm) JvmPlatforms.unspecifiedJvmPlatform else CommonPlatforms.defaultCommonPlatform, - if (isJvm) JvmPlatformAnalyzerServices else CommonPlatformAnalyzerServices + JvmPlatforms.unspecifiedJvmPlatform, + JvmPlatformAnalyzerServices ) val libraryList = DependencyListForCliModule.build(binaryModuleData) { dependencies(configuration.jvmClasspathRoots.map { it.toPath() }) @@ -247,29 +235,6 @@ fun createFirLibraryListAndSession( friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList()) friendDependencies(friendPaths) } - if (isJvm) { - FirJvmSessionFactory.createLibrarySession( - Name.identifier(moduleName), - sessionProvider, - libraryList.moduleDataProvider, - projectEnvironment, - scope, - projectEnvironment.getPackagePartProvider(librariesScope), - configuration.languageVersionSettings, - registerExtraComponents = {}, - ) - } else { - FirCommonSessionFactory.createLibrarySession( - Name.identifier(moduleName), - sessionProvider, - libraryList.moduleDataProvider, - projectEnvironment, - scope, - projectEnvironment.getPackagePartProvider(librariesScope) as PackageAndMetadataPartProvider, - configuration.languageVersionSettings, - registerExtraComponents = {}, - ) - } return libraryList } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt index 41e7721230d..4a449b6d9f4 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt @@ -22,8 +22,7 @@ import org.jetbrains.kotlin.KtVirtualFileSourceFile import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager +import org.jetbrains.kotlin.cli.common.* import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots import org.jetbrains.kotlin.cli.common.fir.reportToMessageCollector import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity @@ -40,21 +39,19 @@ import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver import org.jetbrains.kotlin.codegen.ClassBuilderFactories import org.jetbrains.kotlin.codegen.CodegenFactory import org.jetbrains.kotlin.codegen.state.GenerationState -import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.JVMConfigurationKeys +import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory -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 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.pipeline.* import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider -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 @@ -68,14 +65,11 @@ import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvid 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.jvm.JvmPlatforms import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver 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 kotlin.reflect.KFunction2 @@ -104,13 +98,13 @@ fun compileModulesUsingFrontendIrAndLightTree( val moduleConfiguration = compilerConfiguration.copy().applyModuleProperties(module, buildFile).apply { put(JVMConfigurationKeys.FRIEND_PATHS, module.getFriendPaths()) } - val (platformSources, commonSources, sourcesByModuleName) = collectSources(compilerConfiguration, projectEnvironment, messageCollector) + val groupedSources = collectSources(compilerConfiguration, projectEnvironment, messageCollector) val compilerInput = ModuleCompilerInput( TargetId(module), - CommonPlatforms.defaultCommonPlatform, commonSources, - JvmPlatforms.unspecifiedJvmPlatform, platformSources, - sourcesByModuleName, + groupedSources, + CommonPlatforms.defaultCommonPlatform, + JvmPlatforms.unspecifiedJvmPlatform, moduleConfiguration ) @@ -133,7 +127,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.platformOutput.fir) + mainClassFqName = findMainClass(analysisResults.outputs.last().fir) } if (diagnosticsReporter.hasErrors) { @@ -171,8 +165,8 @@ fun compileModulesUsingFrontendIrAndLightTree( } data class GroupedKtSources( - val platformSources: Set, - val commonSources: Set, + val platformSources: Collection, + val commonSources: Collection, val sourcesByModuleName: Map>, ) @@ -187,7 +181,8 @@ fun collectSources( // TODO: the scripts checking should be part of the scripting plugin functionality, as it is implemented now in ScriptingProcessSourcesBeforeCompilingExtension // TODO: implement in the next round of K2 scripting support (https://youtrack.jetbrains.com/issue/KT-55728) - val skipScriptsInLtMode = compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR) && compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE) + val skipScriptsInLtMode = compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR) && + compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE) var skipScriptsInLtModeWarning = false compilerConfiguration.kotlinSourceRoots.forAllFiles( @@ -308,122 +303,48 @@ fun compileModuleToAnalyzedFir( diagnosticsReporter: DiagnosticReporter, performanceManager: CommonCompilerPerformanceManager? ): 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 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 - )?.also { (_, _, precompiledBinariesFileScope) -> - precompiledBinariesFileScope?.let { librariesScope -= it } - } - } - val platformProviderAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( - moduleConfiguration, - projectEnvironment, - platformSourcesScope, - previousStepsSymbolProviders, - incrementalExcludesScope - )?.also { (_, _, precompiledBinariesFileScope) -> - precompiledBinariesFileScope?.let { librariesScope -= it } - } + val rootModuleName = input.targetId.name - val sessionProvider = FirProjectSessionProvider() - val moduleName = input.targetId.name - - val libraryList = createFirLibraryListAndSession( - moduleName, input.configuration, projectEnvironment, - scope = projectEnvironment.getSearchScopeForProjectLibraries(), - librariesScope = librariesScope, - friendPaths = emptyList(), - 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 extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) } + 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() - } - } - val javaSourcesScope = projectEnvironment.getSearchScopeForProjectJavaSources() - val commonSession = runIf(isMppEnabled) { - FirJvmSessionFactory.createModuleBasedSession( - commonModuleData!!, - sessionProvider, - javaSourcesScope, - projectEnvironment, - commonProviderAndScopeForIncrementalCompilation, - extensionRegistrars, - languageVersionSettings, - lookupTracker, - enumWhenTracker, - needRegisterJavaElementFinder = true, - registerExtraComponents = {}, - sessionConfigurator, - ) + val allSources = mutableListOf().apply { + addAll(input.groupedSources.commonSources) + addAll(input.groupedSources.platformSources) } - val platformSession = FirJvmSessionFactory.createModuleBasedSession( - platformModuleData, - sessionProvider, - javaSourcesScope, - projectEnvironment, - platformProviderAndScopeForIncrementalCompilation, - extensionRegistrars, - languageVersionSettings, - lookupTracker, - enumWhenTracker, - needRegisterJavaElementFinder = true, - registerExtraComponents = {}, - sessionConfigurator + // TODO: handle friends paths + val libraryList = createLibraryListForJvm(rootModuleName, moduleConfiguration, friendPaths = emptyList()) + val sessionWithSources = prepareJvmSessions( + allSources, moduleConfiguration, projectEnvironment, rootModuleName, + extensionRegistrars, librariesScope, libraryList, + isCommonSource = input.groupedSources.isCommonSourceForLt, + fileBelongsToModule = input.groupedSources.fileBelongsToModuleForLt, + createProviderAndScopeForIncrementalCompilation = { files -> + val scope = projectEnvironment.getSearchScopeBySourceFiles(files) + createContextForIncrementalCompilation( + moduleConfiguration, + projectEnvironment, + scope, + previousStepsSymbolProviders, + incrementalExcludesScope + )?.also { (_, _, precompiledBinariesFileScope) -> + precompiledBinariesFileScope?.let { librariesScope -= it } + } + } ) 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) - return FirResult(platformOutput, commonOutput) + val outputs = sessionWithSources.map { (session, sources) -> + buildResolveAndCheckFir(session, sources, diagnosticsReporter, countFilesAndLines) + } + + return FirResult(outputs) } private fun buildResolveAndCheckFir( diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt index b61596e56d8..3fc950ef7f0 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.cli.jvm.compiler.pipeline -import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector @@ -22,11 +21,9 @@ import org.jetbrains.kotlin.platform.TargetPlatform data class ModuleCompilerInput( val targetId: TargetId, + val groupedSources: GroupedKtSources, val commonPlatform: TargetPlatform, - val commonSources: Collection, val platform: TargetPlatform, - val platformSources: Collection, - val sourcesByModule: Map>, val configuration: CompilerConfiguration, val friendFirModules: Collection = emptyList() ) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/FirMetadataSerializer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/FirMetadataSerializer.kt index 9a96c795da1..ccd14d690fa 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/FirMetadataSerializer.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/FirMetadataSerializer.kt @@ -7,22 +7,25 @@ package org.jetbrains.kotlin.cli.metadata import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.VirtualFileManager -import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.* import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter -import org.jetbrains.kotlin.cli.jvm.compiler.* +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment +import org.jetbrains.kotlin.cli.jvm.compiler.createContextForIncrementalCompilation import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.collectSources import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.createContextForIncrementalCompilation +import org.jetbrains.kotlin.cli.jvm.compiler.toAbstractProjectEnvironment +import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots +import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory -import org.jetbrains.kotlin.fir.FirModuleDataImpl -import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers +import org.jetbrains.kotlin.fir.BinaryModuleData +import org.jetbrains.kotlin.fir.DependencyListForCliModule 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.packageFqName import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput @@ -32,23 +35,19 @@ import org.jetbrains.kotlin.fir.pipeline.resolveAndCheckFir import org.jetbrains.kotlin.fir.serialization.FirElementAwareSerializableStringTable import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile -import org.jetbrains.kotlin.fir.session.FirCommonSessionFactory -import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext -import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope import org.jetbrains.kotlin.library.SerializedMetadata import org.jetbrains.kotlin.library.metadata.KlibMetadataHeaderFlags import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf import org.jetbrains.kotlin.modules.TargetId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.CommonPlatforms -import org.jetbrains.kotlin.psi.KtFile import java.io.File internal class FirMetadataSerializer( configuration: CompilerConfiguration, environment: KotlinCoreEnvironment -) : AbstractMetadataSerializer(configuration, environment) { - override fun analyze(): ModuleCompilerAnalyzedOutput? { +) : AbstractMetadataSerializer>(configuration, environment) { + override fun analyze(): List? { val performanceManager = environment.configuration.getNotNull(CLIConfigurationKeys.PERF_MANAGER) performanceManager.notifyAnalysisStarted() @@ -57,23 +56,28 @@ internal class FirMetadataSerializer( val moduleName = Name.special("<${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>") val isLightTree = configuration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE) - val sessionProvider = FirProjectSessionProvider() + val rootModuleName = moduleName.asString() + val binaryModuleData = BinaryModuleData.initialize( + Name.identifier(rootModuleName), + CommonPlatforms.defaultCommonPlatform, + CommonPlatformAnalyzerServices + ) + val libraryList = DependencyListForCliModule.build(binaryModuleData) { + dependencies(configuration.jvmClasspathRoots.map { it.toPath() }) + dependencies(configuration.jvmModularRoots.map { it.toPath() }) + friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList()) + } - val projectEnvironment: VfsBasedProjectEnvironment - var librariesScope: AbstractProjectFileSearchScope - val sourceScope: AbstractProjectFileSearchScope - val librariesHelperScope: AbstractProjectFileSearchScope - var psiFiles: List? = null - var ltFiles: List? = null - val providerAndScopeForIncrementalCompilation: IncrementalCompilationContext? + val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter() - if (isLightTree) { - projectEnvironment = environment.toAbstractProjectEnvironment() as VfsBasedProjectEnvironment - librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() - librariesHelperScope = projectEnvironment.getSearchScopeForProjectLibraries() - ltFiles = collectSources(configuration, projectEnvironment, messageCollector).let { it.commonSources + it.platformSources }.toList() - sourceScope = projectEnvironment.getSearchScopeBySourceFiles(ltFiles) - providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( + val outputs = if (isLightTree) { + val projectEnvironment = environment.toAbstractProjectEnvironment() as VfsBasedProjectEnvironment + var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() + val groupedSources = collectSources(configuration, projectEnvironment, messageCollector) + val extensionRegistrars = FirExtensionRegistrar.getInstances(projectEnvironment.project) + val ltFiles = groupedSources.let { it.commonSources + it.platformSources }.toList() + val sourceScope = projectEnvironment.getSearchScopeBySourceFiles(ltFiles) + val providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( configuration, projectEnvironment, sourceScope, @@ -82,16 +86,26 @@ internal class FirMetadataSerializer( )?.also { (_, _, precompiledBinariesFileScope) -> precompiledBinariesFileScope?.let { librariesScope -= it } } + val sessionsWithSources = prepareCommonSessions( + ltFiles, configuration, projectEnvironment, rootModuleName, extensionRegistrars, + librariesScope, libraryList, groupedSources.isCommonSourceForLt, groupedSources.fileBelongsToModuleForLt, + createProviderAndScopeForIncrementalCompilation = { providerAndScopeForIncrementalCompilation } + ) + sessionsWithSources.map { (session, files) -> + val firFiles = session.buildFirViaLightTree(files, diagnosticsReporter, performanceManager::addSourcesStats) + resolveAndCheckFir(session, firFiles, diagnosticsReporter) + } } else { - projectEnvironment = VfsBasedProjectEnvironment( + val projectEnvironment = VfsBasedProjectEnvironment( environment.project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) ) { environment.createPackagePartProvider(it) } - librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() - librariesHelperScope = librariesScope - psiFiles = environment.getSourceFiles() - sourceScope = projectEnvironment.getSearchScopeByPsiFiles(psiFiles) + projectEnvironment.getSearchScopeForProjectJavaSources() - providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( + var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() + val extensionRegistrars = FirExtensionRegistrar.getInstances(projectEnvironment.project) + val psiFiles = environment.getSourceFiles() + val sourceScope = + projectEnvironment.getSearchScopeByPsiFiles(psiFiles) + projectEnvironment.getSearchScopeForProjectJavaSources() + val providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( projectEnvironment, configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS), configuration, @@ -101,80 +115,51 @@ internal class FirMetadataSerializer( providerAndScopeForIncrementalCompilation?.precompiledBinariesFileScope?.let { librariesScope -= it } + val sessionsWithSources = prepareCommonSessions( + psiFiles, configuration, projectEnvironment, rootModuleName, extensionRegistrars, + librariesScope, libraryList, isCommonSourceForPsi, fileBelongsToModuleForPsi, + createProviderAndScopeForIncrementalCompilation = { providerAndScopeForIncrementalCompilation } + ) + + sessionsWithSources.map { (session, files) -> + val firFiles = session.buildFirFromKtFiles(files) + resolveAndCheckFir(session, firFiles, diagnosticsReporter) + } } - val libraryList = createFirLibraryListAndSession( - moduleName.asString(), configuration, projectEnvironment, - scope = librariesHelperScope, librariesScope = librariesScope, friendPaths = emptyList(), sessionProvider = sessionProvider, - isJvm = false - ) - - val commonModuleData = FirModuleDataImpl( - moduleName, - libraryList.regularDependencies, - listOf(), - libraryList.friendsDependencies, - CommonPlatforms.defaultCommonPlatform, - CommonPlatformAnalyzerServices - ) - val project = projectEnvironment.project - val session = FirCommonSessionFactory.createModuleBasedSession( - commonModuleData, - sessionProvider, - sourceScope, - projectEnvironment, - incrementalCompilationContext = providerAndScopeForIncrementalCompilation, - FirExtensionRegistrar.getInstances(project), - configuration.languageVersionSettings, - lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER), - enumWhenTracker = configuration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER), - needRegisterJavaElementFinder = true, - registerExtraComponents = {}, - init = { - if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)) { - registerExtendedCommonCheckers() - } - } - ) - - val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter() - val firFiles = if (isLightTree) - session.buildFirViaLightTree(ltFiles!!, diagnosticsReporter, performanceManager::addSourcesStats) - else - session.buildFirFromKtFiles(psiFiles!!) - - val result = resolveAndCheckFir(session, firFiles, diagnosticsReporter) return if (diagnosticsReporter.hasErrors) { val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames) null } else { - result + outputs }.also { performanceManager.notifyAnalysisFinished() } } - override fun serialize(analysisResult: ModuleCompilerAnalyzedOutput, destDir: File) { + override fun serialize(analysisResult: List, destDir: File) { val fragments = mutableMapOf>() - val (session, scopeSession, fir) = analysisResult + for (output in analysisResult) { + val (session, scopeSession, fir) = output - val languageVersionSettings = environment.configuration.languageVersionSettings - for (firFile in fir) { - val packageFragment = serializeSingleFirFile( - firFile, - session, - scopeSession, - FirKLibSerializerExtension(session, metadataVersion, FirElementAwareSerializableStringTable()), - languageVersionSettings - ) - fragments.getOrPut(firFile.packageFqName.asString()) { mutableListOf() }.add(packageFragment.toByteArray()) + val languageVersionSettings = environment.configuration.languageVersionSettings + for (firFile in fir) { + val packageFragment = serializeSingleFirFile( + firFile, + session, + scopeSession, + FirKLibSerializerExtension(session, metadataVersion, FirElementAwareSerializableStringTable()), + languageVersionSettings + ) + fragments.getOrPut(firFile.packageFqName.asString()) { mutableListOf() }.add(packageFragment.toByteArray()) + } } val header = KlibMetadataProtoBuf.Header.newBuilder() - header.moduleName = session.moduleData.name.asString() + header.moduleName = analysisResult.last().session.moduleData.name.asString() if (configuration.languageVersionSettings.isPreRelease()) { header.flags = KlibMetadataHeaderFlags.PRE_RELEASE diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt index f791085c97b..b7face78118 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt @@ -24,10 +24,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.util.IdSignatureComposer import org.jetbrains.kotlin.ir.util.KotlinMangler -data class FirResult( - val platformOutput: ModuleCompilerAnalyzedOutput, - val commonOutput: ModuleCompilerAnalyzedOutput? -) +data class FirResult(val outputs: List) data class ModuleCompilerAnalyzedOutput( val session: FirSession, @@ -67,46 +64,58 @@ fun FirResult.convertToIrAndActualize( manglerCreator = { FirJvmKotlinMangler() } // TODO: replace with potentially simpler version for other backends. ) - if (commonOutput != null) { - val commonIrOutput = commonOutput.convertToIr( - fir2IrExtensions, - irGeneratorExtensions, - linkViaSignatures = linkViaSignatures, - commonMemberStorage = commonMemberStorage, - irBuiltIns = null, - irMangler, - visibilityConverter, - kotlinBuiltIns, - ).also { - fir2IrResultPostCompute(it) + when (outputs.size) { + 0 -> error("No modules found") + 1 -> { + result = outputs.single().convertToIr( + fir2IrExtensions, + irGeneratorExtensions, + linkViaSignatures = linkViaSignatures, + commonMemberStorage = commonMemberStorage, + irBuiltIns = null, + irMangler, + visibilityConverter, + kotlinBuiltIns, + ) } - result = platformOutput.convertToIr( - fir2IrExtensions, - irGeneratorExtensions, - linkViaSignatures = linkViaSignatures, - commonMemberStorage = commonMemberStorage, - irBuiltIns = commonIrOutput.components.irBuiltIns, - irMangler, - visibilityConverter, - kotlinBuiltIns, - ).also { - fir2IrResultPostCompute(it) + else -> { + val platformOutput = outputs.last() + val commonOutputs = outputs.dropLast(1) + var irBuiltIns: IrBuiltInsOverFir? = null + val commonIrOutputs = commonOutputs.map { + it.convertToIr( + fir2IrExtensions, + irGeneratorExtensions, + linkViaSignatures = linkViaSignatures, + commonMemberStorage = commonMemberStorage, + irBuiltIns = irBuiltIns, + irMangler, + visibilityConverter, + kotlinBuiltIns, + ).also { result -> + fir2IrResultPostCompute(result) + if (irBuiltIns == null) { + irBuiltIns = result.components.irBuiltIns + } + } + } + result = platformOutput.convertToIr( + fir2IrExtensions, + irGeneratorExtensions, + linkViaSignatures = linkViaSignatures, + commonMemberStorage = commonMemberStorage, + irBuiltIns = irBuiltIns!!, + irMangler, + visibilityConverter, + kotlinBuiltIns, + ).also { + fir2IrResultPostCompute(it) + } + IrActualizer.actualize( + result.irModuleFragment, + commonIrOutputs.map { it.irModuleFragment } + ) } - IrActualizer.actualize( - result.irModuleFragment, - listOf(commonIrOutput.irModuleFragment) - ) - } else { - result = platformOutput.convertToIr( - fir2IrExtensions, - irGeneratorExtensions, - linkViaSignatures = linkViaSignatures, - commonMemberStorage = commonMemberStorage, - irBuiltIns = null, - irMangler, - visibilityConverter, - kotlinBuiltIns, - ) } return result diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt index 1aabad28c79..63959d16ddc 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt @@ -37,7 +37,7 @@ object FirCommonSessionFactory : FirAbstractSessionFactory() { sessionProvider: FirProjectSessionProvider, moduleDataProvider: ModuleDataProvider, projectEnvironment: AbstractProjectEnvironment, - scope: AbstractProjectFileSearchScope, + librariesScope: AbstractProjectFileSearchScope, packageAndMetadataPartProvider: PackageAndMetadataPartProvider, languageVersionSettings: LanguageVersionSettings, registerExtraComponents: ((FirSession) -> Unit), @@ -59,7 +59,7 @@ object FirCommonSessionFactory : FirAbstractSessionFactory() { moduleDataProvider, kotlinScopeProvider, packageAndMetadataPartProvider, - projectEnvironment.getKotlinClassFinder(scope) + projectEnvironment.getKotlinClassFinder(librariesScope) ), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt index 7c5874eca20..05f16d5c99c 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS import org.jetbrains.kotlin.build.report.BuildReporter -import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments @@ -40,26 +39,15 @@ import org.jetbrains.kotlin.cli.jvm.config.* import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.backend.Fir2IrConverter -import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider -import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler -import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions -import org.jetbrains.kotlin.fir.languageVersionSettings -import org.jetbrains.kotlin.fir.moduleData import org.jetbrains.kotlin.fir.pipeline.FirResult -import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualizeForJvm -import org.jetbrains.kotlin.fir.resolve.providers.firProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.InlineConstTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler -import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents @@ -212,13 +200,18 @@ class IncrementalFirJvmCompilerRunner( fun firIncrementalCycle(): FirResult? { while (true) { val dirtySourcesByModuleName = sourcesByModuleName.mapValues { (_, sources) -> - sources.filter { dirtySources.any { df -> df.path == it.path } } + sources.filterTo(mutableSetOf()) { dirtySources.any { df -> df.path == it.path } } } + val groupedSource = GroupedKtSources( + commonSources = allCommonSourceFiles.filter { dirtySources.any { df -> df.path == it.path } }, + platformSources = allPlatformSourceFiles.filter { dirtySources.any { df -> df.path == it.path } }, + sourcesByModuleName = dirtySourcesByModuleName + ) val compilerInput = ModuleCompilerInput( targetId, - CommonPlatforms.defaultCommonPlatform, allCommonSourceFiles.filter { dirtySources.any { df -> df.path == it.path } }, - JvmPlatforms.unspecifiedJvmPlatform, allPlatformSourceFiles.filter { dirtySources.any { df -> df.path == it.path } }, - dirtySourcesByModuleName, + groupedSource, + CommonPlatforms.defaultCommonPlatform, + JvmPlatforms.unspecifiedJvmPlatform, configuration ) @@ -238,7 +231,7 @@ class IncrementalFirJvmCompilerRunner( // TODO: consider what to do if many compilations find a main class if (mainClassFqName == null && configuration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { - mainClassFqName = findMainClass(analysisResults.platformOutput.fir) + mainClassFqName = findMainClass(analysisResults.outputs.last().fir) } // TODO: switch the whole IC to KtSourceFile instead of FIle diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/incrementalFirCacheUtils.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/incrementalFirCacheUtils.kt index 5096871e96c..f8e41fde010 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/incrementalFirCacheUtils.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/incrementalFirCacheUtils.kt @@ -128,8 +128,9 @@ internal fun collectNewDirtySources( } } - analysisResults.commonOutput?.let { visitFirFiles(it) } - visitFirFiles(analysisResults.platformOutput) + for (output in analysisResults.outputs) { + visitFirFiles(output) + } val (dirtyLookupSymbols, dirtyClassFqNames, forceRecompile) = changesCollector.getDirtyData(listOf(caches.platformCache), reporter) diff --git a/compiler/testData/cli/js/successfulHmpp.args b/compiler/testData/cli/js/successfulHmpp.args new file mode 100644 index 00000000000..49ebe847950 --- /dev/null +++ b/compiler/testData/cli/js/successfulHmpp.args @@ -0,0 +1,15 @@ +$TESTDATA_DIR$/../jvm/hmpp/src/a.kt +$TESTDATA_DIR$/../jvm/hmpp/src/b.kt +$TESTDATA_DIR$/../jvm/hmpp/src/c.kt +-ir-output-dir +$TEMP_DIR$/out.js +-ir-output-name +fir-hmpp +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/../jvm/hmpp/src/a.kt +-Xmodule=b;$TESTDATA_DIR$/../jvm/hmpp/src/b.kt +-Xmodule=c;$TESTDATA_DIR$/../jvm/hmpp/src/c.kt +-XdependsOn=b\:a +-XdependsOn=c\:b diff --git a/compiler/testData/cli/js/successfulHmpp.out b/compiler/testData/cli/js/successfulHmpp.out new file mode 100644 index 00000000000..0afdba6a4b9 --- /dev/null +++ b/compiler/testData/cli/js/successfulHmpp.out @@ -0,0 +1,11 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +OK diff --git a/compiler/testData/cli/jvm/hmpp/successfulCompilation.args b/compiler/testData/cli/jvm/hmpp/successfulCompilation.args new file mode 100644 index 00000000000..2f85029e0e6 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/successfulCompilation.args @@ -0,0 +1,13 @@ +$TESTDATA_DIR$/src/a.kt +$TESTDATA_DIR$/src/b.kt +$TESTDATA_DIR$/src/c.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/src/a.kt +-Xmodule=b;$TESTDATA_DIR$/src/b.kt +-Xmodule=c;$TESTDATA_DIR$/src/c.kt +-XdependsOn=b\:a +-XdependsOn=c\:b diff --git a/compiler/testData/cli/jvm/hmpp/successfulCompilation.out b/compiler/testData/cli/jvm/hmpp/successfulCompilation.out new file mode 100644 index 00000000000..0afdba6a4b9 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/successfulCompilation.out @@ -0,0 +1,11 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +OK diff --git a/compiler/testData/cli/metadata/successfulHmpp.args b/compiler/testData/cli/metadata/successfulHmpp.args new file mode 100644 index 00000000000..a7abbafbb0c --- /dev/null +++ b/compiler/testData/cli/metadata/successfulHmpp.args @@ -0,0 +1,13 @@ +$TESTDATA_DIR$/../jvm/hmpp/src/a.kt +$TESTDATA_DIR$/../jvm/hmpp/src/b.kt +$TESTDATA_DIR$/../jvm/hmpp/src/c.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/../jvm/hmpp/src/a.kt +-Xmodule=b;$TESTDATA_DIR$/../jvm/hmpp/src/b.kt +-Xmodule=c;$TESTDATA_DIR$/../jvm/hmpp/src/c.kt +-XdependsOn=b\:a +-XdependsOn=c\:b diff --git a/compiler/testData/cli/metadata/successfulHmpp.out b/compiler/testData/cli/metadata/successfulHmpp.out new file mode 100644 index 00000000000..0afdba6a4b9 --- /dev/null +++ b/compiler/testData/cli/metadata/successfulHmpp.out @@ -0,0 +1,11 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +OK diff --git a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java index 61b95099809..35a2d2955db 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -166,6 +166,11 @@ public class CliTestGenerated extends AbstractCliTest { public void testSourceNotInAnyModule() throws Exception { runTest("compiler/testData/cli/jvm/hmpp/sourceNotInAnyModule.args"); } + + @TestMetadata("successfulCompilation.args") + public void testSuccessfulCompilation() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/successfulCompilation.args"); + } } @TestMetadata("compiler/testData/cli/jvm") @@ -1453,6 +1458,11 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/js/sourceMapRootMultiple.args"); } + @TestMetadata("successfulHmpp.args") + public void testSuccessfulHmpp() throws Exception { + runTest("compiler/testData/cli/js/successfulHmpp.args"); + } + @TestMetadata("suppressAllWarningsJS.args") public void testSuppressAllWarningsJS() throws Exception { runTest("compiler/testData/cli/js/suppressAllWarningsJS.args"); @@ -1618,5 +1628,10 @@ public class CliTestGenerated extends AbstractCliTest { public void testOptionalExpectationUsageWithFir() throws Exception { runTest("compiler/testData/cli/metadata/optionalExpectationUsageWithFir.args"); } + + @TestMetadata("successfulHmpp.args") + public void testSuccessfulHmpp() throws Exception { + runTest("compiler/testData/cli/metadata/successfulHmpp.args"); + } } } 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 49176c23aa7..47e4f06b107 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 @@ -3,42 +3,31 @@ package org.jetbrains.kotlin.backend.konan 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.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.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.* -import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers +import org.jetbrains.kotlin.fir.BinaryModuleData +import org.jetbrains.kotlin.fir.DependencyListForCliModule 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.FirNativeSessionFactory -import org.jetbrains.kotlin.fir.session.FirSessionConfigurator +import org.jetbrains.kotlin.fir.pipeline.FirResult +import org.jetbrains.kotlin.fir.pipeline.buildResolveAndCheckFir +import org.jetbrains.kotlin.fir.render 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 -): FirOutput { +internal fun PhaseContext.firFrontend(input: KotlinCoreEnvironment): 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 sessionProvider = FirProjectSessionProvider() val extensionRegistrars = FirExtensionRegistrar.getInstances(input.project) - val sessionConfigurator: FirSessionConfigurator.() -> Unit = { - if (configuration.languageVersionSettings.getFlag(AnalysisFlags.extendedCompilerChecks)) { - registerExtendedCommonCheckers() - } - } val mainModuleName = Name.special("<${config.moduleId}>") val ktFiles = input.getSourceFiles() val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile -> @@ -51,57 +40,24 @@ internal fun PhaseContext.firFrontend( // TODO: !!! dependencies module data? } val resolvedLibraries: List = config.resolvedLibraries.getFullResolvedList() - FirNativeSessionFactory.createLibrarySession( - mainModuleName, - resolvedLibraries, - sessionProvider, - dependencyList.moduleDataProvider, - configuration.languageVersionSettings, - registerExtraComponents = {}, + + val sessionsWithSources = prepareNativeSessions( + ktFiles, configuration, mainModuleName.asString(), resolvedLibraries, dependencyList, + extensionRegistrars, isCommonSourceForPsi, fileBelongsToModuleForPsi ) - 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) + val outputs = sessionsWithSources.map { (session, sources) -> + buildResolveAndCheckFir(session, sources, diagnosticsReporter).also { + if (shouldPrintFiles()) { + it.fir.forEach { println(it.render()) } + } + } } return if (syntaxErrors || diagnosticsReporter.hasErrors) { FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames) FirOutput.ShouldNotGenerateCode } else { - FirOutput.Full(firResult) + FirOutput.Full(FirResult(outputs)) } } 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 d126257a03f..5b86ac19f46 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 @@ -17,7 +17,10 @@ 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.fir.serialization.FirElementAwareSerializableStringTable +import org.jetbrains.kotlin.fir.serialization.FirElementSerializer +import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension +import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.IrMessageLogger @@ -26,11 +29,10 @@ import org.jetbrains.kotlin.library.SerializedIrFile import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.metadata.ProtoBuf -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 +import org.jetbrains.kotlin.utils.toMetadataVersion internal fun PhaseContext.firSerializer( input: Fir2IrOutput @@ -39,7 +41,7 @@ internal fun PhaseContext.firSerializer( val sourceFiles = mutableListOf() val firFilesAndSessionsBySourceFile = mutableMapOf>() - for (firOutput in listOfNotNull(input.firResult.commonOutput, input.firResult.platformOutput)) { + for (firOutput in input.firResult.outputs) { for (firFile in firOutput.fir) { sourceFiles.add(firFile.sourceFile!!) firFilesAndSessionsBySourceFile[firFile.sourceFile!!] = Triple(firFile, firOutput.session, firOutput.scopeSession) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt index 98ed550b1c3..503d0d3a9fe 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt @@ -7,8 +7,7 @@ package org.jetbrains.kotlin.scripting.compiler.plugin.impl import org.jetbrains.kotlin.KtPsiSourceFile import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage +import org.jetbrains.kotlin.cli.common.* import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter import org.jetbrains.kotlin.cli.common.fir.reportToMessageCollector import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport @@ -26,20 +25,14 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory -import org.jetbrains.kotlin.fir.FirModuleDataImpl -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.* -import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.modules.TargetId -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.CommonPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension -import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptCompilerProxy import org.jetbrains.kotlin.scripting.compiler.plugin.dependencies.ScriptsCompilationDependencies import org.jetbrains.kotlin.scripting.compiler.plugin.services.scriptDefinitionProviderService @@ -108,16 +101,17 @@ private fun withScriptCompilationCache( messageCollector: ScriptDiagnosticsMessageCollector, body: () -> ResultWithDiagnostics ): ResultWithDiagnostics { - val cache = scriptCompilationConfiguration[ScriptCompilationConfiguration.hostConfiguration]?.get(ScriptingHostConfiguration.jvm.compilationCache) + val cache = scriptCompilationConfiguration[ScriptCompilationConfiguration.hostConfiguration] + ?.get(ScriptingHostConfiguration.jvm.compilationCache) val cached = cache?.get(script, scriptCompilationConfiguration) - return if (cached != null) cached.asSuccess(messageCollector.diagnostics) - else body().also { - if (cache != null && it is ResultWithDiagnostics.Success) { - cache.store(it.value, script, scriptCompilationConfiguration) + return cached?.asSuccess(messageCollector.diagnostics) + ?: body().also { + if (cache != null && it is ResultWithDiagnostics.Success) { + cache.store(it.value, script, scriptCompilationConfiguration) + } } - } } private fun compileImpl( @@ -312,7 +306,6 @@ private fun doCompileWithK2( messageCollector: ScriptDiagnosticsMessageCollector, getScriptConfiguration: (KtFile) -> ScriptCompilationConfiguration ): ResultWithDiagnostics { - val syntaxErrors = sourceFiles.fold(false) { errorsFound, ktFile -> AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound } @@ -337,9 +330,9 @@ private fun doCompileWithK2( val compilerInput = ModuleCompilerInput( targetId, - CommonPlatforms.defaultCommonPlatform, emptyList(), - JvmPlatforms.unspecifiedJvmPlatform, sources, - sourcesByModule = emptyMap(), + GroupedKtSources(platformSources = sources, commonSources = emptySet(), sourcesByModuleName = emptyMap()), + CommonPlatforms.defaultCommonPlatform, + JvmPlatforms.unspecifiedJvmPlatform, kotlinCompilerConfiguration ) @@ -347,9 +340,6 @@ private fun doCompileWithK2( val compilerEnvironment = ModuleCompilerEnvironment(projectEnvironment, diagnosticsReporter) val sourcesScope = compilerEnvironment.projectEnvironment.getSearchScopeBySourceFiles(sources) - val sessionProvider = FirProjectSessionProvider() - val extendedAnalysisMode = kotlinCompilerConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS) - var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() val providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( compilerInput.configuration, @@ -360,41 +350,22 @@ private fun doCompileWithK2( )?.also { (_, _, precompiledBinariesFileScope) -> precompiledBinariesFileScope?.let { librariesScope -= it } } - val libraryList = createFirLibraryListAndSession( - targetId.name, + + val extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment) + ?.let { FirExtensionRegistrar.getInstances(it.project) } + .orEmpty() + + val rootModuleName = targetId.name + val libraryList = createLibraryListForJvm( + rootModuleName, kotlinCompilerConfiguration, - projectEnvironment, - scope = projectEnvironment.getSearchScopeForProjectLibraries(), - librariesScope = librariesScope, - friendPaths = emptyList(), - sessionProvider + friendPaths = emptyList() ) - val moduleData = FirModuleDataImpl( - Name.identifier(targetId.name), - libraryList.regularDependencies, - listOf(), - libraryList.friendsDependencies, - JvmPlatforms.unspecifiedJvmPlatform, - JvmPlatformAnalyzerServices - ) - val session = FirJvmSessionFactory.createModuleBasedSession( - moduleData, - sessionProvider, - sourcesScope, - projectEnvironment, - providerAndScopeForIncrementalCompilation, - extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) } - ?: emptyList(), - kotlinCompilerConfiguration.languageVersionSettings, - lookupTracker = kotlinCompilerConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER), - enumWhenTracker = kotlinCompilerConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER), - needRegisterJavaElementFinder = true, - registerExtraComponents = {}, - ) { - if (extendedAnalysisMode) { - registerExtendedCommonCheckers() - } - } + val session = prepareJvmSessions( + sourceFiles, kotlinCompilerConfiguration, projectEnvironment, rootModuleName, extensionRegistrars, + librariesScope, libraryList, isCommonSourceForPsi, fileBelongsToModuleForPsi, + createProviderAndScopeForIncrementalCompilation = { providerAndScopeForIncrementalCompilation } + ).single().session session.scriptDefinitionProviderService?.run { definitionProvider = ScriptDefinitionProvider.getInstance(context.environment.project) @@ -407,7 +378,7 @@ private fun doCompileWithK2( // checkers session.runCheckers(scopeSession, fir, diagnosticsReporter) - val analysisResults = FirResult(ModuleCompilerAnalyzedOutput(session, scopeSession, fir), null) + val analysisResults = FirResult(listOf(ModuleCompilerAnalyzedOutput(session, scopeSession, fir))) if (diagnosticsReporter.hasErrors) { diagnosticsReporter.reportToMessageCollector(messageCollector, renderDiagnosticName)