From 011bb0924ae1b06c1e015bc6ec7960a25db9db89 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 31 Aug 2020 13:58:31 +0300 Subject: [PATCH] [FIR-IDE] Introduce `FirIdeSessionFactory` for creating ide sessions --- .../level/api/FirIdeResolveStateService.kt | 16 +- .../api/sessions/FirIdeLibrarySession.kt | 68 +------- .../api/sessions/FirIdeSessionFactory.kt | 145 ++++++++++++++++++ .../api/sessions/FirIdeSourcesSession.kt | 83 +--------- 4 files changed, 158 insertions(+), 154 deletions(-) create mode 100644 idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionFactory.kt diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt index d1c314b595a..0b2f9b51c0b 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt @@ -7,13 +7,13 @@ package org.jetbrains.kotlin.idea.fir.low.level.api import com.intellij.openapi.components.service import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo +import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo +import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver +import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionFactory +import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProvider import org.jetbrains.kotlin.idea.util.psiModificationTrackerBasedCachedValue import java.util.concurrent.ConcurrentHashMap -import org.jetbrains.kotlin.idea.caches.project.* -import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeLibrariesSession -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProvider -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession internal class FirIdeResolveStateService(private val project: Project) { private val stateCache by psiModificationTrackerBasedCachedValue(project) { @@ -24,8 +24,8 @@ internal class FirIdeResolveStateService(private val project: Project) { val firPhaseRunner = FirPhaseRunner() val sessionProvider = FirIdeSessionProvider(project) - val librariesSession = FirIdeLibrariesSession.create(moduleInfo as ModuleSourceInfo, sessionProvider, project) - val sourcesSession = FirIdeSourcesSession.create( + val librariesSession = FirIdeSessionFactory.createLibrarySession(moduleInfo as ModuleSourceInfo, sessionProvider, project) + val sourcesSession = FirIdeSessionFactory.createSourcesSession( project, moduleInfo, firPhaseRunner, @@ -55,4 +55,4 @@ internal class FirIdeResolveStateService(private val project: Project) { companion object { fun getInstance(project: Project): FirIdeResolveStateService = project.service() } -} \ No newline at end of file +} diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeLibrarySession.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeLibrarySession.kt index 7c0432c2e23..c189800934b 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeLibrarySession.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeLibrarySession.kt @@ -5,78 +5,16 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.sessions -import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.kotlin.fir.PrivateSessionConstructor -import org.jetbrains.kotlin.fir.SessionConfiguration import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.fir.java.JavaSymbolProvider -import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider -import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider -import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped -import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider -import org.jetbrains.kotlin.fir.session.registerCommonComponents -import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo -import org.jetbrains.kotlin.idea.caches.resolve.IDEPackagePartProvider -import org.jetbrains.kotlin.idea.fir.low.level.api.IdeSessionComponents -import org.jetbrains.kotlin.load.java.JavaClassFinderImpl -import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory +import org.jetbrains.kotlin.fir.PrivateSessionConstructor /** * [org.jetbrains.kotlin.fir.FirSession] responsible for all libraries analysing module transitively depends on */ @OptIn(PrivateSessionConstructor::class) -internal class FirIdeLibrariesSession private constructor( +internal class FirIdeLibrariesSession @PrivateSessionConstructor constructor( moduleInfo: ModuleInfo, sessionProvider: FirIdeSessionProvider, override val scope: GlobalSearchScope -) : FirIdeSession(moduleInfo, sessionProvider) { - companion object { - @OptIn(SessionConfiguration::class) - fun create( - moduleInfo: ModuleSourceInfo, - sessionProvider: FirIdeSessionProvider, - project: Project, - ): FirIdeLibrariesSession { - val searchScope = moduleInfo.module.moduleWithLibrariesScope - val javaClassFinder = JavaClassFinderImpl().apply { - setProjectInstance(project) - setScope(searchScope) - } - val packagePartProvider = IDEPackagePartProvider(searchScope) - - val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope) - return FirIdeLibrariesSession(moduleInfo, sessionProvider, searchScope).apply { - registerCommonComponents() - - val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, searchScope) - - val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) - register(IdeSessionComponents::class, IdeSessionComponents.create(this)) - register( - FirSymbolProvider::class, - FirCompositeSymbolProvider( - this, - listOf( - KotlinDeserializedJvmSymbolsProvider( - this, - project, - packagePartProvider, - javaSymbolProvider, - kotlinClassFinder, - javaClassFinder, - kotlinScopeProvider - ), - FirBuiltinSymbolProvider(this, kotlinScopeProvider), - FirCloneableSymbolProvider(this, kotlinScopeProvider), - javaSymbolProvider, - ) - ) - ) - } - } - } -} +) : FirIdeSession(moduleInfo, sessionProvider) diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionFactory.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionFactory.kt new file mode 100644 index 00000000000..099bb478581 --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionFactory.kt @@ -0,0 +1,145 @@ +/* + * Copyright 2010-2020 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.idea.fir.low.level.api.sessions + +import com.intellij.openapi.module.impl.scopes.ModuleWithDependentsScope +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.fir.PrivateSessionConstructor +import org.jetbrains.kotlin.fir.SessionConfiguration +import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers +import org.jetbrains.kotlin.fir.java.JavaSymbolProvider +import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider +import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.FirProvider +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider +import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped +import org.jetbrains.kotlin.fir.resolve.transformers.PhasedFirFileResolver +import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider +import org.jetbrains.kotlin.fir.session.FirSessionFactory +import org.jetbrains.kotlin.fir.session.registerCommonComponents +import org.jetbrains.kotlin.fir.session.registerJavaSpecificComponents +import org.jetbrains.kotlin.fir.session.registerResolveComponents +import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo +import org.jetbrains.kotlin.idea.caches.resolve.IDEPackagePartProvider +import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner +import org.jetbrains.kotlin.idea.fir.low.level.api.IdePhasedFirFileResolver +import org.jetbrains.kotlin.idea.fir.low.level.api.IdeSessionComponents +import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder +import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCacheImpl +import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver +import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider +import org.jetbrains.kotlin.idea.fir.low.level.api.util.collectTransitiveDependenciesWithSelf +import org.jetbrains.kotlin.load.java.JavaClassFinderImpl +import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory + +@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class) +internal object FirIdeSessionFactory { + /** + * Should be invoked only under a [moduleInfo]-based lock + */ + fun createSourcesSession( + project: Project, + moduleInfo: ModuleSourceInfo, + firPhaseRunner: FirPhaseRunner, + sessionProvider: FirIdeSessionProvider, + librariesSession: FirIdeLibrariesSession, + init: FirSessionFactory.FirSessionConfigurator.() -> Unit = {} + ): FirIdeSourcesSession { + val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) + val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner) + val dependentModules = moduleInfo.collectTransitiveDependenciesWithSelf().filterIsInstance() + val searchScope = ModuleWithDependentsScope(project, dependentModules.map { it.module }) + return FirIdeSourcesSession(moduleInfo, sessionProvider, searchScope, firBuilder).apply { + val cache = ModuleFileCacheImpl(this) + val phasedFirFileResolver = IdePhasedFirFileResolver(FirLazyDeclarationResolver(firFileBuilder), cache) + + registerCommonComponents() + registerResolveComponents() + + val provider = FirIdeProvider( + project, + this, + moduleInfo, + scopeProvider, + firFileBuilder, + cache, + searchScope + ) + + register(FirProvider::class, provider) + register(FirIdeProvider::class, provider) + + register(PhasedFirFileResolver::class, phasedFirFileResolver) + + register( + FirSymbolProvider::class, + FirCompositeSymbolProvider( + this, + @OptIn(ExperimentalStdlibApi::class) + buildList { + add(provider.symbolProvider) + add(JavaSymbolProvider(this@apply, sessionProvider.project, searchScope)) + add(librariesSession.firSymbolProvider) + } + ) as FirSymbolProvider + ) + registerJavaSpecificComponents() + FirSessionFactory.FirSessionConfigurator(this).apply { + registerCommonCheckers() + init() + }.configure() + } + } + + /** + * Should be invoked only under a [moduleInfo]-based lock + */ + fun createLibrarySession( + moduleInfo: ModuleSourceInfo, + sessionProvider: FirIdeSessionProvider, + project: Project, + ): FirIdeLibrariesSession { + val searchScope = moduleInfo.module.moduleWithLibrariesScope + val javaClassFinder = JavaClassFinderImpl().apply { + setProjectInstance(project) + setScope(searchScope) + } + val packagePartProvider = IDEPackagePartProvider(searchScope) + + val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope) + return FirIdeLibrariesSession(moduleInfo, sessionProvider, searchScope).apply { + registerCommonComponents() + + val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, searchScope) + + val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) + register(IdeSessionComponents::class, IdeSessionComponents.create(this)) + register( + FirSymbolProvider::class, + FirCompositeSymbolProvider( + this, + listOf( + KotlinDeserializedJvmSymbolsProvider( + this, + project, + packagePartProvider, + javaSymbolProvider, + kotlinClassFinder, + javaClassFinder, + kotlinScopeProvider + ), + FirBuiltinSymbolProvider(this, kotlinScopeProvider), + FirCloneableSymbolProvider(this, kotlinScopeProvider), + javaSymbolProvider, + ) + ) + ) + } + } +} diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSourcesSession.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSourcesSession.kt index 4780e67dc8a..c39594eec0e 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSourcesSession.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSourcesSession.kt @@ -5,100 +5,21 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.sessions -import com.intellij.openapi.module.impl.scopes.ModuleWithDependentsScope -import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.extensions.BunchOfRegisteredExtensions -import org.jetbrains.kotlin.fir.extensions.extensionService -import org.jetbrains.kotlin.fir.extensions.registerExtensions -import org.jetbrains.kotlin.fir.java.JavaSymbolProvider -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.FirProvider -import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider -import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped -import org.jetbrains.kotlin.fir.resolve.transformers.PhasedFirFileResolver -import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider -import org.jetbrains.kotlin.fir.session.registerCommonComponents -import org.jetbrains.kotlin.fir.session.registerJavaSpecificComponents -import org.jetbrains.kotlin.fir.session.registerResolveComponents -import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo -import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver -import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner -import org.jetbrains.kotlin.idea.fir.low.level.api.IdePhasedFirFileResolver +import org.jetbrains.kotlin.fir.PrivateSessionConstructor import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder -import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCacheImpl -import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider -import org.jetbrains.kotlin.idea.fir.low.level.api.util.collectTransitiveDependenciesWithSelf /** * [org.jetbrains.kotlin.fir.FirSession] responsible for all Kotlin & Java source modules analysing module transitively depends on */ @OptIn(PrivateSessionConstructor::class) -internal class FirIdeSourcesSession private constructor( +internal class FirIdeSourcesSession @PrivateSessionConstructor constructor( moduleInfo: ModuleInfo, sessionProvider: FirIdeSessionProvider, override val scope: GlobalSearchScope, val firFileBuilder: FirFileBuilder, ) : FirIdeSession(moduleInfo, sessionProvider) { val cache get() = firIdeProvider.cache - - companion object { - /** - * Should be invoked only under a [moduleInfo]-based lock - */ - @OptIn(SessionConfiguration::class) - fun create( - project: Project, - moduleInfo: ModuleSourceInfo, - firPhaseRunner: FirPhaseRunner, - sessionProvider: FirIdeSessionProvider, - librariesSession: FirIdeLibrariesSession, - ): FirIdeSourcesSession { - val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) - val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner) - val dependentModules = moduleInfo.collectTransitiveDependenciesWithSelf().filterIsInstance() - val searchScope = ModuleWithDependentsScope(project, dependentModules.map { it.module }) - return FirIdeSourcesSession(moduleInfo, sessionProvider, searchScope, firBuilder).apply { - val cache = ModuleFileCacheImpl(this) - val phasedFirFileResolver = IdePhasedFirFileResolver(FirLazyDeclarationResolver(firFileBuilder), cache) - - registerCommonComponents() - registerResolveComponents() - - val provider = FirIdeProvider( - project, - this, - moduleInfo, - scopeProvider, - firFileBuilder, - cache, - searchScope - ) - - register(FirProvider::class, provider) - register(FirIdeProvider::class, provider) - - register(PhasedFirFileResolver::class, phasedFirFileResolver) - - register( - FirSymbolProvider::class, - FirCompositeSymbolProvider( - this, - @OptIn(ExperimentalStdlibApi::class) - buildList { - add(provider.symbolProvider) - add(JavaSymbolProvider(this@apply, sessionProvider.project, searchScope)) - add(librariesSession.firSymbolProvider) - } - ) as FirSymbolProvider - ) - registerJavaSpecificComponents() - extensionService.registerExtensions(BunchOfRegisteredExtensions.empty()) - } - } - } }