[LL FIR] extract base class from LLFirSymbolProviderNameCache

^KT-57930
This commit is contained in:
Ilya Kirillov
2023-04-08 15:53:45 +02:00
committed by Space Team
parent c9d7b47900
commit 3b681cd2eb
3 changed files with 21 additions and 8 deletions
@@ -9,7 +9,7 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.low.level.api.fir.caches.NullableCaffeineCache import org.jetbrains.kotlin.analysis.low.level.api.fir.caches.NullableCaffeineCache
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirSymbolProviderNameCache import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirSymbolProviderNameCacheBase
import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.getKtModule import org.jetbrains.kotlin.analysis.project.structure.getKtModule
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
@@ -46,7 +46,7 @@ internal class LLFirCombinedKotlinSymbolProvider private constructor(
providers: List<LLFirProvider.SymbolProvider>, providers: List<LLFirProvider.SymbolProvider>,
private val declarationProvider: KotlinDeclarationProvider, private val declarationProvider: KotlinDeclarationProvider,
) : LLFirSelectingCombinedSymbolProvider<LLFirProvider.SymbolProvider>(session, project, providers) { ) : LLFirSelectingCombinedSymbolProvider<LLFirProvider.SymbolProvider>(session, project, providers) {
private val symbolNameCache = object : LLFirSymbolProviderNameCache(session) { private val symbolNameCache = object : LLFirSymbolProviderNameCacheBase(session) {
override fun computeClassifierNames(packageFqName: FqName): Set<String>? = buildSet { override fun computeClassifierNames(packageFqName: FqName): Set<String>? = buildSet {
providers.forEach { addAll(it.knownTopLevelClassifiersInPackage(packageFqName) ?: return null) } providers.forEach { addAll(it.knownTopLevelClassifiersInPackage(packageFqName) ?: return null) }
} }
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.name.Name
internal class LLFirKotlinSymbolProviderNameCache( internal class LLFirKotlinSymbolProviderNameCache(
firSession: FirSession, firSession: FirSession,
private val declarationProvider: KotlinDeclarationProvider, private val declarationProvider: KotlinDeclarationProvider,
) : LLFirSymbolProviderNameCache(firSession) { ) : LLFirSymbolProviderNameCacheBase(firSession) {
override fun computeClassifierNames(packageFqName: FqName): Set<String> = override fun computeClassifierNames(packageFqName: FqName): Set<String> =
declarationProvider declarationProvider
.getTopLevelKotlinClassLikeDeclarationNamesInPackage(packageFqName) .getTopLevelKotlinClassLikeDeclarationNamesInPackage(packageFqName)
@@ -18,7 +18,20 @@ import org.jetbrains.kotlin.name.Name
* Caches the names of classifiers and callables contained in a package. [LLFirSymbolProviderNameCache] is used by symbol providers to abort * Caches the names of classifiers and callables contained in a package. [LLFirSymbolProviderNameCache] is used by symbol providers to abort
* symbol finding early if the symbol name isn't contained in the symbol provider's domain. * symbol finding early if the symbol name isn't contained in the symbol provider's domain.
*/ */
internal abstract class LLFirSymbolProviderNameCache(private val firSession: FirSession) { internal abstract class LLFirSymbolProviderNameCache {
abstract fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>?
abstract fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>?
abstract fun mayHaveTopLevelClassifier(classId: ClassId, mayHaveFunctionClass: Boolean): Boolean
abstract fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean
}
internal abstract class LLFirSymbolProviderNameCacheBase(
private val firSession: FirSession
) : LLFirSymbolProviderNameCache() {
abstract fun computeClassifierNames(packageFqName: FqName): Set<String>? abstract fun computeClassifierNames(packageFqName: FqName): Set<String>?
abstract fun computeCallableNames(packageFqName: FqName): Set<Name>? abstract fun computeCallableNames(packageFqName: FqName): Set<Name>?
@@ -28,18 +41,18 @@ internal abstract class LLFirSymbolProviderNameCache(private val firSession: Fir
private val topLevelCallableNamesByPackage = private val topLevelCallableNamesByPackage =
firSession.firCachesFactory.createCache<FqName, Set<Name>?>(::computeCallableNames) firSession.firCachesFactory.createCache<FqName, Set<Name>?>(::computeCallableNames)
fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? = final override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? =
topLevelClassifierNamesByPackage.getValue(packageFqName) topLevelClassifierNamesByPackage.getValue(packageFqName)
fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? = final override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? =
topLevelCallableNamesByPackage.getValue(packageFqName) topLevelCallableNamesByPackage.getValue(packageFqName)
fun mayHaveTopLevelClassifier(classId: ClassId, mayHaveFunctionClass: Boolean): Boolean { final override fun mayHaveTopLevelClassifier(classId: ClassId, mayHaveFunctionClass: Boolean): Boolean {
val names = getTopLevelClassifierNamesInPackage(classId.packageFqName) ?: return true val names = getTopLevelClassifierNamesInPackage(classId.packageFqName) ?: return true
return names.mayHaveTopLevelClassifier(classId, firSession, mayHaveFunctionClass) return names.mayHaveTopLevelClassifier(classId, firSession, mayHaveFunctionClass)
} }
fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean { override fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean {
if (name.isSpecial) return true if (name.isSpecial) return true
val names = getTopLevelCallableNamesInPackage(packageFqName) ?: return true val names = getTopLevelCallableNamesInPackage(packageFqName) ?: return true
return name in names return name in names