[LL FIR] KT-58325 Base LLFirCombinedKotlinSymbolProvider on LLFirKotlinSymbolProvider
This commit is contained in:
committed by
Space Team
parent
f4d3cceabd
commit
3322ec9dd9
+30
-19
@@ -26,10 +26,10 @@ import org.jetbrains.kotlin.name.CallableId
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [LLFirCombinedKotlinSymbolProvider] combines multiple [LLFirProvider.SymbolProvider]s with the following advantages:
|
* [LLFirCombinedKotlinSymbolProvider] combines multiple [LLFirKotlinSymbolProvider]s with the following advantages:
|
||||||
*
|
*
|
||||||
* - The combined symbol provider can combine the "names in package" sets built by individual providers. The name set can then be checked
|
* - The combined symbol provider can combine the "names in package" sets built by individual providers. The name set can then be checked
|
||||||
* once instead of for each subordinate symbol provider. Because Kotlin symbol providers are ordered first in
|
* once instead of for each subordinate symbol provider. Because Kotlin symbol providers are ordered first in
|
||||||
@@ -43,10 +43,10 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
*/
|
*/
|
||||||
internal class LLFirCombinedKotlinSymbolProvider private constructor(
|
internal class LLFirCombinedKotlinSymbolProvider private constructor(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
private val project: Project,
|
project: Project,
|
||||||
providers: List<LLFirProvider.SymbolProvider>,
|
providers: List<LLFirKotlinSymbolProvider>,
|
||||||
private val declarationProvider: KotlinDeclarationProvider,
|
private val declarationProvider: KotlinDeclarationProvider,
|
||||||
) : LLFirSelectingCombinedSymbolProvider<LLFirProvider.SymbolProvider>(session, project, providers) {
|
) : LLFirSelectingCombinedSymbolProvider<LLFirKotlinSymbolProvider>(session, project, providers) {
|
||||||
private val symbolNameCache = object : LLFirSymbolProviderNameCacheBase(session) {
|
private val symbolNameCache = object : LLFirSymbolProviderNameCacheBase(session) {
|
||||||
override fun computeClassifierNames(packageFqName: FqName): Set<String>? =
|
override fun computeClassifierNames(packageFqName: FqName): Set<String>? =
|
||||||
providers.flatMapToNullableSet { it.knownTopLevelClassifiersInPackage(packageFqName) }
|
providers.flatMapToNullableSet { it.knownTopLevelClassifiersInPackage(packageFqName) }
|
||||||
@@ -75,45 +75,50 @@ internal class LLFirCombinedKotlinSymbolProvider private constructor(
|
|||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||||
forEachCallableProvider(packageFqName, name) { callableId, callableFiles ->
|
forEachCallableProvider(
|
||||||
getTopLevelCallableSymbolsTo(destination, callableId, callableFiles)
|
packageFqName,
|
||||||
|
name,
|
||||||
|
declarationProvider::getTopLevelCallables,
|
||||||
|
) { callableId, callables ->
|
||||||
|
getTopLevelCallableSymbolsTo(destination, callableId, callables)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
|
||||||
forEachCallableProvider(packageFqName, name) { callableId, callableFiles ->
|
forEachCallableProvider(packageFqName, name, declarationProvider::getTopLevelFunctions) { callableId, functions ->
|
||||||
getTopLevelFunctionSymbolsTo(destination, callableId, callableFiles)
|
getTopLevelFunctionSymbolsTo(destination, callableId, functions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
|
||||||
forEachCallableProvider(packageFqName, name) { callableId, callableFiles ->
|
forEachCallableProvider(packageFqName, name, declarationProvider::getTopLevelProperties) { callableId, properties ->
|
||||||
getTopLevelPropertySymbolsTo(destination, callableId, callableFiles)
|
getTopLevelPropertySymbolsTo(destination, callableId, properties)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls [provide] on those providers which can contribute a callable of the given name.
|
* Calls [provide] on those providers which can contribute a callable of the given name.
|
||||||
*/
|
*/
|
||||||
private fun forEachCallableProvider(
|
private inline fun <A : KtCallableDeclaration> forEachCallableProvider(
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
name: Name,
|
name: Name,
|
||||||
provide: LLFirProvider.SymbolProvider.(CallableId, Collection<KtFile>) -> Unit,
|
getCallables: (CallableId) -> Collection<A>,
|
||||||
|
provide: LLFirKotlinSymbolProvider.(CallableId, Collection<A>) -> Unit,
|
||||||
) {
|
) {
|
||||||
if (!symbolNameCache.mayHaveTopLevelCallable(packageFqName, name)) return
|
if (!symbolNameCache.mayHaveTopLevelCallable(packageFqName, name)) return
|
||||||
|
|
||||||
val callableId = CallableId(packageFqName, name)
|
val callableId = CallableId(packageFqName, name)
|
||||||
|
|
||||||
declarationProvider.getTopLevelCallableFiles(callableId)
|
getCallables(callableId)
|
||||||
.groupBy { getModule(it) }
|
.groupBy { getModule(it) }
|
||||||
.forEach { (ktModule, ktFiles) ->
|
.forEach { (ktModule, callables) ->
|
||||||
// If `ktModule` cannot be found in the map, `ktFiles` cannot be processed by any of the available providers, because none
|
// If `ktModule` cannot be found in the map, `callables` cannot be processed by any of the available providers, because none
|
||||||
// of them belong to the correct module. We can skip in that case, because iterating through all providers wouldn't lead to
|
// of them belong to the correct module. We can skip in that case, because iterating through all providers wouldn't lead to
|
||||||
// any results for `ktFiles`.
|
// any results for `callables`.
|
||||||
val provider = providersByKtModule[ktModule] ?: return@forEach
|
val provider = providersByKtModule[ktModule] ?: return@forEach
|
||||||
provider.provide(callableId, ktFiles)
|
provider.provide(callableId, callables)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +133,7 @@ internal class LLFirCombinedKotlinSymbolProvider private constructor(
|
|||||||
symbolNameCache.getTopLevelCallableNamesInPackage(packageFqName)
|
symbolNameCache.getTopLevelCallableNamesInPackage(packageFqName)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun merge(session: LLFirSession, project: Project, providers: List<LLFirProvider.SymbolProvider>): FirSymbolProvider? =
|
fun merge(session: LLFirSession, project: Project, providers: List<LLFirKotlinSymbolProvider>): FirSymbolProvider? =
|
||||||
if (providers.size > 1) {
|
if (providers.size > 1) {
|
||||||
val combinedScope = GlobalSearchScope.union(providers.map { it.session.llFirModuleData.ktModule.contentScope })
|
val combinedScope = GlobalSearchScope.union(providers.map { it.session.llFirModuleData.ktModule.contentScope })
|
||||||
val declarationProvider = project.createDeclarationProvider(combinedScope, session.ktModule)
|
val declarationProvider = project.createDeclarationProvider(combinedScope, session.ktModule)
|
||||||
@@ -136,3 +141,9 @@ internal class LLFirCombinedKotlinSymbolProvider private constructor(
|
|||||||
} else providers.singleOrNull()
|
} else providers.singleOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callables are provided very rarely (compared to functions/properties individually), so it's okay to hit indices twice here.
|
||||||
|
*/
|
||||||
|
private fun KotlinDeclarationProvider.getTopLevelCallables(callableId: CallableId): List<KtCallableDeclaration> =
|
||||||
|
getTopLevelFunctions(callableId) + getTopLevelProperties(callableId)
|
||||||
|
|||||||
+1
-1
@@ -504,7 +504,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
|||||||
destination: MutableList<FirSymbolProvider>,
|
destination: MutableList<FirSymbolProvider>,
|
||||||
) {
|
) {
|
||||||
SymbolProviderMerger(this, destination).apply {
|
SymbolProviderMerger(this, destination).apply {
|
||||||
merge<LLFirProvider.SymbolProvider> { LLFirCombinedKotlinSymbolProvider.merge(session, project, it) }
|
merge<LLFirKotlinSymbolProvider> { LLFirCombinedKotlinSymbolProvider.merge(session, project, it) }
|
||||||
merge<JavaSymbolProvider> { LLFirCombinedJavaSymbolProvider.merge(session, project, it) }
|
merge<JavaSymbolProvider> { LLFirCombinedJavaSymbolProvider.merge(session, project, it) }
|
||||||
merge<FirExtensionSyntheticFunctionInterfaceProvider> { LLFirCombinedSyntheticFunctionSymbolProvider.merge(session, it) }
|
merge<FirExtensionSyntheticFunctionInterfaceProvider> { LLFirCombinedSyntheticFunctionSymbolProvider.merge(session, it) }
|
||||||
finish()
|
finish()
|
||||||
|
|||||||
Reference in New Issue
Block a user