[FIR/LL FIR] Introduce FirSymbolNamesProvider
- In LL FIR, we have increasingly formalized symbol name caches as
palpable objects. The main reasons for this formalization were the
need to share implementations of caching between different (LL FIR)
symbol providers, the need to build composite name caches from
individual name caches, and the introduction of resolve extensions
which may provide additional declarations and thus complicate the name
set construction for Kotlin symbol providers in LL FIR.
- `LLFirSymbolProviderNameCache` also shared a lot of similarities with
cache handling in FIR providers like
`FirCachingCompositeSymbolProvider` and
`AbstractFirDeserializedSymbolProvider`.
- This commit introduces a `FirSymbolNamesProvider` as a component of
`FirSymbolProvider`. This symbol names provider's task is to provide
the sets of names which `FirSymbolProvider` previously provided. It
also allows sharing implementations of `mayHaveTopLevel*` once and for
all, which is an improvement over the previously scattered
implementations (the same ideas replicated many times throughout
different symbol providers).
- `FirSymbolNamesProvider` by design doesn't cache, as many symbol
providers may not need such a cache. `FirCachedSymbolNamesProvider`
can be used to cache symbol names if needed. The symbol name provider
architecture also makes it easier to switch between caching and
non-caching, without the need to reimplement caches every time.
- Synthetic function types complicate the picture, but this complication
is now exposed with the rest of the API, instead of being hidden in a
few implementations here and there. This allows symbol providers to
more explicitly state whether they can provide generated function
types, which is an advantage for the correctness of composite symbol
providers.
Some specific notes:
- In `FirSyntheticFunctionInterfaceProviderBase`, the class ID check has
been replaced with a full `mayHaveTopLevelClassifier` check so that
the cache doesn't get filled with `null` entries.
- `LLFirKotlinSymbolProviderNameCache` is turned into a non-caching
`LLFirKotlinSymbolNamesProvider` so that this symbol names provider
and those of resolve extensions can be composed into one caching
symbol provider in `LLFirProviderHelper` without creating layers of
caches. If the Kotlin symbol names provider was caching out of the
box, `LLFirProviderHelper.symbolNameCache` would cache the
names (1) in the combined symbol names cache and (2) in the Kotlin
symbol names cache.
- A caching Kotlin symbol names cache can still be created easily with
the `LLFirKotlinSymbolNamesProvider.cached` constructor function.
This commit is contained in:
committed by
Space Team
parent
b82a589e56
commit
accc9b0eb3
+7
-4
@@ -12,6 +12,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirMo
|
|||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProviderWithoutCallables
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
@@ -48,6 +50,11 @@ internal class LLFirCombinedJavaSymbolProvider private constructor(
|
|||||||
*/
|
*/
|
||||||
private val classCache: NullableCaffeineCache<ClassId, FirRegularClassSymbol> = NullableCaffeineCache { it.maximumSize(2500) }
|
private val classCache: NullableCaffeineCache<ClassId, FirRegularClassSymbol> = NullableCaffeineCache { it.maximumSize(2500) }
|
||||||
|
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProviderWithoutCallables() {
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? = null
|
||||||
|
override fun mayHaveTopLevelClassifier(classId: ClassId): Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||||
classCache.get(classId) { computeClassLikeSymbolByClassId(it) }
|
classCache.get(classId) { computeClassLikeSymbolByClassId(it) }
|
||||||
|
|
||||||
@@ -82,10 +89,6 @@ internal class LLFirCombinedJavaSymbolProvider private constructor(
|
|||||||
|
|
||||||
override fun getPackage(fqName: FqName): FqName? = providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
override fun getPackage(fqName: FqName): FqName? = providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? = null
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? = null
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? = null
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun merge(session: FirSession, project: Project, providers: List<JavaSymbolProvider>): FirSymbolProvider? =
|
fun merge(session: FirSession, project: Project, providers: List<JavaSymbolProvider>): FirSymbolProvider? =
|
||||||
if (providers.size > 1) {
|
if (providers.size > 1) {
|
||||||
|
|||||||
+5
-22
@@ -10,14 +10,14 @@ 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.sessions.LLFirSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
||||||
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.providers.KotlinDeclarationProvider
|
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
||||||
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirCompositeCachedSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.flatMapToNullableSet
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
@@ -47,21 +47,12 @@ internal class LLFirCombinedKotlinSymbolProvider private constructor(
|
|||||||
providers: List<LLFirKotlinSymbolProvider>,
|
providers: List<LLFirKotlinSymbolProvider>,
|
||||||
private val declarationProvider: KotlinDeclarationProvider,
|
private val declarationProvider: KotlinDeclarationProvider,
|
||||||
) : LLFirSelectingCombinedSymbolProvider<LLFirKotlinSymbolProvider>(session, project, providers) {
|
) : LLFirSelectingCombinedSymbolProvider<LLFirKotlinSymbolProvider>(session, project, providers) {
|
||||||
private val symbolNameCache = object : LLFirSymbolProviderNameCacheBase(session) {
|
override val symbolNamesProvider: FirSymbolNamesProvider = FirCompositeCachedSymbolNamesProvider.fromSymbolProviders(session, providers)
|
||||||
override fun computeClassifierNames(packageFqName: FqName): Set<String>? =
|
|
||||||
providers.flatMapToNullableSet { it.knownTopLevelClassifiersInPackage(packageFqName) }
|
|
||||||
|
|
||||||
override fun computeCallableNames(packageFqName: FqName): Set<Name>? =
|
|
||||||
providers.flatMapToNullableSet { it.computeCallableNamesInPackage(packageFqName) }
|
|
||||||
|
|
||||||
override fun computePackageNamesWithTopLevelCallables(): Set<String>? =
|
|
||||||
providers.flatMapToNullableSet { it.computePackageSetWithTopLevelCallables() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private val classifierCache = NullableCaffeineCache<ClassId, FirClassLikeSymbol<*>> { it.maximumSize(500) }
|
private val classifierCache = NullableCaffeineCache<ClassId, FirClassLikeSymbol<*>> { it.maximumSize(500) }
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
if (!symbolNameCache.mayHaveTopLevelClassifier(classId, mayHaveFunctionClass = false)) return null
|
if (!symbolNamesProvider.mayHaveTopLevelClassifier(classId)) return null
|
||||||
|
|
||||||
return classifierCache.get(classId) { computeClassLikeSymbolByClassId(it) }
|
return classifierCache.get(classId) { computeClassLikeSymbolByClassId(it) }
|
||||||
}
|
}
|
||||||
@@ -107,7 +98,7 @@ internal class LLFirCombinedKotlinSymbolProvider private constructor(
|
|||||||
getCallables: (CallableId) -> Collection<A>,
|
getCallables: (CallableId) -> Collection<A>,
|
||||||
provide: LLFirKotlinSymbolProvider.(CallableId, Collection<A>) -> Unit,
|
provide: LLFirKotlinSymbolProvider.(CallableId, Collection<A>) -> Unit,
|
||||||
) {
|
) {
|
||||||
if (!symbolNameCache.mayHaveTopLevelCallable(packageFqName, name)) return
|
if (!symbolNamesProvider.mayHaveTopLevelCallable(packageFqName, name)) return
|
||||||
|
|
||||||
val callableId = CallableId(packageFqName, name)
|
val callableId = CallableId(packageFqName, name)
|
||||||
|
|
||||||
@@ -124,14 +115,6 @@ internal class LLFirCombinedKotlinSymbolProvider private constructor(
|
|||||||
|
|
||||||
override fun getPackage(fqName: FqName): FqName? = providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
override fun getPackage(fqName: FqName): FqName? = providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? = null
|
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? =
|
|
||||||
symbolNameCache.getTopLevelClassifierNamesInPackage(packageFqName)
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? =
|
|
||||||
symbolNameCache.getTopLevelCallableNamesInPackage(packageFqName)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun merge(session: LLFirSession, project: Project, providers: List<LLFirKotlinSymbolProvider>): FirSymbolProvider? =
|
fun merge(session: LLFirSession, project: Project, providers: List<LLFirKotlinSymbolProvider>): FirSymbolProvider? =
|
||||||
if (providers.size > 1) {
|
if (providers.size > 1) {
|
||||||
|
|||||||
+12
-5
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirCompositeSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirSyntheticFunctionInterfaceProviderBase
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirSyntheticFunctionInterfaceProviderBase
|
||||||
@@ -29,11 +31,20 @@ internal class LLFirCombinedSyntheticFunctionSymbolProvider private constructor(
|
|||||||
) : FirSymbolProvider(session) {
|
) : FirSymbolProvider(session) {
|
||||||
private val combinedPackageNames: Set<FqName> = providers.flatMapTo(mutableSetOf()) { it.getFunctionKindPackageNames() }
|
private val combinedPackageNames: Set<FqName> = providers.flatMapTo(mutableSetOf()) { it.getFunctionKindPackageNames() }
|
||||||
|
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider =
|
||||||
|
// `FirCompositeSymbolNamesProvider` defines `mayHaveSyntheticFunctionTypes` and `mayHaveSyntheticFunctionType` correctly, which is
|
||||||
|
// needed for consistency should this symbol provider be part of another composite symbol provider.
|
||||||
|
object : FirCompositeSymbolNamesProvider(providers.map { it.symbolNamesProvider }) {
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> = emptySet()
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> = emptySet()
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name> = emptySet()
|
||||||
|
}
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
if (!classId.mayBeSyntheticFunctionClassName()) return null
|
if (!classId.mayBeSyntheticFunctionClassName()) return null
|
||||||
if (classId.packageFqName !in combinedPackageNames) return null
|
if (classId.packageFqName !in combinedPackageNames) return null
|
||||||
|
|
||||||
return providers.firstNotNullOfOrNull { it.getClassLikeSymbolByClassIdWithoutClassIdChecks(classId) }
|
return providers.firstNotNullOfOrNull { it.getClassLikeSymbolByClassId(classId) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
@@ -50,10 +61,6 @@ internal class LLFirCombinedSyntheticFunctionSymbolProvider private constructor(
|
|||||||
|
|
||||||
override fun getPackage(fqName: FqName): FqName? = fqName.takeIf { it in combinedPackageNames }
|
override fun getPackage(fqName: FqName): FqName? = fqName.takeIf { it in combinedPackageNames }
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? = null
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? = null
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? = null
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun merge(session: FirSession, providers: List<FirSyntheticFunctionInterfaceProviderBase>): FirSymbolProvider? =
|
fun merge(session: FirSession, providers: List<FirSyntheticFunctionInterfaceProviderBase>): FirSymbolProvider? =
|
||||||
if (providers.size > 1) LLFirCombinedSyntheticFunctionSymbolProvider(session, providers)
|
if (providers.size > 1) LLFirCombinedSyntheticFunctionSymbolProvider(session, providers)
|
||||||
|
|||||||
-15
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
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.analysis.providers.KotlinDeclarationProvider
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
@@ -16,8 +15,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
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.Name
|
|
||||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
|
import org.jetbrains.kotlin.psi.KtClassLikeDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
@@ -65,15 +62,3 @@ internal abstract class LLFirKotlinSymbolProvider(session: FirSession) : FirSymb
|
|||||||
properties: Collection<KtProperty>,
|
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()
|
|
||||||
}
|
|
||||||
|
|||||||
+6
-8
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.JvmStubBasedFirDeserializedSymbolProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.JvmStubBasedFirDeserializedSymbolProvider
|
||||||
import org.jetbrains.kotlin.analysis.utils.collections.buildSmartList
|
import org.jetbrains.kotlin.analysis.utils.collections.buildSmartList
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirNullSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
@@ -29,6 +31,8 @@ internal class LLFirModuleWithDependenciesSymbolProvider(
|
|||||||
val providers: List<FirSymbolProvider>,
|
val providers: List<FirSymbolProvider>,
|
||||||
val dependencyProvider: LLFirDependenciesSymbolProvider,
|
val dependencyProvider: LLFirDependenciesSymbolProvider,
|
||||||
) : FirSymbolProvider(session) {
|
) : FirSymbolProvider(session) {
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider = FirNullSymbolNamesProvider
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||||
getClassLikeSymbolByClassIdWithoutDependencies(classId)
|
getClassLikeSymbolByClassIdWithoutDependencies(classId)
|
||||||
?: dependencyProvider.getClassLikeSymbolByClassId(classId)
|
?: dependencyProvider.getClassLikeSymbolByClassId(classId)
|
||||||
@@ -96,10 +100,6 @@ internal class LLFirModuleWithDependenciesSymbolProvider(
|
|||||||
|
|
||||||
fun getPackageWithoutDependencies(fqName: FqName): FqName? =
|
fun getPackageWithoutDependencies(fqName: FqName): FqName? =
|
||||||
providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? = null
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? = null
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LLFirDependenciesSymbolProvider(
|
internal class LLFirDependenciesSymbolProvider(
|
||||||
@@ -113,6 +113,8 @@ internal class LLFirDependenciesSymbolProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider = FirNullSymbolNamesProvider
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||||
providers.firstNotNullOfOrNull { it.getClassLikeSymbolByClassId(classId) }
|
providers.firstNotNullOfOrNull { it.getClassLikeSymbolByClassId(classId) }
|
||||||
|
|
||||||
@@ -151,10 +153,6 @@ internal class LLFirDependenciesSymbolProvider(
|
|||||||
|
|
||||||
override fun getPackage(fqName: FqName): FqName? = providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
override fun getPackage(fqName: FqName): FqName? = providers.firstNotNullOfOrNull { it.getPackage(fqName) }
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? = null
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? = null
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? = null
|
|
||||||
|
|
||||||
private fun <S : FirCallableSymbol<*>> addNewSymbolsConsideringJvmFacades(
|
private fun <S : FirCallableSymbol<*>> addNewSymbolsConsideringJvmFacades(
|
||||||
destination: MutableList<S>,
|
destination: MutableList<S>,
|
||||||
newSymbols: List<S>,
|
newSymbols: List<S>,
|
||||||
|
|||||||
+4
-9
@@ -7,7 +7,6 @@ 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
|
||||||
@@ -17,10 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.*
|
||||||
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.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -112,12 +108,11 @@ internal class LLFirProvider(
|
|||||||
declarationProvider.getTopLevelKotlinClassLikeDeclarationNamesInPackage(fqName)
|
declarationProvider.getTopLevelKotlinClassLikeDeclarationNamesInPackage(fqName)
|
||||||
|
|
||||||
@NoMutableState
|
@NoMutableState
|
||||||
internal inner class SymbolProvider : LLFirKotlinSymbolProviderWithNameCache(session) {
|
internal inner class SymbolProvider : LLFirKotlinSymbolProvider(session) {
|
||||||
override val symbolNameCache: LLFirSymbolProviderNameCache
|
override val symbolNamesProvider: FirSymbolNamesProvider get() = providerHelper.symbolNameCache
|
||||||
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)) return null
|
||||||
return getFirClassifierByFqName(classId)?.symbol
|
return getFirClassifierByFqName(classId)?.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -10,8 +10,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.Composi
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.LLFirResolveExtensionTool
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.LLFirResolveExtensionTool
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.llResolveExtensionTool
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.llResolveExtensionTool
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirCompositeSymbolProviderNameCache
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirKotlinSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirKotlinSymbolProviderNameCache
|
|
||||||
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.analysis.providers.impl.CompositeKotlinDeclarationProvider
|
import org.jetbrains.kotlin.analysis.providers.impl.CompositeKotlinDeclarationProvider
|
||||||
@@ -24,6 +23,7 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirCompositeCachedSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
@@ -80,10 +80,11 @@ internal class LLFirProviderHelper(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val symbolNameCache = LLFirCompositeSymbolProviderNameCache.create(
|
val symbolNameCache = FirCompositeCachedSymbolNamesProvider.create(
|
||||||
|
firSession,
|
||||||
listOfNotNull(
|
listOfNotNull(
|
||||||
LLFirKotlinSymbolProviderNameCache(firSession, declarationProvider),
|
LLFirKotlinSymbolNamesProvider(declarationProvider),
|
||||||
extensionTool?.symbolNameCache,
|
extensionTool?.symbolNamesProvider,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+8
-7
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFi
|
|||||||
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
|
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
|
||||||
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionReferencePsiTargetsProvider
|
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionReferencePsiTargetsProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirSymbolProviderNameCache
|
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleStructureInternals
|
import org.jetbrains.kotlin.analysis.project.structure.KtModuleStructureInternals
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.analysisExtensionFileContextModule
|
import org.jetbrains.kotlin.analysis.project.structure.analysisExtensionFileContextModule
|
||||||
@@ -23,6 +22,7 @@ import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
|
|||||||
import org.jetbrains.kotlin.analysis.providers.impl.FileBasedKotlinDeclarationProvider
|
import org.jetbrains.kotlin.analysis.providers.impl.FileBasedKotlinDeclarationProvider
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
@@ -32,14 +32,15 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
/**
|
/**
|
||||||
* Encapsulate all the work with the [KtResolveExtension] for the LL API.
|
* Encapsulate all the work with the [KtResolveExtension] for the LL API.
|
||||||
*
|
*
|
||||||
* Caches generated [KtResolveExtensionFile]s, creates [KotlinDeclarationProvider], [KotlinPackageProvider], [LLFirSymbolProviderNameCache] needed for the [org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider].
|
* Caches generated [KtResolveExtensionFile]s, creates [KotlinDeclarationProvider], [KotlinPackageProvider], [FirSymbolNamesProvider] needed
|
||||||
|
* for the [org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider].
|
||||||
*/
|
*/
|
||||||
abstract class LLFirResolveExtensionTool : FirSessionComponent {
|
abstract class LLFirResolveExtensionTool : FirSessionComponent {
|
||||||
abstract val modificationTrackers: List<ModificationTracker>
|
abstract val modificationTrackers: List<ModificationTracker>
|
||||||
abstract val declarationProvider: LLFirResolveExtensionToolDeclarationProvider
|
abstract val declarationProvider: LLFirResolveExtensionToolDeclarationProvider
|
||||||
abstract val packageProvider: KotlinPackageProvider
|
abstract val packageProvider: KotlinPackageProvider
|
||||||
abstract val packageFilter: LLFirResolveExtensionToolPackageFilter
|
abstract val packageFilter: LLFirResolveExtensionToolPackageFilter
|
||||||
internal abstract val symbolNameCache: LLFirSymbolProviderNameCache
|
internal abstract val symbolNamesProvider: FirSymbolNamesProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.llResolveExtensionTool: LLFirResolveExtensionTool? by FirSession.nullableSessionComponentAccessor()
|
val FirSession.llResolveExtensionTool: LLFirResolveExtensionTool? by FirSession.nullableSessionComponentAccessor()
|
||||||
@@ -63,13 +64,13 @@ internal class LLFirNonEmptyResolveExtensionTool(
|
|||||||
|
|
||||||
override val packageProvider: KotlinPackageProvider = LLFirResolveExtensionToolPackageProvider(packageFilter)
|
override val packageProvider: KotlinPackageProvider = LLFirResolveExtensionToolPackageProvider(packageFilter)
|
||||||
|
|
||||||
override val symbolNameCache: LLFirSymbolProviderNameCache = LLFirResolveExtensionToolNameCache(packageFilter, fileProvider)
|
override val symbolNamesProvider: FirSymbolNamesProvider = LLFirResolveExtensionToolSymbolNamesProvider(packageFilter, fileProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class LLFirResolveExtensionToolNameCache(
|
private class LLFirResolveExtensionToolSymbolNamesProvider(
|
||||||
private val packageFilter: LLFirResolveExtensionToolPackageFilter,
|
private val packageFilter: LLFirResolveExtensionToolPackageFilter,
|
||||||
private val fileProvider: LLFirResolveExtensionsFileProvider,
|
private val fileProvider: LLFirResolveExtensionsFileProvider,
|
||||||
) : LLFirSymbolProviderNameCache() {
|
) : FirSymbolNamesProvider() {
|
||||||
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> = forbidAnalysis {
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> = forbidAnalysis {
|
||||||
if (!packageFilter.packageExists(packageFqName)) return emptySet()
|
if (!packageFilter.packageExists(packageFqName)) return emptySet()
|
||||||
fileProvider.getFilesByPackage(packageFqName)
|
fileProvider.getFilesByPackage(packageFqName)
|
||||||
@@ -87,7 +88,7 @@ private class LLFirResolveExtensionToolNameCache(
|
|||||||
.flatMapTo(mutableSetOf()) { it.getTopLevelCallableNames() }
|
.flatMapTo(mutableSetOf()) { it.getTopLevelCallableNames() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mayHaveTopLevelClassifier(classId: ClassId, mayHaveFunctionClass: Boolean): Boolean = forbidAnalysis {
|
override fun mayHaveTopLevelClassifier(classId: ClassId): Boolean = forbidAnalysis {
|
||||||
if (!packageFilter.packageExists(classId.packageFqName)) return false
|
if (!packageFilter.packageExists(classId.packageFqName)) return false
|
||||||
|
|
||||||
fileProvider.getFilesByPackage(classId.packageFqName)
|
fileProvider.getFilesByPackage(classId.packageFqName)
|
||||||
|
|||||||
+9
-8
@@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirKotlinSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirKotlinSymbolNamesProvider
|
||||||
import com.intellij.openapi.project.Project
|
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.providers.LLFirKotlinSymbolProviderWithNameCache
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirKotlinSymbolProviderNameCache
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
||||||
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
|||||||
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider
|
import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.java.deserialization.KotlinBuiltins
|
import org.jetbrains.kotlin.fir.java.deserialization.KotlinBuiltins
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.realPsi
|
import org.jetbrains.kotlin.fir.realPsi
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
@@ -50,11 +51,11 @@ internal open class JvmStubBasedFirDeserializedSymbolProvider(
|
|||||||
project: Project,
|
project: Project,
|
||||||
scope: GlobalSearchScope,
|
scope: GlobalSearchScope,
|
||||||
private val initialOrigin: FirDeclarationOrigin
|
private val initialOrigin: FirDeclarationOrigin
|
||||||
) : LLFirKotlinSymbolProviderWithNameCache(session) {
|
) : LLFirKotlinSymbolProvider(session) {
|
||||||
private val declarationProvider by lazy(LazyThreadSafetyMode.PUBLICATION) { project.createDeclarationProvider(scope, module = null) }
|
private val declarationProvider by lazy(LazyThreadSafetyMode.PUBLICATION) { project.createDeclarationProvider(scope, module = null) }
|
||||||
private val moduleData = moduleDataProvider.getModuleData(null)
|
private val moduleData = moduleDataProvider.getModuleData(null)
|
||||||
|
|
||||||
override val symbolNameCache: LLFirKotlinSymbolProviderNameCache = LLFirKotlinSymbolProviderNameCache(session, declarationProvider)
|
override val symbolNamesProvider: FirSymbolNamesProvider = LLFirKotlinSymbolNamesProvider.cached(session, declarationProvider)
|
||||||
|
|
||||||
private val typeAliasCache: FirCache<ClassId, FirTypeAliasSymbol?, StubBasedFirDeserializationContext?> =
|
private val typeAliasCache: FirCache<ClassId, FirTypeAliasSymbol?, StubBasedFirDeserializationContext?> =
|
||||||
session.firCachesFactory.createCacheWithPostCompute(
|
session.firCachesFactory.createCacheWithPostCompute(
|
||||||
@@ -192,7 +193,7 @@ internal open class JvmStubBasedFirDeserializedSymbolProvider(
|
|||||||
private fun <C : FirCallableSymbol<*>, CONTEXT> FirCache<CallableId, List<C>, CONTEXT?>.getCallablesWithoutContext(
|
private fun <C : FirCallableSymbol<*>, CONTEXT> FirCache<CallableId, List<C>, CONTEXT?>.getCallablesWithoutContext(
|
||||||
id: CallableId,
|
id: CallableId,
|
||||||
): List<C> {
|
): List<C> {
|
||||||
if (!symbolNameCache.mayHaveTopLevelCallable(id.packageName, id.callableName)) return emptyList()
|
if (!symbolNamesProvider.mayHaveTopLevelCallable(id.packageName, id.callableName)) return emptyList()
|
||||||
return getValue(id, null)
|
return getValue(id, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,12 +242,12 @@ internal open class JvmStubBasedFirDeserializedSymbolProvider(
|
|||||||
|
|
||||||
override fun getPackage(fqName: FqName): FqName? =
|
override fun getPackage(fqName: FqName): FqName? =
|
||||||
fqName.takeIf {
|
fqName.takeIf {
|
||||||
symbolNameCache.getTopLevelClassifierNamesInPackage(fqName)?.isNotEmpty() == true ||
|
symbolNamesProvider.getTopLevelClassifierNamesInPackage(fqName)?.isNotEmpty() == true ||
|
||||||
symbolNameCache.getPackageNamesWithTopLevelCallables()?.contains(fqName.asString()) == true
|
symbolNamesProvider.getPackageNamesWithTopLevelCallables()?.contains(fqName.asString()) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
if (!symbolNameCache.mayHaveTopLevelClassifier(classId, mayHaveFunctionClass = false)) return null
|
if (!symbolNamesProvider.mayHaveTopLevelClassifier(classId)) return null
|
||||||
return getClass(classId) ?: getTypeAlias(classId)
|
return getClass(classId) ?: getTypeAlias(classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirDelegatingCachedSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirCachedSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [FirSymbolNamesProvider] that fetches top-level names from a Kotlin [declarationProvider].
|
||||||
|
*/
|
||||||
|
internal class LLFirKotlinSymbolNamesProvider(
|
||||||
|
private val declarationProvider: KotlinDeclarationProvider,
|
||||||
|
) : FirSymbolNamesProvider() {
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> =
|
||||||
|
declarationProvider
|
||||||
|
.getTopLevelKotlinClassLikeDeclarationNamesInPackage(packageFqName)
|
||||||
|
.mapTo(mutableSetOf()) { it.asString() }
|
||||||
|
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> =
|
||||||
|
declarationProvider.computePackageSetWithTopLevelCallableDeclarations()
|
||||||
|
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name> =
|
||||||
|
declarationProvider.getTopLevelCallableNamesInPackage(packageFqName)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun cached(session: FirSession, declarationProvider: KotlinDeclarationProvider): FirCachedSymbolNamesProvider =
|
||||||
|
FirDelegatingCachedSymbolNamesProvider(session, LLFirKotlinSymbolNamesProvider(declarationProvider))
|
||||||
|
}
|
||||||
|
}
|
||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.util
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An [LLFirSymbolProviderNameCache] that fetches top-level names from a Kotlin [declarationProvider].
|
|
||||||
*/
|
|
||||||
internal class LLFirKotlinSymbolProviderNameCache(
|
|
||||||
firSession: FirSession,
|
|
||||||
private val declarationProvider: KotlinDeclarationProvider,
|
|
||||||
) : LLFirSymbolProviderNameCacheBase(firSession) {
|
|
||||||
override fun computeClassifierNames(packageFqName: FqName): Set<String> =
|
|
||||||
declarationProvider
|
|
||||||
.getTopLevelKotlinClassLikeDeclarationNamesInPackage(packageFqName)
|
|
||||||
.mapTo(mutableSetOf()) { it.asString() }
|
|
||||||
|
|
||||||
override fun computePackageNamesWithTopLevelCallables(): Set<String> =
|
|
||||||
declarationProvider.computePackageSetWithTopLevelCallableDeclarations()
|
|
||||||
|
|
||||||
override fun computeCallableNames(packageFqName: FqName): Set<Name> =
|
|
||||||
declarationProvider.getTopLevelCallableNamesInPackage(packageFqName)
|
|
||||||
}
|
|
||||||
-149
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.util
|
|
||||||
|
|
||||||
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.resolve.providers.flatMapToNullableSet
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.mayHaveTopLevelClassifier
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
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
|
|
||||||
* symbol finding early if the symbol name isn't contained in the symbol provider's domain.
|
|
||||||
*
|
|
||||||
* For [getTopLevelClassifierNamesInPackage], [getTopLevelCallableNamesInPackage], and [getPackageNamesWithTopLevelCallables], the result
|
|
||||||
* may have false-positive entries but cannot have false-negative entries.
|
|
||||||
* It should contain all the names in the package/all package names but may have some additional names that are not there.
|
|
||||||
* Also, `null` might be returned when it's too expensive to calculate the sets.
|
|
||||||
*
|
|
||||||
* For [mayHaveTopLevelClassifier] and [mayHaveTopLevelCallable], the result may be a false-positive result but cannot be a false-negative.
|
|
||||||
*/
|
|
||||||
internal abstract class LLFirSymbolProviderNameCache {
|
|
||||||
/**
|
|
||||||
* Returns the set of top-level classifier names (classes, interfaces, objects, and type aliases) inside the [packageFqName] package
|
|
||||||
* within the cache's scope.
|
|
||||||
*
|
|
||||||
* @see LLFirSymbolProviderNameCache
|
|
||||||
*/
|
|
||||||
abstract fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the set of package names which contain a top-level callable declaration within the cache's scope.
|
|
||||||
*
|
|
||||||
* @see LLFirSymbolProviderNameCache
|
|
||||||
*/
|
|
||||||
abstract fun getPackageNamesWithTopLevelCallables(): Set<String>?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the set of top-level callable names (functions and properties) inside the [packageFqName] package within the cache's scope.
|
|
||||||
*
|
|
||||||
* @see LLFirSymbolProviderNameCache
|
|
||||||
*/
|
|
||||||
abstract fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the cache's scope may contain a top-level classifier (class, interface, object, or type alias) with the given [classId].
|
|
||||||
*
|
|
||||||
* @see LLFirSymbolProviderNameCache
|
|
||||||
*/
|
|
||||||
abstract fun mayHaveTopLevelClassifier(classId: ClassId, mayHaveFunctionClass: Boolean): Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the cache's scope may contain a top-level callable (function or property) called [name] inside the [packageFqName] package.
|
|
||||||
*
|
|
||||||
* @see LLFirSymbolProviderNameCache
|
|
||||||
*/
|
|
||||||
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 computePackageNamesWithTopLevelCallables(): Set<String>?
|
|
||||||
abstract fun computeCallableNames(packageFqName: FqName): Set<Name>?
|
|
||||||
|
|
||||||
private val topLevelClassifierNamesByPackage =
|
|
||||||
firSession.firCachesFactory.createCache(::computeClassifierNames)
|
|
||||||
|
|
||||||
private val topLevelCallablePackageNames by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
|
||||||
computePackageNamesWithTopLevelCallables()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val topLevelCallableNamesByPackage =
|
|
||||||
firSession.firCachesFactory.createCache(::computeCallableNames)
|
|
||||||
|
|
||||||
final override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? =
|
|
||||||
topLevelClassifierNamesByPackage.getValue(packageFqName)
|
|
||||||
|
|
||||||
final override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? {
|
|
||||||
val packageNames = getPackageNamesWithTopLevelCallables()
|
|
||||||
if (packageNames != null && packageFqName.asString() !in packageNames) return null
|
|
||||||
|
|
||||||
return topLevelCallableNamesByPackage.getValue(packageFqName)
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun getPackageNamesWithTopLevelCallables(): Set<String>? = topLevelCallablePackageNames
|
|
||||||
|
|
||||||
final override fun mayHaveTopLevelClassifier(classId: ClassId, mayHaveFunctionClass: Boolean): Boolean {
|
|
||||||
val names = getTopLevelClassifierNamesInPackage(classId.packageFqName) ?: return true
|
|
||||||
return names.mayHaveTopLevelClassifier(classId, firSession, mayHaveFunctionClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean {
|
|
||||||
if (name.isSpecial) return true
|
|
||||||
val names = getTopLevelCallableNamesInPackage(packageFqName) ?: return true
|
|
||||||
return name in names
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object LLFirEmptySymbolProviderNameCache : LLFirSymbolProviderNameCache() {
|
|
||||||
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> = emptySet()
|
|
||||||
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name> = emptySet()
|
|
||||||
override fun getPackageNamesWithTopLevelCallables(): Set<String> = emptySet()
|
|
||||||
override fun mayHaveTopLevelClassifier(classId: ClassId, mayHaveFunctionClass: Boolean): Boolean = false
|
|
||||||
override fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean = false
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class LLFirCompositeSymbolProviderNameCache
|
|
||||||
private constructor(
|
|
||||||
private val caches: List<LLFirSymbolProviderNameCache>
|
|
||||||
) : LLFirSymbolProviderNameCache() {
|
|
||||||
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? {
|
|
||||||
return caches.flatMapToNullableSet { it.getTopLevelClassifierNamesInPackage(packageFqName) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPackageNamesWithTopLevelCallables(): Set<String>? {
|
|
||||||
return caches.flatMapToNullableSet { it.getPackageNamesWithTopLevelCallables() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? {
|
|
||||||
return caches.flatMapToNullableSet { it.getTopLevelCallableNamesInPackage(packageFqName) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mayHaveTopLevelClassifier(classId: ClassId, mayHaveFunctionClass: Boolean): Boolean {
|
|
||||||
return caches.any { it.mayHaveTopLevelClassifier(classId, mayHaveFunctionClass) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean {
|
|
||||||
return caches.any { it.mayHaveTopLevelCallable(packageFqName, name) }
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create(caches: List<LLFirSymbolProviderNameCache>): LLFirSymbolProviderNameCache {
|
|
||||||
return when (caches.size) {
|
|
||||||
0 -> LLFirEmptySymbolProviderNameCache
|
|
||||||
1 -> caches.single()
|
|
||||||
else -> LLFirCompositeSymbolProviderNameCache(caches)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-6
@@ -18,6 +18,8 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
|||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.getDeprecationsProvider
|
import org.jetbrains.kotlin.fir.declarations.getDeprecationsProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProviderWithoutCallables
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
@@ -137,11 +139,8 @@ class NativeForwardDeclarationsSymbolProvider(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String> {
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProviderWithoutCallables() {
|
||||||
return includedForwardDeclarationsByPackage[packageFqName].orEmpty()
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> =
|
||||||
|
includedForwardDeclarationsByPackage[packageFqName].orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String> = emptySet()
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> = emptySet()
|
|
||||||
}
|
}
|
||||||
+36
-34
@@ -13,8 +13,10 @@ import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
|||||||
import org.jetbrains.kotlin.fir.caches.getValue
|
import org.jetbrains.kotlin.fir.caches.getValue
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.isNewPlaceForBodyGeneration
|
import org.jetbrains.kotlin.fir.isNewPlaceForBodyGeneration
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirCachedSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
@@ -83,23 +85,46 @@ abstract class AbstractFirDeserializedSymbolProvider(
|
|||||||
) : FirSymbolProvider(session) {
|
) : FirSymbolProvider(session) {
|
||||||
// ------------------------ Caches ------------------------
|
// ------------------------ Caches ------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [packageNamesForNonClassDeclarations] might contain names of packages containing type aliases, on top of packages containing
|
||||||
|
* callables, so it's not the same as `symbolNamesProvider.getPackageNamesWithTopLevelCallables` and cannot be replaced by it.
|
||||||
|
*/
|
||||||
private val packageNamesForNonClassDeclarations: Set<String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
private val packageNamesForNonClassDeclarations: Set<String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
computePackageSetWithNonClassDeclarations()
|
computePackageSetWithNonClassDeclarations()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirCachedSymbolNamesProvider(session) {
|
||||||
|
override fun computeTopLevelClassifierNames(packageFqName: FqName): Set<String>? {
|
||||||
|
val classesInPackage = knownTopLevelClassesInPackage(packageFqName) ?: return null
|
||||||
|
|
||||||
|
if (packageFqName.asString() !in packageNamesForNonClassDeclarations) return classesInPackage
|
||||||
|
|
||||||
|
val typeAliasNames = typeAliasesNamesByPackage.getValue(packageFqName)
|
||||||
|
if (typeAliasNames.isEmpty()) return classesInPackage
|
||||||
|
|
||||||
|
return buildSet {
|
||||||
|
addAll(classesInPackage)
|
||||||
|
typeAliasNames.mapTo(this) { it.asString() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> = packageNamesForNonClassDeclarations
|
||||||
|
|
||||||
|
override fun computePackageNamesWithTopLevelCallables(): Set<String> = packageNamesForNonClassDeclarations
|
||||||
|
|
||||||
|
override fun computeTopLevelCallableNames(packageFqName: FqName): Set<Name> =
|
||||||
|
getPackageParts(packageFqName).flatMapTo(mutableSetOf()) {
|
||||||
|
it.topLevelFunctionNameIndex.keys + it.topLevelPropertyNameIndex.keys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val typeAliasesNamesByPackage: FirCache<FqName, Set<Name>, Nothing?> =
|
private val typeAliasesNamesByPackage: FirCache<FqName, Set<Name>, Nothing?> =
|
||||||
session.firCachesFactory.createCache { fqName: FqName ->
|
session.firCachesFactory.createCache { fqName: FqName ->
|
||||||
getPackageParts(fqName).flatMapTo(mutableSetOf()) { it.typeAliasNameIndex.keys }
|
getPackageParts(fqName).flatMapTo(mutableSetOf()) { it.typeAliasNameIndex.keys }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val allNamesByPackage: FirCache<FqName, Set<Name>, Nothing?> =
|
|
||||||
session.firCachesFactory.createCache { fqName: FqName ->
|
|
||||||
getPackageParts(fqName).flatMapTo(mutableSetOf()) {
|
|
||||||
it.topLevelFunctionNameIndex.keys + it.topLevelPropertyNameIndex.keys
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val packagePartsCache = session.firCachesFactory.createCache(::tryComputePackagePartInfos)
|
private val packagePartsCache = session.firCachesFactory.createCache(::tryComputePackagePartInfos)
|
||||||
|
|
||||||
private val typeAliasCache: FirCache<ClassId, FirTypeAliasSymbol?, FirDeserializationContext?> =
|
private val typeAliasCache: FirCache<ClassId, FirTypeAliasSymbol?, FirDeserializationContext?> =
|
||||||
session.firCachesFactory.createCacheWithPostCompute(
|
session.firCachesFactory.createCacheWithPostCompute(
|
||||||
createValue = { classId, _ -> findAndDeserializeTypeAlias(classId) },
|
createValue = { classId, _ -> findAndDeserializeTypeAlias(classId) },
|
||||||
@@ -109,6 +134,7 @@ abstract class AbstractFirDeserializedSymbolProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
private val classCache: FirCache<ClassId, FirRegularClassSymbol?, FirDeserializationContext?> =
|
private val classCache: FirCache<ClassId, FirRegularClassSymbol?, FirDeserializationContext?> =
|
||||||
session.firCachesFactory.createCacheWithPostCompute(
|
session.firCachesFactory.createCacheWithPostCompute(
|
||||||
createValue = { classId, context -> findAndDeserializeClass(classId, context) },
|
createValue = { classId, context -> findAndDeserializeClass(classId, context) },
|
||||||
@@ -132,24 +158,6 @@ abstract class AbstractFirDeserializedSymbolProvider(
|
|||||||
// This method should only be used for sake of optimization to avoid having too many empty-list/null values in our caches
|
// This method should only be used for sake of optimization to avoid having too many empty-list/null values in our caches
|
||||||
protected abstract fun computePackageSetWithNonClassDeclarations(): Set<String>
|
protected abstract fun computePackageSetWithNonClassDeclarations(): Set<String>
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String> = computePackageSetWithNonClassDeclarations()
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> = allNamesByPackage.getValue(packageFqName)
|
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? {
|
|
||||||
val classesInPackage = knownTopLevelClassesInPackage(packageFqName) ?: return null
|
|
||||||
|
|
||||||
if (packageFqName.asString() !in packageNamesForNonClassDeclarations) return classesInPackage
|
|
||||||
|
|
||||||
val typeAliasNames = typeAliasesNamesByPackage.getValue(packageFqName)
|
|
||||||
if (typeAliasNames.isEmpty()) return classesInPackage
|
|
||||||
|
|
||||||
return buildSet {
|
|
||||||
addAll(classesInPackage)
|
|
||||||
typeAliasNames.mapTo(this) { it.asString() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun knownTopLevelClassesInPackage(packageFqName: FqName): Set<String>?
|
protected abstract fun knownTopLevelClassesInPackage(packageFqName: FqName): Set<String>?
|
||||||
|
|
||||||
protected abstract fun extractClassMetadata(
|
protected abstract fun extractClassMetadata(
|
||||||
@@ -253,8 +261,8 @@ abstract class AbstractFirDeserializedSymbolProvider(
|
|||||||
val parentClassId = classId.outerClassId
|
val parentClassId = classId.outerClassId
|
||||||
|
|
||||||
// Actually, the second "if" should be enough but the first one might work faster
|
// Actually, the second "if" should be enough but the first one might work faster
|
||||||
if (parentClassId == null && !mayHaveTopLevelClass(classId)) return null
|
if (parentClassId == null && !symbolNamesProvider.mayHaveTopLevelClassifier(classId)) return null
|
||||||
if (parentClassId != null && !mayHaveTopLevelClass(classId.outermostClassId)) return null
|
if (parentClassId != null && !symbolNamesProvider.mayHaveTopLevelClassifier(classId.outermostClassId)) return null
|
||||||
|
|
||||||
if (parentContext == null && parentClassId != null) {
|
if (parentContext == null && parentClassId != null) {
|
||||||
val alreadyLoaded = classCache.getValueIfComputed(classId)
|
val alreadyLoaded = classCache.getValueIfComputed(classId)
|
||||||
@@ -266,11 +274,6 @@ abstract class AbstractFirDeserializedSymbolProvider(
|
|||||||
return classCache.getValue(classId, parentContext)
|
return classCache.getValue(classId, parentContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mayHaveTopLevelClass(topLevelClassId: ClassId): Boolean {
|
|
||||||
val knownClassNames = knownTopLevelClassifiersInPackage(topLevelClassId.packageFqName) ?: return true
|
|
||||||
return topLevelClassId.shortClassName.asString() in knownClassNames
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getTypeAlias(classId: ClassId): FirTypeAliasSymbol? {
|
private fun getTypeAlias(classId: ClassId): FirTypeAliasSymbol? {
|
||||||
if (!classId.relativeClassName.isOneSegmentFQN()) return null
|
if (!classId.relativeClassName.isOneSegmentFQN()) return null
|
||||||
|
|
||||||
@@ -295,8 +298,7 @@ abstract class AbstractFirDeserializedSymbolProvider(
|
|||||||
private fun <C : FirCallableSymbol<*>> FirCache<CallableId, List<C>, Nothing?>.getCallables(id: CallableId): List<C> {
|
private fun <C : FirCallableSymbol<*>> FirCache<CallableId, List<C>, Nothing?>.getCallables(id: CallableId): List<C> {
|
||||||
// Don't actually query FirCache when we're sure there are no relevant value
|
// Don't actually query FirCache when we're sure there are no relevant value
|
||||||
// It helps to decrease the size of a cache thus leading to better query time
|
// It helps to decrease the size of a cache thus leading to better query time
|
||||||
if (id.packageName.asString() !in packageNamesForNonClassDeclarations) return emptyList()
|
if (!symbolNamesProvider.mayHaveTopLevelCallable(id.packageName, id.callableName)) return emptyList()
|
||||||
if (id.callableName !in allNamesByPackage.getValue(id.packageName)) return emptyList()
|
|
||||||
return getValue(id)
|
return getValue(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-10
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer
|
|||||||
import org.jetbrains.kotlin.fir.deserialization.FirConstDeserializer
|
import org.jetbrains.kotlin.fir.deserialization.FirConstDeserializer
|
||||||
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
|
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
|
||||||
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
|
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
@@ -71,18 +72,26 @@ open class FirBuiltinSymbolProvider(
|
|||||||
} ?: syntheticFunctionInterfaceProvider.getClassLikeSymbolByClassId(classId)
|
} ?: syntheticFunctionInterfaceProvider.getClassLikeSymbolByClassId(classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String> =
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProvider() {
|
||||||
allPackageFragments.keys.mapTo(mutableSetOf()) { it.asString() }
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> =
|
||||||
|
allPackageFragments.keys.mapTo(mutableSetOf()) { it.asString() }
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String> =
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> =
|
||||||
allPackageFragments[packageFqName]?.flatMapTo(mutableSetOf()) { fragment ->
|
allPackageFragments[packageFqName]?.flatMapTo(mutableSetOf()) { fragment ->
|
||||||
fragment.classDataFinder.allClassIds.map { it.shortClassName.asString() }
|
fragment.classDataFinder.allClassIds.map { it.shortClassName.asString() }
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> =
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name> =
|
||||||
allPackageFragments[packageFqName]?.flatMapTo(mutableSetOf()) {
|
allPackageFragments[packageFqName]?.flatMapTo(mutableSetOf()) {
|
||||||
it.getTopLevelCallableNames()
|
it.getTopLevelCallableNames()
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
|
// This symbol provider delegates to `FirBuiltinSyntheticFunctionInterfaceProvider`, so synthetic function types can be provided.
|
||||||
|
override val mayHaveSyntheticFunctionTypes: Boolean get() = true
|
||||||
|
|
||||||
|
override fun mayHaveSyntheticFunctionType(classId: ClassId): Boolean =
|
||||||
|
syntheticFunctionInterfaceProvider.symbolNamesProvider.mayHaveSyntheticFunctionType(classId)
|
||||||
|
}
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.java
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProviderWithoutCallables
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
@@ -68,9 +70,10 @@ class JavaSymbolProvider(
|
|||||||
|
|
||||||
override fun getPackage(fqName: FqName): FqName? = javaFacade.getPackage(fqName)
|
override fun getPackage(fqName: FqName): FqName? = javaFacade.getPackage(fqName)
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String> = emptySet()
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProviderWithoutCallables() {
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? = javaFacade.knownClassNamesInPackage(packageFqName)
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? =
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> = emptySet()
|
javaFacade.knownClassNamesInPackage(packageFqName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.javaSymbolProvider: JavaSymbolProvider? by FirSession.nullableSessionComponentAccessor()
|
val FirSession.javaSymbolProvider: JavaSymbolProvider? by FirSession.nullableSessionComponentAccessor()
|
||||||
|
|||||||
+14
-11
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.caches.*
|
|||||||
import org.jetbrains.kotlin.fir.declarations.validate
|
import org.jetbrains.kotlin.fir.declarations.validate
|
||||||
import org.jetbrains.kotlin.fir.ownerGenerator
|
import org.jetbrains.kotlin.fir.ownerGenerator
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
@@ -146,6 +147,19 @@ class FirExtensionDeclarationsSymbolProvider private constructor(
|
|||||||
|
|
||||||
// ------------------------------------------ provider methods ------------------------------------------
|
// ------------------------------------------ provider methods ------------------------------------------
|
||||||
|
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProvider() {
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> =
|
||||||
|
classNamesInPackageCache.getValue()[packageFqName] ?: emptySet()
|
||||||
|
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> =
|
||||||
|
extensions.flatMapTo(mutableSetOf()) { extension ->
|
||||||
|
extension.topLevelCallableIdsCache.getValue().map { it.packageName.asString() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name> =
|
||||||
|
callableNamesInPackageCache.getValue()[packageFqName].orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
return classCache.getValue(classId)
|
return classCache.getValue(classId)
|
||||||
}
|
}
|
||||||
@@ -170,15 +184,4 @@ class FirExtensionDeclarationsSymbolProvider private constructor(
|
|||||||
override fun getPackage(fqName: FqName): FqName? {
|
override fun getPackage(fqName: FqName): FqName? {
|
||||||
return fqName.takeIf { packageCache.getValue(fqName, null) }
|
return fqName.takeIf { packageCache.getValue(fqName, null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String> =
|
|
||||||
extensions.flatMapTo(mutableSetOf()) { extension ->
|
|
||||||
extension.topLevelCallableIdsCache.getValue().map { it.packageName.asString() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String> =
|
|
||||||
classNamesInPackageCache.getValue()[packageFqName] ?: emptySet()
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> =
|
|
||||||
callableNamesInPackageCache.getValue()[packageFqName].orEmpty()
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-10
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.extensions
|
package org.jetbrains.kotlin.fir.extensions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
@@ -33,6 +34,17 @@ class FirSwitchableExtensionDeclarationsSymbolProvider private constructor(
|
|||||||
|
|
||||||
private var disabled: Boolean = false
|
private var disabled: Boolean = false
|
||||||
|
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProvider() {
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String>? =
|
||||||
|
if (disabled) null else delegate.symbolNamesProvider.getPackageNamesWithTopLevelCallables()
|
||||||
|
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? =
|
||||||
|
if (disabled) null else delegate.symbolNamesProvider.getTopLevelClassifierNamesInPackage(packageFqName)
|
||||||
|
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? =
|
||||||
|
if (disabled) null else delegate.symbolNamesProvider.getTopLevelCallableNamesInPackage(packageFqName)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
if (disabled) return null
|
if (disabled) return null
|
||||||
return delegate.getClassLikeSymbolByClassId(classId)
|
return delegate.getClassLikeSymbolByClassId(classId)
|
||||||
@@ -70,16 +82,6 @@ class FirSwitchableExtensionDeclarationsSymbolProvider private constructor(
|
|||||||
fun enable() {
|
fun enable() {
|
||||||
disabled = false
|
disabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? =
|
|
||||||
if (disabled) null else delegate.computePackageSetWithTopLevelCallables()
|
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? =
|
|
||||||
if (disabled) null else delegate.knownTopLevelClassifiersInPackage(packageFqName)
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? =
|
|
||||||
if (disabled) null else delegate.computeCallableNamesInPackage(packageFqName)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.generatedDeclarationsSymbolProvider: FirSwitchableExtensionDeclarationsSymbolProvider? by FirSession.nullableSessionComponentAccessor()
|
val FirSession.generatedDeclarationsSymbolProvider: FirSwitchableExtensionDeclarationsSymbolProvider? by FirSession.nullableSessionComponentAccessor()
|
||||||
|
|||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.fir.resolve.providers
|
||||||
|
|
||||||
|
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.resolve.providers.impl.FirSyntheticFunctionInterfaceProviderBase.Companion.mayBeSyntheticFunctionClassName
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [FirSymbolNamesProvider] that caches all name sets.
|
||||||
|
*/
|
||||||
|
abstract class FirCachedSymbolNamesProvider(protected val session: FirSession) : FirSymbolNamesProvider() {
|
||||||
|
abstract fun computeTopLevelClassifierNames(packageFqName: FqName): Set<String>?
|
||||||
|
abstract fun computePackageNamesWithTopLevelCallables(): Set<String>?
|
||||||
|
abstract fun computeTopLevelCallableNames(packageFqName: FqName): Set<Name>?
|
||||||
|
|
||||||
|
private val topLevelClassifierNamesByPackage =
|
||||||
|
session.firCachesFactory.createCache(::computeTopLevelClassifierNames)
|
||||||
|
|
||||||
|
private val topLevelCallablePackageNames by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
|
computePackageNamesWithTopLevelCallables()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val topLevelCallableNamesByPackage =
|
||||||
|
session.firCachesFactory.createCache(::computeTopLevelCallableNames)
|
||||||
|
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? =
|
||||||
|
topLevelClassifierNamesByPackage.getValue(packageFqName)
|
||||||
|
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String>? = topLevelCallablePackageNames
|
||||||
|
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? {
|
||||||
|
val packageNames = getPackageNamesWithTopLevelCallables()
|
||||||
|
if (packageNames != null && packageFqName.asString() !in packageNames) return emptySet()
|
||||||
|
|
||||||
|
return topLevelCallableNamesByPackage.getValue(packageFqName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FirDelegatingCachedSymbolNamesProvider(
|
||||||
|
session: FirSession,
|
||||||
|
private val delegate: FirSymbolNamesProvider,
|
||||||
|
) : FirCachedSymbolNamesProvider(session) {
|
||||||
|
override fun computeTopLevelClassifierNames(packageFqName: FqName): Set<String>? =
|
||||||
|
delegate.getTopLevelClassifierNamesInPackage(packageFqName)
|
||||||
|
|
||||||
|
override fun computePackageNamesWithTopLevelCallables(): Set<String>? =
|
||||||
|
delegate.getPackageNamesWithTopLevelCallables()
|
||||||
|
|
||||||
|
override fun computeTopLevelCallableNames(packageFqName: FqName): Set<Name>? =
|
||||||
|
delegate.getTopLevelCallableNamesInPackage(packageFqName)
|
||||||
|
|
||||||
|
override val mayHaveSyntheticFunctionTypes: Boolean
|
||||||
|
get() = delegate.mayHaveSyntheticFunctionTypes
|
||||||
|
|
||||||
|
override fun mayHaveSyntheticFunctionType(classId: ClassId): Boolean = delegate.mayHaveSyntheticFunctionType(classId)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class FirCompositeCachedSymbolNamesProvider(
|
||||||
|
session: FirSession,
|
||||||
|
val providers: List<FirSymbolNamesProvider>,
|
||||||
|
) : FirCachedSymbolNamesProvider(session) {
|
||||||
|
override fun computeTopLevelClassifierNames(packageFqName: FqName): Set<String>? =
|
||||||
|
providers.flatMapToNullableSet { it.getTopLevelClassifierNamesInPackage(packageFqName) }
|
||||||
|
|
||||||
|
override fun computePackageNamesWithTopLevelCallables(): Set<String>? =
|
||||||
|
providers.flatMapToNullableSet { it.getPackageNamesWithTopLevelCallables() }
|
||||||
|
|
||||||
|
override fun computeTopLevelCallableNames(packageFqName: FqName): Set<Name>? =
|
||||||
|
providers.flatMapToNullableSet { it.getTopLevelCallableNamesInPackage(packageFqName) }
|
||||||
|
|
||||||
|
override val mayHaveSyntheticFunctionTypes: Boolean = providers.any { it.mayHaveSyntheticFunctionTypes }
|
||||||
|
|
||||||
|
@OptIn(FirSymbolProviderInternals::class)
|
||||||
|
override fun mayHaveSyntheticFunctionType(classId: ClassId): Boolean {
|
||||||
|
if (!classId.mayBeSyntheticFunctionClassName()) return false
|
||||||
|
|
||||||
|
// We cannot use `session`'s function type service directly, because the sessions of `providers` aren't necessarily the same as
|
||||||
|
// `session`. So we might miss some other session's synthetic function type.
|
||||||
|
return providers.any { it.mayHaveSyntheticFunctionType(classId) }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun create(session: FirSession, providers: List<FirSymbolNamesProvider>): FirSymbolNamesProvider = when (providers.size) {
|
||||||
|
0 -> FirEmptySymbolNamesProvider
|
||||||
|
1 -> when (val provider = providers.single()) {
|
||||||
|
is FirCachedSymbolNamesProvider -> provider
|
||||||
|
else -> FirDelegatingCachedSymbolNamesProvider(session, provider)
|
||||||
|
}
|
||||||
|
else -> FirCompositeCachedSymbolNamesProvider(session, providers)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fromSymbolProviders(session: FirSession, providers: List<FirSymbolProvider>): FirSymbolNamesProvider =
|
||||||
|
create(session, providers.map { it.symbolNamesProvider })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works almost as regular flatMap, but returns a set and returns null if any lambda call returned null
|
||||||
|
*/
|
||||||
|
inline fun <T, R> Iterable<T>.flatMapToNullableSet(transform: (T) -> Iterable<R>?): Set<R>? =
|
||||||
|
flatMapTo(mutableSetOf()) { transform(it) ?: return null }
|
||||||
+160
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* 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.fir.resolve.providers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [FirSymbolNamesProvider] provides information about which symbols may be provided by a [FirSymbolProvider] given the symbol's name. This
|
||||||
|
* is usually checked before the symbol is requested with functions such as [FirSymbolProvider.getClassLikeSymbolByClassId].
|
||||||
|
*
|
||||||
|
* All `get*` functions in this interface have the following common contract:
|
||||||
|
* - They return `null` in case a name set is too hard, expensive, or even impossible to compute.
|
||||||
|
* - They might return a strict superset of the name set, i.e. the resulting set might contain some names that do not exist in the symbol
|
||||||
|
* provider. In other words, these sets allow false positives, but not false negatives.
|
||||||
|
* - It is usually not cheap to compute such sets on each query, so their result should be cached properly (see [FirCachedSymbolNamesProvider]).
|
||||||
|
* [FirSymbolNamesProvider]s may choose not to cache name sets if they are only going to be used for the construction of composite symbol
|
||||||
|
* name caches (to avoid useless layered caches) and the `mayHaveTopLevel*` functions aren't expected to be used.
|
||||||
|
*
|
||||||
|
* The result of [mayHaveTopLevelClassifier] and [mayHaveTopLevelCallable] may be a false positive but cannot be a false negative.
|
||||||
|
*/
|
||||||
|
abstract class FirSymbolNamesProvider {
|
||||||
|
/**
|
||||||
|
* Returns the set of top-level classifier names (classes, interfaces, objects, and type aliases) inside the [packageFqName] package
|
||||||
|
* within the provider's scope.
|
||||||
|
*
|
||||||
|
* All usages must take into account that the result might not include `kotlin.FunctionN` (and others for which a [FunctionTypeKind]
|
||||||
|
* exists).
|
||||||
|
*/
|
||||||
|
abstract fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of fully qualified package names which contain a top-level callable declaration within the provider's scope.
|
||||||
|
*/
|
||||||
|
abstract fun getPackageNamesWithTopLevelCallables(): Set<String>?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of top-level callable names (functions and properties) inside the [packageFqName] package within the provider's
|
||||||
|
* scope.
|
||||||
|
*
|
||||||
|
* When implementing this function, [getPackageNamesWithTopLevelCallables] should be taken into account. Specifically, if a package name
|
||||||
|
* is not in the set of package names with top-level callables, [getTopLevelCallableNamesInPackage] must return an empty set or `null`.
|
||||||
|
*/
|
||||||
|
abstract fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the [FirSymbolProvider] supported by this [FirSymbolNamesProvider] may contain generated function types (see
|
||||||
|
* [FunctionTypeKind]). Names of such function types cannot be included in [getTopLevelClassifierNamesInPackage], because they are
|
||||||
|
* generated on demand.
|
||||||
|
*
|
||||||
|
* [mayHaveSyntheticFunctionTypes] only needs to be overridden together with [mayHaveSyntheticFunctionType] if the supported
|
||||||
|
* [FirSymbolProvider] can provide generated function types. The value should be constant, which allows composite symbol providers to
|
||||||
|
* cache the result and achieve acceptable performance.
|
||||||
|
*/
|
||||||
|
open val mayHaveSyntheticFunctionTypes: Boolean = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether [classId] is considered a generated function type within the provider's scope and session.
|
||||||
|
*/
|
||||||
|
open fun mayHaveSyntheticFunctionType(classId: ClassId): Boolean =
|
||||||
|
error("`mayHaveSyntheticFunctionType` needs to be implemented when `mayHaveSyntheticFunctionTypes` is true.")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the provider's scope may contain a top-level classifier (class, interface, object, or type alias) with the given [classId].
|
||||||
|
*/
|
||||||
|
open fun mayHaveTopLevelClassifier(classId: ClassId): Boolean {
|
||||||
|
if (mayHaveSyntheticFunctionTypes && mayHaveSyntheticFunctionType(classId)) return true
|
||||||
|
|
||||||
|
val names = getTopLevelClassifierNamesInPackage(classId.packageFqName) ?: return true
|
||||||
|
if (classId.outerClassId == null) {
|
||||||
|
if (!names.mayContainTopLevelClassifier(classId.shortClassName)) return false
|
||||||
|
} else {
|
||||||
|
if (!names.mayContainTopLevelClassifier(classId.outermostClassId.shortClassName)) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the provider's scope may contain a top-level callable (function or property) called [name] inside the [packageFqName]
|
||||||
|
* package.
|
||||||
|
*/
|
||||||
|
open fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean {
|
||||||
|
// Symbol providers can potentially provide symbols for special names. Hence, special names have to be allowed.
|
||||||
|
if (name.isSpecial) return true
|
||||||
|
|
||||||
|
// The `packageNamesWithTopLevelCallables` check is implemented in `FirCachedSymbolNamesProvider` via
|
||||||
|
// `getTopLevelCallableNamesInPackage`. It is probably not worth checking it in uncached situations, since building the set of
|
||||||
|
// package names with top-level callables is likely as expensive as just calling an uncached `getTopLevelCallableNamesInPackage`.
|
||||||
|
val names = getTopLevelCallableNamesInPackage(packageFqName) ?: return true
|
||||||
|
return name in names
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Set<String>.mayContainTopLevelClassifier(shortClassName: Name): Boolean {
|
||||||
|
// Symbol providers can potentially provide symbols for special names. Hence, special names have to be allowed.
|
||||||
|
return shortClassName.isSpecial || shortClassName.asString() in this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [FirSymbolNamesProvider] for symbol providers which can't provide any symbol name sets.
|
||||||
|
*/
|
||||||
|
object FirNullSymbolNamesProvider : FirSymbolNamesProvider() {
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? = null
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? = null
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String>? = null
|
||||||
|
override fun mayHaveTopLevelClassifier(classId: ClassId): Boolean = true
|
||||||
|
override fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [FirSymbolNamesProvider] for symbol providers which don't contain *any* symbols.
|
||||||
|
*/
|
||||||
|
object FirEmptySymbolNamesProvider : FirSymbolNamesProvider() {
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> = emptySet()
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name> = emptySet()
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> = emptySet()
|
||||||
|
override fun mayHaveTopLevelClassifier(classId: ClassId): Boolean = false
|
||||||
|
override fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class FirSymbolNamesProviderWithoutCallables : FirSymbolNamesProvider() {
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> = emptySet()
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? = emptySet()
|
||||||
|
override fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
open class FirCompositeSymbolNamesProvider(val providers: List<FirSymbolNamesProvider>) : FirSymbolNamesProvider() {
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String>? {
|
||||||
|
return providers.flatMapToNullableSet { it.getTopLevelClassifierNamesInPackage(packageFqName) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String>? {
|
||||||
|
return providers.flatMapToNullableSet { it.getPackageNamesWithTopLevelCallables() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>? {
|
||||||
|
return providers.flatMapToNullableSet { it.getTopLevelCallableNamesInPackage(packageFqName) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override val mayHaveSyntheticFunctionTypes: Boolean = providers.any { it.mayHaveSyntheticFunctionTypes }
|
||||||
|
|
||||||
|
override fun mayHaveSyntheticFunctionType(classId: ClassId): Boolean = providers.any { it.mayHaveSyntheticFunctionType(classId) }
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun create(providers: List<FirSymbolNamesProvider>): FirSymbolNamesProvider = when (providers.size) {
|
||||||
|
0 -> FirEmptySymbolNamesProvider
|
||||||
|
1 -> providers.single()
|
||||||
|
else -> FirCompositeSymbolNamesProvider(providers)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fromSymbolProviders(providers: List<FirSymbolProvider>): FirSymbolNamesProvider {
|
||||||
|
return create(providers.map { it.symbolNamesProvider })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-64
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirSyntheticFunctionInterfaceProviderBase.Companion.mayBeSyntheticFunctionClassName
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.getDeclaredConstructors
|
import org.jetbrains.kotlin.fir.scopes.getDeclaredConstructors
|
||||||
import org.jetbrains.kotlin.fir.scopes.getFunctions
|
import org.jetbrains.kotlin.fir.scopes.getFunctions
|
||||||
@@ -17,7 +16,10 @@ import org.jetbrains.kotlin.fir.scopes.getProperties
|
|||||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeSimpleKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
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
|
||||||
@@ -26,6 +28,8 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
annotation class FirSymbolProviderInternals
|
annotation class FirSymbolProviderInternals
|
||||||
|
|
||||||
abstract class FirSymbolProvider(val session: FirSession) : FirSessionComponent {
|
abstract class FirSymbolProvider(val session: FirSession) : FirSessionComponent {
|
||||||
|
abstract val symbolNamesProvider: FirSymbolNamesProvider
|
||||||
|
|
||||||
abstract fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>?
|
abstract fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>?
|
||||||
|
|
||||||
@OptIn(FirSymbolProviderInternals::class)
|
@OptIn(FirSymbolProviderInternals::class)
|
||||||
@@ -53,37 +57,8 @@ abstract class FirSymbolProvider(val session: FirSession) : FirSessionComponent
|
|||||||
abstract fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name)
|
abstract fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name)
|
||||||
|
|
||||||
abstract fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime
|
abstract fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime
|
||||||
|
|
||||||
/**
|
|
||||||
* All the three "compute*" functions below have the following common contract:
|
|
||||||
* - They return null in case necessary name set is too hard/impossible to compute.
|
|
||||||
* - They might return a strict superset of the name set, i.e. the resulting set might contain some names that do not belong to the provider.
|
|
||||||
* - It might be non-cheap to compute them on each query, thus their result should be cached properly.
|
|
||||||
*
|
|
||||||
* @returns full package names that contain some top-level callables
|
|
||||||
*/
|
|
||||||
abstract fun computePackageSetWithTopLevelCallables(): Set<String>?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns top-level classifier names that belong to `packageFqName` or null if it's complicated to compute the set
|
|
||||||
*
|
|
||||||
* All usages must take into account that the result might not include kotlin.FunctionN
|
|
||||||
* (and others for which org.jetbrains.kotlin.builtins.functions.FunctionClassKind.Companion.byClassNamePrefix not-null)
|
|
||||||
*/
|
|
||||||
abstract fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns top-level callable names that belong to `packageFqName` or null if it's complicated to compute the set
|
|
||||||
*/
|
|
||||||
abstract fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Works almost as regular flatMap, but returns a set and returns null if any lambda call returned null
|
|
||||||
*/
|
|
||||||
inline fun <T, R> Iterable<T>.flatMapToNullableSet(transform: (T) -> Iterable<R>?): Set<R>? =
|
|
||||||
flatMapTo(mutableSetOf()) { transform(it) ?: return null }
|
|
||||||
|
|
||||||
private fun FirSymbolProvider.getClassDeclaredMemberScope(classId: ClassId): FirScope? {
|
private fun FirSymbolProvider.getClassDeclaredMemberScope(classId: ClassId): FirScope? {
|
||||||
val classSymbol = getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol ?: return null
|
val classSymbol = getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol ?: return null
|
||||||
return session.declaredMemberScope(classSymbol.fir, memberRequiredPhase = null)
|
return session.declaredMemberScope(classSymbol.fir, memberRequiredPhase = null)
|
||||||
@@ -114,39 +89,6 @@ fun FirSymbolProvider.getRegularClassSymbolByClassId(classId: ClassId): FirRegul
|
|||||||
return getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol
|
return getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether [classId] may be contained in the set of known classifier names.
|
|
||||||
*
|
|
||||||
* If it's certain that [classId] cannot be a function class (for example when [classId] is known to come from a package without
|
|
||||||
* function classes), [mayBeFunctionClass] can be set to `false`. This avoids a hash map access in
|
|
||||||
* [org.jetbrains.kotlin.builtins.functions.FunctionTypeKindExtractor.getFunctionalClassKindWithArity].
|
|
||||||
*/
|
|
||||||
fun Set<String>.mayHaveTopLevelClassifier(
|
|
||||||
classId: ClassId,
|
|
||||||
session: FirSession,
|
|
||||||
mayBeFunctionClass: Boolean = true,
|
|
||||||
): Boolean {
|
|
||||||
if (mayBeFunctionClass && isNameForFunctionClass(classId, session)) return true
|
|
||||||
|
|
||||||
if (classId.outerClassId == null) {
|
|
||||||
if (!mayHaveTopLevelClassifier(classId.shortClassName)) return false
|
|
||||||
} else {
|
|
||||||
if (!mayHaveTopLevelClassifier(classId.outermostClassId.shortClassName)) return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
private inline fun Set<String>.mayHaveTopLevelClassifier(shortClassName: Name): Boolean =
|
|
||||||
shortClassName.asString() in this || shortClassName.isSpecial
|
|
||||||
|
|
||||||
@OptIn(FirSymbolProviderInternals::class)
|
|
||||||
private fun isNameForFunctionClass(classId: ClassId, session: FirSession): Boolean {
|
|
||||||
if (!classId.mayBeSyntheticFunctionClassName()) return false
|
|
||||||
return session.functionTypeService.getKindByClassNamePrefix(classId.packageFqName, classId.shortClassName.asString()) != null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ClassId.toSymbol(session: FirSession): FirClassifierSymbol<*>? {
|
fun ClassId.toSymbol(session: FirSession): FirClassifierSymbol<*>? {
|
||||||
return session.symbolProvider.getClassLikeSymbolByClassId(this)
|
return session.symbolProvider.getClassLikeSymbolByClassId(this)
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-37
@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.fir.resolve.providers.impl
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.NoMutableState
|
import org.jetbrains.kotlin.fir.NoMutableState
|
||||||
import org.jetbrains.kotlin.fir.caches.FirCache
|
|
||||||
import org.jetbrains.kotlin.fir.caches.createCache
|
import org.jetbrains.kotlin.fir.caches.createCache
|
||||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||||
import org.jetbrains.kotlin.fir.caches.getValue
|
import org.jetbrains.kotlin.fir.caches.getValue
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirCompositeCachedSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.flatMapToNullableSet
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirSyntheticFunctionInterfaceProviderBase.Companion.isNameForFunctionClass
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.mayHaveTopLevelClassifier
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
@@ -39,25 +39,31 @@ class FirCachingCompositeSymbolProvider(
|
|||||||
private val topLevelPropertyCache = session.firCachesFactory.createCache(::computeTopLevelProperties)
|
private val topLevelPropertyCache = session.firCachesFactory.createCache(::computeTopLevelProperties)
|
||||||
private val packageCache = session.firCachesFactory.createCache(::computePackage)
|
private val packageCache = session.firCachesFactory.createCache(::computePackage)
|
||||||
|
|
||||||
private val callablePackageSet: Set<String>? by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirCompositeCachedSymbolNamesProvider(
|
||||||
computePackageSetWithTopLevelCallables().also {
|
session,
|
||||||
ensureNotNull(it) { "package names with callables" }
|
providers.map { it.symbolNamesProvider },
|
||||||
}
|
) {
|
||||||
}
|
override fun computeTopLevelClassifierNames(packageFqName: FqName): Set<String>? =
|
||||||
|
super.computeTopLevelClassifierNames(packageFqName).also {
|
||||||
private val knownTopLevelClassifierNamesInPackage: FirCache<FqName, Set<String>?, Nothing?> =
|
|
||||||
session.firCachesFactory.createCache { packageFqName ->
|
|
||||||
knownTopLevelClassifiersInPackage(packageFqName).also {
|
|
||||||
ensureNotNull(it) { "classifier names in package $packageFqName" }
|
ensureNotNull(it) { "classifier names in package $packageFqName" }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private val callableNamesInPackage: FirCache<FqName, Set<Name>?, Nothing?> =
|
override fun computePackageNamesWithTopLevelCallables(): Set<String>? =
|
||||||
session.firCachesFactory.createCache { packageFqName ->
|
super.computePackageNamesWithTopLevelCallables().also {
|
||||||
computeCallableNamesInPackage(packageFqName).also {
|
ensureNotNull(it) { "package names with top-level callables" }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeTopLevelCallableNames(packageFqName: FqName): Set<Name>? =
|
||||||
|
super.computeTopLevelCallableNames(packageFqName).also {
|
||||||
ensureNotNull(it) { "callable names in package $packageFqName" }
|
ensureNotNull(it) { "callable names in package $packageFqName" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(FirSymbolProviderInternals::class)
|
||||||
|
override fun mayHaveSyntheticFunctionType(classId: ClassId): Boolean {
|
||||||
|
// We know that `session` is the same as the sessions of all `providers`, so we can take a shortcut here.
|
||||||
|
return classId.isNameForFunctionClass(session)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun ensureNotNull(v: Any?, representation: () -> String) {
|
private inline fun ensureNotNull(v: Any?, representation: () -> String) {
|
||||||
require(v != null || expectedCachesToBeCleanedOnce) {
|
require(v != null || expectedCachesToBeCleanedOnce) {
|
||||||
@@ -73,16 +79,10 @@ class FirCachingCompositeSymbolProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
|
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
|
||||||
if (!mayHaveTopLevelCallablesInPackage(packageFqName, name)) return emptyList()
|
if (!symbolNamesProvider.mayHaveTopLevelCallable(packageFqName, name)) return emptyList()
|
||||||
return topLevelCallableCache.getValue(CallableId(packageFqName, name))
|
return topLevelCallableCache.getValue(CallableId(packageFqName, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mayHaveTopLevelCallablesInPackage(packageFqName: FqName, name: Name): Boolean {
|
|
||||||
if (callablePackageSet != null && packageFqName.asString() !in callablePackageSet!!) return false
|
|
||||||
val callableNamesInPackage = callableNamesInPackage.getValue(packageFqName) ?: return true
|
|
||||||
return name in callableNamesInPackage
|
|
||||||
}
|
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||||
destination += getTopLevelCallableSymbols(packageFqName, name)
|
destination += getTopLevelCallableSymbols(packageFqName, name)
|
||||||
@@ -90,13 +90,13 @@ class FirCachingCompositeSymbolProvider(
|
|||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
|
||||||
if (!mayHaveTopLevelCallablesInPackage(packageFqName, name)) return
|
if (!symbolNamesProvider.mayHaveTopLevelCallable(packageFqName, name)) return
|
||||||
destination += topLevelFunctionCache.getValue(CallableId(packageFqName, name))
|
destination += topLevelFunctionCache.getValue(CallableId(packageFqName, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
|
||||||
if (!mayHaveTopLevelCallablesInPackage(packageFqName, name)) return
|
if (!symbolNamesProvider.mayHaveTopLevelCallable(packageFqName, name)) return
|
||||||
destination += topLevelPropertyCache.getValue(CallableId(packageFqName, name))
|
destination += topLevelPropertyCache.getValue(CallableId(packageFqName, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,9 +105,7 @@ class FirCachingCompositeSymbolProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
val knownClassifierNames = knownTopLevelClassifierNamesInPackage.getValue(classId.packageFqName)
|
if (!symbolNamesProvider.mayHaveTopLevelClassifier(classId)) return null
|
||||||
if (knownClassifierNames != null && !knownClassifierNames.mayHaveTopLevelClassifier(classId, session)) return null
|
|
||||||
|
|
||||||
return classLikeCache.getValue(classId)
|
return classLikeCache.getValue(classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,13 +129,4 @@ class FirCachingCompositeSymbolProvider(
|
|||||||
|
|
||||||
private fun computeClass(classId: ClassId): FirClassLikeSymbol<*>? =
|
private fun computeClass(classId: ClassId): FirClassLikeSymbol<*>? =
|
||||||
providers.firstNotNullOfOrNull { provider -> provider.getClassLikeSymbolByClassId(classId) }
|
providers.firstNotNullOfOrNull { provider -> provider.getClassLikeSymbolByClassId(classId) }
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? =
|
|
||||||
providers.flatMapToNullableSet { it.computePackageSetWithTopLevelCallables() }
|
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? =
|
|
||||||
providers.flatMapToNullableSet { it.knownTopLevelClassifiersInPackage(packageFqName) }
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? =
|
|
||||||
providers.flatMapToNullableSet { it.computeCallableNamesInPackage(packageFqName) }
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-10
@@ -7,9 +7,10 @@ package org.jetbrains.kotlin.fir.resolve.providers.impl
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.NoMutableState
|
import org.jetbrains.kotlin.fir.NoMutableState
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirCompositeSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.flatMapToNullableSet
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
@@ -20,6 +21,8 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
|
|
||||||
@NoMutableState
|
@NoMutableState
|
||||||
class FirCompositeSymbolProvider(session: FirSession, val providers: List<FirSymbolProvider>) : FirSymbolProvider(session) {
|
class FirCompositeSymbolProvider(session: FirSession, val providers: List<FirSymbolProvider>) : FirSymbolProvider(session) {
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider = FirCompositeSymbolNamesProvider.fromSymbolProviders(providers)
|
||||||
|
|
||||||
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
|
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
|
||||||
return providers.flatMap { it.getTopLevelCallableSymbols(packageFqName, name) }
|
return providers.flatMap { it.getTopLevelCallableSymbols(packageFqName, name) }
|
||||||
}
|
}
|
||||||
@@ -50,13 +53,4 @@ class FirCompositeSymbolProvider(session: FirSession, val providers: List<FirSym
|
|||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
return providers.firstNotNullOfOrNull { it.getClassLikeSymbolByClassId(classId) }
|
return providers.firstNotNullOfOrNull { it.getClassLikeSymbolByClassId(classId) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String>? =
|
|
||||||
providers.flatMapToNullableSet { it.computePackageSetWithTopLevelCallables() }
|
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? =
|
|
||||||
providers.flatMapToNullableSet { it.knownTopLevelClassifiersInPackage(packageFqName) }
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? =
|
|
||||||
providers.flatMapToNullableSet { it.computeCallableNamesInPackage(packageFqName) }
|
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-25
@@ -14,9 +14,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
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.firCachesFactory
|
||||||
import org.jetbrains.kotlin.fir.caches.getValue
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
||||||
@@ -28,6 +26,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.addDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation
|
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyAnnotationArgumentMapping
|
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyAnnotationArgumentMapping
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
@@ -84,14 +83,29 @@ abstract class FirSyntheticFunctionInterfaceProviderBase(
|
|||||||
val moduleData: FirModuleData,
|
val moduleData: FirModuleData,
|
||||||
val kotlinScopeProvider: FirKotlinScopeProvider
|
val kotlinScopeProvider: FirKotlinScopeProvider
|
||||||
) : FirSymbolProvider(session) {
|
) : FirSymbolProvider(session) {
|
||||||
@OptIn(FirSymbolProviderInternals::class)
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProvider() {
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? {
|
override val mayHaveSyntheticFunctionTypes: Boolean get() = true
|
||||||
if (!classId.mayBeSyntheticFunctionClassName()) return null
|
|
||||||
return getClassLikeSymbolByClassIdWithoutClassIdChecks(classId)
|
override fun mayHaveSyntheticFunctionType(classId: ClassId): Boolean = classId.getAcceptableFunctionTypeKind() != null
|
||||||
|
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> =
|
||||||
|
// Generated function type names aren't included in the top-level classifier names set.
|
||||||
|
emptySet()
|
||||||
|
|
||||||
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> = emptySet()
|
||||||
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name> = emptySet()
|
||||||
|
|
||||||
|
override fun mayHaveTopLevelClassifier(classId: ClassId): Boolean = mayHaveSyntheticFunctionType(classId)
|
||||||
|
override fun mayHaveTopLevelCallable(packageFqName: FqName, name: Name): Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? {
|
||||||
fun getClassLikeSymbolByClassIdWithoutClassIdChecks(classId: ClassId): FirRegularClassSymbol? = cache.getValue(classId)
|
val functionTypeKind = classId.getAcceptableFunctionTypeKind() ?: return null
|
||||||
|
return cache.getValue(classId, functionTypeKind)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(FirSymbolProviderInternals::class)
|
||||||
|
private fun ClassId.getAcceptableFunctionTypeKind(): FunctionTypeKind? = getFunctionTypeKind(session)?.takeIf { it.isAcceptable() }
|
||||||
|
|
||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||||
@@ -112,29 +126,13 @@ abstract class FirSyntheticFunctionInterfaceProviderBase(
|
|||||||
return fqName.takeIf { session.functionTypeService.hasKindWithSpecificPackage(it) }
|
return fqName.takeIf { session.functionTypeService.hasKindWithSpecificPackage(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String> {
|
|
||||||
return emptySet()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method has no sense for synthetic function interfaces
|
|
||||||
*/
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String>? {
|
|
||||||
return emptySet()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>? {
|
|
||||||
return emptySet()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val cache = moduleData.session.firCachesFactory.createCache(::createSyntheticFunctionInterface)
|
private val cache = moduleData.session.firCachesFactory.createCache(::createSyntheticFunctionInterface)
|
||||||
|
|
||||||
protected abstract fun FunctionTypeKind.isAcceptable(): Boolean
|
protected abstract fun FunctionTypeKind.isAcceptable(): Boolean
|
||||||
|
|
||||||
private fun createSyntheticFunctionInterface(classId: ClassId): FirRegularClassSymbol? {
|
private fun createSyntheticFunctionInterface(classId: ClassId, kind: FunctionTypeKind): FirRegularClassSymbol? {
|
||||||
return with(classId) {
|
return with(classId) {
|
||||||
val className = relativeClassName.asString()
|
val className = relativeClassName.asString()
|
||||||
val kind = session.functionTypeService.getKindByClassNamePrefix(packageFqName, className) ?: return null
|
|
||||||
if (!kind.isAcceptable()) return null
|
if (!kind.isAcceptable()) return null
|
||||||
val prefix = kind.classNamePrefix
|
val prefix = kind.classNamePrefix
|
||||||
val arity = className.substring(prefix.length).toIntOrNull() ?: return null
|
val arity = className.substring(prefix.length).toIntOrNull() ?: return null
|
||||||
@@ -258,6 +256,15 @@ abstract class FirSyntheticFunctionInterfaceProviderBase(
|
|||||||
private fun FunctionTypeKind.classId(arity: Int) = ClassId(packageFqName, numberedClassName(arity))
|
private fun FunctionTypeKind.classId(arity: Int) = ClassId(packageFqName, numberedClassName(arity))
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@FirSymbolProviderInternals
|
||||||
|
fun ClassId.isNameForFunctionClass(session: FirSession): Boolean = getFunctionTypeKind(session) != null
|
||||||
|
|
||||||
|
@FirSymbolProviderInternals
|
||||||
|
private fun ClassId.getFunctionTypeKind(session: FirSession): FunctionTypeKind? {
|
||||||
|
if (!mayBeSyntheticFunctionClassName()) return null
|
||||||
|
return session.functionTypeService.getKindByClassNamePrefix(packageFqName, shortClassName.asString())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [ClassId] can only be a name for a generated function class if it ends with a digit. See [FunctionTypeKind].
|
* A [ClassId] can only be a name for a generated function class if it ends with a digit. See [FunctionTypeKind].
|
||||||
*
|
*
|
||||||
|
|||||||
+10
-9
@@ -16,6 +16,9 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProviderWithoutCallables
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
@@ -67,6 +70,13 @@ class FirCloneableSymbolProvider(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProviderWithoutCallables() {
|
||||||
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> =
|
||||||
|
if (packageFqName == StandardClassIds.Cloneable.packageFqName) {
|
||||||
|
setOf(StandardClassIds.Cloneable.shortClassName.asString())
|
||||||
|
} else emptySet()
|
||||||
|
}
|
||||||
|
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
return if (classId == StandardClassIds.Cloneable) klass.symbol else null
|
return if (classId == StandardClassIds.Cloneable) klass.symbol else null
|
||||||
}
|
}
|
||||||
@@ -86,13 +96,4 @@ class FirCloneableSymbolProvider(
|
|||||||
override fun getPackage(fqName: FqName): FqName? {
|
override fun getPackage(fqName: FqName): FqName? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String> = emptySet()
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String> =
|
|
||||||
if (packageFqName == StandardClassIds.Cloneable.packageFqName)
|
|
||||||
setOf(StandardClassIds.Cloneable.shortClassName.asString())
|
|
||||||
else
|
|
||||||
emptySet()
|
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> = emptySet()
|
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-16
@@ -9,10 +9,7 @@ import org.jetbrains.annotations.TestOnly
|
|||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.*
|
||||||
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.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||||
@@ -80,22 +77,24 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: FirKotli
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computePackageSetWithTopLevelCallables(): Set<String> =
|
override val symbolNamesProvider: FirSymbolNamesProvider = object : FirSymbolNamesProvider() {
|
||||||
state.allSubPackages.mapTo(mutableSetOf()) { it.asString() }
|
override fun getPackageNamesWithTopLevelCallables(): Set<String> =
|
||||||
|
state.allSubPackages.mapTo(mutableSetOf()) { it.asString() }
|
||||||
|
|
||||||
override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set<String> =
|
override fun getTopLevelClassifierNamesInPackage(packageFqName: FqName): Set<String> =
|
||||||
state.classifierInPackage[packageFqName].orEmpty().mapTo(mutableSetOf()) { it.asString() }
|
state.classifierInPackage[packageFqName].orEmpty().mapTo(mutableSetOf()) { it.asString() }
|
||||||
|
|
||||||
override fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name> = buildSet {
|
override fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name> = buildSet {
|
||||||
for (key in state.functionMap.keys) {
|
for (key in state.functionMap.keys) {
|
||||||
if (key.packageName == packageFqName) {
|
if (key.packageName == packageFqName) {
|
||||||
add(key.callableName)
|
add(key.callableName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (key in state.propertyMap.keys) {
|
for (key in state.propertyMap.keys) {
|
||||||
if (key.packageName == packageFqName) {
|
if (key.packageName == packageFqName) {
|
||||||
add(key.callableName)
|
add(key.callableName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user