diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmPackagePartProvider.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmPackagePartProvider.kt index 26d1e453bc4..dfa5d15c826 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmPackagePartProvider.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmPackagePartProvider.kt @@ -38,7 +38,7 @@ class JvmPackagePartProvider( languageVersionSettings: LanguageVersionSettings, private val scope: GlobalSearchScope ) : JvmPackagePartProviderBase() { - private val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings) + override val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings) override val loadedModules: MutableList> = SmartList() 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 6ca6ce328a6..c378d68e495 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 @@ -61,6 +61,7 @@ import org.jetbrains.kotlin.fir.createSessionWithDependencies import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries import org.jetbrains.kotlin.javac.JavacWrapper import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager +import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider import org.jetbrains.kotlin.modules.Module import org.jetbrains.kotlin.modules.TargetId import org.jetbrains.kotlin.name.FqName @@ -308,6 +309,8 @@ object KotlinToJVMBytecodeCompiler { val projectConfiguration = environment.configuration val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) val outputs = newLinkedHashMapWithExpectedSize(chunk.size) + val targetIds = environment.configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId) + val incrementalComponents = environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) for (module in chunk) { performanceManager?.notifyAnalysisStarted() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() @@ -334,7 +337,14 @@ object KotlinToJVMBytecodeCompiler { sourceScope, librariesScope, lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER), - environment::createPackagePartProvider + getPackagePartProvider = { environment.createPackagePartProvider(it) }, + getAdditionalModulePackagePartProvider = { + if (targetIds == null || incrementalComponents == null) null + else IncrementalPackagePartProvider( + environment.createPackagePartProvider(it), + targetIds.map(incrementalComponents::getIncrementalCache) + ) + } ) { if (extendedAnalysisMode) { registerExtendedCommonCheckers() diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt index e8373e30e03..47a9db8b2d3 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt @@ -217,7 +217,7 @@ object TopDownAnalyzerFacadeForJVM { val partProvider = packagePartProvider(sourceScope).let { fragment -> if (targetIds == null || incrementalComponents == null) fragment - else IncrementalPackagePartProvider(fragment, targetIds.map(incrementalComponents::getIncrementalCache), storageManager) + else IncrementalPackagePartProvider(fragment, targetIds.map(incrementalComponents::getIncrementalCache)) } // Note that it's necessary to create container for sources _after_ creation of container for dependencies because diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt index 336bcb72e9b..19624e17e29 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt @@ -19,8 +19,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers import org.jetbrains.kotlin.fir.analysis.checkersComponent import org.jetbrains.kotlin.fir.analysis.extensions.additionalCheckers -import org.jetbrains.kotlin.fir.caches.FirCachesFactory -import org.jetbrains.kotlin.fir.caches.FirThreadUnsafeCachesFactory import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers import org.jetbrains.kotlin.fir.checkers.registerJvmCheckers import org.jetbrains.kotlin.fir.extensions.BunchOfRegisteredExtensions @@ -67,6 +65,8 @@ object FirSessionFactory { sessionProvider: FirProjectSessionProvider, scope: GlobalSearchScope, project: Project, + additionalPackagePartProvider: PackagePartProvider? = null, + additionalScope: GlobalSearchScope? = null, dependenciesProvider: FirSymbolProvider? = null, languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, lookupTracker: LookupTracker? = null, @@ -83,14 +83,25 @@ object FirSessionFactory { val firProvider = FirProviderImpl(this, kotlinScopeProvider) register(FirProvider::class, firProvider) + val deserializedJvmSymbolsProvider = + if (additionalPackagePartProvider == null) null + else { + val javaSymbolProvider = JavaSymbolProvider(this, project, additionalScope ?: scope) + + makeDeserializedJvmSymbolsProvider( + project, additionalScope ?: scope, additionalPackagePartProvider, javaSymbolProvider, kotlinScopeProvider + ) + } + register( FirSymbolProvider::class, FirCompositeSymbolProvider( this, - listOf( + listOfNotNull( firProvider.symbolProvider, JavaSymbolProvider(this, project, scope), - dependenciesProvider ?: FirDependenciesSymbolProviderImpl(this) + dependenciesProvider ?: FirDependenciesSymbolProviderImpl(this), + deserializedJvmSymbolsProvider ) ) as FirSymbolProvider ) @@ -113,12 +124,6 @@ object FirSessionFactory { packagePartProvider: PackagePartProvider, languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, ): FirLibrarySession { - val javaClassFinder = JavaClassFinderImpl().apply { - this.setProjectInstance(project) - this.setScope(scope) - } - - val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(scope) return FirLibrarySession(moduleInfo, sessionProvider).apply { registerThreadUnsafeCaches() registerCommonComponents(languageVersionSettings) @@ -127,17 +132,14 @@ object FirSessionFactory { val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) + val deserializedJvmSymbolsProvider = makeDeserializedJvmSymbolsProvider( + project, scope, packagePartProvider, javaSymbolProvider, kotlinScopeProvider + ) + val symbolProvider = FirCompositeSymbolProvider( this, listOf( - KotlinDeserializedJvmSymbolsProvider( - this, project, - packagePartProvider, - javaSymbolProvider, - kotlinClassFinder, - javaClassFinder, - kotlinScopeProvider - ), + deserializedJvmSymbolsProvider, FirBuiltinSymbolProvider(this, kotlinScopeProvider), FirCloneableSymbolProvider(this, kotlinScopeProvider), javaSymbolProvider, @@ -149,6 +151,25 @@ object FirSessionFactory { } } + private fun FirSession.makeDeserializedJvmSymbolsProvider( + project: Project, + scope: GlobalSearchScope, + packagePartProvider: PackagePartProvider, + javaSymbolProvider: JavaSymbolProvider, + kotlinScopeProvider: KotlinScopeProvider + ): KotlinDeserializedJvmSymbolsProvider { + + val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(scope) + val javaClassFinder = JavaClassFinderImpl().apply { + this.setProjectInstance(project) + this.setScope(scope) + } + + return KotlinDeserializedJvmSymbolsProvider( + this, project, packagePartProvider, javaSymbolProvider, kotlinClassFinder, javaClassFinder, kotlinScopeProvider + ) + } + @TestOnly fun createEmptySession(): FirSession { return object : FirSession(null) {} diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/sessionCreationUtils.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/sessionCreationUtils.kt index 737d5d43caf..ea85e4f2936 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/sessionCreationUtils.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/sessionCreationUtils.kt @@ -26,7 +26,8 @@ fun createSessionWithDependencies( sourceScope: GlobalSearchScope, librariesScope: GlobalSearchScope, lookupTracker: LookupTracker?, - packagePartProvider: (GlobalSearchScope) -> PackagePartProvider, + getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider, + getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?, sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {} ): FirSession { return createSessionWithDependencies( @@ -36,7 +37,8 @@ fun createSessionWithDependencies( sourceScope, librariesScope, lookupTracker, - packagePartProvider, + getPackagePartProvider, + getAdditionalModulePackagePartProvider, sessionConfigurator ) { FirJvmModuleInfo(name, it, friendPaths, outputDirectory) @@ -50,7 +52,8 @@ fun createSessionWithDependencies( sourceScope: GlobalSearchScope, librariesScope: GlobalSearchScope, lookupTracker: LookupTracker?, - packagePartProvider: (GlobalSearchScope) -> PackagePartProvider, + getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider, + getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?, sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {} ): FirSession { return createSessionWithDependencies( @@ -60,7 +63,8 @@ fun createSessionWithDependencies( sourceScope, librariesScope, lookupTracker, - packagePartProvider, + getPackagePartProvider, + getAdditionalModulePackagePartProvider, sessionConfigurator ) { FirJvmModuleInfo(module, it) @@ -74,7 +78,8 @@ private inline fun createSessionWithDependencies( sourceScope: GlobalSearchScope, librariesScope: GlobalSearchScope, lookupTracker: LookupTracker?, - packagePartProvider: (GlobalSearchScope) -> PackagePartProvider, + getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider, + getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?, noinline sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit, moduleInfoProvider: (dependencies: List) -> ModuleInfo, ): FirSession { @@ -82,13 +87,15 @@ private inline fun createSessionWithDependencies( val librariesModuleInfo = FirJvmModuleInfo.createForLibraries(moduleName) FirSessionFactory.createLibrarySession( librariesModuleInfo, provider, librariesScope, - project, packagePartProvider(librariesScope) + project, getPackagePartProvider(librariesScope) ) return FirSessionFactory.createJavaModuleBasedSession( moduleInfoProvider(listOf(librariesModuleInfo)), provider, sourceScope, project, + additionalPackagePartProvider = getAdditionalModulePackagePartProvider(sourceScope), + additionalScope = librariesScope, languageVersionSettings = languageVersionSettings, lookupTracker = lookupTracker, init = sessionConfigurator diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt index 4e439270dd0..170c98bd1bd 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt @@ -24,16 +24,21 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.serialization.deserialization.ClassData import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration -import org.jetbrains.kotlin.storage.StorageManager class IncrementalPackagePartProvider( private val parent: PackagePartProvider, - incrementalCaches: List, - storageManager: StorageManager + incrementalCaches: List ) : PackagePartProvider { + lateinit var deserializationConfiguration: DeserializationConfiguration - private val moduleMappings = storageManager.createLazyValue { + init { + (parent as? JvmPackagePartProviderBase<*>)?.deserializationConfiguration?.let { + deserializationConfiguration = it + } + } + + private val moduleMappings by lazy { incrementalCaches.map { cache -> ModuleMapping.loadModuleMapping(cache.getModuleMappingData(), "", deserializationConfiguration) { version -> // Incremental compilation should fall back to full rebuild if the minor component of the metadata version has changed @@ -43,7 +48,7 @@ class IncrementalPackagePartProvider( } override fun findPackageParts(packageFqName: String): List { - return (moduleMappings().mapNotNull { it.findPackageParts(packageFqName) }.flatMap { it.parts } + + return (moduleMappings.mapNotNull { it.findPackageParts(packageFqName) }.flatMap { it.parts } + parent.findPackageParts(packageFqName)).distinct() } @@ -52,6 +57,6 @@ class IncrementalPackagePartProvider( } override fun getAllOptionalAnnotationClasses(): List = - moduleMappings().flatMap((JvmPackagePartProviderBase)::getAllOptionalAnnotationClasses) + + moduleMappings.flatMap((JvmPackagePartProviderBase)::getAllOptionalAnnotationClasses) + parent.getAllOptionalAnnotationClasses() } diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt index 47472666bed..5aef406b700 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt @@ -104,7 +104,7 @@ object GenerationUtils { val scope = GlobalSearchScope.filesScope(project, files.map { it.virtualFile }) .uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project)) val librariesScope = ProjectScope.getLibrariesScope(project) - val session = createSessionForTests(project, scope, librariesScope, "main", packagePartProvider = packagePartProvider) + val session = createSessionForTests(project, scope, librariesScope, "main", getPackagePartProvider = packagePartProvider) // TODO: add running checkers and check that it's safe to compile val firAnalyzerFacade = FirAnalyzerFacade(session, configuration.languageVersionSettings, files) diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt index f84b69e681b..e60569c2b50 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt @@ -37,7 +37,8 @@ fun createSessionForTests( moduleName: String = "TestModule", friendPaths: List = emptyList(), lookupTracker: LookupTracker? = null, - packagePartProvider: (GlobalSearchScope) -> PackagePartProvider + getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider, + getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider? = { null } ): FirSession { return createSessionWithDependencies( Name.identifier(moduleName), @@ -48,7 +49,8 @@ fun createSessionForTests( sourceScope, librariesScope, lookupTracker, - packagePartProvider + getPackagePartProvider, + getAdditionalModulePackagePartProvider ) } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt index ca97263b9fd..262434cff81 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping import org.jetbrains.kotlin.metadata.jvm.deserialization.PackageParts import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.serialization.deserialization.ClassData +import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider abstract class JvmPackagePartProviderBase : PackagePartProvider, MetadataPartProvider { @@ -18,6 +19,8 @@ abstract class JvmPackagePartProviderBase : PackagePartProvider, Me protected abstract val loadedModules: MutableList> + abstract val deserializationConfiguration : DeserializationConfiguration + override fun findPackageParts(packageFqName: String): List { val rootToPackageParts: Collection = getPackageParts(packageFqName) if (rootToPackageParts.isEmpty()) return emptyList() diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/PackagePartFromClassLoaderProvider.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/PackagePartFromClassLoaderProvider.kt index 2d74aee7286..75ccd4447c4 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/PackagePartFromClassLoaderProvider.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/PackagePartFromClassLoaderProvider.kt @@ -19,7 +19,7 @@ class PackagePartFromClassLoaderProvider( languageVersionSettings: LanguageVersionSettings, messageCollector: MessageCollector ) : JvmPackagePartProviderBase() { - private val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings) + override val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings) override val loadedModules: MutableList> = SmartList()