[FIR] Safe dependency symbol provider in IDE session

This commit is contained in:
Dmitriy Novozhilov
2021-06-28 17:33:26 +03:00
committed by teamcityserver
parent 37c096cb10
commit 749dbf4d44
6 changed files with 51 additions and 41 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.registerExtensions import org.jetbrains.kotlin.fir.extensions.registerExtensions
import org.jetbrains.kotlin.fir.java.* import org.jetbrains.kotlin.fir.java.*
import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.* import org.jetbrains.kotlin.fir.resolve.providers.impl.*
@@ -175,7 +176,7 @@ object FirSessionFactory {
) )
register( register(
FirDependenciesSymbolProviderImpl::class, FirDependenciesSymbolProvider::class,
dependenciesSymbolProvider dependenciesSymbolProvider
) )
@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.fir.resolve package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirDependenciesSymbolProviderImpl
import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
val FirSession.symbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor() val FirSession.symbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor()
val FirSession.dependenciesSymbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor<FirDependenciesSymbolProviderImpl>() val FirSession.dependenciesSymbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor<FirDependenciesSymbolProvider>()
val FirSession.firProvider: FirProvider by FirSession.sessionComponentAccessor() val FirSession.firProvider: FirProvider by FirSession.sessionComponentAccessor()
val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by FirSession.sessionComponentAccessor() val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by FirSession.sessionComponentAccessor()
val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by FirSession.sessionComponentAccessor() val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by FirSession.sessionComponentAccessor()
@@ -55,6 +55,8 @@ abstract class FirSymbolProvider(val session: FirSession) : FirSessionComponent
abstract fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime abstract fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime
} }
abstract class FirDependenciesSymbolProvider(session: FirSession) : FirSymbolProvider(session)
private fun FirSymbolProvider.getClassDeclaredMemberScope(classId: ClassId): FirScope? { private fun FirSymbolProvider.getClassDeclaredMemberScope(classId: ClassId): FirScope? {
val classSymbol = getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol ?: return null val classSymbol = getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol ?: return null
return session.declaredMemberScope(classSymbol.fir) return session.declaredMemberScope(classSymbol.fir)
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.providers.impl
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.caches.* import org.jetbrains.kotlin.fir.caches.*
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
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
@@ -20,7 +21,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@ThreadSafeMutableState @ThreadSafeMutableState
open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirSymbolProvider(session) { open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirDependenciesSymbolProvider(session) {
private val classCache = session.firCachesFactory.createCache(::computeClass) private val classCache = session.firCachesFactory.createCache(::computeClass)
private val topLevelCallableCache = session.firCachesFactory.createCache(::computeTopLevelCallables) private val topLevelCallableCache = session.firCachesFactory.createCache(::computeTopLevelCallables)
private val topLevelFunctionCache = session.firCachesFactory.createCache(::computeTopLevelFunctions) private val topLevelFunctionCache = session.firCachesFactory.createCache(::computeTopLevelFunctions)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.providers package org.jetbrains.kotlin.idea.fir.low.level.api.providers
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
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
@@ -19,13 +20,12 @@ import org.jetbrains.kotlin.name.Name
internal class FirModuleWithDependenciesSymbolProvider( internal class FirModuleWithDependenciesSymbolProvider(
session: FirSession, session: FirSession,
private val providers: List<FirSymbolProvider>, private val providers: List<FirSymbolProvider>,
dependentProviders: List<FirSymbolProvider>, val dependencyProvider: DependentModuleProviders
) : FirSymbolProvider(session) { ) : FirSymbolProvider(session) {
private val dependentProviders = DependentModuleProviders(session, dependentProviders)
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? = override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? =
getClassLikeSymbolByFqNameWithoutDependencies(classId) getClassLikeSymbolByFqNameWithoutDependencies(classId)
?: dependentProviders.getClassLikeSymbolByFqName(classId) ?: dependencyProvider.getClassLikeSymbolByFqName(classId)
fun getClassLikeSymbolByFqNameWithoutDependencies(classId: ClassId): FirClassLikeSymbol<*>? = fun getClassLikeSymbolByFqNameWithoutDependencies(classId: ClassId): FirClassLikeSymbol<*>? =
@@ -34,7 +34,7 @@ internal class FirModuleWithDependenciesSymbolProvider(
@FirSymbolProviderInternals @FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) { override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
getTopLevelCallableSymbolsToWithoutDependencies(destination, packageFqName, name) getTopLevelCallableSymbolsToWithoutDependencies(destination, packageFqName, name)
dependentProviders.getTopLevelCallableSymbolsTo(destination, packageFqName, name) dependencyProvider.getTopLevelCallableSymbolsTo(destination, packageFqName, name)
} }
@FirSymbolProviderInternals @FirSymbolProviderInternals
@@ -45,13 +45,13 @@ internal class FirModuleWithDependenciesSymbolProvider(
@FirSymbolProviderInternals @FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) { override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
getTopLevelFunctionSymbolsToWithoutDependencies(destination, packageFqName, name) getTopLevelFunctionSymbolsToWithoutDependencies(destination, packageFqName, name)
dependentProviders.getTopLevelFunctionSymbolsTo(destination, packageFqName, name) dependencyProvider.getTopLevelFunctionSymbolsTo(destination, packageFqName, name)
} }
@FirSymbolProviderInternals @FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) { override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
getTopLevelPropertySymbolsToWithoutDependencies(destination, packageFqName, name) getTopLevelPropertySymbolsToWithoutDependencies(destination, packageFqName, name)
dependentProviders.getTopLevelPropertySymbolsTo(destination, packageFqName, name) dependencyProvider.getTopLevelPropertySymbolsTo(destination, packageFqName, name)
} }
@FirSymbolProviderInternals @FirSymbolProviderInternals
@@ -70,14 +70,14 @@ internal class FirModuleWithDependenciesSymbolProvider(
override fun getPackage(fqName: FqName): FqName? = override fun getPackage(fqName: FqName): FqName? =
getPackageWithoutDependencies(fqName) getPackageWithoutDependencies(fqName)
?: dependentProviders.getPackage(fqName) ?: dependencyProvider.getPackage(fqName)
fun getPackageWithoutDependencies(fqName: FqName): FqName? = fun getPackageWithoutDependencies(fqName: FqName): FqName? =
providers.firstNotNullOfOrNull { it.getPackage(fqName) } providers.firstNotNullOfOrNull { it.getPackage(fqName) }
} }
private class DependentModuleProviders(session: FirSession, private val providers: List<FirSymbolProvider>) : FirSymbolProvider(session) { internal class DependentModuleProviders(session: FirSession, private val providers: List<FirSymbolProvider>) : FirDependenciesSymbolProvider(session) {
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? = override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? =
providers.firstNotNullOfOrNull { provider -> providers.firstNotNullOfOrNull { provider ->
when (provider) { when (provider) {
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider
@@ -102,6 +103,38 @@ internal object FirIdeSessionFactory {
register(FirPhaseManager::class, firPhaseManager) register(FirPhaseManager::class, firPhaseManager)
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
val dependentProviders = buildList {
add(
createLibrarySession(
moduleInfo,
project,
builtinsAndCloneableSession,
builtinTypes,
librariesCache,
languageVersionSettings = languageVersionSettings,
configureSession = configureSession,
).symbolProvider
)
dependentModules
.mapTo(this) {
createSourcesSession(
project,
configurator,
it,
builtinsAndCloneableSession,
firPhaseRunner,
sessionInvalidator,
builtinTypes,
sessionsCache,
isRootModule = false,
librariesCache,
configureSession = configureSession,
).symbolProvider
}
}
val dependencyProvider = DependentModuleProviders(this, dependentProviders)
register( register(
FirSymbolProvider::class, FirSymbolProvider::class,
FirModuleWithDependenciesSymbolProvider( FirModuleWithDependenciesSymbolProvider(
@@ -110,38 +143,11 @@ internal object FirIdeSessionFactory {
provider.symbolProvider, provider.symbolProvider,
JavaSymbolProvider(this@session, moduleData, project, searchScope), JavaSymbolProvider(this@session, moduleData, project, searchScope),
), ),
dependentProviders = buildList { dependencyProvider
add(
createLibrarySession(
moduleInfo,
project,
builtinsAndCloneableSession,
builtinTypes,
librariesCache,
languageVersionSettings = languageVersionSettings,
configureSession = configureSession,
).symbolProvider
)
dependentModules
.mapTo(this) {
createSourcesSession(
project,
configurator,
it,
builtinsAndCloneableSession,
firPhaseRunner,
sessionInvalidator,
builtinTypes,
sessionsCache,
isRootModule = false,
librariesCache,
configureSession = configureSession,
).symbolProvider
}
}
) )
) )
register(FirDependenciesSymbolProvider::class, dependencyProvider)
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this)) register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
registerJavaSpecificResolveComponents() registerJavaSpecificResolveComponents()