K2: Get rid of FirDependenciesSymbolProviderImpl

Its usages will be safely replaced
with FirCachingCompositeSymbolProvider

But here, in the commit plain FirCompositeSymbolProvider used temporary
This commit is contained in:
Denis.Zharkov
2023-01-04 13:41:10 +01:00
committed by Space Team
parent 9302fe3cb5
commit 6705d211a6
6 changed files with 58 additions and 151 deletions
@@ -13,11 +13,8 @@ import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.extensions.FirSwitchableExtensionDeclarationsSymbolProvider
import org.jetbrains.kotlin.fir.java.FirCliSession
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.*
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirDependenciesSymbolProviderImpl
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirLibrarySessionProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
@@ -78,7 +75,7 @@ abstract class FirAbstractSessionFactory {
createProviders: (
FirSession, FirKotlinScopeProvider, FirSymbolProvider,
FirSwitchableExtensionDeclarationsSymbolProvider?,
FirDependenciesSymbolProvider
dependencies: List<FirSymbolProvider>,
) -> List<FirSymbolProvider>
): FirSession {
return FirCliSession(sessionProvider, FirSession.Kind.Source).apply session@{
@@ -106,17 +103,56 @@ abstract class FirAbstractSessionFactory {
init()
}.configure()
val dependenciesSymbolProvider = FirDependenciesSymbolProviderImpl(this)
val dependencyProviders = computeDependencyProviderList(moduleData)
val generatedSymbolsProvider = FirSwitchableExtensionDeclarationsSymbolProvider.create(this)
val providers = createProviders(
this, kotlinScopeProvider, firProvider.symbolProvider, generatedSymbolsProvider, dependenciesSymbolProvider,
this, kotlinScopeProvider, firProvider.symbolProvider, generatedSymbolsProvider,
dependencyProviders,
)
register(FirSymbolProvider::class, FirCompositeSymbolProvider(this, providers))
generatedSymbolsProvider?.let { register(FirSwitchableExtensionDeclarationsSymbolProvider::class, it) }
register(DEPENDENCIES_SYMBOL_PROVIDER_QUALIFIED_KEY, dependenciesSymbolProvider)
register(DEPENDENCIES_SYMBOL_PROVIDER_QUALIFIED_KEY, FirCompositeSymbolProvider(this, dependencyProviders))
}
}
}
private fun FirSession.computeDependencyProviderList(moduleData: FirModuleData): List<FirSymbolProvider> {
val visited = mutableSetOf<FirSymbolProvider>()
return (moduleData.dependencies + moduleData.friendDependencies + moduleData.dependsOnDependencies)
.mapNotNull { sessionProvider?.getSession(it) }
.map { it.symbolProvider }
.flatMap { it.flatten(visited, collectSourceProviders = it.session.kind == FirSession.Kind.Source) }
.sortedBy { it.session.kind }
}
/* It eliminates dependency and composite providers since the current dependency provider is composite in fact.
* To prevent duplications and resolving errors, library or source providers from other modules should be filtered out during flattening.
* It depends on the session's kind of the top-level provider */
private fun FirSymbolProvider.flatten(
visited: MutableSet<FirSymbolProvider>,
collectSourceProviders: Boolean
): List<FirSymbolProvider> {
val result = mutableListOf<FirSymbolProvider>()
fun FirSymbolProvider.collectProviders() {
if (!visited.add(this)) return
when {
this is FirCompositeSymbolProvider -> {
for (provider in providers) {
provider.collectProviders()
}
}
collectSourceProviders && session.kind == FirSession.Kind.Source ||
!collectSourceProviders && session.kind == FirSession.Kind.Library -> {
result.add(this)
}
}
}
collectProviders()
return result
}
}
@@ -44,11 +44,11 @@ object FirJsSessionFactory : FirAbstractSessionFactory() {
},
registerExtraCheckers = { it.registerJsCheckers() },
createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } },
createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependenciesSymbolProvider ->
createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependencies ->
listOfNotNull(
symbolProvider,
generatedSymbolsProvider,
dependenciesSymbolProvider,
*dependencies.toTypedArray(),
)
}
)
@@ -100,7 +100,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
},
registerExtraCheckers = { it.registerJvmCheckers() },
createKotlinScopeProvider = { FirKotlinScopeProvider(::wrapScopeWithJvmMapped) },
createProviders = { session, kotlinScopeProvider, symbolProvider, generatedSymbolsProvider, dependenciesSymbolProvider ->
createProviders = { session, kotlinScopeProvider, symbolProvider, generatedSymbolsProvider, dependencies ->
var symbolProviderForBinariesFromIncrementalCompilation: JvmClassFileBasedSymbolProvider? = null
var optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation: OptionalAnnotationClassesProvider? = null
incrementalCompilationContext?.let {
@@ -137,7 +137,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
symbolProviderForBinariesFromIncrementalCompilation,
generatedSymbolsProvider,
javaSymbolProvider,
dependenciesSymbolProvider,
*dependencies.toTypedArray(),
optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation,
)
}
@@ -67,11 +67,11 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
},
registerExtraCheckers = { it.registerNativeCheckers() },
createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } },
createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependenciesSymbolProvider ->
createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependencies ->
listOfNotNull(
symbolProvider,
generatedSymbolsProvider,
dependenciesSymbolProvider,
*dependencies.toTypedArray(),
)
}
)
@@ -84,4 +84,4 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
register(FirPlatformClassMapper::class, FirPlatformClassMapper.Default)
register(FirOverridesBackwardCompatibilityHelper::class, FirOverridesBackwardCompatibilityHelper.Default())
}
}
}
@@ -1,126 +0,0 @@
/*
* Copyright 2010-2021 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.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.ThreadSafeMutableState
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.nullableModuleData
import org.jetbrains.kotlin.fir.resolve.providers.*
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@ThreadSafeMutableState
open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirSymbolProvider(session) {
private val classCache = session.firCachesFactory.createCache(::computeClass)
private val topLevelCallableCache = session.firCachesFactory.createCache(::computeTopLevelCallables)
private val topLevelFunctionCache = session.firCachesFactory.createCache(::computeTopLevelFunctions)
private val topLevelPropertyCache = session.firCachesFactory.createCache(::computeTopLevelProperties)
private val packageCache = session.firCachesFactory.createCache(::computePackage)
protected open val dependencyProviders by lazy {
val moduleData =
session.nullableModuleData ?: error("FirDependenciesSymbolProvider should not be created if there are no dependencies")
val visited = mutableSetOf<FirSymbolProvider>()
(moduleData.dependencies + moduleData.friendDependencies + moduleData.dependsOnDependencies)
.mapNotNull { session.sessionProvider?.getSession(it) }
.map { it.symbolProvider }
.flatMap { it.flatten(visited, collectSourceProviders = it.session.kind == FirSession.Kind.Source) }
.sortedBy { it.session.kind }
}
/* It eliminates dependency and composite providers since the current dependency provider is composite in fact.
* To prevent duplications and resolving errors, library or source providers from other modules should be filtered out during flattening.
* It depends on the session's kind of the top-level provider */
private fun FirSymbolProvider.flatten(
visited: MutableSet<FirSymbolProvider>,
collectSourceProviders: Boolean
): List<FirSymbolProvider> {
val result = mutableListOf<FirSymbolProvider>()
fun FirSymbolProvider.collectProviders() {
if (!visited.add(this)) return
when {
this is FirDependenciesSymbolProviderImpl -> {
for (provider in dependencyProviders) {
provider.collectProviders()
}
}
this is FirCompositeSymbolProvider -> {
for (provider in providers) {
provider.collectProviders()
}
}
collectSourceProviders && session.kind == FirSession.Kind.Source ||
!collectSourceProviders && session.kind == FirSession.Kind.Library -> {
result.add(this)
}
}
}
collectProviders()
return result
}
@OptIn(FirSymbolProviderInternals::class)
private fun computeTopLevelCallables(callableId: CallableId): List<FirCallableSymbol<*>> = buildList {
dependencyProviders.forEach { it.getTopLevelCallableSymbolsTo(this, callableId.packageName, callableId.callableName) }
}
@OptIn(FirSymbolProviderInternals::class)
private fun computeTopLevelFunctions(callableId: CallableId): List<FirNamedFunctionSymbol> = buildList {
dependencyProviders.forEach { it.getTopLevelFunctionSymbolsTo(this, callableId.packageName, callableId.callableName) }
}
@OptIn(FirSymbolProviderInternals::class)
private fun computeTopLevelProperties(callableId: CallableId): List<FirPropertySymbol> = buildList {
dependencyProviders.forEach { it.getTopLevelPropertySymbolsTo(this, callableId.packageName, callableId.callableName) }
}
private fun computePackage(it: FqName): FqName? =
dependencyProviders.firstNotNullOfOrNull { provider -> provider.getPackage(it) }
private fun computeClass(classId: ClassId): FirClassLikeSymbol<*>? =
dependencyProviders.firstNotNullOfOrNull { provider -> provider.getClassLikeSymbolByClassId(classId) }
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
destination += topLevelFunctionCache.getValue(CallableId(packageFqName, name))
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
destination += topLevelPropertyCache.getValue(CallableId(packageFqName, name))
}
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
destination += getTopLevelCallableSymbols(packageFqName, name)
}
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
return topLevelCallableCache.getValue(CallableId(packageFqName, name))
}
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
return classCache.getValue(classId)
}
override fun getPackage(fqName: FqName): FqName? {
return packageCache.getValue(fqName)
}
}
@@ -6,17 +6,14 @@
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirDependenciesSymbolProviderImpl
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.FirScope
abstract class FirAbstractProviderBasedScope(val session: FirSession, lookupInFir: Boolean = true) :
FirScope() {
val provider = when (val symbolProvider = session.symbolProvider) {
is FirCompositeSymbolProvider -> symbolProvider.takeIf { !lookupInFir }?.providers?.find {
it is FirDependenciesSymbolProviderImpl
} ?: symbolProvider
else -> symbolProvider
abstract class FirAbstractProviderBasedScope(val session: FirSession, lookupInFir: Boolean = true) : FirScope() {
val provider: FirSymbolProvider = when {
lookupInFir -> session.symbolProvider
else -> session.dependenciesSymbolProvider
}
}