[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.LLFirModuleResolveComponents
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.SyntheticFirClassProvider
|
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.KotlinDeclarationProvider
|
||||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
|
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
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.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.KtCallableDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
|
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
|
@ThreadSafeMutableState
|
||||||
internal class LLFirProvider(
|
internal class LLFirProvider(
|
||||||
@@ -109,17 +112,17 @@ internal class LLFirProvider(
|
|||||||
declarationProvider.getTopLevelKotlinClassLikeDeclarationNamesInPackage(fqName)
|
declarationProvider.getTopLevelKotlinClassLikeDeclarationNamesInPackage(fqName)
|
||||||
|
|
||||||
@NoMutableState
|
@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<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
if (!providerHelper.symbolNameCache.mayHaveTopLevelClassifier(classId, mayHaveFunctionClass = false)) return null
|
if (!providerHelper.symbolNameCache.mayHaveTopLevelClassifier(classId, mayHaveFunctionClass = false)) return null
|
||||||
return getFirClassifierByFqName(classId)?.symbol
|
return getFirClassifierByFqName(classId)?.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is optimized for a known [classLikeDeclaration].
|
|
||||||
*/
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>? {
|
||||||
return getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration)?.symbol
|
return getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration)?.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,16 +137,13 @@ internal class LLFirProvider(
|
|||||||
destination += providerHelper.getTopLevelCallableSymbols(packageFqName, name)
|
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
|
@FirSymbolProviderInternals
|
||||||
fun getTopLevelCallableSymbolsTo(
|
override fun getTopLevelCallableSymbolsTo(
|
||||||
destination: MutableList<FirCallableSymbol<*>>,
|
destination: MutableList<FirCallableSymbol<*>>,
|
||||||
callableId: CallableId,
|
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> {
|
override fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List<FirNamedFunctionSymbol> {
|
||||||
@@ -157,16 +157,13 @@ internal class LLFirProvider(
|
|||||||
destination += providerHelper.getTopLevelFunctionSymbols(packageFqName, name)
|
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
|
@FirSymbolProviderInternals
|
||||||
fun getTopLevelFunctionSymbolsTo(
|
override fun getTopLevelFunctionSymbolsTo(
|
||||||
destination: MutableList<FirNamedFunctionSymbol>,
|
destination: MutableList<FirNamedFunctionSymbol>,
|
||||||
callableId: CallableId,
|
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> {
|
override fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List<FirPropertySymbol> {
|
||||||
@@ -180,28 +177,16 @@ internal class LLFirProvider(
|
|||||||
destination += providerHelper.getTopLevelPropertySymbols(packageFqName, name)
|
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
|
@FirSymbolProviderInternals
|
||||||
fun getTopLevelPropertySymbolsTo(
|
override fun getTopLevelPropertySymbolsTo(
|
||||||
destination: MutableList<FirPropertySymbol>,
|
destination: MutableList<FirPropertySymbol>,
|
||||||
callableId: CallableId,
|
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? =
|
override fun getPackage(fqName: FqName): FqName? =
|
||||||
providerHelper.getPackage(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