From f1c808384e33c168cbd2a45d9230be0b9bebbcb5 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Sat, 12 Sep 2020 12:38:16 +0300 Subject: [PATCH] FIR IDE: do not resolve symbols by transitive module dependencies --- .../fir/session/ComponentsContainers.kt | 4 +- .../kotlin/fir/session/FirSessionFactory.kt | 2 +- .../org/jetbrains/kotlin/fir/FirSession.kt | 2 +- .../level/api/FirIdeResolveStateService.kt | 69 +----- .../low/level/api/FirModuleResolveState.kt | 25 +-- .../api/FirModuleResolveStateForCompletion.kt | 13 +- .../idea/fir/low/level/api/FirPhaseRunner.kt | 4 +- .../low/level/api/FirTransformerProvider.kt | 33 +-- .../fir/low/level/api/LowLevelFirApiFacade.kt | 6 +- .../fir/low/level/api/annotations/threads.kt | 5 +- ...rDesignatedBodyResolveTransformerForIDE.kt | 6 +- .../level/api/file/builder/FirFileBuilder.kt | 2 +- .../level/api/file/structure/FileStructure.kt | 2 +- .../resolve/FirLazyDeclarationResolver.kt | 3 +- .../low/level/api/providers/FirIdeProvider.kt | 7 +- ...FirModuleWithDependenciesSymbolProvider.kt | 63 ++++++ .../low/level/api/public/firSessionUtils.kt | 4 +- .../FirIdeBuiltinsAndCloneableSession.kt | 16 ++ .../api/sessions/FirIdeLibrarySession.kt | 9 +- .../low/level/api/sessions/FirIdeSession.kt | 13 +- .../api/sessions/FirIdeSessionFactory.kt | 212 +++++++++--------- .../api/sessions/FirIdeSessionProvider.kt | 37 +-- .../sessions/FirIdeSessionProviderStorage.kt | 36 +++ .../api/sessions/FirIdeSourcesSession.kt | 31 +-- .../api/util/ModuleLibrariesSearchScope.kt | 30 +++ .../level/api/AbstractFirLazyResolveTest.kt | 2 +- ...deDeserializedDeclarationSourceProvider.kt | 4 +- .../frontend/api/fir/KtFirAnalysisSession.kt | 2 +- .../frontend/api/fir/KtSymbolByFirBuilder.kt | 5 +- .../api/fir/components/KtFirCallResolver.kt | 2 +- .../KtFirCompletionCandidateChecker.kt | 2 +- .../api/fir/components/KtFirScopeProvider.kt | 14 +- .../references/FirReferenceResolveHelper.kt | 2 +- 33 files changed, 355 insertions(+), 312 deletions(-) create mode 100644 idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirModuleWithDependenciesSymbolProvider.kt create mode 100644 idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeBuiltinsAndCloneableSession.kt create mode 100644 idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionProviderStorage.kt create mode 100644 idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/ModuleLibrariesSearchScope.kt diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt index 61b77e4fd66..f381eeec1c7 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt @@ -43,7 +43,7 @@ fun FirSession.registerCommonComponents() { * Resolve components which are same on all platforms */ @OptIn(SessionConfiguration::class) -fun FirModuleBasedSession.registerResolveComponents() { +fun FirSession.registerResolveComponents() { register(FirQualifierResolver::class, FirQualifierResolverImpl(this)) register(FirTypeResolver::class, FirTypeResolverImpl(this)) register(CheckersComponent::class, CheckersComponent()) @@ -53,7 +53,7 @@ fun FirModuleBasedSession.registerResolveComponents() { * Resolve components which have specific implementations on JVM */ @OptIn(SessionConfiguration::class) -fun FirModuleBasedSession.registerJavaSpecificResolveComponents() { +fun FirSession.registerJavaSpecificResolveComponents() { register(FirVisibilityChecker::class, FirJavaVisibilityChecker) register(ConeCallConflictResolverFactory::class, JvmCallConflictResolverFactory) register(FirEffectiveVisibilityResolver::class, FirJvmEffectiveVisibilityResolver(this)) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt index 53816c5a9d6..bab7635941b 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt @@ -35,7 +35,7 @@ import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory @OptIn(PrivateSessionConstructor::class, SessionConfiguration::class) object FirSessionFactory { - class FirSessionConfigurator(private val session: FirModuleBasedSession) { + class FirSessionConfigurator(private val session: FirSession) { private val registeredExtensions = mutableListOf(BunchOfRegisteredExtensions.empty()) fun registerExtensions(extensions: BunchOfRegisteredExtensions) { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt index 4b83a5d82d8..3c713e60af8 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt @@ -30,7 +30,7 @@ abstract class FirSession @PrivateSessionConstructor constructor(val sessionProv open val moduleInfo: ModuleInfo? get() = null - val builtinTypes: BuiltinTypes = BuiltinTypes() + open val builtinTypes: BuiltinTypes = BuiltinTypes() final override val typeRegistry: TypeRegistry = Companion 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 c8921da16b0..033a79b0d4d 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 @@ -11,87 +11,40 @@ import com.intellij.openapi.util.ModificationTracker import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager +import org.jetbrains.kotlin.fir.dependenciesWithoutSelf import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo -import org.jetbrains.kotlin.idea.caches.project.LibraryModificationTracker import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener -import org.jetbrains.kotlin.idea.caches.trackers.KotlinModuleOutOfCodeBlockModificationTracker import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeDependentModulesSourcesSession -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeLibrariesSession 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.fir.low.level.api.sessions.FirIdeSessionProviderStorage +import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession import org.jetbrains.kotlin.idea.util.cachedValue import org.jetbrains.kotlin.idea.util.getValue -import org.jetbrains.kotlin.idea.util.psiModificationTrackerBasedCachedValue import java.util.concurrent.ConcurrentHashMap -internal class FirIdeResolveStateService(private val project: Project) { +internal class FirIdeResolveStateService(project: Project) { + private val sessionProviderStorage = FirIdeSessionProviderStorage(project) + private val stateCache by cachedValue(project, KotlinCodeBlockModificationListener.getInstance(project).kotlinOutOfCodeBlockTracker) { ConcurrentHashMap() } - private val moduleLibraryDependencyStateCache = ConcurrentHashMap>() - - private val librarySessionCache by cachedValue(project, LibraryModificationTracker.getInstance(project)) { - ConcurrentHashMap() - } - private fun createResolveStateFor(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl { require(moduleInfo is ModuleSourceInfo) - val firPhaseRunner = FirPhaseRunner() - val sessionProvider = FirIdeSessionProvider(project) - - val librariesSession = librarySessionCache.computeIfAbsent(moduleInfo) { - FirIdeSessionFactory.createLibrarySession(moduleInfo, sessionProvider, project) - } - - val dependentModulesSession = moduleLibraryDependencyStateCache.compute(moduleInfo) { _, cachedIdeaModuleInfo -> - if (cachedIdeaModuleInfo?.hasUpToDateValue() == true) cachedIdeaModuleInfo - else { - CachedValuesManager.getManager(project).createCachedValue { - val dependentSession = FirIdeSessionFactory.createDependentModulesSourcesSession( - project, - moduleInfo, - firPhaseRunner, - sessionProvider, - librariesSession, - ) - CachedValueProvider.Result.create( - dependentSession, - dependentSession.dependentModules.map { it.createModificationTracker() } - .takeUnless { it.isEmpty() } - ?: listOf(ModificationTracker.NEVER_CHANGED) - ) - } - } - }?.value ?: error("ModuleLibraryDependencyStateCache should be computed") - - - val currentModuleSession = FirIdeSessionFactory.createCurrentModuleSourcesSession( - project, - moduleInfo, - firPhaseRunner, - dependentModulesSession, - sessionProvider, - ) - - sessionProvider.init(currentModuleSession, dependentModulesSession, librariesSession) - + val sessionProvider = sessionProviderStorage.getSessionProvider(moduleInfo) + val firFileBuilder = sessionProvider.rootModuleSession.firFileBuilder return FirModuleResolveStateImpl( moduleInfo, - currentModuleSession, - dependentModulesSession, - librariesSession, sessionProvider, - currentModuleSession.firFileBuilder, - FirLazyDeclarationResolver(currentModuleSession.firFileBuilder), + firFileBuilder, + FirLazyDeclarationResolver(firFileBuilder), ) } - fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl = - stateCache.getOrPut(moduleInfo) { createResolveStateFor(moduleInfo) } + stateCache.computeIfAbsent(moduleInfo) { createResolveStateFor(moduleInfo) } companion object { fun getInstance(project: Project): FirIdeResolveStateService = project.service() diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirModuleResolveState.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirModuleResolveState.kt index ae609c128e6..be2d1616840 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirModuleResolveState.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirModuleResolveState.kt @@ -20,10 +20,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataC import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureCache 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.sessions.FirIdeCurrentModuleSourcesSession -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeDependentModulesSourcesSession -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 import org.jetbrains.kotlin.psi.KtElement @@ -31,9 +27,9 @@ import org.jetbrains.kotlin.psi.KtFile abstract class FirModuleResolveState { abstract val moduleInfo: IdeaModuleInfo - abstract val currentModuleSourcesSession: FirSession - abstract val dependentModulesSourcesSession: FirSession - abstract val librariesSession: FirSession + abstract val rootModuleSession: FirSession + + abstract val firTransformerProvider: FirTransformerProvider abstract fun getSessionFor(moduleInfo: IdeaModuleInfo): FirSession @@ -62,25 +58,24 @@ abstract class FirModuleResolveState { internal class FirModuleResolveStateImpl( override val moduleInfo: IdeaModuleInfo, - override val currentModuleSourcesSession: FirIdeCurrentModuleSourcesSession, - override val dependentModulesSourcesSession: FirIdeDependentModulesSourcesSession, - override val librariesSession: FirIdeLibrariesSession, private val sessionProvider: FirIdeSessionProvider, val firFileBuilder: FirFileBuilder, val firLazyDeclarationResolver: FirLazyDeclarationResolver, ) : FirModuleResolveState() { + override val rootModuleSession: FirIdeSourcesSession get() = sessionProvider.rootModuleSession + override val firTransformerProvider: FirTransformerProvider get() = firFileBuilder.firPhaseRunner.transformerProvider val fileStructureCache = FileStructureCache(firFileBuilder, firLazyDeclarationResolver) val elementBuilder = FirElementBuilder() - private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, currentModuleSourcesSession.cache) + private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, rootModuleSession.cache) override fun getSessionFor(moduleInfo: IdeaModuleInfo): FirSession = - sessionProvider.getSession(moduleInfo) + sessionProvider.getSession(moduleInfo)!! override fun getOrBuildFirFor(element: KtElement, toPhase: FirResolvePhase): FirElement = - elementBuilder.getOrBuildFirFor(element, currentModuleSourcesSession.cache, fileStructureCache) + elementBuilder.getOrBuildFirFor(element, rootModuleSession.cache, fileStructureCache) override fun getFirFile(ktFile: KtFile): FirFile = - firFileBuilder.buildRawFirFileWithCaching(ktFile, currentModuleSourcesSession.cache) + firFileBuilder.buildRawFirFileWithCaching(ktFile, rootModuleSession.cache) override fun getDiagnostics(element: KtElement): List = diagnosticsCollector.getDiagnosticsFor(element) @@ -107,7 +102,7 @@ internal class FirModuleResolveStateImpl( ) { firLazyDeclarationResolver.runLazyResolveWithoutLock( firFunction, - currentModuleSourcesSession.cache, + rootModuleSession.cache, containerFirFile, firIdeProvider, fromPhase = firFunction.resolvePhase, diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirModuleResolveStateForCompletion.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirModuleResolveStateForCompletion.kt index 4e79954de11..59ae6ddd4c8 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirModuleResolveStateForCompletion.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirModuleResolveStateForCompletion.kt @@ -14,12 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector -import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureCache import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FirElementsRecorder -import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeCurrentModuleSourcesSession -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeDependentModulesSourcesSession -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeLibrariesSession import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile @@ -27,10 +22,8 @@ internal class FirModuleResolveStateForCompletion( private val originalState: FirModuleResolveStateImpl ) : FirModuleResolveState() { override val moduleInfo: IdeaModuleInfo get() = originalState.moduleInfo - override val currentModuleSourcesSession: FirIdeCurrentModuleSourcesSession get() = originalState.currentModuleSourcesSession - override val dependentModulesSourcesSession: FirIdeDependentModulesSourcesSession get() = originalState.dependentModulesSourcesSession - override val librariesSession: FirIdeLibrariesSession get() = originalState.librariesSession - + override val rootModuleSession get() = originalState.rootModuleSession + override val firTransformerProvider: FirTransformerProvider get() = originalState.firTransformerProvider private val fileStructureCache = originalState.fileStructureCache private val completionMapping = mutableMapOf() @@ -42,7 +35,7 @@ internal class FirModuleResolveStateForCompletion( completionMapping[element]?.let { return it } return originalState.elementBuilder.getOrBuildFirFor( element, - originalState.currentModuleSourcesSession.cache, + originalState.rootModuleSession.cache, fileStructureCache, ) } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirPhaseRunner.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirPhaseRunner.kt index 3e66215ba0c..b5733c88a53 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirPhaseRunner.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirPhaseRunner.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock -internal class FirPhaseRunner { +internal class FirPhaseRunner(val transformerProvider: FirTransformerProvider) { private val superTypesBodyResolveLock = ReentrantLock() private val implicitTypesResolveLock = ReentrantLock() @@ -28,7 +28,7 @@ internal class FirPhaseRunner { } private fun runPhaseWithoutLock(firFile: FirFile, phase: FirResolvePhase) { - val phaseProcessor = firFile.session.firTransformerProvider.getTransformerForPhase(phase) + val phaseProcessor = transformerProvider.getTransformerForPhase(firFile.session, phase) executeWithoutPCE { phaseProcessor.processFile(firFile) } } } \ 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/FirTransformerProvider.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirTransformerProvider.kt index 4e0c18487c8..ced4308384b 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirTransformerProvider.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirTransformerProvider.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api +import com.google.common.collect.MapMaker import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.declarations.FirResolvePhase @@ -13,23 +14,23 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveP import org.jetbrains.kotlin.fir.resolve.transformers.createTransformerBasedProcessorByPhase import java.util.* -class FirTransformerProvider(session: FirSession) : FirSessionComponent { - private val scopeSession = ThreadLocal.withInitial { ScopeSession() } - private val transformers = ThreadLocal.withInitial { - val scopesSession = scopeSession.get() - EnumMap(FirResolvePhase::class.java).apply { - FirResolvePhase.values().forEach { resolvePhase -> - if (resolvePhase != FirResolvePhase.RAW_FIR) { - put(resolvePhase, resolvePhase.createTransformerBasedProcessorByPhase(session, scopesSession)) +class FirTransformerProvider { + private val scopeSession = MapMaker().weakKeys().makeMap() + private val transformers = MapMaker().weakKeys().makeMap>() + + + fun getTransformerForPhase(session: FirSession, phase: FirResolvePhase): FirTransformerBasedResolveProcessor = + transformers.computeIfAbsent(session) { + val scopesSession = getScopeSession(session) + EnumMap(FirResolvePhase::class.java).apply { + FirResolvePhase.values().forEach { resolvePhase -> + if (resolvePhase != FirResolvePhase.RAW_FIR) { + put(resolvePhase, resolvePhase.createTransformerBasedProcessorByPhase(session, scopesSession)) + } } } - } - } + }.getValue(phase) - fun getTransformerForPhase(phase: FirResolvePhase): FirTransformerBasedResolveProcessor = - transformers.get().getValue(phase) - - fun getScopeSession(): ScopeSession = scopeSession.get() + fun getScopeSession(session: FirSession): ScopeSession = + scopeSession.getOrPut(session) { ScopeSession() } } - -val FirSession.firTransformerProvider: FirTransformerProvider by FirSession.sessionComponentAccessor() diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/LowLevelFirApiFacade.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/LowLevelFirApiFacade.kt index 11b082b1d64..9046d271b20 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/LowLevelFirApiFacade.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/LowLevelFirApiFacade.kt @@ -114,7 +114,7 @@ object LowLevelFirApiFacade { symbol = builtFunction.symbol as FirNamedFunctionSymbol resolvePhase = minOf(originalFunction.resolvePhase, FirResolvePhase.DECLARATIONS) source = builtFunction.source - session = state.currentModuleSourcesSession + session = state.rootModuleSession } } @@ -137,7 +137,7 @@ object LowLevelFirApiFacade { symbol = builtSetter.symbol resolvePhase = minOf(builtSetter.resolvePhase, FirResolvePhase.DECLARATIONS) source = builtSetter.source - session = state.currentModuleSourcesSession + session = state.rootModuleSession } } else { builtSetter @@ -151,7 +151,7 @@ object LowLevelFirApiFacade { resolvePhase = minOf(originalProperty.resolvePhase, FirResolvePhase.DECLARATIONS) source = builtProperty.source - session = state.currentModuleSourcesSession + session = state.rootModuleSession } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/annotations/threads.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/annotations/threads.kt index 80191ddad19..e871ec82de3 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/annotations/threads.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/annotations/threads.kt @@ -9,4 +9,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.annotations annotation class ThreadSafe @Target(AnnotationTarget.CLASS) -annotation class NotThreadSafe \ No newline at end of file +annotation class NotThreadSafe + +@Target(AnnotationTarget.CLASS) +annotation class Immutable \ 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/element/builder/FirDesignatedBodyResolveTransformerForIDE.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/element/builder/FirDesignatedBodyResolveTransformerForIDE.kt index a7e67b8f24f..af78d91d291 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/element/builder/FirDesignatedBodyResolveTransformerForIDE.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/element/builder/FirDesignatedBodyResolveTransformerForIDE.kt @@ -21,12 +21,12 @@ internal class FirDesignatedBodyResolveTransformerForIDE( private val designation: Iterator, session: FirSession, scopeSession: ScopeSession, - implicitTypeOnly: Boolean, + phase: FirResolvePhase, private val towerDataContextCollector: FirTowerDataContextCollector? = null ) : FirBodyResolveTransformer( session, - phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE, - implicitTypeOnly = implicitTypeOnly, + phase = phase, + implicitTypeOnly = phase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE, scopeSession = scopeSession, returnTypeCalculator = createReturnTypeCalculatorForIDE(session, scopeSession) ) { diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt index 7d871b36f80..ec2a58d4fe0 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.util.lockWithPCECheck @ThreadSafe internal class FirFileBuilder( private val scopeProvider: FirScopeProvider, - private val firPhaseRunner: FirPhaseRunner + val firPhaseRunner: FirPhaseRunner ) { /** * Builds a [FirFile] by given [ktFile] and records it's parenting info if it not present in [cache] diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt index b38270de564..fec531ef281 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt @@ -142,7 +142,7 @@ internal class FileStructure( val firFile = firFileBuilder.getFirFileResolvedToPhaseWithCaching( container, moduleFileCache, - FirResolvePhase.BODY_RESOLVE, + FirResolvePhase.IMPORTS, checkPCE = true ) FileWithoutDeclarationsFileStructureElement( diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/FirLazyDeclarationResolver.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/FirLazyDeclarationResolver.kt index 0c5530c0079..f9bb986bc9a 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/FirLazyDeclarationResolver.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/FirLazyDeclarationResolver.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirDesignated import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache -import org.jetbrains.kotlin.idea.fir.low.level.api.firTransformerProvider import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE @@ -128,7 +127,7 @@ internal class FirLazyDeclarationResolver( if (designation.all { it.resolvePhase >= toPhase }) { return } - val scopeSession = containerFirFile.session.firTransformerProvider.getScopeSession() + val scopeSession = firFileBuilder.firPhaseRunner.transformerProvider.getScopeSession(containerFirFile.session) val transformer = FirDesignatedBodyResolveTransformerForIDE( designation.iterator(), containerFirFile.session, scopeSession, diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirIdeProvider.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirIdeProvider.kt index 89cf8cc29c9..34bd9f5b53a 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirIdeProvider.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirIdeProvider.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.ThreadSafeMutableState import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty +import org.jetbrains.kotlin.fir.dependenciesWithoutSelf import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProviderInternals import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider @@ -24,6 +25,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceCheckerForMultipleModules +import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceCheckerForSingleModule import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache import org.jetbrains.kotlin.idea.fir.low.level.api.util.collectTransitiveDependenciesWithSelf @@ -46,10 +48,7 @@ internal class FirIdeProvider( override val symbolProvider: FirSymbolProvider = SymbolProvider() private val indexHelper = IndexHelper(project, searchScope) - private val packageExistenceChecker = PackageExistenceCheckerForMultipleModules( - project, - moduleInfo.collectTransitiveDependenciesWithSelf().filterIsInstance() - ) + private val packageExistenceChecker = PackageExistenceCheckerForSingleModule(project, moduleInfo) private val providerHelper = FirProviderHelper( cache, diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirModuleWithDependenciesSymbolProvider.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirModuleWithDependenciesSymbolProvider.kt new file mode 100644 index 00000000000..b940142e127 --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirModuleWithDependenciesSymbolProvider.kt @@ -0,0 +1,63 @@ +/* + * 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.providers + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult + +internal class FirModuleWithDependenciesSymbolProvider( + session: FirSession, + private val providers: List, + private val dependentProviders: List, +) : FirSymbolProvider(session) { + + override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? = + providers.firstNotNullResult { it.getClassLikeSymbolByFqName(classId) } + ?: withDependent(default = null) { + dependentProviders.firstNotNullResult { it.getClassLikeSymbolByFqName(classId) } + } + + @FirSymbolProviderInternals + override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) { + providers.flatMapTo(destination) { it.getTopLevelCallableSymbols(packageFqName, name) } + withDependent { + dependentProviders.flatMapTo(destination) { it.getTopLevelCallableSymbols(packageFqName, name) } + } + } + + override fun getPackage(fqName: FqName): FqName? = + providers.firstNotNullResult { it.getPackage(fqName) } + ?: withDependent(default = null) { + dependentProviders.firstNotNullResult { it.getPackage(fqName) } + } + + companion object { + private val canUseDependent = ThreadLocal.withInitial { true } + + private inline fun withDependent(default: R, action: () -> R): R { + if (canUseDependent.get()) { + canUseDependent.set(false) + try { + return action() + } finally { + canUseDependent.set(true) + } + } + return default + } + + private inline fun withDependent(action: () -> Unit) { + withDependent(Unit, action) + } + } +} diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/public/firSessionUtils.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/public/firSessionUtils.kt index 9e29c5c3375..b45267bd155 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/public/firSessionUtils.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/public/firSessionUtils.kt @@ -7,13 +7,13 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.public import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession +import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeModuleSession /** * Returns a [GlobalSearchScope] declarations from which [FirSession] knows about */ val FirSession.searchScope: GlobalSearchScope get() { - check(this is FirIdeSession) + check(this is FirIdeModuleSession) return scope } \ 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/FirIdeBuiltinsAndCloneableSession.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeBuiltinsAndCloneableSession.kt new file mode 100644 index 00000000000..59f679eaab9 --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeBuiltinsAndCloneableSession.kt @@ -0,0 +1,16 @@ +/* + * 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.project.Project +import org.jetbrains.kotlin.fir.BuiltinTypes +import org.jetbrains.kotlin.fir.PrivateSessionConstructor + +@OptIn(PrivateSessionConstructor::class) +class FirIdeBuiltinsAndCloneableSession @PrivateSessionConstructor constructor( + override val project: Project, + builtinTypes: BuiltinTypes, +) : FirIdeSession(builtinTypes) \ 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 c189800934b..36afe3c6189 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,8 +5,10 @@ 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.analyzer.ModuleInfo +import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.PrivateSessionConstructor /** @@ -15,6 +17,7 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor @OptIn(PrivateSessionConstructor::class) internal class FirIdeLibrariesSession @PrivateSessionConstructor constructor( moduleInfo: ModuleInfo, - sessionProvider: FirIdeSessionProvider, - override val scope: GlobalSearchScope -) : FirIdeSession(moduleInfo, sessionProvider) + override val project: Project, + override val scope: GlobalSearchScope, + builtinTypes: BuiltinTypes, +) : FirIdeModuleSession(moduleInfo, builtinTypes) diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSession.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSession.kt index ef2ce3d78e8..842dae85ed4 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSession.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSession.kt @@ -5,15 +5,20 @@ 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.analyzer.ModuleInfo +import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.FirModuleBasedSession +import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.PrivateSessionConstructor @OptIn(PrivateSessionConstructor::class) -internal abstract class FirIdeSession( - moduleInfo: ModuleInfo, - sessionProvider: FirIdeSessionProvider -) : FirModuleBasedSession(moduleInfo, sessionProvider) { +abstract class FirIdeSession(override val builtinTypes: BuiltinTypes) : FirSession(sessionProvider = null) { + abstract val project: Project +} + +@OptIn(PrivateSessionConstructor::class) +abstract class FirIdeModuleSession(override val moduleInfo: ModuleInfo, builtinTypes: BuiltinTypes) : FirIdeSession(builtinTypes) { abstract val scope: GlobalSearchScope } 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 index 6036fecb33a..f03a6be6e81 100644 --- 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 @@ -5,12 +5,12 @@ 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.fir.BuiltinTypes import org.jetbrains.kotlin.fir.PrivateSessionConstructor import org.jetbrains.kotlin.fir.SessionConfiguration import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers +import org.jetbrains.kotlin.fir.dependenciesWithoutSelf import org.jetbrains.kotlin.fir.java.JavaSymbolProvider import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider @@ -29,133 +29,106 @@ import org.jetbrains.kotlin.fir.session.registerResolveComponents import org.jetbrains.kotlin.idea.caches.project.* 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.FirTransformerProvider import org.jetbrains.kotlin.idea.fir.low.level.api.IdeFirPhaseManager 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.ModuleFileCache 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.FirModuleWithDependenciesSymbolProvider 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.idea.fir.low.level.api.util.ModuleLibrariesSearchScope +import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled import org.jetbrains.kotlin.load.java.JavaClassFinderImpl import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory @OptIn(PrivateSessionConstructor::class, SessionConfiguration::class) internal object FirIdeSessionFactory { - fun createCurrentModuleSourcesSession( + fun createSourcesSession( project: Project, moduleInfo: ModuleSourceInfo, + builtinsAndCloneableSession: FirIdeBuiltinsAndCloneableSession, firPhaseRunner: FirPhaseRunner, - dependentModulesSourcesSession: FirIdeDependentModulesSourcesSession, - sessionProvider: FirIdeSessionProvider, - ): FirIdeCurrentModuleSourcesSession { + builtinTypes: BuiltinTypes, + sessionsCache: MutableMap, + isRootModule: Boolean, + ): FirIdeSourcesSession { + sessionsCache[moduleInfo]?.let { return it } val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner) val searchScope = ModuleProductionSourceScope(moduleInfo.module) - return FirIdeCurrentModuleSourcesSession(moduleInfo, sessionProvider, searchScope, firBuilder).apply { + val session = FirIdeSourcesSession(moduleInfo, project, searchScope, firBuilder, builtinTypes) + sessionsCache[moduleInfo] = session + val dependentModules = moduleInfo.dependenciesWithoutSelf() + .filterIsInstanceTo>(mutableListOf()) + + return session.apply { val cache = ModuleFileCacheImpl(this) - registerCommonSourceSessionComponents( + val firPhaseManager = IdeFirPhaseManager(FirLazyDeclarationResolver(firFileBuilder), cache) + + registerCommonComponents() + registerResolveComponents() + registerIdeComponents() + + val provider = FirIdeProvider( project, + this, moduleInfo, scopeProvider, - searchScope, + firFileBuilder, cache, - additionalSymbolProviders = listOf( - dependentModulesSourcesSession.firSymbolProvider, + searchScope + ) + + register(FirProvider::class, provider) + register(FirIdeProvider::class, provider) + + register(FirPhaseManager::class, firPhaseManager) + + @OptIn(ExperimentalStdlibApi::class) + register( + FirSymbolProvider::class, + FirModuleWithDependenciesSymbolProvider( + this, + providers = listOf( + provider.symbolProvider, + JavaSymbolProvider(this@apply, project, searchScope), + ), + dependentProviders = buildList { + add(createLibrarySession(moduleInfo, project, builtinsAndCloneableSession, builtinTypes).firSymbolProvider) + dependentModules + .mapTo(this) { + createSourcesSession( + project, + it, + builtinsAndCloneableSession, + firPhaseRunner, + builtinTypes, + sessionsCache, + isRootModule = false + ).firSymbolProvider + } + } ) ) + + registerJavaSpecificComponents() FirSessionFactory.FirSessionConfigurator(this).apply { - registerCommonCheckers() + if (isRootModule) { + registerCommonCheckers() + } }.configure() } } - fun createDependentModulesSourcesSession( - project: Project, - moduleInfo: ModuleSourceInfo, - firPhaseRunner: FirPhaseRunner, - sessionProvider: FirIdeSessionProvider, - librariesSession: FirIdeLibrariesSession, - ): FirIdeDependentModulesSourcesSession { - val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) - val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner) - val dependentModules = moduleInfo.collectTransitiveDependenciesWithSelf() - .filterIsInstance() - .filterNot { it == moduleInfo } - val searchScope = if (dependentModules.isNotEmpty()) GlobalSearchScope.union(dependentModules.map { it.contentScope() }) - else GlobalSearchScope.EMPTY_SCOPE - return FirIdeDependentModulesSourcesSession(moduleInfo, dependentModules, sessionProvider, searchScope, firBuilder).apply { - val cache = ModuleFileCacheImpl(this) - registerCommonSourceSessionComponents( - project, - moduleInfo, - scopeProvider, - searchScope, - cache, - additionalSymbolProviders = listOf(librariesSession.firSymbolProvider) - ) - FirSessionFactory.FirSessionConfigurator(this).configure() - } - } - - private fun FirIdeSourcesSession.registerCommonSourceSessionComponents( - project: Project, - moduleInfo: ModuleSourceInfo, - scopeProvider: KotlinScopeProvider, - searchScope: GlobalSearchScope, - cache: ModuleFileCache, - additionalSymbolProviders: List = emptyList() - ) { - val firPhaseManager = IdeFirPhaseManager(FirLazyDeclarationResolver(firFileBuilder), cache) - - registerCommonComponents() - registerResolveComponents() - registerIdeComponents() - - val provider = FirIdeProvider( - project, - this, - moduleInfo, - scopeProvider, - firFileBuilder, - cache, - searchScope - ) - - register(FirProvider::class, provider) - register(FirIdeProvider::class, provider) - - register(FirPhaseManager::class, firPhaseManager) - - register( - FirSymbolProvider::class, - FirCompositeSymbolProvider( - this, - @OptIn(ExperimentalStdlibApi::class) - buildList { - add(provider.symbolProvider) - add(JavaSymbolProvider(this@registerCommonSourceSessionComponents, project, searchScope)) - addAll(additionalSymbolProviders) - } - ) as FirSymbolProvider - ) - registerJavaSpecificComponents() - } - - private fun IdeaModuleInfo.librarySearchScope(): GlobalSearchScope? = when (this) { - is LibraryInfo -> contentScope() - is SdkInfo -> contentScope() - else -> null - } - fun createLibrarySession( moduleInfo: ModuleSourceInfo, - sessionProvider: FirIdeSessionProvider, project: Project, + builtinsAndCloneableSession: FirIdeBuiltinsAndCloneableSession, + builtinTypes: BuiltinTypes, ): FirIdeLibrariesSession { - val dependencies = moduleInfo.collectTransitiveDependenciesWithSelf() - .mapNotNullTo(mutableListOf()) { it.librarySearchScope() } - val searchScope = if (dependencies.isEmpty()) GlobalSearchScope.EMPTY_SCOPE else GlobalSearchScope.union(dependencies) + checkCanceled() + val searchScope = ModuleLibrariesSearchScope(moduleInfo.module) val javaClassFinder = JavaClassFinderImpl().apply { setProjectInstance(project) setScope(searchScope) @@ -163,32 +136,52 @@ internal object FirIdeSessionFactory { val packagePartProvider = IDEPackagePartProvider(searchScope) val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope) - return FirIdeLibrariesSession(moduleInfo, sessionProvider, searchScope).apply { + return FirIdeLibrariesSession(moduleInfo, project, searchScope, builtinTypes).apply { registerCommonComponents() registerJavaSpecificComponents() registerIdeComponents() - val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, searchScope) + val javaSymbolProvider = JavaSymbolProvider(this, project, searchScope) + + val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) + + @OptIn(ExperimentalStdlibApi::class) + register( + FirSymbolProvider::class, + FirCompositeSymbolProvider( + this, + buildList { + add( + KotlinDeserializedJvmSymbolsProvider( + this@apply, + project, + packagePartProvider, + javaSymbolProvider, + kotlinClassFinder, + javaClassFinder, + kotlinScopeProvider + ) + ) + add(javaSymbolProvider) + addAll((builtinsAndCloneableSession.firSymbolProvider as FirCompositeSymbolProvider).providers) + } + ) + ) + } + } + + fun createBuiltinsAndCloneableSession(project: Project, builtinTypes: BuiltinTypes): FirIdeBuiltinsAndCloneableSession { + return FirIdeBuiltinsAndCloneableSession(project, builtinTypes).apply { + registerCommonComponents() 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, ) ) ) @@ -197,6 +190,5 @@ internal object FirIdeSessionFactory { private fun FirIdeSession.registerIdeComponents() { register(IdeSessionComponents::class, IdeSessionComponents.create(this)) - register(FirTransformerProvider::class, FirTransformerProvider(this)) } } \ 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/FirIdeSessionProvider.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionProvider.kt index 710b7a4c834..c3155535786 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionProvider.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionProvider.kt @@ -12,38 +12,15 @@ import org.jetbrains.kotlin.fir.FirSessionProvider import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo import org.jetbrains.kotlin.idea.caches.project.isLibraryClasses +import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.Immutable import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.ThreadSafe -@ThreadSafe -internal class FirIdeSessionProvider( +@Immutable +class FirIdeSessionProvider internal constructor( override val project: Project, + internal val rootModuleSession: FirIdeSourcesSession, + val sessions: Map ) : FirSessionProvider { - private lateinit var currentModuleSourcesSession: FirIdeSourcesSession - private lateinit var dependentModulesModuleSourcesSession: FirIdeSourcesSession - private lateinit var librariesSession: FirIdeLibrariesSession - - - fun init( - currentModuleSourcesSession: FirIdeSourcesSession, - dependentModulesModuleSourcesSession: FirIdeSourcesSession, - librariesSession: FirIdeLibrariesSession, - ) { - this.currentModuleSourcesSession = currentModuleSourcesSession - this.dependentModulesModuleSourcesSession = dependentModulesModuleSourcesSession - this.librariesSession = librariesSession - } - - - override fun getSession(moduleInfo: ModuleInfo): FirSession = when { - moduleInfo is IdeaModuleInfo && moduleInfo.isLibraryClasses() -> { - librariesSession /* TODO check if library is in libraries session scope */ - } - moduleInfo == currentModuleSourcesSession.moduleInfo -> { - currentModuleSourcesSession - } - moduleInfo is ModuleSourceInfo -> { - currentModuleSourcesSession /* TODO check if source is in sources session scope */ - } - else -> error("Invalid module info $moduleInfo") - } + override fun getSession(moduleInfo: ModuleInfo): FirSession? = + sessions[moduleInfo] } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionProviderStorage.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionProviderStorage.kt new file mode 100644 index 00000000000..ba008ec7fe1 --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/sessions/FirIdeSessionProviderStorage.kt @@ -0,0 +1,36 @@ +/* + * 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.project.Project +import org.jetbrains.kotlin.fir.BuiltinTypes +import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo +import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner +import org.jetbrains.kotlin.idea.fir.low.level.api.FirTransformerProvider +import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE + +internal class FirIdeSessionProviderStorage(private val project: Project) { + fun getSessionProvider(rootModule: ModuleSourceInfo): FirIdeSessionProvider { + val transformerProvider = FirTransformerProvider() + val firPhaseRunner = FirPhaseRunner(transformerProvider) + val builtinTypes = BuiltinTypes() + val builtinsAndCloneableSession = FirIdeSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes) + val sessions = mutableMapOf() + val session = executeWithoutPCE { + FirIdeSessionFactory.createSourcesSession( + project, + rootModule, + builtinsAndCloneableSession, + firPhaseRunner, + builtinTypes, + sessions, + isRootModule = true + ) + } + + return FirIdeSessionProvider(project, session, sessions) + } +} \ 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/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 627152ac09f..5068a57c7ab 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,41 +5,22 @@ 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.analyzer.ModuleInfo +import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.PrivateSessionConstructor -import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider -/** - * [org.jetbrains.kotlin.fir.FirSession] responsible for all Kotlin & Java source modules analysing module transitively depends on - */ @OptIn(PrivateSessionConstructor::class) -internal abstract class FirIdeSourcesSession @PrivateSessionConstructor constructor( +internal class FirIdeSourcesSession @PrivateSessionConstructor constructor( moduleInfo: ModuleInfo, - sessionProvider: FirIdeSessionProvider, + override val project: Project, override val scope: GlobalSearchScope, val firFileBuilder: FirFileBuilder, -) : FirIdeSession(moduleInfo, sessionProvider) { + builtinTypes: BuiltinTypes, +) : FirIdeModuleSession(moduleInfo, builtinTypes) { val cache get() = firIdeProvider.cache } - -@OptIn(PrivateSessionConstructor::class) -internal class FirIdeCurrentModuleSourcesSession @PrivateSessionConstructor constructor( - moduleInfo: ModuleInfo, - sessionProvider: FirIdeSessionProvider, - scope: GlobalSearchScope, - firFileBuilder: FirFileBuilder, -) : FirIdeSourcesSession(moduleInfo, sessionProvider, scope, firFileBuilder) { -} - -@OptIn(PrivateSessionConstructor::class) -internal class FirIdeDependentModulesSourcesSession @PrivateSessionConstructor constructor( - moduleInfo: ModuleInfo, - val dependentModules: List, - sessionProvider: FirIdeSessionProvider, - scope: GlobalSearchScope, - firFileBuilder: FirFileBuilder, -) : FirIdeSourcesSession(moduleInfo, sessionProvider, scope, firFileBuilder) diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/ModuleLibrariesSearchScope.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/ModuleLibrariesSearchScope.kt new file mode 100644 index 00000000000..081eafc8f12 --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/ModuleLibrariesSearchScope.kt @@ -0,0 +1,30 @@ +/* + * 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.util + +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.JdkOrderEntry +import com.intellij.openapi.roots.LibraryOrderEntry +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.util.Comparing +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.search.GlobalSearchScope + +internal class ModuleLibrariesSearchScope(private val module: Module) : GlobalSearchScope(module.project) { + override fun contains(file: VirtualFile): Boolean { + val orderEntry = ModuleRootManager.getInstance(module).fileIndex.getOrderEntryForFile(file) + return orderEntry is JdkOrderEntry || orderEntry is LibraryOrderEntry + } + + override fun compare(file1: VirtualFile, file2: VirtualFile): Int { + val fileIndex = ModuleRootManager.getInstance(module).fileIndex + return Comparing.compare(fileIndex.getOrderEntryForFile(file2), fileIndex.getOrderEntryForFile(file1)) + } + + override fun isSearchInModuleContent(aModule: Module): Boolean = false + + override fun isSearchInLibraries(): Boolean = true +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/AbstractFirLazyResolveTest.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/AbstractFirLazyResolveTest.kt index 25e34181266..f878a24134e 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/AbstractFirLazyResolveTest.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/AbstractFirLazyResolveTest.kt @@ -102,7 +102,7 @@ abstract class AbstractFirLazyResolveTest : KotlinLightCodeInsightFixtureTestCas val files = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, contentScope) for (file in files) { val psiFile = psiManager.findFile(file) as KtFile - val session = resolveState.currentModuleSourcesSession + val session = resolveState.rootModuleSession val firProvider = session.firIdeProvider val firFile = firProvider.cache.getCachedFirFile(psiFile) ?: continue KotlinTestUtils.assertEqualsToFile(File(expectedTxtPath(file)), firFile.render()) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirIdeDeserializedDeclarationSourceProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirIdeDeserializedDeclarationSourceProvider.kt index b3db547560f..ac148068fb7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirIdeDeserializedDeclarationSourceProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirIdeDeserializedDeclarationSourceProvider.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.psi -import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol +import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelTypeAliasFqNameIndex @@ -143,4 +143,4 @@ fun FirElement.findPsi(project: Project): PsiElement? = psi ?: FirIdeDeserializedDeclarationSourceProvider.findPsi(this, project) fun FirElement.findPsi(session: FirSession): PsiElement? = - findPsi(session.sessionProvider!!.project) \ No newline at end of file + findPsi((session as FirIdeSession).project) \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt index 8c0f476d6f9..1f9c3d279c7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt @@ -40,7 +40,7 @@ private constructor( override val callResolver: KtCallResolver = KtFirCallResolver(this, token) override val scopeProvider by threadLocal { KtFirScopeProvider(this, firSymbolBuilder, project, firResolveState, token) } override val symbolProvider: KtSymbolProvider = - KtFirSymbolProvider(this, firResolveState.currentModuleSourcesSession.firSymbolProvider, firResolveState, firSymbolBuilder, token) + KtFirSymbolProvider(this, firResolveState.rootModuleSession.firSymbolProvider, firResolveState, firSymbolBuilder, token) override val completionCandidateChecker: KtCompletionCandidateChecker by threadLocal { KtFirCompletionCandidateChecker(this, token) } override val symbolDeclarationOverridesProvider: KtSymbolDeclarationOverridesProvider by threadLocal { KtFirSymbolDeclarationOverridesProvider(this, token) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt index 4b673cb6b7a..e735e7f88e7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt @@ -10,7 +10,6 @@ import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag @@ -47,11 +46,11 @@ internal class KtSymbolByFirBuilder private constructor( ConeTypeCheckerContext( isErrorTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true, - resolveState.currentModuleSourcesSession + resolveState.rootModuleSession ) } - private val firProvider get() = resolveState.currentModuleSourcesSession.firSymbolProvider + private val firProvider get() = resolveState.rootModuleSession.firSymbolProvider constructor( resolveState: FirModuleResolveState, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt index 323609268af..17a61f6b703 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt @@ -50,7 +50,7 @@ internal class KtFirCallResolver( } private fun resolveCall(firCall: FirFunctionCall, callExpression: KtExpression): CallInfo? { - val session = firResolveState.currentModuleSourcesSession + val session = firResolveState.rootModuleSession val resolvedFunctionSymbol = firCall.calleeReference.toTargetSymbol(session, firSymbolBuilder) val resolvedCalleeSymbol = (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol return when { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCompletionCandidateChecker.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCompletionCandidateChecker.kt index 8ff1bc0939a..e3a6ddb7e1c 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCompletionCandidateChecker.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCompletionCandidateChecker.kt @@ -68,7 +68,7 @@ internal class KtFirCompletionCandidateChecker( ): Boolean { val file = firResolveState.getFirFile(originalFile) val explicitReceiverExpression = possibleExplicitReceiver?.getOrBuildFirOfType(firResolveState) - val resolver = SingleCandidateResolver(firResolveState.currentModuleSourcesSession, file) + val resolver = SingleCandidateResolver(firResolveState.rootModuleSession, file) val implicitReceivers = getImplicitReceivers(originalFile, file, nameExpression) for (implicitReceiverValue in implicitReceivers) { val resolutionParameters = ResolutionParameters( diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt index d244b6250d9..f1b947b49c2 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt @@ -6,18 +6,14 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase -import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope -import org.jetbrains.kotlin.idea.fir.getOrBuildFirOfType import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade -import org.jetbrains.kotlin.idea.fir.low.level.api.firTransformerProvider import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner @@ -60,7 +56,8 @@ internal class KtFirScopeProvider( check(classSymbol is KtFirClassOrObjectSymbol) val firScope = classSymbol.firRef.withFir(FirResolvePhase.SUPER_TYPES) { fir -> - fir.unsubstitutedScope(fir.session, fir.session.firTransformerProvider.getScopeSession()) + val firSession = fir.session + fir.unsubstitutedScope(firSession, firResolveState.firTransformerProvider.getScopeSession(firSession)) }.also(firScopeStorage::register) KtFirMemberScope(classSymbol, firScope, token, builder) } @@ -80,7 +77,7 @@ internal class KtFirScopeProvider( val firPackageScope = FirPackageMemberScope( packageSymbol.fqName, - firResolveState.currentModuleSourcesSession/*TODO use correct session here*/ + firResolveState.rootModuleSession/*TODO use correct session here*/ ).also(firScopeStorage::register) KtFirPackageScope(firPackageScope, project, builder, token) } @@ -92,8 +89,9 @@ internal class KtFirScopeProvider( override fun getTypeScope(type: KtType): KtScope? { check(type is KtFirType) { "KtFirScopeProvider can only work with KtFirType, but ${type::class} was provided" } - val firSession = firResolveState.currentModuleSourcesSession - val firTypeScope = type.coneType.scope(firSession, firSession.firTransformerProvider.getScopeSession()) ?: return null + val firSession = firResolveState.rootModuleSession + val firTypeScope = type.coneType.scope(firSession, firResolveState.firTransformerProvider.getScopeSession(firSession)) + ?: return null return convertToKtScope(firTypeScope) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt index c35e9abeb60..9d927564134 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt @@ -136,7 +136,7 @@ internal object FirReferenceResolveHelper { val expression = ref.expression val symbolBuilder = analysisSession.firSymbolBuilder val fir = expression.getOrBuildFir(analysisSession.firResolveState) - val session = analysisSession.firResolveState.currentModuleSourcesSession + val session = analysisSession.firResolveState.rootModuleSession when (fir) { is FirResolvable -> { val calleeReference =