[fir low level, refactoring] refactor LLFirSessionFactory

This commit is contained in:
Ilya Kirillov
2022-05-04 00:59:08 +02:00
parent f5c95f8a12
commit 82bfa3db05
4 changed files with 103 additions and 103 deletions
@@ -6,18 +6,34 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeSessionComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createSealedInheritorsProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.FirThreadSafeCachesFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirIdePredicateBasedProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirIdeRegisteredPluginAnnotations
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibraryOrLibrarySourceResolvableModuleSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSourcesSession
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.moduleScopeProvider
import org.jetbrains.kotlin.analysis.providers.createAnnotationResolver
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.extensions.FirPredicateBasedProvider
import org.jetbrains.kotlin.fir.extensions.FirRegisteredPluginAnnotations
import org.jetbrains.kotlin.fir.java.FirJavaFacadeForSource
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.load.java.createJavaClassFinder
@OptIn(SessionConfiguration::class)
@SessionConfiguration
internal fun LLFirSession.registerIdeComponents(project: Project) {
register(IdeSessionComponents::class, IdeSessionComponents.create(this))
register(FirCachesFactory::class, FirThreadSafeCachesFactory)
@@ -26,6 +42,45 @@ internal fun LLFirSession.registerIdeComponents(project: Project) {
internal inline fun createCompositeSymbolProvider(
session: FirSession,
builderAction: MutableList<FirSymbolProvider>.() -> Unit
createSubProviders: MutableList<FirSymbolProvider>.() -> Unit
): FirCompositeSymbolProvider =
FirCompositeSymbolProvider(session, buildList(builderAction))
FirCompositeSymbolProvider(session, buildList(createSubProviders))
@SessionConfiguration
internal fun FirSession.registerCompilerPluginExtensions(project: Project) {
FirSessionFactory.FirSessionConfigurator(this).apply {
for (extensionRegistrar in FirExtensionRegistrar.getInstances(project)) {
registerExtensions(extensionRegistrar.configure())
}
}.configure()
}
@SessionConfiguration
internal fun LLFirSourcesSession.registerCompilerPluginServices(
contentScope: GlobalSearchScope,
project: Project,
module: KtSourceModule
) {
val projectWithDependenciesScope = contentScope.uniteWith(project.moduleScopeProvider.getModuleLibrariesScope(module))
val annotationsResolver = project.createAnnotationResolver(projectWithDependenciesScope)
// We need FirRegisteredPluginAnnotations and FirPredicateBasedProvider during extensions' registration process
register(FirRegisteredPluginAnnotations::class, LLFirIdeRegisteredPluginAnnotations(this, annotationsResolver))
register(
FirPredicateBasedProvider::class,
LLFirIdePredicateBasedProvider(this, annotationsResolver, project.createDeclarationProvider(projectWithDependenciesScope))
)
}
internal fun createJavaSymbolProvider(
firSession: LLFirSession,
moduleData: LLFirKtModuleBasedModuleData,
project: Project,
contentScope: GlobalSearchScope
): JavaSymbolProvider {
return JavaSymbolProvider(
firSession,
FirJavaFacadeForSource(firSession, moduleData, project.createJavaClassFinder(contentScope))
)
}
@@ -19,8 +19,8 @@ import org.jetbrains.kotlin.name.Name
internal class LLFirModuleWithDependenciesSymbolProvider(
session: FirSession,
val dependencyProvider: LLFirDependentModuleProviders,
private val providers: List<FirSymbolProvider>,
val dependencyProvider: DependentModuleProviders
) : FirSymbolProvider(session) {
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
@@ -77,7 +77,14 @@ internal class LLFirModuleWithDependenciesSymbolProvider(
providers.firstNotNullOfOrNull { it.getPackage(fqName) }
}
internal class DependentModuleProviders(session: FirSession, private val providers: List<FirSymbolProvider>) : FirDependenciesSymbolProvider(session) {
internal class LLFirDependentModuleProviders(
session: FirSession,
private val providers: List<FirSymbolProvider>
) : FirDependenciesSymbolProvider(session) {
constructor(session: FirSession, createSubProviders: MutableList<FirSymbolProvider>.() -> Unit)
: this(session, buildList { createSubProviders() })
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? =
providers.firstNotNullOfOrNull { provider ->
when (provider) {
@@ -11,7 +11,7 @@ import com.intellij.psi.search.ProjectScope
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseManager
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirKtModuleBasedModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.*
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibraryProviderFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySessionFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.registerIdeComponents
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.extensions.*
import org.jetbrains.kotlin.fir.java.FirJavaFacadeForSource
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -38,12 +35,10 @@ import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.session.*
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
import org.jetbrains.kotlin.load.java.createJavaClassFinder
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import java.nio.file.Path
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
internal object LLFirSessionFactory {
@@ -53,7 +48,6 @@ internal object LLFirSessionFactory {
globalResolveComponents: LLFirGlobalResolveComponents,
sessionInvalidator: LLFirSessionInvalidator,
sessionsCache: MutableMap<KtModule, LLFirResolvableModuleSession>,
isRootModule: Boolean,
librariesSessionFactory: LLFirLibrarySessionFactory,
configureSession: (LLFirSession.() -> Unit)? = null
): LLFirSourcesSession {
@@ -100,73 +94,40 @@ internal object LLFirSessionFactory {
register(FirProvider::class, provider)
register(FirPhaseManager::class, LLFirPhaseManager(sessionInvalidator))
@OptIn(ExperimentalStdlibApi::class)
val dependentProviders = buildList {
add(
librariesSessionFactory.getLibrarySessionForSourceModule(module).symbolProvider
)
dependentModules
.mapTo(this) {
createSourcesSession(
project,
it,
globalResolveComponents,
sessionInvalidator,
sessionsCache,
isRootModule = false,
librariesSessionFactory = librariesSessionFactory,
configureSession = configureSession,
).symbolProvider
}
}
registerCompilerPluginServices(contentScope, project, module)
registerCompilerPluginExtensions(project)
val projectWithDependenciesScope = contentScope.uniteWith(project.moduleScopeProvider.getModuleLibrariesScope(module))
val annotationsResolver = project.createAnnotationResolver(projectWithDependenciesScope)
// We need FirRegisteredPluginAnnotations and FirPredicateBasedProvider during extensions' registration process
register(FirRegisteredPluginAnnotations::class, LLFirIdeRegisteredPluginAnnotations(this@session, annotationsResolver))
register(
FirPredicateBasedProvider::class,
LLFirIdePredicateBasedProvider(
this@session,
annotationsResolver,
project.createDeclarationProvider(projectWithDependenciesScope)
)
)
FirSessionFactory.FirSessionConfigurator(this).apply {
if (isRootModule) {
registerExtendedCommonCheckers()
}
for (extensionRegistrar in FirExtensionRegistrar.getInstances(project)) {
registerExtensions(extensionRegistrar.configure())
}
}.configure()
val switchableExtensionDeclarationsSymbolProvider =
FirSwitchableExtensionDeclarationsSymbolProvider.create(session)
switchableExtensionDeclarationsSymbolProvider?.let {
val switchableExtensionDeclarationsSymbolProvider = FirSwitchableExtensionDeclarationsSymbolProvider.create(session)?.also {
register(FirSwitchableExtensionDeclarationsSymbolProvider::class, it)
}
val dependencyProvider = DependentModuleProviders(this, dependentProviders)
val dependencyProvider = LLFirDependentModuleProviders(this) {
add(librariesSessionFactory.getLibrarySessionForSourceModule(module).symbolProvider)
dependentModules
.mapTo(this) { dependentSourceModule ->
val dependentSourceSession = createSourcesSession(
project,
dependentSourceModule,
globalResolveComponents,
sessionInvalidator,
sessionsCache,
librariesSessionFactory = librariesSessionFactory,
configureSession = configureSession,
)
dependentSourceSession.symbolProvider
}
}
register(
FirSymbolProvider::class,
LLFirModuleWithDependenciesSymbolProvider(
this,
dependencyProvider,
providers = listOfNotNull(
provider.symbolProvider,
switchableExtensionDeclarationsSymbolProvider,
JavaSymbolProvider(
this,
FirJavaFacadeForSource(
this, moduleData, project.createJavaClassFinder(contentScope)
)
),
createJavaSymbolProvider(this, moduleData, project, contentScope)
),
dependencyProvider
)
)
@@ -228,48 +189,35 @@ internal object LLFirSessionFactory {
register(FirProvider::class, provider)
register(FirPhaseManager::class, LLFirPhaseManager(sessionInvalidator))
val dependentProviders = buildList {
val librariesSearchScope = ProjectScope.getLibrariesScope(project)
.intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope)) // <all libraries scope> - <current library scope>
add(builtinsAndCloneableSession.symbolProvider)
addAll(
LLFirLibraryProviderFactory.createProvidersByModuleLibraryDependencies(
session,
module,
scopeProvider,
project,
builtinTypes
) { librariesSearchScope }
)
}
// We need FirRegisteredPluginAnnotations during extensions' registration process
val annotationsResolver = project.createAnnotationResolver(contentScope)
register(FirRegisteredPluginAnnotations::class, LLFirIdeRegisteredPluginAnnotations(this@session, annotationsResolver))
register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider())
FirSessionFactory.FirSessionConfigurator(this).apply {
for (extensionRegistrar in FirExtensionRegistrar.getInstances(project)) {
registerExtensions(extensionRegistrar.configure())
}
}.configure()
registerCompilerPluginExtensions(project)
val dependencyProvider = DependentModuleProviders(this, dependentProviders)
val dependencyProvider = LLFirDependentModuleProviders(this) {
// <all libraries scope> - <current library scope>
val librariesSearchScope =
ProjectScope.getLibrariesScope(project).intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope))
add(builtinsAndCloneableSession.symbolProvider)
addAll(
LLFirLibraryProviderFactory.createProvidersByModuleLibraryDependencies(
session, module, scopeProvider, project, builtinTypes
) { librariesSearchScope }
)
}
register(
FirSymbolProvider::class,
LLFirModuleWithDependenciesSymbolProvider(
this,
dependencyProvider,
providers = listOf(
provider.symbolProvider,
JavaSymbolProvider(
this,
FirJavaFacadeForSource(
this, moduleData, project.createJavaClassFinder(contentScope)
)
),
createJavaSymbolProvider(this, moduleData, project, contentScope),
),
dependencyProvider
)
)
@@ -282,13 +230,6 @@ internal object LLFirSessionFactory {
}
}
private fun List<KtModule>.extractLibraryPaths(): List<Path> =
asSequence()
.filterIsInstance<KtBinaryModule>()
.flatMap { it.getBinaryRoots() }
.map { it.toAbsolutePath() }
.toList()
@Deprecated(
"This is a dirty hack used only for one usage (building fir for psi from stubs) and it should be removed after fix of that usage",
level = DeprecationLevel.ERROR
@@ -21,9 +21,7 @@ import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOu
import org.jetbrains.kotlin.analysis.utils.caches.getValue
import org.jetbrains.kotlin.analysis.utils.caches.softCachedValue
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.BuiltinTypes
import java.util.concurrent.ConcurrentHashMap
class LLFirSessionProviderStorage(val project: Project) {
@@ -60,7 +58,6 @@ class LLFirSessionProviderStorage(val project: Project) {
globalComponents,
cache.sessionInvalidator,
sessions,
isRootModule = true,
librariesSessionFactory = librariesSessionFactory,
configureSession = configureSession,
)