[LL FIR] KT-57314 Allow passing index results to Kotlin symbol provider
- If a `KtClassLikeDeclaration` or all `KtFile`s which contain a callable are already known, they can now be passed to `LLFirProvider$SymbolProvider` directly. This avoids index accesses in `providerHelper`.
This commit is contained in:
committed by
Space Team
parent
bf1ee6ebed
commit
16af67e99c
+46
@@ -21,10 +21,12 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
@ThreadSafeMutableState
|
||||
internal class LLFirProvider(
|
||||
@@ -113,6 +115,14 @@ internal class LLFirProvider(
|
||||
return getFirClassifierByFqName(classId)?.symbol
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is optimized for a known [classLikeDeclaration].
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>? {
|
||||
return getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration)?.symbol
|
||||
}
|
||||
|
||||
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
|
||||
if (!providerHelper.symbolNameCache.mayHaveTopLevelCallable(packageFqName, name)) return emptyList()
|
||||
return providerHelper.getTopLevelCallableSymbols(packageFqName, name)
|
||||
@@ -124,6 +134,18 @@ internal class LLFirProvider(
|
||||
destination += providerHelper.getTopLevelCallableSymbols(packageFqName, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is optimized for known [callableFiles], which should be the list of all [KtFile]s that contain the callables.
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
fun getTopLevelCallableSymbolsTo(
|
||||
destination: MutableList<FirCallableSymbol<*>>,
|
||||
callableId: CallableId,
|
||||
callableFiles: Collection<KtFile>,
|
||||
) {
|
||||
destination += providerHelper.getTopLevelCallableSymbols(callableId, callableFiles)
|
||||
}
|
||||
|
||||
override fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List<FirNamedFunctionSymbol> {
|
||||
if (!providerHelper.symbolNameCache.mayHaveTopLevelCallable(packageFqName, name)) return emptyList()
|
||||
return providerHelper.getTopLevelFunctionSymbols(packageFqName, name)
|
||||
@@ -135,6 +157,18 @@ internal class LLFirProvider(
|
||||
destination += providerHelper.getTopLevelFunctionSymbols(packageFqName, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is optimized for known [callableFiles], which should be the list of all [KtFile]s that contain the functions.
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
fun getTopLevelFunctionSymbolsTo(
|
||||
destination: MutableList<FirNamedFunctionSymbol>,
|
||||
callableId: CallableId,
|
||||
callableFiles: Collection<KtFile>,
|
||||
) {
|
||||
destination += providerHelper.getTopLevelFunctionSymbols(callableId, callableFiles)
|
||||
}
|
||||
|
||||
override fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List<FirPropertySymbol> {
|
||||
if (!providerHelper.symbolNameCache.mayHaveTopLevelCallable(packageFqName, name)) return emptyList()
|
||||
return providerHelper.getTopLevelPropertySymbols(packageFqName, name)
|
||||
@@ -146,6 +180,18 @@ internal class LLFirProvider(
|
||||
destination += providerHelper.getTopLevelPropertySymbols(packageFqName, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is optimized for known [callableFiles], which should be the list of all [KtFile]s that contain the properties.
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
fun getTopLevelPropertySymbolsTo(
|
||||
destination: MutableList<FirPropertySymbol>,
|
||||
callableId: CallableId,
|
||||
callableFiles: Collection<KtFile>,
|
||||
) {
|
||||
destination += providerHelper.getTopLevelPropertySymbols(callableId, callableFiles)
|
||||
}
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? =
|
||||
providerHelper.getPackage(fqName)
|
||||
|
||||
|
||||
+26
-8
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.caches.createCache
|
||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||
import org.jetbrains.kotlin.fir.caches.getValue
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||
@@ -28,6 +27,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
internal class LLFirProviderHelper(
|
||||
firSession: FirSession,
|
||||
@@ -49,15 +49,16 @@ internal class LLFirProviderHelper(
|
||||
?: error("Classifier $classId was found in file ${ktClass.containingKtFile.virtualFilePath} but was not found in FirFile")
|
||||
}
|
||||
|
||||
private val callablesByCallableId = firSession.firCachesFactory.createCache<CallableId, List<FirCallableSymbol<*>>> { callableId ->
|
||||
val files = declarationProvider.getTopLevelCallableFiles(callableId).ifEmpty { return@createCache emptyList() }
|
||||
buildList {
|
||||
files.forEach { ktFile ->
|
||||
val firFile = firFileBuilder.buildRawFirFileWithCaching(ktFile)
|
||||
firFile.collectCallableDeclarationsTo(this, callableId.callableName)
|
||||
private val callablesByCallableId =
|
||||
firSession.firCachesFactory.createCache<CallableId, List<FirCallableSymbol<*>>, Collection<KtFile>?> { callableId, context ->
|
||||
val files = context ?: declarationProvider.getTopLevelCallableFiles(callableId).ifEmpty { return@createCache emptyList() }
|
||||
buildList {
|
||||
files.forEach { ktFile ->
|
||||
val firFile = firFileBuilder.buildRawFirFileWithCaching(ktFile)
|
||||
firFile.collectCallableDeclarationsTo(this, callableId.callableName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val symbolNameCache = object : LLFirSymbolProviderNameCache(firSession) {
|
||||
override fun computeClassifierNames(packageFqName: FqName): Set<String>? =
|
||||
@@ -84,14 +85,31 @@ internal class LLFirProviderHelper(
|
||||
return callablesByCallableId.getValue(callableId)
|
||||
}
|
||||
|
||||
/**
|
||||
* [callableFiles] are the [KtFile]s which contain callables of the given package and name. If already known, they can be provided to
|
||||
* avoid index accesses.
|
||||
*/
|
||||
fun getTopLevelCallableSymbols(callableId: CallableId, callableFiles: Collection<KtFile>?): List<FirCallableSymbol<*>> {
|
||||
if (!allowKotlinPackage && callableId.packageName.isKotlinPackage()) return emptyList()
|
||||
return callablesByCallableId.getValue(callableId, callableFiles)
|
||||
}
|
||||
|
||||
fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List<FirNamedFunctionSymbol> {
|
||||
return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance<FirNamedFunctionSymbol>()
|
||||
}
|
||||
|
||||
fun getTopLevelFunctionSymbols(callableId: CallableId, callableFiles: Collection<KtFile>): List<FirNamedFunctionSymbol> {
|
||||
return getTopLevelCallableSymbols(callableId, callableFiles).filterIsInstance<FirNamedFunctionSymbol>()
|
||||
}
|
||||
|
||||
fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List<FirPropertySymbol> {
|
||||
return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance<FirPropertySymbol>()
|
||||
}
|
||||
|
||||
fun getTopLevelPropertySymbols(callableId: CallableId, callableFiles: Collection<KtFile>): List<FirPropertySymbol> {
|
||||
return getTopLevelCallableSymbols(callableId, callableFiles).filterIsInstance<FirPropertySymbol>()
|
||||
}
|
||||
|
||||
private fun FirFile.collectCallableDeclarationsTo(list: MutableList<FirCallableSymbol<*>>, name: Name) {
|
||||
declarations.mapNotNullTo(list) { declaration ->
|
||||
if (declaration is FirCallableDeclaration && declaration.symbol.callableId.callableName == name) {
|
||||
|
||||
Reference in New Issue
Block a user