diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt index 0f8debf4ea5..21774e03b98 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveCompone import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createPackagePartProviderForLibrary import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createSealedInheritorsProvider -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCacheImpl import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.FirThreadSafeCachesFactory import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirKtModuleBasedModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirBuiltinsModuleData @@ -213,7 +212,6 @@ internal object LLFirSessionFactory { configureSession: (LLFirSession.() -> Unit)?, ): LLFirLibrariesSession = librariesCache.cached(sourceModule) { checkCanceled() - val searchScope = project.moduleScopeProvider.getModuleLibrariesScope(sourceModule) LLFirLibrariesSession(project, builtinTypes).apply session@{ registerModuleData(LLFirKtModuleBasedModuleData(sourceModule).apply { bindSession(this@session) }) registerIdeComponents(project) @@ -225,32 +223,24 @@ internal object LLFirSessionFactory { val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped) register(FirKotlinScopeProvider::class, kotlinScopeProvider) - val moduleDataProvider = createModuleDataProviderWithLibraryDependencies(sourceModule, this) - val packagePartProvider = project.createPackagePartProviderForLibrary(searchScope) - val classFileBasedSymbolProvider = JvmClassFileBasedSymbolProvider( - this@session, - moduleDataProvider = moduleDataProvider, - kotlinScopeProvider = kotlinScopeProvider, - packagePartProvider = packagePartProvider, - kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope), - javaFacade = LLFirJavaFacadeForBinaries( - this@session, - builtinTypes, - project.createJavaClassFinder(searchScope), - moduleDataProvider - ) - ) - val optionalAnnotationClassesProvider = OptionalAnnotationClassesProvider( + val providers = createProvidersByModulePrimaryDependencies( this, - moduleDataProvider, + sourceModule, kotlinScopeProvider, - packagePartProvider + project, + builtinTypes + ) { binaryDependencies -> + GlobalSearchScope.union(binaryDependencies.map { it.contentScope }) + } + + + val symbolProvider = FirCompositeSymbolProvider( + this, + buildList { + addAll(providers) + add(builtinsAndCloneableSession.symbolProvider) + } ) - val symbolProvider = - FirCompositeSymbolProvider( - this, - listOf(classFileBasedSymbolProvider, optionalAnnotationClassesProvider, builtinsAndCloneableSession.symbolProvider) - ) register(FirProvider::class, LLFirLibrariesSessionProvider(symbolProvider)) register(FirSymbolProvider::class, symbolProvider) register(FirJvmTypeMapper::class, FirJvmTypeMapper(this)) @@ -258,28 +248,50 @@ internal object LLFirSessionFactory { } } - private fun createModuleDataProviderWithLibraryDependencies(sourceModule: KtModule, session: LLFirSession): ModuleDataProvider { - val regularDependenciesOnLibs = - sourceModule.directRegularDependenciesOfType().map { LLFirKtModuleBasedModuleData(it) } - val friendDependenciesOnLibs = - sourceModule.directFriendDependenciesOfType().map { LLFirKtModuleBasedModuleData(it) } - val dependsOnDependenciesOnLibs = - sourceModule.directRefinementDependenciesOfType().map { LLFirKtModuleBasedModuleData(it) } + private fun createProvidersByModulePrimaryDependencies( + session: LLFirSession, + module: KtModule, + kotlinScopeProvider: FirKotlinScopeProvider, + project: Project, + builtinTypes: BuiltinTypes, + createSearchScopeForModules: (List) -> GlobalSearchScope + ): List = buildList { + module + .allDirectDependenciesOfType() + .groupBy { it.platform } + .forEach { (_, binaryDependencies) -> + val moduleDataProvider = createModuleDataProviderWithLibraryDependencies(module, binaryDependencies, session) + val scope = createSearchScopeForModules(binaryDependencies) + val packagePartProvider = project.createPackagePartProviderForLibrary(scope) + add( + JvmClassFileBasedSymbolProvider( + session, + moduleDataProvider, + kotlinScopeProvider, + packagePartProvider, + VirtualFileFinderFactory.getInstance(project).create(scope), + LLFirJavaFacadeForBinaries(session, builtinTypes, project.createJavaClassFinder(scope), moduleDataProvider) + ) + ) + add(OptionalAnnotationClassesProvider(session, moduleDataProvider, kotlinScopeProvider, packagePartProvider)) + } + } - val allDependencies = buildList { - addAll(regularDependenciesOnLibs) - addAll(friendDependenciesOnLibs) - addAll(dependsOnDependenciesOnLibs) - } + private fun createModuleDataProviderWithLibraryDependencies( + sourceModule: KtModule, + binaryDependencies: List, + session: LLFirSession + ): ModuleDataProvider { + val moduleDatas = binaryDependencies.map { LLFirKtModuleBasedModuleData(it) } - if (allDependencies.isEmpty()) { + if (moduleDatas.isEmpty()) { return EmptyModuleDataProvider(sourceModule.platform, sourceModule.analyzerServices) } - allDependencies.forEach { it.bindSession(session) } + moduleDatas.forEach { it.bindSession(session) } val moduleDataWithFilters: Map = - allDependencies.associateWith { moduleData -> + moduleDatas.associateWith { moduleData -> checkIsInstance(moduleData) val ktBinaryModule = moduleData.ktModule as KtBinaryModule val moduleBinaryRoots = ktBinaryModule.getBinaryRoots().mapTo(mutableSetOf()) { it.toAbsolutePath() } @@ -375,32 +387,8 @@ internal object LLFirSessionFactory { val dependentProviders = buildList { val librariesSearchScope = ProjectScope.getLibrariesScope(project) .intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope)) // - - val packagePartProvider = project.createPackagePartProviderForLibrary(librariesSearchScope) add(builtinsAndCloneableSession.symbolProvider) - val libraryDependenciesModuleDataProvider = createModuleDataProviderWithLibraryDependencies(module, this@session) - add( - JvmClassFileBasedSymbolProvider( - this@session, - moduleDataProvider = libraryDependenciesModuleDataProvider, - kotlinScopeProvider = scopeProvider, - packagePartProvider = packagePartProvider, - kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(librariesSearchScope), - javaFacade = LLFirJavaFacadeForBinaries( - this@session, - builtinTypes, - project.createJavaClassFinder(librariesSearchScope), - libraryDependenciesModuleDataProvider - ) - ) - ) - add( - OptionalAnnotationClassesProvider( - this@session, - moduleDataProvider = libraryDependenciesModuleDataProvider, - kotlinScopeProvider = scopeProvider, - packagePartProvider = packagePartProvider, - ) - ) + addAll(createProvidersByModulePrimaryDependencies(session, module, scopeProvider, project, builtinTypes) { librariesSearchScope }) } // We need FirRegisteredPluginAnnotations during extensions' registration process