[AA] Introduce `KotlinGlobalSearchScopeMerger` platform component - The scope merger allows LL FIR to access scope merge logic provided by the Analysis API platform. ^KT-57733
diff --git a/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/declarations/KotlinDeclarationProviderFactory.kt b/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/declarations/KotlinDeclarationProviderFactory.kt index c9bded4..2baa55d 100644 --- a/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/declarations/KotlinDeclarationProviderFactory.kt +++ b/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/declarations/KotlinDeclarationProviderFactory.kt
@@ -38,6 +38,9 @@ * Hence, [KotlinDeclarationProvider]s cannot just be combined by combining the scopes of all declaration providers and calling * [createDeclarationProvider]. [KotlinDeclarationProviderMerger] should implement proper merging logic that takes these concerns into * account. + * + * The provider merger should consider merging scopes with [KotlinGlobalSearchScopeMerger][org.jetbrains.kotlin.analysis.api.platform.projectStructure.KotlinGlobalSearchScopeMerger] + * if there is a useful implementation provided by the platform. */ public interface KotlinDeclarationProviderMerger : KotlinComposableProviderMerger<KotlinDeclarationProvider>, KotlinPlatformComponent { public companion object {
diff --git a/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/packages/KotlinPackageProviderFactory.kt b/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/packages/KotlinPackageProviderFactory.kt index 5d1e13e..9b8fceb 100644 --- a/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/packages/KotlinPackageProviderFactory.kt +++ b/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/packages/KotlinPackageProviderFactory.kt
@@ -33,6 +33,9 @@ * * Package providers should not be naively merged by combining scopes and calling [createPackageProvider], because there may be additional * package providers which do not operate based on scopes (e.g. resolve extension package providers). + * + * The provider merger should consider merging scopes with [KotlinGlobalSearchScopeMerger][org.jetbrains.kotlin.analysis.api.platform.projectStructure.KotlinGlobalSearchScopeMerger] + * if there is a useful implementation provided by the platform. */ public interface KotlinPackageProviderMerger : KotlinComposableProviderMerger<KotlinPackageProvider>, KotlinPlatformComponent { public companion object {
diff --git a/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/projectStructure/KotlinGlobalSearchScopeMerger.kt b/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/projectStructure/KotlinGlobalSearchScopeMerger.kt new file mode 100644 index 0000000..d7883fb --- /dev/null +++ b/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/projectStructure/KotlinGlobalSearchScopeMerger.kt
@@ -0,0 +1,28 @@ +/* + * Copyright 2010-2024 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.analysis.api.platform.projectStructure + +import com.intellij.openapi.components.service +import com.intellij.openapi.project.Project +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.analysis.api.platform.KotlinPlatformComponent + +/** + * Merges [GlobalSearchScope]s according to platform-specific strategies with the goal of creating an optimized combined scope. If possible, + * the merger should especially try to merge scopes which can be the basis of [KaModule.contentScope][org.jetbrains.kotlin.analysis.api.projectStructure.KaModule.contentScope]s. + * + * If there are no good scope merging strategies, [KotlinSimpleGlobalSearchScopeMerger] should be registered by the platform. + */ +public interface KotlinGlobalSearchScopeMerger : KotlinPlatformComponent { + /** + * Creates a merged [GlobalSearchScope] which represents a *union* of all [scopes]. + */ + public fun union(scopes: Collection<GlobalSearchScope>): GlobalSearchScope + + public companion object { + public fun getInstance(project: Project): KotlinGlobalSearchScopeMerger = project.service() + } +}
diff --git a/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/projectStructure/KotlinSimpleGlobalSearchScopeMerger.kt b/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/projectStructure/KotlinSimpleGlobalSearchScopeMerger.kt new file mode 100644 index 0000000..f68b886 --- /dev/null +++ b/analysis/analysis-api-platform-interface/src/org/jetbrains/kotlin/analysis/api/platform/projectStructure/KotlinSimpleGlobalSearchScopeMerger.kt
@@ -0,0 +1,17 @@ +/* + * Copyright 2010-2024 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.analysis.api.platform.projectStructure + +import com.intellij.psi.search.GlobalSearchScope + +/** + * A non-optimizing [KotlinGlobalSearchScopeMerger] which simply creates naive union scopes. It may be registered if the platform cannot + * provide any scope merging strategies. + */ +public class KotlinSimpleGlobalSearchScopeMerger : KotlinGlobalSearchScopeMerger { + override fun union(scopes: Collection<GlobalSearchScope>): GlobalSearchScope = + GlobalSearchScope.union(scopes.toList()) +}
diff --git a/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/resources/META-INF/analysis-api/analysis-api-fir-standalone-base.xml b/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/resources/META-INF/analysis-api/analysis-api-fir-standalone-base.xml index b589928..252a5d1 100644 --- a/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/resources/META-INF/analysis-api/analysis-api-fir-standalone-base.xml +++ b/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/resources/META-INF/analysis-api/analysis-api-fir-standalone-base.xml
@@ -6,6 +6,10 @@ serviceInterface="org.jetbrains.kotlin.analysis.api.platform.declarations.KotlinDirectInheritorsProvider" serviceImplementation="org.jetbrains.kotlin.analysis.api.standalone.base.declarations.KotlinStandaloneFirDirectInheritorsProvider" /> + <projectService + serviceInterface="org.jetbrains.kotlin.analysis.api.platform.projectStructure.KotlinGlobalSearchScopeMerger" + serviceImplementation="org.jetbrains.kotlin.analysis.api.platform.projectStructure.KotlinSimpleGlobalSearchScopeMerger" + /> <applicationService serviceInterface="org.jetbrains.kotlin.analysis.decompiler.psi.BuiltinsVirtualFileProvider" serviceImplementation="org.jetbrains.kotlin.analysis.decompiler.psi.BuiltinsVirtualFileProviderCliImpl"/> </extensions>
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirCombinedJavaSymbolProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirCombinedJavaSymbolProvider.kt index 4e3d25f..7817dd7 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirCombinedJavaSymbolProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirCombinedJavaSymbolProvider.kt
@@ -6,7 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.providers import com.intellij.openapi.project.Project -import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.analysis.api.platform.projectStructure.KotlinGlobalSearchScopeMerger import org.jetbrains.kotlin.analysis.low.level.api.fir.caches.NullableCaffeineCache import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.java.JavaSymbolProvider @@ -93,7 +93,7 @@ companion object { fun merge(session: FirSession, project: Project, providers: List<LLFirJavaSymbolProvider>): FirSymbolProvider? = if (providers.size > 1) { - val combinedScope = GlobalSearchScope.union(providers.map { it.searchScope }) + val combinedScope = KotlinGlobalSearchScopeMerger.getInstance(project).union(providers.map { it.searchScope }) val javaClassFinder = project.createJavaClassFinder(combinedScope) LLFirCombinedJavaSymbolProvider(session, project, providers, javaClassFinder) } else providers.singleOrNull()