[LL FIR] KT-58325 Introduce LLFirKotlinSymbolProvider
- `LLFirKotlinSymbolProvider` is a shared interface for any symbol
providers that are based on `KotlinDeclarationProvider`.
- `LLFirKotlinSymbolProviderWithNameCache` simplifies symbol provider
implementations which use a `LLFirSymbolProviderNameCache`.
- Note that the domain is not limited to "Kotlin symbol providers",
but I don't want to introduce a general base class like
`LLFirSymbolProviderWithNameCache` without multiple class
inheritance (think Scala traits).
- It would be possible to use delegation instead of such a base class,
but that would require a shared interface for the "package name"
functions, which would require some compiler refactoring as well.
- We can base `LLFirProvider$SymbolProvider` on
`LLFirKotlinSymbolProvider`.
- The callables functions in `LLFirKotlinSymbolProvider` expect
`KtCallableDeclaration`s instead of `KtFile`s. This is the preferred
interface, because callable files are only needed for `LLFirProvider`,
not Kotlin symbol providers in general (such as the stub-based
deserialized symbol provider). This also has the advantage that FIR
files containing only properties won't be built for
`getTopLevelFunctionSymbolsTo` and vice versa.
This commit is contained in:
committed by
Space Team
parent
29f7e922f6
commit
f4d3cceabd
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.low.level.api.fir.providers
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirSymbolProviderNameCache
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
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.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
|
||||
/**
|
||||
* A [FirSymbolProvider] which provides symbols from Kotlin sources via [KotlinDeclarationProvider].
|
||||
*
|
||||
* @see LLFirCombinedKotlinSymbolProvider
|
||||
*/
|
||||
internal abstract class LLFirKotlinSymbolProvider(session: FirSession) : FirSymbolProvider(session) {
|
||||
/**
|
||||
* This function is optimized for a known [classLikeDeclaration].
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
abstract fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>?
|
||||
|
||||
/**
|
||||
* This function is optimized for known [callables].
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
abstract fun getTopLevelCallableSymbolsTo(
|
||||
destination: MutableList<FirCallableSymbol<*>>,
|
||||
callableId: CallableId,
|
||||
callables: Collection<KtCallableDeclaration>,
|
||||
)
|
||||
|
||||
/**
|
||||
* This function is optimized for known [functions].
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
abstract fun getTopLevelFunctionSymbolsTo(
|
||||
destination: MutableList<FirNamedFunctionSymbol>,
|
||||
callableId: CallableId,
|
||||
functions: Collection<KtNamedFunction>,
|
||||
)
|
||||
|
||||
/**
|
||||
* This function is optimized for known [properties].
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
abstract fun getTopLevelPropertySymbolsTo(
|
||||
destination: MutableList<FirPropertySymbol>,
|
||||
callableId: CallableId,
|
||||
properties: Collection<KtProperty>,
|
||||
)
|
||||
}
|
||||
|
||||
internal abstract class LLFirKotlinSymbolProviderWithNameCache(session: FirSession) : LLFirKotlinSymbolProvider(session) {
|
||||
protected abstract val symbolNameCache: LLFirSymbolProviderNameCache
|
||||
|
||||
final override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? =
|
||||
symbolNameCache.getTopLevelClassifierNamesInPackage(packageFqName)
|
||||
|
||||
final override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? =
|
||||
symbolNameCache.getTopLevelCallableNamesInPackage(packageFqName)
|
||||
|
||||
final override fun computePackageSetWithTopLevelCallables(): Set<String>? = symbolNameCache.getPackageNamesWithTopLevelCallables()
|
||||
}
|
||||
+18
-33
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.SyntheticFirClassProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirSymbolProviderNameCache
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
@@ -25,8 +26,10 @@ 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.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
|
||||
@ThreadSafeMutableState
|
||||
internal class LLFirProvider(
|
||||
@@ -109,17 +112,17 @@ internal class LLFirProvider(
|
||||
declarationProvider.getTopLevelKotlinClassLikeDeclarationNamesInPackage(fqName)
|
||||
|
||||
@NoMutableState
|
||||
internal inner class SymbolProvider : FirSymbolProvider(session) {
|
||||
internal inner class SymbolProvider : LLFirKotlinSymbolProviderWithNameCache(session) {
|
||||
override val symbolNameCache: LLFirSymbolProviderNameCache
|
||||
get() = providerHelper.symbolNameCache
|
||||
|
||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||
if (!providerHelper.symbolNameCache.mayHaveTopLevelClassifier(classId, mayHaveFunctionClass = false)) return null
|
||||
return getFirClassifierByFqName(classId)?.symbol
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is optimized for a known [classLikeDeclaration].
|
||||
*/
|
||||
@FirSymbolProviderInternals
|
||||
fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>? {
|
||||
override fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>? {
|
||||
return getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration)?.symbol
|
||||
}
|
||||
|
||||
@@ -134,16 +137,13 @@ 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(
|
||||
override fun getTopLevelCallableSymbolsTo(
|
||||
destination: MutableList<FirCallableSymbol<*>>,
|
||||
callableId: CallableId,
|
||||
callableFiles: Collection<KtFile>,
|
||||
callables: Collection<KtCallableDeclaration>
|
||||
) {
|
||||
destination += providerHelper.getTopLevelCallableSymbols(callableId, callableFiles)
|
||||
destination += providerHelper.getTopLevelCallableSymbols(callableId, callables.map { it.containingKtFile })
|
||||
}
|
||||
|
||||
override fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List<FirNamedFunctionSymbol> {
|
||||
@@ -157,16 +157,13 @@ 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(
|
||||
override fun getTopLevelFunctionSymbolsTo(
|
||||
destination: MutableList<FirNamedFunctionSymbol>,
|
||||
callableId: CallableId,
|
||||
callableFiles: Collection<KtFile>,
|
||||
functions: Collection<KtNamedFunction>
|
||||
) {
|
||||
destination += providerHelper.getTopLevelFunctionSymbols(callableId, callableFiles)
|
||||
destination += providerHelper.getTopLevelFunctionSymbols(callableId, functions.map { it.containingKtFile })
|
||||
}
|
||||
|
||||
override fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List<FirPropertySymbol> {
|
||||
@@ -180,28 +177,16 @@ 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(
|
||||
override fun getTopLevelPropertySymbolsTo(
|
||||
destination: MutableList<FirPropertySymbol>,
|
||||
callableId: CallableId,
|
||||
callableFiles: Collection<KtFile>,
|
||||
properties: Collection<KtProperty>
|
||||
) {
|
||||
destination += providerHelper.getTopLevelPropertySymbols(callableId, callableFiles)
|
||||
destination += providerHelper.getTopLevelPropertySymbols(callableId, properties.mapTo(mutableSetOf()) { it.containingKtFile })
|
||||
}
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? =
|
||||
providerHelper.getPackage(fqName)
|
||||
|
||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? =
|
||||
providerHelper.symbolNameCache.getPackageNamesWithTopLevelCallables()
|
||||
|
||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? =
|
||||
providerHelper.symbolNameCache.getTopLevelClassifierNamesInPackage(packageFqName)
|
||||
|
||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? =
|
||||
providerHelper.symbolNameCache.getTopLevelCallableNamesInPackage(packageFqName)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user