diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt index 8603a725869..dd5eae6742a 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirModuleResolveSta import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.moduleData +import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.platform.TargetPlatform @@ -116,6 +117,8 @@ private constructor( val firSymbolProvider: FirSymbolProvider get() = rootModuleSession.symbolProvider val targetPlatform: TargetPlatform get() = rootModuleSession.moduleData.platform + fun getScopeSessionFor(session: FirSession): ScopeSession = firResolveState.getScopeSessionFor(session) + companion object { @InvalidWayOfUsingAnalysisSession internal fun createAnalysisSessionByResolveState( diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt index 87a8db0d27a..12e745ba5bb 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt @@ -929,7 +929,11 @@ internal class KtFirCallResolver( } private fun FirClassSymbol<*>.getEqualsSymbol(equalsSymbolInAny: FirNamedFunctionSymbol): FirNamedFunctionSymbol { - val scope = unsubstitutedScope(analysisSession.rootModuleSession, ScopeSession(), false) + val scope = unsubstitutedScope( + analysisSession.rootModuleSession, + analysisSession.getScopeSessionFor(analysisSession.rootModuleSession), + false + ) var equalsSymbol: FirNamedFunctionSymbol? = null scope.processFunctionsByName(EQUALS) { equalsSymbolFromScope -> if (equalsSymbol != null) return@processFunctionsByName diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt index a611f07689f..86cd49ad605 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt @@ -66,7 +66,7 @@ internal class KtFirReferenceShortener( override val token: ValidityToken, override val firResolveState: LLFirModuleResolveState, ) : KtReferenceShortener(), KtFirAnalysisSessionComponent { - private val context = FirShorteningContext(firResolveState) + private val context = FirShorteningContext(analysisSession) override fun collectShortenings( file: KtFile, @@ -163,7 +163,8 @@ private data class AvailableSymbol( val importKind: ImportKind, ) -private class FirShorteningContext(val firResolveState: LLFirModuleResolveState) { +private class FirShorteningContext(val analysisSession: KtFirAnalysisSession) { + private val firResolveState = analysisSession.firResolveState private val firSession: FirSession get() = firResolveState.rootModuleSession @@ -229,7 +230,11 @@ private class FirShorteningContext(val firResolveState: LLFirModuleResolveState) val resolvedNewImports = newImports.mapNotNull { createFakeResolvedImport(it) } if (resolvedNewImports.isEmpty()) return null - return FirExplicitSimpleImportingScope(resolvedNewImports, firSession, ScopeSession()) + return FirExplicitSimpleImportingScope( + resolvedNewImports, + firSession, + analysisSession.getScopeSessionFor(firSession), + ) } private fun createFakeResolvedImport(fqNameToImport: FqName): FirResolvedImport? { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSamResolver.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSamResolver.kt index ea3f3f255f9..c02f8ec5f2d 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSamResolver.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSamResolver.kt @@ -28,16 +28,18 @@ internal class KtFirSamResolver( override fun getSamConstructor(ktClassLikeSymbol: KtClassLikeSymbol): KtSamConstructorSymbol? { val classId = ktClassLikeSymbol.classIdIfNonLocal ?: return null val owner = analysisSession.getClassLikeSymbol(classId) as? FirRegularClass ?: return null - val resolver = LocalSamResolver(analysisSession.rootModuleSession) + val resolver = LocalSamResolver(analysisSession, analysisSession.rootModuleSession) return resolver.getSamConstructor(owner)?.let { analysisSession.firSymbolBuilder.functionLikeBuilder.buildSamConstructorSymbol(it.symbol) } } private class LocalSamResolver( + analysisSession: KtFirAnalysisSession, private val firSession: FirSession, ) { - private val scopeSession = ScopeSession() + private val scopeSession = analysisSession.getScopeSessionFor(firSession) + // TODO: This transformer is not intended for actual transformations and // created here only to simplify access to SAM resolver in body resolve components diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirScopeProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirScopeProvider.kt index a83cc103fc8..1744d61da4f 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirScopeProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirScopeProvider.kt @@ -36,7 +36,6 @@ import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.utils.delegateFields import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression -import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.scopes.* @@ -53,6 +52,10 @@ internal class KtFirScopeProvider( firResolveState: LLFirModuleResolveState, override val token: ValidityToken, ) : KtScopeProvider(), ValidityTokenOwner { + // KtFirScopeProvider is thread local, so it's okay to use the same session here + private val scopeSession = analysisSession.getScopeSessionFor(analysisSession.rootModuleSession) + + override val analysisSession: KtFirAnalysisSession by weakRef(analysisSession) private val builder by weakRef(builder) private val firResolveState by weakRef(firResolveState) @@ -89,7 +92,7 @@ internal class KtFirScopeProvider( val firSession = analysisSession.rootModuleSession fir.unsubstitutedScope( firSession, - ScopeSession(), + scopeSession, withForcedTypeCalculator = false ) } ?: return@getOrPut getEmptyScope() @@ -100,7 +103,12 @@ internal class KtFirScopeProvider( override fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope { val firScope = symbol.withFirForScope { fir -> - fir.scopeProvider.getStaticScope(fir, analysisSession.rootModuleSession, ScopeSession()) + val firSession = analysisSession.rootModuleSession + fir.scopeProvider.getStaticScope( + fir, + firSession, + scopeSession, + ) } ?: return getEmptyScope() return KtFirDelegatingScope(firScope, builder, token) } @@ -122,9 +130,10 @@ internal class KtFirScopeProvider( val firScope = classSymbol.withFirForScope { fir -> val delegateFields = fir.delegateFields if (delegateFields.isNotEmpty()) { + val firSession = analysisSession.rootModuleSession FirDelegatedMemberScope( - analysisSession.rootModuleSession, - ScopeSession(), + firSession, + scopeSession, fir, declaredScope, delegateFields @@ -170,7 +179,7 @@ internal class KtFirScopeProvider( val firSession = firResolveState.rootModuleSession val firTypeScope = type.coneType.scope( firSession, - ScopeSession(), + scopeSession, FakeOverrideTypeCalculator.Forced ) ?: return null return getCompositeScope( diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt index 1832a00cc75..48e557bc020 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt @@ -117,9 +117,10 @@ internal class KtFirSymbolDeclarationOverridesProvider( val firContainer = containingDeclaration.firSymbol.fir val firCallableDeclaration = callableSymbol.firSymbol.fir + val firSession = firContainer.moduleData.session val firTypeScope = firContainer.unsubstitutedScope( - firContainer.moduleData.session, - ScopeSession(), + firSession, + analysisSession.getScopeSessionFor(firSession), withForcedTypeCalculator = false ) firTypeScope.processCallableByName(firCallableDeclaration) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeInfoProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeInfoProvider.kt index 0dcb7e96849..1d345979e34 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeInfoProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeInfoProvider.kt @@ -25,7 +25,11 @@ internal class KtFirTypeInfoProvider( override fun isFunctionalInterfaceType(type: KtType): Boolean { val coneType = (type as KtFirType).coneType - val samResolver = FirSamResolverImpl(analysisSession.rootModuleSession, ScopeSession()) + val firSession = analysisSession.rootModuleSession + val samResolver = FirSamResolverImpl( + firSession, + analysisSession.getScopeSessionFor(firSession), + ) return samResolver.getFunctionTypeForPossibleSamType(coneType) != null } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirOverrideInfoProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirOverrideInfoProvider.kt index 062fab4110f..49a42626bb6 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirOverrideInfoProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirOverrideInfoProvider.kt @@ -54,7 +54,10 @@ internal class KtFirOverrideInfoProvider( val parentClassFir = parentClassSymbol.firSymbol.fir as? FirClass ?: return null return memberFir.symbol.getImplementationStatus( - SessionHolderImpl(rootModuleSession, ScopeSession()), + SessionHolderImpl( + rootModuleSession, + analysisSession.getScopeSessionFor(analysisSession.rootModuleSession), + ), parentClassFir.symbol ) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirMemberSymbolPointer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirMemberSymbolPointer.kt index e00773308d8..7299622a3b6 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirMemberSymbolPointer.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirMemberSymbolPointer.kt @@ -24,9 +24,10 @@ internal abstract class KtFirMemberSymbolPointer( require(analysisSession is KtFirAnalysisSession) val owner = analysisSession.getClassLikeSymbol(ownerClassId) as? FirRegularClass ?: return null + val firSession = analysisSession.rootModuleSession val scope = owner.unsubstitutedScope( - analysisSession.firResolveState.rootModuleSession, - ScopeSession(), + firSession, + analysisSession.getScopeSessionFor(firSession), withForcedTypeCalculator = false ) return analysisSession.chooseCandidateAndCreateSymbol(scope, owner.moduleData.session) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirModuleResolveStateDepended.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirModuleResolveStateDepended.kt index 0d82db6a547..e4c079e8a51 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirModuleResolveStateDepended.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirModuleResolveStateDepended.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectRootModificationTracker +import com.intellij.psi.util.PsiModificationTracker import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirModuleResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirElementBuilder @@ -14,19 +16,23 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCa import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.KtToFirMapping import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableModuleResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.state.TowerProviderForElementForState +import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirScopeSessionProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.util.containingKtFileIfAny import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalKtFile import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.utils.caches.* import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirDeclaration 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.symbols.FirBasedSymbol import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile +import java.util.concurrent.ConcurrentHashMap internal class FirModuleResolveStateDepended( val originalState: LLFirResolvableModuleResolveState, @@ -37,6 +43,20 @@ internal class FirModuleResolveStateDepended( override val module: KtModule get() = originalState.module override val rootModuleSession get() = originalState.rootModuleSession + private val scopeSessionProviderCache by softCachedValue( + project, + PsiModificationTracker.MODIFICATION_COUNT, + ProjectRootModificationTracker.getInstance(project), + ) { + ConcurrentHashMap() + } + + override fun getScopeSessionFor(firSession: FirSession): ScopeSession { + return scopeSessionProviderCache + .getOrPut(firSession) { LLFirScopeSessionProvider.create(project, invalidationTrackers = emptyList()) } + .getScopeSession() + } + override fun getSessionFor(module: KtModule): FirSession = originalState.getSessionFor(module) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirGlobalResolveComponents.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirGlobalResolveComponents.kt new file mode 100644 index 00000000000..09bcd33a9fc --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirGlobalResolveComponents.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2022 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.analysis.low.level.api.fir + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LockProvider +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.fir.declarations.FirFile + +@Suppress("unused") +internal class LLFirGlobalResolveComponents( + val useSiteKtModule: KtModule, + val project: Project, +) { + val phaseRunner: LLFirPhaseRunner = LLFirPhaseRunner() + val lockProvider: LockProvider = LockProvider() +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirModuleResolveComponents.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirModuleResolveComponents.kt new file mode 100644 index 00000000000..f895d1e5cd2 --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirModuleResolveComponents.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2022 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.analysis.low.level.api.fir + +import com.intellij.openapi.roots.ProjectRootModificationTracker +import com.intellij.psi.util.PsiModificationTracker +import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.DiagnosticsCollector +import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirElementBuilder +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCacheImpl +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FileStructureCache +import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession +import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirScopeSessionProvider +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.fir.scopes.FirScopeProvider + +@Suppress("CanBeParameter") +internal class LLFirModuleResolveComponents( + val module: KtModule, + val globalResolveComponents: LLFirGlobalResolveComponents, + val scopeProvider: FirScopeProvider, +) { + val cache: ModuleFileCache = ModuleFileCacheImpl(this) + val firFileBuilder: FirFileBuilder = FirFileBuilder(this) + val lazyFirDeclarationsResolver = FirLazyDeclarationResolver(this) + + val scopeSessionProvider: LLFirScopeSessionProvider = LLFirScopeSessionProvider.create( + globalResolveComponents.project, + invalidationTrackers = listOf( + PsiModificationTracker.MODIFICATION_COUNT, + ProjectRootModificationTracker.getInstance(globalResolveComponents.project), + ) + ) + + val fileStructureCache: FileStructureCache = FileStructureCache(this) + val elementsBuilder = FirElementBuilder(this) + val diagnosticsCollector = DiagnosticsCollector(fileStructureCache) + + lateinit var session: LLFirResolvableModuleSession +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirPhaseManager.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirPhaseManager.kt index 2d4348c14dd..e2093069b7f 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirPhaseManager.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirPhaseManager.kt @@ -7,34 +7,27 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir import org.jetbrains.kotlin.fir.ThreadSafeMutableState import org.jetbrains.kotlin.fir.declarations.FirResolvePhase -import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.symbols.FirPhaseManager import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionInvalidator @ThreadSafeMutableState -internal class LLFirPhaseManager( - private val lazyDeclarationResolver: FirLazyDeclarationResolver, - private val cache: ModuleFileCache, - private val sessionInvalidator: LLFirSessionInvalidator, -) : FirPhaseManager() { - override fun ensureResolved( - symbol: FirBasedSymbol<*>, - requiredPhase: FirResolvePhase - ) { +internal class LLFirPhaseManager(private val sessionInvalidator: LLFirSessionInvalidator) : FirPhaseManager() { + override fun ensureResolved(symbol: FirBasedSymbol<*>, requiredPhase: FirResolvePhase) { val fir = symbol.fir + val session = fir.moduleData.session + if (session !is LLFirResolvableModuleSession) return + val moduleComponents = session.moduleComponents try { - lazyDeclarationResolver.lazyResolveDeclaration( + moduleComponents.lazyFirDeclarationsResolver.lazyResolveDeclaration( firDeclarationToResolve = fir, - moduleFileCache = cache, - scopeSession = ScopeSession(), + scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(), toPhase = requiredPhase, checkPCE = true, ) } catch (e: Throwable) { - sessionInvalidator.invalidate(fir.moduleData.session) + sessionInvalidator.invalidate(session) throw e } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveStateService.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveStateService.kt index 7f7126921e8..41ff0287a91 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveStateService.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveStateService.kt @@ -11,10 +11,9 @@ import com.intellij.openapi.roots.ProjectRootModificationTracker import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirModuleResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver -import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession -import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionProviderStorage -import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSourcesSession +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.* import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibraryOrLibrarySourceResolvableModuleSession +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionProviderStorage import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceModuleResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirLibraryOrLibrarySourceResolvableModuleResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableModuleResolveState @@ -49,25 +48,22 @@ internal class LLFirResolveStateService(project: Project) { configureSession: (LLFirSession.() -> Unit)? = null, ): LLFirResolvableModuleResolveState { val sessionProvider = sessionProviderStorage.getSessionProvider(module, configureSession) + val useSiteSession = sessionProvider.rootModuleSession return when (module) { is KtSourceModule -> { - val firFileBuilder = (sessionProvider.rootModuleSession as LLFirSourcesSession).firFileBuilder LLFirSourceModuleResolveState( + useSiteSession.moduleComponents.globalResolveComponents, sessionProviderStorage.project, module, sessionProvider, - firFileBuilder, - FirLazyDeclarationResolver(firFileBuilder), ) } is KtLibraryModule, is KtLibrarySourceModule -> { - val firFileBuilder = (sessionProvider.rootModuleSession as LLFirLibraryOrLibrarySourceResolvableModuleSession).firFileBuilder LLFirLibraryOrLibrarySourceResolvableModuleResolveState( + useSiteSession.moduleComponents.globalResolveComponents, sessionProviderStorage.project, module, sessionProvider, - firFileBuilder, - FirLazyDeclarationResolver(firFileBuilder), ) } else -> { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirModuleResolveState.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirModuleResolveState.kt index cc4ea6732a5..c00df7954e1 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirModuleResolveState.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirModuleResolveState.kt @@ -6,8 +6,10 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.api import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule @@ -18,6 +20,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirDeclaration 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.symbols.FirBasedSymbol import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtElement @@ -33,6 +36,9 @@ abstract class LLFirModuleResolveState { internal abstract fun getSessionFor(module: KtModule): FirSession + abstract fun getScopeSessionFor(firSession: FirSession): ScopeSession + + /** * Build fully resolved FIR node for requested element. * This operation could be performance affective because it create FIleStructureElement and resolve non-local declaration into BODY phase, use diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt index 19fcf2e6ea7..bef9b043ef4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FirElement import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.KtToFirMapping import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.* import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableModuleResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getElementTextInContext import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration @@ -121,20 +122,18 @@ object LowLevelFirApiFacadeForResolveOnAir { ): FirTowerDataContext { require(file.isPhysical) val session = state.getSessionFor(file.getKtModule(state.project)) as LLFirResolvableModuleSession + val moduleComponents = session.moduleComponents - val firFile = session.firFileBuilder.buildRawFirFileWithCaching( - ktFile = file, - cache = session.cache, - ) + val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(file) - state.firLazyDeclarationResolver.lazyResolveFileDeclaration( + val scopeSession = state.getScopeSessionFor(session) + moduleComponents.lazyFirDeclarationsResolver.lazyResolveFileDeclaration( firFile = firFile, - moduleFileCache = session.cache, - scopeSession = ScopeSession(), + scopeSession = scopeSession, toPhase = FirResolvePhase.IMPORTS ) - val importingScopes = createImportingScopes(firFile, firFile.moduleData.session, ScopeSession(), useCaching = false) + val importingScopes = createImportingScopes(firFile, firFile.moduleData.session, scopeSession, useCaching = false) val fileScopeElements = importingScopes.map { it.asTowerDataElement(isLocal = false) } return FirTowerDataContext().addNonLocalTowerDataElements(fileScopeElements) } @@ -178,7 +177,6 @@ object LowLevelFirApiFacadeForResolveOnAir { private fun tryResolveAsFileAnnotation( annotationEntry: KtAnnotationEntry, - state: LLFirResolvableModuleResolveState, replacement: RawFirReplacement, firFile: FirFile, collector: FirTowerDataContextCollector? = null, @@ -189,10 +187,12 @@ object LowLevelFirApiFacadeForResolveOnAir { fileAnnotation = annotationEntry, replacement = replacement ) - state.firLazyDeclarationResolver.resolveFileAnnotations( + val llFirResolvableSession = firFile.llFirResolvableSession ?: error("FirFile session expected to be a resolvable session") + val declarationResolver = llFirResolvableSession.moduleComponents.lazyFirDeclarationsResolver + + declarationResolver.resolveFileAnnotations( firFile = firFile, annotations = listOf(annotationCall), - moduleFileCache = state.cache, scopeSession = ScopeSession(), checkPCE = true, collector = collector @@ -207,7 +207,6 @@ object LowLevelFirApiFacadeForResolveOnAir { onAirCreatedDeclaration: Boolean, collector: FirTowerDataContextCollector? = null, ): FirElement { - val nonLocalDeclaration = findEnclosingNonLocalDeclaration(replacement.from) val originalFirFile = state.getOrBuildFirFile(replacement.from.containingKtFile) @@ -217,7 +216,6 @@ object LowLevelFirApiFacadeForResolveOnAir { if (annotationCall != null) { return tryResolveAsFileAnnotation( annotationEntry = annotationCall, - state = state, replacement = replacement, firFile = originalFirFile, collector = collector, @@ -241,7 +239,7 @@ object LowLevelFirApiFacadeForResolveOnAir { val isInBodyReplacement = isInBodyReplacement(nonLocalDeclaration, replacement) - return state.cache.firFileLockProvider.runCustomResolveUnderLock(originalFirFile, true) { + return state.globalComponents.lockProvider.runCustomResolveUnderLock(originalFirFile, true) { val copiedFirDeclaration = if (isInBodyReplacement) { when (originalDeclaration) { is FirSimpleFunction -> @@ -261,13 +259,15 @@ object LowLevelFirApiFacadeForResolveOnAir { firFile = originalFirFile ) ResolveTreeBuilder.resolveEnsure(onAirDesignation.declaration, FirResolvePhase.BODY_RESOLVE) { - state.firLazyDeclarationResolver.runLazyDesignatedOnAirResolveToBodyWithoutLock( - designation = onAirDesignation, - moduleFileCache = state.cache, - checkPCE = true, - onAirCreatedDeclaration = onAirCreatedDeclaration, - towerDataContextCollector = collector, - ) + val resolvableSession = onAirDesignation.declaration.llFirResolvableSession + ?: error("Expected resolvable session") + resolvableSession.moduleComponents.lazyFirDeclarationsResolver + .runLazyDesignatedOnAirResolveToBodyWithoutLock( + designation = onAirDesignation, + checkPCE = true, + onAirCreatedDeclaration = onAirCreatedDeclaration, + towerDataContextCollector = collector, + ) } copiedFirDeclaration } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/DiagnosticsCollector.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/DiagnosticsCollector.kt index b02d6182ab3..0454487c65c 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/DiagnosticsCollector.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/DiagnosticsCollector.kt @@ -12,19 +12,16 @@ import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile -internal class DiagnosticsCollector( - private val fileStructureCache: FileStructureCache, - private val cache: ModuleFileCache, -) { +internal class DiagnosticsCollector(private val fileStructureCache: FileStructureCache) { fun getDiagnosticsFor(element: KtElement, filter: DiagnosticCheckerFilter): List { - val fileStructure = fileStructureCache.getFileStructure(element.containingKtFile, cache) + val fileStructure = fileStructureCache.getFileStructure(element.containingKtFile) val structureElement = fileStructure.getStructureElementFor(element) val diagnostics = structureElement.diagnostics return diagnostics.diagnosticsFor(filter, element) } fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection { - val fileStructure = fileStructureCache.getFileStructure(ktFile, cache) + val fileStructure = fileStructureCache.getFileStructure(ktFile) return fileStructure.getAllDiagnosticsForFile(filter) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt index 98feb108a1e..fc2adf8ef0e 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt @@ -6,9 +6,9 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics import org.jetbrains.kotlin.KtFakeSourceElementKind +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistenceContextCollector import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistentCheckerContextFactory -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LockProvider import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent @@ -19,7 +19,7 @@ internal abstract class FileStructureElementDiagnosticRetriever { abstract fun retrieve( firFile: FirFile, collector: FileStructureElementDiagnosticsCollector, - lockProvider: LockProvider + moduleComponents: LLFirModuleResolveComponents, ): FileStructureElementDiagnosticList } @@ -29,10 +29,10 @@ internal class SingleNonLocalDeclarationDiagnosticRetriever( override fun retrieve( firFile: FirFile, collector: FileStructureElementDiagnosticsCollector, - lockProvider: LockProvider + moduleComponents: LLFirModuleResolveComponents, ): FileStructureElementDiagnosticList { - val sessionHolder = SessionHolderImpl.createWithEmptyScopeSession(firFile.moduleData.session) - val context = lockProvider.withWriteLock(firFile) { + val sessionHolder = SessionHolderImpl(moduleComponents.session, moduleComponents.scopeSessionProvider.getScopeSession()) + val context = moduleComponents.globalResolveComponents.lockProvider.withWriteLock(firFile) { PersistenceContextCollector.collectContext(sessionHolder, firFile, structureElementDeclaration) } return collector.collectForStructureElement(structureElementDeclaration) { components -> @@ -95,17 +95,19 @@ internal object FileDiagnosticRetriever : FileStructureElementDiagnosticRetrieve override fun retrieve( firFile: FirFile, collector: FileStructureElementDiagnosticsCollector, - lockProvider: LockProvider + moduleComponents: LLFirModuleResolveComponents, ): FileStructureElementDiagnosticList = collector.collectForStructureElement(firFile) { components -> - Visitor(firFile, components) + Visitor(components, moduleComponents) } private class Visitor( - firFile: FirFile, - components: List + components: List, + moduleComponents: LLFirModuleResolveComponents, ) : LLFirDiagnosticVisitor( - PersistentCheckerContextFactory.createEmptyPersistenceCheckerContext(SessionHolderImpl.createWithEmptyScopeSession(firFile.moduleData.session)), + PersistentCheckerContextFactory.createEmptyPersistenceCheckerContext( + SessionHolderImpl(moduleComponents.session, moduleComponents.scopeSessionProvider.getScopeSession()) + ), components, ) { override fun visitFile(file: FirFile, data: Nothing?) { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnostics.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnostics.kt index b343392761f..480cae79d9b 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnostics.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnostics.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics import com.intellij.psi.PsiElement import com.intellij.util.SmartList +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LockProvider import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic @@ -14,15 +15,15 @@ import org.jetbrains.kotlin.fir.declarations.FirFile internal class FileStructureElementDiagnostics( private val firFile: FirFile, - private val lockProvider: LockProvider, - private val retriever: FileStructureElementDiagnosticRetriever + private val retriever: FileStructureElementDiagnosticRetriever, + private val moduleComponents: LLFirModuleResolveComponents, ) { private val diagnosticByCommonCheckers: FileStructureElementDiagnosticList by lazy { - retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.USUAL_COLLECTOR, lockProvider) + retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.USUAL_COLLECTOR, moduleComponents) } private val diagnosticByExtendedCheckers: FileStructureElementDiagnosticList by lazy { - retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.EXTENDED_COLLECTOR, lockProvider) + retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.EXTENDED_COLLECTOR, moduleComponents) } fun diagnosticsFor(filter: DiagnosticCheckerFilter, element: PsiElement): List = diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/PersistentCheckerContextFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/PersistentCheckerContextFactory.kt index 41bb5cfe2da..c428372f5a7 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/PersistentCheckerContextFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/PersistentCheckerContextFactory.kt @@ -16,7 +16,7 @@ internal object PersistentCheckerContextFactory { fun createEmptyPersistenceCheckerContext(sessionHolder: SessionHolder): PersistentCheckerContext { val returnTypeCalculator = createReturnTypeCalculatorForIDE( sessionHolder.session, - ScopeSession(), + sessionHolder.scopeSession, ImplicitBodyResolveComputationSession(), ::LLFirDesignatedImpliciteTypesBodyResolveTransformerForReturnTypeCalculator ) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt index 80b157ab5e2..36e4976bd13 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt @@ -8,16 +8,12 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder import com.intellij.psi.PsiElement import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.ThreadSafe +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.fir.FirElement 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.analysis.low.level.api.fir.api.LLFirModuleResolveState -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FileStructureCache import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FileStructureElement -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.declarationCanBeLazilyResolved import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getElementTextInContext import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isNonAnonymousClassOrObject @@ -26,12 +22,11 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi2ir.deparenthesize -/** - * Maps [KtElement] to [FirElement] - * Stateless, caches everything into [ModuleFileCache] & [FileStructureCache] passed into the function - */ + @ThreadSafe -internal class FirElementBuilder { +internal class FirElementBuilder( + private val moduleComponents: LLFirModuleResolveComponents, +) { companion object { fun getPsiAsFirElementSource(element: KtElement): KtElement? { val deparenthesized = if (element is KtPropertyDelegate) element.deparenthesize() else element @@ -65,28 +60,18 @@ internal class FirElementBuilder { fun getOrBuildFirFor( element: KtElement, - firFileBuilder: FirFileBuilder, - moduleFileCache: ModuleFileCache, - fileStructureCache: FileStructureCache, - firLazyDeclarationResolver: FirLazyDeclarationResolver, state: LLFirModuleResolveState, ): FirElement? = when (element) { - is KtFile -> getOrBuildFirForKtFile(element, firFileBuilder, moduleFileCache, firLazyDeclarationResolver) - else -> getOrBuildFirForNonKtFileElement(element, fileStructureCache, moduleFileCache, state) + is KtFile -> getOrBuildFirForKtFile(element) + else -> getOrBuildFirForNonKtFileElement(element, state) } - private fun getOrBuildFirForKtFile( - ktFile: KtFile, - firFileBuilder: FirFileBuilder, - moduleFileCache: ModuleFileCache, - firLazyDeclarationResolver: FirLazyDeclarationResolver - ): FirFile { - val firFile = firFileBuilder.buildRawFirFileWithCaching(ktFile, moduleFileCache) - firLazyDeclarationResolver.lazyResolveFileDeclaration( + private fun getOrBuildFirForKtFile(ktFile: KtFile): FirFile { + val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile) + moduleComponents.lazyFirDeclarationsResolver.lazyResolveFileDeclaration( firFile = firFile, - moduleFileCache = moduleFileCache, toPhase = FirResolvePhase.BODY_RESOLVE, - scopeSession = ScopeSession(), + scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(), checkPCE = true ) return firFile @@ -94,8 +79,6 @@ internal class FirElementBuilder { private fun getOrBuildFirForNonKtFileElement( element: KtElement, - fileStructureCache: FileStructureCache, - moduleFileCache: ModuleFileCache, state: LLFirModuleResolveState, ): FirElement? { require(element !is KtFile) @@ -105,7 +88,7 @@ internal class FirElementBuilder { } val firFile = element.containingKtFile - val fileStructure = fileStructureCache.getFileStructure(firFile, moduleFileCache) + val fileStructure = moduleComponents.fileStructureCache.getFileStructure(firFile) val mappings = fileStructure.getStructureElementFor(element).mappings val psi = getPsiAsFirElementSource(element) ?: return null @@ -114,12 +97,8 @@ internal class FirElementBuilder { } @TestOnly - fun getStructureElementFor( - element: KtElement, - moduleFileCache: ModuleFileCache, - fileStructureCache: FileStructureCache, - ): FileStructureElement { - val fileStructure = fileStructureCache.getFileStructure(element.containingKtFile, moduleFileCache) + fun getStructureElementFor(element: KtElement): FileStructureElement { + val fileStructure = moduleComponents.fileStructureCache.getFileStructure(element.containingKtFile) return fileStructure.getStructureElementFor(element) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/FirFileBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/FirFileBuilder.kt index 40dd23025da..0232d5a1119 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/FirFileBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/FirFileBuilder.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.ThreadSafe +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.builder.BodyBuildingMode import org.jetbrains.kotlin.fir.builder.PsiHandlingMode @@ -16,24 +17,15 @@ import org.jetbrains.kotlin.psi.KtFile /** * Responsible for building [FirFile] by [KtFile] - * Stateless, all caches are stored in [ModuleFileCache] passed into corresponding functions */ @ThreadSafe internal class FirFileBuilder( - private val scopeProvider: FirScopeProvider, - val firPhaseRunner: LLFirPhaseRunner + val moduleComponents: LLFirModuleResolveComponents, ) { - /** - * Builds a [FirFile] by given [ktFile] and records it's parenting info if it not present in [cache] - * [FirFile] building a happens at most once per each [KtFile] - */ - fun buildRawFirFileWithCaching( - ktFile: KtFile, - cache: ModuleFileCache, - ): FirFile = cache.fileCached(ktFile) { + fun buildRawFirFileWithCaching(ktFile: KtFile): FirFile = moduleComponents.cache.fileCached(ktFile) { RawFirBuilder( - cache.session, - scopeProvider, + moduleComponents.session, + moduleComponents.scopeProvider, psiMode = PsiHandlingMode.IDE, bodyBuildingMode = BodyBuildingMode.LAZY_BODIES ).buildFirFile(ktFile) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/LLFirLibraryResolveModuleFileCache.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/LLFirLibraryResolveModuleFileCache.kt index eecd5c089ce..e58d0be40ae 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/LLFirLibraryResolveModuleFileCache.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/LLFirLibraryResolveModuleFileCache.kt @@ -5,19 +5,16 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder -import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerDataContextAllElementsCollector import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FirElementsRecorder import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.KtToFirMapping -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibraryOrLibrarySourceResolvableModuleSession import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.psi -import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.scopes.FirScopeProvider import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId @@ -25,13 +22,7 @@ import org.jetbrains.kotlin.psi.KtFile import java.util.* import java.util.concurrent.ConcurrentHashMap -internal class LLFirLibraryResolveModuleFileCache( - val kotlinScopeProvider: FirScopeProvider, - override val session: LLFirLibraryOrLibrarySourceResolvableModuleSession -) : ModuleFileCache() { - private val firFileBuilder = FirFileBuilder(kotlinScopeProvider, LLFirPhaseRunner()) - - private val firLazyDeclarationResolver = FirLazyDeclarationResolver(firFileBuilder) +internal class LLFirLibraryResolveModuleFileCache: ModuleFileCache() { private val kfFileToFirCache = ConcurrentHashMap() @@ -58,16 +49,16 @@ internal class LLFirLibraryResolveModuleFileCache( createKtFile: (KtFile) -> FirFile ): ResolvedFile = kfFileToFirCache.computeIfAbsent(ktFile) { val collector = FirTowerDataContextAllElementsCollector() - val scopeSession = ScopeSession() + + val scopeSession = moduleComponents.scopeSessionProvider.getScopeSession() val firFile = createKtFile(ktFile) - firLazyDeclarationResolver.lazyResolveFileDeclaration( + moduleComponents.lazyFirDeclarationsResolver.lazyResolveFileDeclaration( firFile, - this, FirResolvePhase.BODY_RESOLVE, scopeSession, - collector = collector, + collector, checkPCE = true ) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/ModuleFileCache.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/ModuleFileCache.kt index 955c545b22a..6ebe312105c 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/ModuleFileCache.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/ModuleFileCache.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder import com.intellij.concurrency.ConcurrentCollectionFactory import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.ThreadSafe -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile @@ -24,7 +24,7 @@ import java.util.concurrent.ConcurrentHashMap */ @ThreadSafe internal abstract class ModuleFileCache { - abstract val session: FirSession + abstract val moduleComponents: LLFirModuleResolveComponents /** * Maps [ClassId] to corresponding classifiers @@ -47,11 +47,9 @@ internal abstract class ModuleFileCache { abstract fun getContainerFirFile(declaration: FirDeclaration): FirFile? abstract fun getCachedFirFile(ktFile: KtFile): FirFile? - - abstract val firFileLockProvider: LockProvider } -internal class ModuleFileCacheImpl(override val session: FirSession) : ModuleFileCache() { +internal class ModuleFileCacheImpl(override val moduleComponents: LLFirModuleResolveComponents) : ModuleFileCache() { private val ktFileToFirFile = ConcurrentCollectionFactory.createConcurrentIdentityMap() override val classifierByClassId: ConcurrentHashMap> = ConcurrentHashMap() @@ -66,6 +64,4 @@ internal class ModuleFileCacheImpl(override val session: FirSession) : ModuleFil val ktFile = declaration.psi?.containingFile as? KtFile ?: return null return getCachedFirFile(ktFile) } - - override val firFileLockProvider: LockProvider = LockProvider() } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileElementFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileElementFactory.kt index 30b4ad97e81..29c895983f4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileElementFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileElementFactory.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LockProvider import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtProperty @@ -22,14 +22,14 @@ internal object FileElementFactory { firDeclaration: FirDeclaration, ktDeclaration: KtDeclaration, firFile: FirFile, - firFileLockProvider: LockProvider, + moduleComponents: LLFirModuleResolveComponents, ): FileStructureElement = when { ktDeclaration is KtNamedFunction && ktDeclaration.isReanalyzableContainer() -> ReanalyzableFunctionStructureElement( firFile, ktDeclaration, (firDeclaration as FirSimpleFunction).symbol, ktDeclaration.modificationStamp, - firFileLockProvider, + moduleComponents, ) ktDeclaration is KtProperty && ktDeclaration.isReanalyzableContainer() -> ReanalyzablePropertyStructureElement( @@ -37,14 +37,14 @@ internal object FileElementFactory { ktDeclaration, (firDeclaration as FirProperty).symbol, ktDeclaration.modificationStamp, - firFileLockProvider, + moduleComponents, ) else -> NonReanalyzableDeclarationStructureElement( firFile, firDeclaration, ktDeclaration, - firFileLockProvider, + moduleComponents, ) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt index 3da44244750..15c18045536 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt @@ -6,18 +6,14 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver -import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getElementTextInContext import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic 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.providers.firProvider import org.jetbrains.kotlin.psi.* import java.util.concurrent.ConcurrentHashMap @@ -25,19 +21,15 @@ import java.util.concurrent.ConcurrentHashMap internal class FileStructure private constructor( private val ktFile: KtFile, private val firFile: FirFile, - private val firLazyDeclarationResolver: FirLazyDeclarationResolver, - private val firFileBuilder: FirFileBuilder, - private val moduleFileCache: ModuleFileCache, + private val moduleComponents: LLFirModuleResolveComponents, ) { companion object { fun build( ktFile: KtFile, - firLazyDeclarationResolver: FirLazyDeclarationResolver, - firFileBuilder: FirFileBuilder, - moduleFileCache: ModuleFileCache, + moduleComponents: LLFirModuleResolveComponents, ): FileStructure { - val firFile = firFileBuilder.buildRawFirFileWithCaching(ktFile, moduleFileCache) - return FileStructure(ktFile, firFile, firLazyDeclarationResolver, firFileBuilder, moduleFileCache) + val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile) + return FileStructure(ktFile, firFile, moduleComponents) } } @@ -56,11 +48,7 @@ internal class FileStructure private constructor( when { structureElement == null -> createStructureElement(declaration) structureElement is ReanalyzableStructureElement && !structureElement.isUpToDate() -> { - structureElement.reanalyze( - newKtDeclaration = declaration as KtDeclaration, - cache = moduleFileCache, - firLazyDeclarationResolver = firLazyDeclarationResolver, - ) + structureElement.reanalyze(newKtDeclaration = declaration as KtDeclaration,) } else -> structureElement } @@ -111,15 +99,13 @@ internal class FileStructure private constructor( private fun createDeclarationStructure(declaration: KtDeclaration): FileStructureElement { val firDeclaration = declaration.findSourceNonLocalFirDeclaration( - firFileBuilder, - firProvider.symbolProvider, - moduleFileCache, + moduleComponents.firFileBuilder, + firProvider, firFile ) - firLazyDeclarationResolver.lazyResolveDeclaration( + moduleComponents.lazyFirDeclarationsResolver.lazyResolveDeclaration( firDeclarationToResolve = firDeclaration, - moduleFileCache = moduleFileCache, - scopeSession = ScopeSession(), + scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(), toPhase = FirResolvePhase.BODY_RESOLVE, checkPCE = true, ) @@ -127,25 +113,20 @@ internal class FileStructure private constructor( firDeclaration = firDeclaration, ktDeclaration = declaration, firFile = firFile, - firFileLockProvider = moduleFileCache.firFileLockProvider + moduleComponents = moduleComponents ) } private fun createStructureElement(container: KtAnnotated): FileStructureElement = when (container) { is KtFile -> { - val firFile = firFileBuilder.buildRawFirFileWithCaching(ktFile, moduleFileCache) - firLazyDeclarationResolver.resolveFileAnnotations( + val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile) + moduleComponents.lazyFirDeclarationsResolver.resolveFileAnnotations( firFile = firFile, annotations = firFile.annotations, - moduleFileCache = moduleFileCache, - scopeSession = ScopeSession(), + scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(), checkPCE = true ) - RootStructureElement( - firFile, - container, - moduleFileCache.firFileLockProvider, - ) + RootStructureElement(firFile, container, moduleComponents) } is KtDeclaration -> createDeclarationStructure(container) else -> error("Invalid container $container") diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureCache.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureCache.kt index 01c80ddfaaa..da5d4ff5426 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureCache.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureCache.kt @@ -5,22 +5,17 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.psi.KtFile import java.util.concurrent.ConcurrentHashMap /** * Belongs to a [org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirModuleResolveState] */ -internal class FileStructureCache( - private val fileBuilder: FirFileBuilder, - private val firLazyDeclarationResolver: FirLazyDeclarationResolver, -) { +internal class FileStructureCache(private val moduleResolveComponents: LLFirModuleResolveComponents) { private val cache = ConcurrentHashMap() - fun getFileStructure(ktFile: KtFile, moduleFileCache: ModuleFileCache): FileStructure = cache.computeIfAbsent(ktFile) { - FileStructure.build(ktFile, firLazyDeclarationResolver, fileBuilder, moduleFileCache) + fun getFileStructure(ktFile: KtFile): FileStructure = cache.computeIfAbsent(ktFile) { + FileStructure.build(ktFile, moduleResolveComponents) } } \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt index 2a174702c36..754cc48ad15 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt @@ -6,21 +6,18 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirModuleResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileDiagnosticRetriever import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileStructureElementDiagnostics import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.SingleNonLocalDeclarationDiagnosticRetriever -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LockProvider -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.RawFirNonLocalDeclarationBuilder import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.declarationCanBeLazilyResolved import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.psi -import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol @@ -28,7 +25,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.psi.* import java.util.concurrent.ConcurrentHashMap -internal sealed class FileStructureElement(val firFile: FirFile, protected val lockProvider: LockProvider) { +internal sealed class FileStructureElement(val firFile: FirFile, protected val moduleComponents: LLFirModuleResolveComponents) { abstract val psi: KtAnnotated abstract val mappings: KtToFirMapping abstract val diagnostics: FileStructureElementDiagnostics @@ -71,8 +68,8 @@ internal class KtToFirMapping(firElement: FirElement, recorder: FirElementsRecor internal sealed class ReanalyzableStructureElement>( firFile: FirFile, val firSymbol: S, - lockProvider: LockProvider, -) : FileStructureElement(firFile, lockProvider) { + moduleComponents: LLFirModuleResolveComponents, +) : FileStructureElement(firFile, moduleComponents) { abstract override val psi: KtDeclaration abstract val timestamp: Long @@ -82,16 +79,14 @@ internal sealed class ReanalyzableStructureElement fun isUpToDate(): Boolean = psi.getModificationStamp() == timestamp override val diagnostics = FileStructureElementDiagnostics( firFile, - lockProvider, - SingleNonLocalDeclarationDiagnosticRetriever(firSymbol.fir) + SingleNonLocalDeclarationDiagnosticRetriever(firSymbol.fir), + moduleComponents, ) companion object { @@ -104,15 +99,11 @@ internal class ReanalyzableFunctionStructureElement( override val psi: KtNamedFunction, firSymbol: FirFunctionSymbol<*>, override val timestamp: Long, - lockProvider: LockProvider, -) : ReanalyzableStructureElement>(firFile, firSymbol, lockProvider) { + moduleComponents: LLFirModuleResolveComponents, +) : ReanalyzableStructureElement>(firFile, firSymbol, moduleComponents) { override val mappings = KtToFirMapping(firSymbol.fir, recorder) - override fun reanalyze( - newKtDeclaration: KtNamedFunction, - cache: ModuleFileCache, - firLazyDeclarationResolver: FirLazyDeclarationResolver, - ): ReanalyzableFunctionStructureElement { + override fun reanalyze(newKtDeclaration: KtNamedFunction): ReanalyzableFunctionStructureElement { val originalFunction = firSymbol.fir as FirSimpleFunction val designation = originalFunction.collectDesignation() @@ -123,7 +114,7 @@ internal class ReanalyzableFunctionStructureElement( rootNonLocalDeclaration = newKtDeclaration, ) as FirSimpleFunction - return cache.firFileLockProvider.withWriteLock(firFile) { + return moduleComponents.globalResolveComponents.lockProvider.withWriteLock(firFile) { val upgradedPhase = minOf(originalFunction.resolvePhase, FirResolvePhase.DECLARATIONS) with(originalFunction) { replaceBody(temporaryFunction.body) @@ -134,10 +125,9 @@ internal class ReanalyzableFunctionStructureElement( it.replaceResolvePhase(minOf(it.resolvePhase, upgradedPhase)) } - firLazyDeclarationResolver.lazyResolveDeclaration( + moduleComponents.lazyFirDeclarationsResolver.lazyResolveDeclaration( firDeclarationToResolve = originalFunction, - moduleFileCache = cache, - scopeSession = ScopeSession(), + scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(), toPhase = FirResolvePhase.BODY_RESOLVE, checkPCE = true, ) @@ -147,7 +137,7 @@ internal class ReanalyzableFunctionStructureElement( newKtDeclaration, originalFunction.symbol, newKtDeclaration.modificationStamp, - lockProvider, + moduleComponents, ) } } @@ -158,15 +148,11 @@ internal class ReanalyzablePropertyStructureElement( override val psi: KtProperty, firSymbol: FirPropertySymbol, override val timestamp: Long, - lockProvider: LockProvider, -) : ReanalyzableStructureElement(firFile, firSymbol, lockProvider) { + moduleComponents: LLFirModuleResolveComponents, +) : ReanalyzableStructureElement(firFile, firSymbol, moduleComponents) { override val mappings = KtToFirMapping(firSymbol.fir, recorder) - override fun reanalyze( - newKtDeclaration: KtProperty, - cache: ModuleFileCache, - firLazyDeclarationResolver: FirLazyDeclarationResolver, - ): ReanalyzablePropertyStructureElement { + override fun reanalyze(newKtDeclaration: KtProperty): ReanalyzablePropertyStructureElement { val originalProperty = firSymbol.fir val designation = originalProperty.collectDesignation() @@ -177,7 +163,7 @@ internal class ReanalyzablePropertyStructureElement( rootNonLocalDeclaration = newKtDeclaration, ) as FirProperty - return cache.firFileLockProvider.withWriteLock(firFile) { + return moduleComponents.globalResolveComponents.lockProvider.withWriteLock(firFile) { val getterPhase = originalProperty.getter?.resolvePhase ?: originalProperty.resolvePhase val setterPhase = originalProperty.setter?.resolvePhase ?: originalProperty.resolvePhase @@ -193,10 +179,9 @@ internal class ReanalyzablePropertyStructureElement( replaceBodyResolveState(FirPropertyBodyResolveState.NOTHING_RESOLVED) } - firLazyDeclarationResolver.lazyResolveDeclaration( + moduleComponents.lazyFirDeclarationsResolver.lazyResolveDeclaration( firDeclarationToResolve = originalProperty, - moduleFileCache = cache, - scopeSession = ScopeSession(), + scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(), toPhase = FirResolvePhase.BODY_RESOLVE, checkPCE = true, ) @@ -207,7 +192,7 @@ internal class ReanalyzablePropertyStructureElement( newKtDeclaration, originalProperty.symbol, newKtDeclaration.modificationStamp, - lockProvider, + moduleComponents, ) } } @@ -217,11 +202,15 @@ internal class NonReanalyzableDeclarationStructureElement( firFile: FirFile, val fir: FirDeclaration, override val psi: KtDeclaration, - lockProvider: LockProvider, -) : FileStructureElement(firFile, lockProvider) { + moduleComponents: LLFirModuleResolveComponents, +) : FileStructureElement(firFile, moduleComponents) { override val mappings = KtToFirMapping(fir, recorder) - override val diagnostics = FileStructureElementDiagnostics(firFile, lockProvider, SingleNonLocalDeclarationDiagnosticRetriever(fir)) + override val diagnostics = FileStructureElementDiagnostics( + firFile, + SingleNonLocalDeclarationDiagnosticRetriever(fir), + moduleComponents, + ) companion object { @@ -247,11 +236,12 @@ internal class NonReanalyzableDeclarationStructureElement( internal class RootStructureElement( firFile: FirFile, override val psi: KtFile, - lockProvider: LockProvider, -) : FileStructureElement(firFile, lockProvider) { + moduleComponents: LLFirModuleResolveComponents, +) : FileStructureElement(firFile, moduleComponents) { override val mappings = KtToFirMapping(firFile, recorder) - override val diagnostics = FileStructureElementDiagnostics(firFile, lockProvider, FileDiagnosticRetriever) + override val diagnostics = + FileStructureElementDiagnostics(firFile, FileDiagnosticRetriever, moduleComponents) companion object { private val recorder = object : FirElementsRecorder() { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyDeclarationResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyDeclarationResolver.kt index 90aa6da0350..c9d19024b17 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyDeclarationResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyDeclarationResolver.kt @@ -5,12 +5,13 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LockProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.runCustomResolveUnderLock import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirFileAnnotationsResolveTransformer import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirFirProviderInterceptor @@ -30,7 +31,7 @@ import org.jetbrains.kotlin.psi.KtClassBody import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtEnumEntry -internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBuilder) { +internal class FirLazyDeclarationResolver(val moduleComponents: LLFirModuleResolveComponents) { /** * Fully resolve file annotations (synchronized) * @see resolveFileAnnotationsWithoutLock not synchronized @@ -38,13 +39,12 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui fun resolveFileAnnotations( firFile: FirFile, annotations: List, - moduleFileCache: ModuleFileCache, scopeSession: ScopeSession, checkPCE: Boolean, collector: FirTowerDataContextCollector? = null, ) { if (firFile.resolvePhase >= FirResolvePhase.IMPORTS && annotations.all { it.resolved }) return - moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(firFile, checkPCE) { + moduleComponents.globalResolveComponents.lockProvider.runCustomResolveUnderLock(firFile, checkPCE) { resolveFileAnnotationsWithoutLock( firFile = firFile, annotations = annotations, @@ -75,7 +75,7 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui session = firFile.moduleData.session, scopeSession = scopeSession, firTowerDataContextCollector = collector, - ).transformDeclaration(firFileBuilder.firPhaseRunner) + ).transformDeclaration(moduleComponents.globalResolveComponents.phaseRunner) } } @@ -110,21 +110,19 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui fun lazyResolveFileDeclaration( firFile: FirFile, - moduleFileCache: ModuleFileCache, toPhase: FirResolvePhase, scopeSession: ScopeSession, collector: FirTowerDataContextCollector? = null, checkPCE: Boolean = false, ) { if (toPhase == FirResolvePhase.RAW_FIR) return - resolveFileToImports(firFile, moduleFileCache, checkPCE) + resolveFileToImports(firFile, checkPCE) if (toPhase == FirResolvePhase.IMPORTS) return if (firFile.resolvePhase >= toPhase) return - moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(firFile, checkPCE) { + moduleComponents.globalResolveComponents.lockProvider.runCustomResolveUnderLock(firFile, checkPCE) { ResolveTreeBuilder.resolveEnsure(firFile, toPhase) { lazyResolveFileDeclarationWithoutLock( firFile = firFile, - moduleFileCache = moduleFileCache, toPhase = toPhase, collector = collector, scopeSession = scopeSession, @@ -134,9 +132,9 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui } } - private fun resolveFileToImports(firFile: FirFile, moduleFileCache: ModuleFileCache, checkPCE: Boolean) { + private fun resolveFileToImports(firFile: FirFile, checkPCE: Boolean) { if (firFile.resolvePhase >= FirResolvePhase.IMPORTS) return - moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(firFile, checkPCE) { + moduleComponents.globalResolveComponents.lockProvider.runCustomResolveUnderLock(firFile, checkPCE) { resolveFileToImportsWithoutLock(firFile, checkPCE) } } @@ -150,7 +148,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui private fun lazyResolveFileDeclarationWithoutLock( firFile: FirFile, - moduleFileCache: ModuleFileCache, toPhase: FirResolvePhase, scopeSession: ScopeSession, checkPCE: Boolean = false, @@ -183,7 +180,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui phase = currentPhase, designation = it, scopeSession = scopeSession, - moduleFileCache = moduleFileCache, lazyDeclarationResolver = this, towerDataContextCollector = collector, firProviderInterceptor = null, @@ -193,9 +189,9 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui } if (transformersToApply.isEmpty()) continue - firFileBuilder.firPhaseRunner.runPhaseWithCustomResolve(currentPhase) { + moduleComponents.globalResolveComponents.phaseRunner.runPhaseWithCustomResolve(currentPhase) { for (currentTransformer in transformersToApply) { - currentTransformer.transformDeclaration(firFileBuilder.firPhaseRunner) + currentTransformer.transformDeclaration(moduleComponents.globalResolveComponents.phaseRunner) } } firFile.replaceResolvePhase(currentPhase) @@ -204,7 +200,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui private fun fastTrackForImportsPhase( firDeclarationToResolve: FirDeclaration, - moduleFileCache: ModuleFileCache, checkPCE: Boolean, ): Boolean { val provider = firDeclarationToResolve.moduleData.session.firProvider @@ -214,7 +209,7 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(firDeclarationToResolve.symbol) else -> null } ?: return false - resolveFileToImports(firFile, moduleFileCache, checkPCE) + resolveFileToImports(firFile, checkPCE) return true } @@ -226,14 +221,13 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui */ fun lazyResolveDeclaration( firDeclarationToResolve: FirDeclaration, - moduleFileCache: ModuleFileCache, scopeSession: ScopeSession, toPhase: FirResolvePhase, checkPCE: Boolean, ) { if (toPhase == FirResolvePhase.RAW_FIR) return if (toPhase == FirResolvePhase.IMPORTS) { - if (fastTrackForImportsPhase(firDeclarationToResolve, moduleFileCache, checkPCE)) { + if (fastTrackForImportsPhase(firDeclarationToResolve, checkPCE)) { return } } @@ -241,7 +235,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui is FirSyntheticPropertyAccessor -> { lazyResolveDeclaration( firDeclarationToResolve.delegate, - moduleFileCache, scopeSession, toPhase, checkPCE, @@ -252,7 +245,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui is FirBackingField -> { lazyResolveDeclaration( firDeclarationToResolve.propertySymbol.fir, - moduleFileCache, scopeSession, toPhase, checkPCE, @@ -262,7 +254,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui is FirFile -> { lazyResolveFileDeclaration( firFile = firDeclarationToResolve, - moduleFileCache = moduleFileCache, toPhase = toPhase, scopeSession = scopeSession, checkPCE = checkPCE, @@ -297,16 +288,14 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui val enumEntry = possiblyLocalDeclaration.getContainingEnumEntryAsMemberOfEnumEntry() ?: return declarationToResolve = enumEntry.findSourceNonLocalFirDeclaration( - firFileBuilder, - firDeclarationToResolve.moduleData.session.firProvider.symbolProvider, - moduleFileCache + moduleComponents.firFileBuilder, + firDeclarationToResolve.moduleData.session.firProvider, ) neededPhase = FirResolvePhase.BODY_RESOLVE } else { declarationToResolve = nonLocalDeclaration.findSourceNonLocalFirDeclaration( - firFileBuilder, - firDeclarationToResolve.moduleData.session.firProvider.symbolProvider, - moduleFileCache + moduleComponents.firFileBuilder, + firDeclarationToResolve.moduleData.session.firProvider, ) neededPhase = toPhase } @@ -320,15 +309,14 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui if (designation.declaration.resolvePhase >= neededPhase) return if (neededPhase == FirResolvePhase.IMPORTS) { - resolveFileToImports(designation.firFile, moduleFileCache, checkPCE) + resolveFileToImports(designation.firFile, checkPCE) return } - moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(designation.firFile, checkPCE) { + moduleComponents.globalResolveComponents.lockProvider.runCustomResolveUnderLock(designation.firFile, checkPCE) { ResolveTreeBuilder.resolveEnsure(designation.declaration, neededPhase) { runLazyDesignatedResolveWithoutLock( designation = designation, - moduleFileCache = moduleFileCache, scopeSession = scopeSession, toPhase = neededPhase, checkPCE = checkPCE, @@ -341,7 +329,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui private fun runLazyDesignatedResolveWithoutLock( designation: FirDeclarationDesignationWithFile, - moduleFileCache: ModuleFileCache, scopeSession: ScopeSession, toPhase: FirResolvePhase, checkPCE: Boolean, @@ -363,18 +350,16 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui phase = currentPhase, designation = designation, scopeSession = scopeSession, - moduleFileCache = moduleFileCache, lazyDeclarationResolver = this, towerDataContextCollector = null, firProviderInterceptor = null, checkPCE = checkPCE, - ).transformDeclaration(firFileBuilder.firPhaseRunner) + ).transformDeclaration(moduleComponents.globalResolveComponents.phaseRunner) } } internal fun runLazyDesignatedOnAirResolveToBodyWithoutLock( designation: FirDeclarationDesignationWithFile, - moduleFileCache: ModuleFileCache, checkPCE: Boolean, onAirCreatedDeclaration: Boolean, towerDataContextCollector: FirTowerDataContextCollector?, @@ -400,12 +385,11 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui phase = currentPhase, designation = designation, scopeSession = scopeSession, - moduleFileCache = moduleFileCache, lazyDeclarationResolver = this, towerDataContextCollector = towerDataContextCollector, firProviderInterceptor = firProviderInterceptor, checkPCE = checkPCE, - ).transformDeclaration(firFileBuilder.firPhaseRunner) + ).transformDeclaration(moduleComponents.globalResolveComponents.phaseRunner) } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt index 469ebba2dea..9b1138e82ad 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt @@ -5,10 +5,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.providers -import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache -import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider import org.jetbrains.kotlin.fir.FirSession @@ -21,7 +19,6 @@ import org.jetbrains.kotlin.fir.originalForSubstitutionOverride import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals -import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -29,20 +26,16 @@ import org.jetbrains.kotlin.name.Name @ThreadSafeMutableState internal class LLFirProvider( - @Suppress("UNUSED_PARAMETER") project: Project, val session: FirSession, - @Suppress("UNUSED_PARAMETER") module: KtModule, - val kotlinScopeProvider: FirKotlinScopeProvider, - firFileBuilder: FirFileBuilder, - val cache: ModuleFileCache, + private val moduleComponents: LLFirModuleResolveComponents, private val declarationProvider: KotlinDeclarationProvider, packageProvider: KotlinPackageProvider, ) : FirProvider() { override val symbolProvider: FirSymbolProvider = SymbolProvider() private val providerHelper = LLFirProviderHelper( - cache, - firFileBuilder, + moduleComponents.cache, + moduleComponents.firFileBuilder, declarationProvider, packageProvider, ) @@ -59,7 +52,7 @@ internal class LLFirProvider( override fun getFirClassifierContainerFileIfAny(fqName: ClassId): FirFile? { val fir = getFirClassifierByFqName(fqName) ?: return null // Necessary to ensure cacheProvider contains this classifier - return cache.getContainerFirFile(fir) + return moduleComponents.cache.getContainerFirFile(fir) } override fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile { @@ -68,7 +61,7 @@ internal class LLFirProvider( } override fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? = - cache.getContainerFirFile(symbol.fir) + moduleComponents.cache.getContainerFirFile(symbol.fir) override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? { @@ -81,7 +74,7 @@ internal class LLFirProvider( return getFirCallableContainerFile(fir.getter.delegate.symbol) } } - return cache.getContainerFirFile(symbol.fir) + return moduleComponents.cache.getContainerFirFile(symbol.fir) } override fun getFirFilesByPackage(fqName: FqName): List = error("Should not be called in FIR IDE") diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt index 1ec428d77d6..5c9324610ce 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt @@ -39,7 +39,7 @@ internal class LLFirProviderHelper( null -> declarationProvider.getTypeAliasesByClassId(classId).firstOrNull() else -> if (klass.getClassId() == null) null else klass } ?: return@computeIfAbsent Optional.empty() - val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile, cache) + val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile) val classifier = FirElementFinder.findElementIn(firFile) { classifier -> classifier.symbol.classId == classId } @@ -61,7 +61,7 @@ internal class LLFirProviderHelper( @OptIn(ExperimentalStdlibApi::class) buildList { files.forEach { ktFile -> - val firFile = firFileBuilder.buildRawFirFileWithCaching(ktFile, cache) + val firFile = firFileBuilder.buildRawFirFileWithCaching(ktFile) firFile.collectCallableDeclarationsTo(this, name) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/SingleCandidateResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/SingleCandidateResolver.kt index 8f119699876..52a946e13cf 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/SingleCandidateResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/SingleCandidateResolver.kt @@ -24,8 +24,6 @@ class SingleCandidateResolver( private val firSession: FirSession, private val firFile: FirFile, ) { - private val scopeSession = ScopeSession() - private val bodyResolveComponents = createStubBodyResolveComponents(firSession) private val firCallCompleter = FirCallCompleter( bodyResolveComponents.transformer, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirBuiltinsAndCloneableSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirBuiltinsAndCloneableSession.kt index 9bddaf39573..aa1cb811bea 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirBuiltinsAndCloneableSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirBuiltinsAndCloneableSession.kt @@ -11,6 +11,6 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor @OptIn(PrivateSessionConstructor::class) class LLFirBuiltinsAndCloneableSession @PrivateSessionConstructor constructor( - override val project: Project, + project: Project, builtinTypes: BuiltinTypes, -) : LLFirSession(builtinTypes, Kind.Library) +) : LLFirLibraryLikeSession(project, builtinTypes) \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibrariesSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibrariesSession.kt index 2276ac681c0..e1eca5d90cf 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibrariesSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibrariesSession.kt @@ -14,6 +14,6 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor */ @OptIn(PrivateSessionConstructor::class) internal class LLFirLibrariesSession @PrivateSessionConstructor constructor( - override val project: Project, + project: Project, builtinTypes: BuiltinTypes, -) : LLFirSession(builtinTypes, Kind.Library) +) : LLFirLibraryLikeSession(project, builtinTypes) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryLikeSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryLikeSession.kt new file mode 100644 index 00000000000..afc5a5137b2 --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryLikeSession.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2022 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.analysis.low.level.api.fir.sessions + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirScopeSessionProvider +import org.jetbrains.kotlin.fir.BuiltinTypes +import org.jetbrains.kotlin.fir.resolve.ScopeSession + +abstract class LLFirLibraryLikeSession( + final override val project: Project, + builtinTypes: BuiltinTypes, +) : LLFirSession(builtinTypes, Kind.Library) { + private val scopeSessionProvider = LLFirScopeSessionProvider.create(project, invalidationTrackers = emptyList()) + + override fun getScopeSession(): ScopeSession { + return scopeSessionProvider.getScopeSession() + } +} + diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryOrLibrarySourceResolvableModuleSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryOrLibrarySourceResolvableModuleSession.kt index fe097d52911..102f3470914 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryOrLibrarySourceResolvableModuleSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryOrLibrarySourceResolvableModuleSession.kt @@ -6,7 +6,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder +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.project.structure.KtLibraryModule import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule import org.jetbrains.kotlin.analysis.project.structure.KtModule @@ -15,7 +16,7 @@ import org.jetbrains.kotlin.fir.BuiltinTypes internal class LLFirLibraryOrLibrarySourceResolvableModuleSession( override val module: KtModule, override val project: Project, - override val firFileBuilder: FirFileBuilder, + override val moduleComponents: LLFirModuleResolveComponents, builtinTypes: BuiltinTypes, ) : LLFirResolvableModuleSession(builtinTypes) { init { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirResolvableModuleSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirResolvableModuleSession.kt index 92066fc4a70..fc706e281a9 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirResolvableModuleSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirResolvableModuleSession.kt @@ -5,15 +5,27 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirProvider import org.jetbrains.kotlin.fir.BuiltinTypes +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.providers.firProvider +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -internal abstract class LLFirResolvableModuleSession( +abstract class LLFirResolvableModuleSession( builtinTypes: BuiltinTypes, ) : LLFirModuleSession(builtinTypes, Kind.Source) { - internal val cache: ModuleFileCache get() = (firProvider as LLFirProvider).cache - abstract val firFileBuilder: FirFileBuilder -} \ No newline at end of file + internal abstract val moduleComponents: LLFirModuleResolveComponents + + final override fun getScopeSession(): ScopeSession { + return moduleComponents.scopeSessionProvider.getScopeSession() + } +} + +internal val FirDeclaration.llFirResolvableSession: LLFirResolvableModuleSession? + get() = llFirSession as? LLFirResolvableModuleSession + +internal val FirBasedSymbol<*>.llFirResolvableSession: LLFirResolvableModuleSession? + get() = fir.llFirResolvableSession \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSession.kt index 4c4278775a8..c89e6d19cfb 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSession.kt @@ -6,17 +6,30 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firModuleData import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.fir.BuiltinTypes +import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.PrivateSessionConstructor +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol @OptIn(PrivateSessionConstructor::class) abstract class LLFirSession(override val builtinTypes: BuiltinTypes, kind: Kind) : FirSession(sessionProvider = null, kind) { abstract val project: Project + + abstract fun getScopeSession(): ScopeSession } @OptIn(PrivateSessionConstructor::class) abstract class LLFirModuleSession(builtinTypes: BuiltinTypes, kind: Kind) : LLFirSession(builtinTypes, kind) { abstract val module: KtModule } + +val FirDeclaration.llFirSession: LLFirSession + get() = moduleData.session as LLFirSession + +val FirBasedSymbol<*>.llFirSession: LLFirSession + get() = moduleData.session as LLFirSession \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt index ee3cd1135b8..0f8debf4ea5 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt @@ -8,15 +8,14 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.ProjectScope -import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseManager import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeSessionComponents +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.api.services.createPackagePartProviderForLibrary import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createSealedInheritorsProvider -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCacheImpl import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.FirThreadSafeCachesFactory -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirKtModuleBasedModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirBuiltinsModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.* @@ -74,7 +73,7 @@ internal object LLFirSessionFactory { project: Project, module: KtSourceModule, builtinsAndCloneableSession: LLFirBuiltinsAndCloneableSession, - firPhaseRunner: LLFirPhaseRunner, + globalResolveComponents: LLFirGlobalResolveComponents, sessionInvalidator: LLFirSessionInvalidator, builtinTypes: BuiltinTypes, sessionsCache: MutableMap, @@ -85,20 +84,20 @@ internal object LLFirSessionFactory { sessionsCache[module]?.let { return it as LLFirSourcesSession } val languageVersionSettings = module.languageVersionSettings val scopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped) - val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner) + + val components = LLFirModuleResolveComponents(module, globalResolveComponents, scopeProvider) + val contentScope = module.contentScope val dependentModules = module.directRegularDependenciesOfType() - val session = LLFirSourcesSession(module, project, firBuilder, builtinTypes) + val session = LLFirSourcesSession(module, project, components, builtinTypes) sessionsCache[module] = session + components.session = session return session.apply session@{ val moduleData = LLFirKtModuleBasedModuleData(module).apply { bindSession(this@session) } registerModuleData(moduleData) register(FirKotlinScopeProvider::class, scopeProvider) - val cache = ModuleFileCacheImpl(this) - val firPhaseManager = LLFirPhaseManager(FirLazyDeclarationResolver(firFileBuilder), cache, sessionInvalidator) - registerIdeComponents(project) registerCommonComponents(languageVersionSettings) registerCommonJavaComponents(JavaModuleResolver.getInstance(project)) @@ -106,12 +105,8 @@ internal object LLFirSessionFactory { registerJavaSpecificResolveComponents() val provider = LLFirProvider( - project, this, - module, - scopeProvider, - firFileBuilder, - cache, + components, project.createDeclarationProvider(contentScope), project.createPackageProvider(contentScope), ) @@ -119,7 +114,7 @@ internal object LLFirSessionFactory { register(FirProvider::class, provider) register(LLFirProvider::class, provider) - register(FirPhaseManager::class, firPhaseManager) + register(FirPhaseManager::class, LLFirPhaseManager(sessionInvalidator)) @OptIn(ExperimentalStdlibApi::class) val dependentProviders = buildList { @@ -140,7 +135,7 @@ internal object LLFirSessionFactory { project, it, builtinsAndCloneableSession, - firPhaseRunner, + globalResolveComponents, sessionInvalidator, builtinTypes, sessionsCache, @@ -330,7 +325,7 @@ internal object LLFirSessionFactory { project: Project, module: KtModule, builtinsAndCloneableSession: LLFirBuiltinsAndCloneableSession, - firPhaseRunner: LLFirPhaseRunner, + globalComponents: LLFirGlobalResolveComponents, sessionInvalidator: LLFirSessionInvalidator, builtinTypes: BuiltinTypes, sessionsCache: MutableMap, @@ -348,19 +343,18 @@ internal object LLFirSessionFactory { } val scopeProvider = FirKotlinScopeProvider() - val firFileBuilder = FirFileBuilder(scopeProvider, firPhaseRunner) + val components = LLFirModuleResolveComponents(module, globalComponents, scopeProvider) + val contentScope = module.contentScope - val session = LLFirLibraryOrLibrarySourceResolvableModuleSession(module, project, firFileBuilder, builtinTypes) + val session = LLFirLibraryOrLibrarySourceResolvableModuleSession(module, project, components, builtinTypes) sessionsCache[module] = session + components.session = session return session.apply session@{ val moduleData = LLFirKtModuleBasedModuleData(module).apply { bindSession(this@session) } registerModuleData(moduleData) register(FirKotlinScopeProvider::class, scopeProvider) - val cache = ModuleFileCacheImpl(this) - val firPhaseManager = LLFirPhaseManager(FirLazyDeclarationResolver(firFileBuilder), cache, sessionInvalidator) - registerIdeComponents(project) registerCommonComponents(languageVersionSettings) registerCommonJavaComponents(JavaModuleResolver.getInstance(project)) @@ -368,12 +362,8 @@ internal object LLFirSessionFactory { registerJavaSpecificResolveComponents() val provider = LLFirProvider( - project, this, - module, - scopeProvider, - firFileBuilder, - cache, + components, project.createDeclarationProvider(contentScope), project.createPackageProvider(contentScope), ) @@ -381,7 +371,7 @@ internal object LLFirSessionFactory { register(FirProvider::class, provider) register(LLFirProvider::class, provider) - register(FirPhaseManager::class, firPhaseManager) + register(FirPhaseManager::class, LLFirPhaseManager(sessionInvalidator)) val dependentProviders = buildList { val librariesSearchScope = ProjectScope.getLibrariesScope(project) .intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope)) // - diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProvider.kt index 11cfafc9f14..1da425e2cc4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProvider.kt @@ -8,7 +8,9 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.Immutable import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache +import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirBuiltinsModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirKtModuleBasedModuleData +import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.NoCacheForModuleException import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance @@ -23,17 +25,16 @@ class LLFirSessionProvider internal constructor( private val moduleToSession: Map ) : FirSessionProvider() { - override fun getSession(moduleData: FirModuleData): FirSession? { - requireIsInstance(moduleData) - return moduleToSession[moduleData.ktModule] + override fun getSession(moduleData: FirModuleData): LLFirSession { + requireIsInstance(moduleData) + return when (moduleData) { + is LLFirBuiltinsModuleData -> moduleData.session as LLFirBuiltinsAndCloneableSession + is LLFirKtModuleBasedModuleData -> getSession(moduleData.ktModule) + } } - fun getSession(module: KtModule): FirSession? = - moduleToSession[module] - - internal fun getModuleCache(module: KtModule): ModuleFileCache = - moduleToSession[module]?.cache - ?: throw NoCacheForModuleException(module, moduleToSession.keys) + fun getSession(module: KtModule): LLFirResolvableModuleSession = + moduleToSession.getValue(module) val allSessions: Collection get() = moduleToSession.values diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt index 639e9d35f97..51ab2a66e89 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt @@ -10,6 +10,7 @@ import com.intellij.openapi.util.ModificationTracker import kotlinx.collections.immutable.PersistentMap import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toPersistentMap +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firKtModuleBasedModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor @@ -20,7 +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.fir.BuiltinTypes -import org.jetbrains.kotlin.fir.moduleData +import org.jetbrains.kotlin.fir.FirSessionProvider import java.util.concurrent.ConcurrentHashMap class LLFirSessionProviderStorage(val project: Project) { @@ -32,7 +33,7 @@ class LLFirSessionProviderStorage(val project: Project) { rootModule: KtModule, configureSession: (LLFirSession.() -> Unit)? = null ): LLFirSessionProvider { - val firPhaseRunner = LLFirPhaseRunner() + val globalComponents = LLFirGlobalResolveComponents(rootModule, project) val builtinTypes = BuiltinTypes() @@ -47,7 +48,7 @@ class LLFirSessionProviderStorage(val project: Project) { project, rootModule, builtinsAndCloneableSession, - firPhaseRunner, + globalComponents, cache.sessionInvalidator, builtinTypes, sessions, @@ -61,7 +62,7 @@ class LLFirSessionProviderStorage(val project: Project) { project, rootModule, builtinsAndCloneableSession, - firPhaseRunner, + globalComponents, cache.sessionInvalidator, builtinTypes, sessions, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSourcesSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSourcesSession.kt index df3e347afd4..0e8b07c7632 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSourcesSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSourcesSession.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule import org.jetbrains.kotlin.fir.BuiltinTypes @@ -14,6 +15,6 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor internal class LLFirSourcesSession @PrivateSessionConstructor constructor( override val module: KtSourceModule, override val project: Project, - override val firFileBuilder: FirFileBuilder, + override val moduleComponents: LLFirModuleResolveComponents, builtinTypes: BuiltinTypes, ) : LLFirResolvableModuleSession(builtinTypes) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirLibraryOrLibrarySourceResolvableModuleResolveState.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirLibraryOrLibrarySourceResolvableModuleResolveState.kt index f5f5ebf7a83..5dfb76d1a5e 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirLibraryOrLibrarySourceResolvableModuleResolveState.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirLibraryOrLibrarySourceResolvableModuleResolveState.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.state import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver @@ -18,12 +19,11 @@ import org.jetbrains.kotlin.psi.KtFile internal class LLFirLibraryOrLibrarySourceResolvableModuleResolveState( + override val globalComponents: LLFirGlobalResolveComponents, override val project: Project, override val module: KtModule, sessionProvider: LLFirSessionProvider, - firFileBuilder: FirFileBuilder, - firLazyDeclarationResolver: FirLazyDeclarationResolver, -) : LLFirResolvableModuleResolveState(sessionProvider, firFileBuilder, firLazyDeclarationResolver) { +) : LLFirResolvableModuleResolveState(sessionProvider) { override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List = emptyList() diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableModuleResolveState.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableModuleResolveState.kt index 142e6b3a1d7..ddf32d3eb4e 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableModuleResolveState.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableModuleResolveState.kt @@ -5,23 +5,22 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.state +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.api.LLFirModuleResolveState -import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirElementBuilder import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FileStructureCache -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver -import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirProvider +import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firModuleData +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionProvider -import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSourcesSession import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCompiledElementSearcher import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getElementTextInContext import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.getKtModule +import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirDeclaration @@ -36,36 +35,38 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.psi.* internal abstract class LLFirResolvableModuleResolveState( - protected val sessionProvider: LLFirSessionProvider, - val firFileBuilder: FirFileBuilder, - val firLazyDeclarationResolver: FirLazyDeclarationResolver, + private val sessionProvider: LLFirSessionProvider, ) : LLFirModuleResolveState() { - final override val rootModuleSession = sessionProvider.rootModuleSession - val cache = (rootModuleSession.firProvider as LLFirProvider).cache + abstract val globalComponents: LLFirGlobalResolveComponents - val fileStructureCache = FileStructureCache(firFileBuilder, firLazyDeclarationResolver) - val elementBuilder = FirElementBuilder() + final override val rootModuleSession = sessionProvider.rootModuleSession override fun getSessionFor(module: KtModule): FirSession = - sessionProvider.getSession(module)!! + sessionProvider.getSession(module) - override fun getOrBuildFirFor(element: KtElement): FirElement? = - elementBuilder.getOrBuildFirFor( - element = element, - firFileBuilder = firFileBuilder, - moduleFileCache = cache, - fileStructureCache = fileStructureCache, - firLazyDeclarationResolver = firLazyDeclarationResolver, - state = this - ) + override fun getScopeSessionFor(firSession: FirSession): ScopeSession { + requireIsInstance(firSession) + return firSession.getScopeSession() + } + override fun getOrBuildFirFor(element: KtElement): FirElement? { + val moduleComponents = getModuleComponentsForElement(element) + return moduleComponents.elementsBuilder.getOrBuildFirFor(element, this) + } - override fun getOrBuildFirFile(ktFile: KtFile): FirFile = - firFileBuilder.buildRawFirFileWithCaching(ktFile, cache) + override fun getOrBuildFirFile(ktFile: KtFile): FirFile { + val moduleComponents = getModuleComponentsForElement(ktFile) + return moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile) + } override fun tryGetCachedFirFile(declaration: FirDeclaration, cache: ModuleFileCache): FirFile? = cache.getContainerFirFile(declaration) + protected fun getModuleComponentsForElement(element: KtElement): LLFirModuleResolveComponents { + val ktModule = element.getKtModule() + return sessionProvider.getSession(ktModule).moduleComponents + } + override fun resolveToFirSymbol( ktDeclaration: KtDeclaration, phase: FirResolvePhase @@ -102,10 +103,10 @@ internal abstract class LLFirResolvableModuleResolveState( ?: error("Declaration should have non-local container${ktDeclaration.getElementTextInContext()}") if (ktDeclaration == nonLocalNamedDeclaration) { + val session = sessionProvider.getSession(module) return nonLocalNamedDeclaration.findSourceNonLocalFirDeclaration( - firFileBuilder = firFileBuilder, - firSymbolProvider = rootModuleSession.firProvider.symbolProvider, - moduleFileCache = sessionProvider.getModuleCache(module) + firFileBuilder = session.moduleComponents.firFileBuilder, + provider = session.firProvider, ).symbol } @@ -126,14 +127,12 @@ internal abstract class LLFirResolvableModuleResolveState( override fun resolveFirToPhase(declaration: FirDeclaration, toPhase: FirResolvePhase) { if (toPhase == FirResolvePhase.RAW_FIR) return - val fileCache = when (val session = declaration.moduleData.session) { - is LLFirSourcesSession -> session.cache - else -> return - } - firLazyDeclarationResolver.lazyResolveDeclaration( + val llFirResolvableModuleSession = declaration.firModuleData.session as? LLFirResolvableModuleSession ?: return + + val moduleComponents = llFirResolvableModuleSession.moduleComponents + moduleComponents.lazyFirDeclarationsResolver.lazyResolveDeclaration( firDeclarationToResolve = declaration, - moduleFileCache = fileCache, - scopeSession = ScopeSession(), + scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(), toPhase = toPhase, checkPCE = true, ) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirSourceModuleResolveState.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirSourceModuleResolveState.kt index 973429e896e..2e92ad0fe4a 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirSourceModuleResolveState.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirSourceModuleResolveState.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.state import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.DiagnosticsCollector import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder @@ -20,19 +21,20 @@ import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile internal class LLFirSourceModuleResolveState( + override val globalComponents: LLFirGlobalResolveComponents, override val project: Project, override val module: KtModule, sessionProvider: LLFirSessionProvider, - firFileBuilder: FirFileBuilder, - firLazyDeclarationResolver: FirLazyDeclarationResolver, -) : LLFirResolvableModuleResolveState(sessionProvider, firFileBuilder, firLazyDeclarationResolver) { - private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, cache) +) : LLFirResolvableModuleResolveState(sessionProvider) { + override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List { + val moduleComponents = getModuleComponentsForElement(element) + return moduleComponents.diagnosticsCollector.getDiagnosticsFor(element, filter) + } - override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List = - diagnosticsCollector.getDiagnosticsFor(element, filter) - - override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection = - diagnosticsCollector.collectDiagnosticsForFile(ktFile, filter) + override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection { + val moduleComponents = getModuleComponentsForElement(ktFile) + return moduleComponents.diagnosticsCollector.collectDiagnosticsForFile(ktFile, filter) + } override fun getModuleKind(module: KtModule): ModuleKind { return when (module) { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedSupertypeResolverTransformer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedSupertypeResolverTransformer.kt index 1af89ee57e9..b49979d7d67 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedSupertypeResolverTransformer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedSupertypeResolverTransformer.kt @@ -17,10 +17,12 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LockProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.runCustomResolveUnderLock import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveTreeBuilder +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformer.Companion.updatePhaseDeep import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ensurePhase @@ -32,8 +34,8 @@ internal class LLFirDesignatedSupertypeResolverTransformer( private val designation: FirDeclarationDesignationWithFile, private val session: FirSession, private val scopeSession: ScopeSession, - private val moduleFileCache: ModuleFileCache, private val firLazyDeclarationResolver: FirLazyDeclarationResolver, + private val lockProvider: LockProvider, private val firProviderInterceptor: FirProviderInterceptor?, private val checkPCE: Boolean, ) : LLFirLazyTransformer { @@ -80,10 +82,9 @@ internal class LLFirDesignatedSupertypeResolverTransformer( for (nowVisit in toVisit) { if (checkPCE) checkCanceled() val resolver = DesignatedFirSupertypeResolverVisitor(nowVisit) - moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(nowVisit.firFile, checkPCE) { + lockProvider.runCustomResolveUnderLock(nowVisit.firFile, checkPCE) { firLazyDeclarationResolver.lazyResolveFileDeclaration( firFile = nowVisit.firFile, - moduleFileCache = moduleFileCache, toPhase = FirResolvePhase.IMPORTS, scopeSession = scopeSession, checkPCE = true, @@ -102,7 +103,8 @@ internal class LLFirDesignatedSupertypeResolverTransformer( if (classLikeDeclaration !is FirClassLikeDeclaration) continue if (classLikeDeclaration is FirJavaClass) continue if (visited.containsKey(classLikeDeclaration)) continue - val containingFile = moduleFileCache.getContainerFirFile(classLikeDeclaration) ?: continue + val cache = classLikeDeclaration.llFirResolvableSession?.moduleComponents?.cache ?: continue + val containingFile = cache.getContainerFirFile(classLikeDeclaration) ?: continue toVisit.add(classLikeDeclaration.collectDesignation(containingFile)) } } @@ -123,7 +125,7 @@ internal class LLFirDesignatedSupertypeResolverTransformer( val filesToDesignations = visited.groupBy { it.firFile } for (designationsPerFile in filesToDesignations) { if (checkPCE) checkCanceled() - moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(designationsPerFile.key, checkPCE) { + lockProvider.runCustomResolveUnderLock(designationsPerFile.key, checkPCE) { applyToFileSymbols(designationsPerFile.value) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LazyTransformerFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LazyTransformerFactory.kt index 8acc8171995..763ee5db28a 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LazyTransformerFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LazyTransformerFactory.kt @@ -18,7 +18,6 @@ internal object LazyTransformerFactory { phase: FirResolvePhase, designation: FirDeclarationDesignationWithFile, scopeSession: ScopeSession, - moduleFileCache: ModuleFileCache, lazyDeclarationResolver: FirLazyDeclarationResolver, towerDataContextCollector: FirTowerDataContextCollector?, firProviderInterceptor: FirProviderInterceptor?, @@ -33,8 +32,8 @@ internal object LazyTransformerFactory { designation = designation, session = designation.firFile.moduleData.session, scopeSession = scopeSession, - moduleFileCache = moduleFileCache, firLazyDeclarationResolver = lazyDeclarationResolver, + lockProvider = lazyDeclarationResolver.moduleComponents.globalResolveComponents.lockProvider, firProviderInterceptor = firProviderInterceptor, checkPCE = checkPCE, ) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/LLFirScopeSessionProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/LLFirScopeSessionProvider.kt new file mode 100644 index 00000000000..f848e987016 --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/LLFirScopeSessionProvider.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2022 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.analysis.low.level.api.fir.util + +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectRootModificationTracker +import com.intellij.psi.util.PsiModificationTracker +import org.jetbrains.kotlin.analysis.utils.caches.getValue +import org.jetbrains.kotlin.analysis.utils.caches.softCachedValue +import org.jetbrains.kotlin.fir.resolve.ScopeSession +import java.util.concurrent.ConcurrentHashMap + + +abstract class LLFirScopeSessionProvider { + abstract fun getScopeSession(): ScopeSession + + companion object { + fun create(project: Project, invalidationTrackers: List): LLFirScopeSessionProvider = when { + invalidationTrackers.isEmpty() -> LLFirNonInvalidatableScopeSessionProvider() + else -> LLFirInvalidatableScopeSessionProvider(project, invalidationTrackers) + } + } +} + +private class LLFirInvalidatableScopeSessionProvider(project: Project, invalidationTrackers: List) : LLFirScopeSessionProvider() { + // ScopeSession is thread-local, so we use Thread id as a key + // We cannot use thread locals here as it may lead to memory leaks + private val cache by softCachedValue( + project, + *invalidationTrackers.toTypedArray(), + ) { + ConcurrentHashMap() + } + + override fun getScopeSession(): ScopeSession { + return cache.getOrPut(Thread.currentThread().id) { ScopeSession() } + } +} + +private class LLFirNonInvalidatableScopeSessionProvider : LLFirScopeSessionProvider() { + // ScopeSession is thread-local, so we use Thread id as a key + // We cannot use thread locals here as it may lead to memory leaks + private val cache = ConcurrentHashMap() + + override fun getScopeSession(): ScopeSession { + return cache.getOrPut(Thread.currentThread().id) { ScopeSession() } + } +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt index 7033368fdd5..d3875cb36f5 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt @@ -8,13 +8,13 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.util import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.realPsi +import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject @@ -24,24 +24,22 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject */ internal fun KtDeclaration.findSourceNonLocalFirDeclaration( firFileBuilder: FirFileBuilder, - firSymbolProvider: FirSymbolProvider, - moduleFileCache: ModuleFileCache, + provider: FirProvider, containerFirFile: FirFile? = null ): FirDeclaration { //TODO test what way faster - findSourceNonLocalFirDeclarationByProvider(firFileBuilder, firSymbolProvider, moduleFileCache, containerFirFile)?.let { return it } - findSourceOfNonLocalFirDeclarationByTraversingWholeTree(firFileBuilder, moduleFileCache, containerFirFile)?.let { return it } + findSourceNonLocalFirDeclarationByProvider(firFileBuilder, provider, containerFirFile)?.let { return it } + findSourceOfNonLocalFirDeclarationByTraversingWholeTree(firFileBuilder, containerFirFile)?.let { return it } error("No fir element was found for\n${getElementTextInContext()}") } internal fun KtDeclaration.findFirDeclarationForAnyFirSourceDeclaration( firFileBuilder: FirFileBuilder, - firSymbolProvider: FirSymbolProvider, - moduleFileCache: ModuleFileCache + provider: FirProvider, ): FirDeclaration { val nonLocalDeclaration = getNonLocalContainingOrThisDeclaration() - ?.findSourceNonLocalFirDeclaration(firFileBuilder, firSymbolProvider, moduleFileCache) - ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile, moduleFileCache) + ?.findSourceNonLocalFirDeclaration(firFileBuilder, provider) + ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile) val originalDeclaration = originalDeclaration val fir = FirElementFinder.findElementIn(nonLocalDeclaration) { firDeclaration -> firDeclaration.psi == this || firDeclaration.psi == originalDeclaration @@ -52,20 +50,18 @@ internal fun KtDeclaration.findFirDeclarationForAnyFirSourceDeclaration( internal inline fun KtDeclaration.findFirDeclarationForAnyFirSourceDeclarationOfType( firFileBuilder: FirFileBuilder, - firSymbolProvider: FirSymbolProvider, - moduleFileCache: ModuleFileCache + provider: FirProvider, ): FirDeclaration { - val fir = findFirDeclarationForAnyFirSourceDeclaration(firFileBuilder, firSymbolProvider, moduleFileCache) + val fir = findFirDeclarationForAnyFirSourceDeclaration(firFileBuilder, provider) if (fir !is F) throwUnexpectedFirElementError(fir, this, F::class) return fir } private fun KtDeclaration.findSourceOfNonLocalFirDeclarationByTraversingWholeTree( firFileBuilder: FirFileBuilder, - moduleFileCache: ModuleFileCache, containerFirFile: FirFile?, ): FirDeclaration? { - val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile, moduleFileCache) + val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile) val originalDeclaration = originalDeclaration return FirElementFinder.findElementIn(firFile, goInside = { it is FirRegularClass }) { firDeclaration -> firDeclaration.psi == this || firDeclaration.psi == originalDeclaration @@ -74,20 +70,19 @@ private fun KtDeclaration.findSourceOfNonLocalFirDeclarationByTraversingWholeTre private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider( firFileBuilder: FirFileBuilder, - firSymbolProvider: FirSymbolProvider, - moduleFileCache: ModuleFileCache, + provider: FirProvider, containerFirFile: FirFile? ): FirDeclaration? { val candidate = when { - this is KtClassOrObject -> findFir(firSymbolProvider) + this is KtClassOrObject -> findFir(provider) this is KtNamedDeclaration && (this is KtProperty || this is KtNamedFunction) -> { val containerClass = containingClassOrObject val declarations = if (containerClass != null) { - val containerClassFir = containerClass.findFir(firSymbolProvider) as? FirRegularClass + val containerClassFir = containerClass.findFir(provider) as? FirRegularClass containerClassFir?.declarations } else { val ktFile = containingKtFile - val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(ktFile, moduleFileCache) + val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(ktFile) firFile.declarations } val original = originalDeclaration @@ -101,10 +96,10 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider( this is KtConstructor<*> -> { val containingClass = containingClassOrObject ?: error("Container class should be not null for KtConstructor") - val containerClassFir = containingClass.findFir(firSymbolProvider) as? FirRegularClass ?: return null + val containerClassFir = containingClass.findFir(provider) as? FirRegularClass ?: return null containerClassFir.declarations.firstOrNull { it.psi === this } } - this is KtTypeAlias -> findFir(firSymbolProvider) + this is KtTypeAlias -> findFir(provider) else -> error("Invalid container ${this::class}\n${getElementTextInContext()}") } return candidate?.takeIf { it.realPsi == this } @@ -117,10 +112,10 @@ private val ORIGINAL_KT_FILE_KEY = com.intellij.openapi.util.Key("ORIGIN var KtFile.originalKtFile by UserDataProperty(ORIGINAL_KT_FILE_KEY) -private fun KtClassLikeDeclaration.findFir(firSymbolProvider: FirSymbolProvider): FirClassLikeDeclaration? { +private fun KtClassLikeDeclaration.findFir(provider: FirProvider): FirClassLikeDeclaration? { val classId = getClassId() ?: return null return executeWithoutPCE { - firSymbolProvider.getClassLikeSymbolByClassId(classId)?.fir as? FirRegularClass + provider.getFirClassifierByFqName(classId) as? FirRegularClass } } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/AbstractFirContextCollectionTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/AbstractFirContextCollectionTest.kt index 54a7e779e4f..3c4f4ac52bc 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/AbstractFirContextCollectionTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/AbstractFirContextCollectionTest.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceModuleRe import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getDiagnostics import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.BeforeElementDiagnosticCollectionHandler import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistenceContextCollector import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FileStructureElement @@ -23,7 +24,9 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.Reanalyzab import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.RootStructureElement import org.jetbrains.kotlin.analysis.low.level.api.fir.name import org.jetbrains.kotlin.analysis.low.level.api.fir.resolveWithClearCaches +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest +import org.jetbrains.kotlin.analysis.project.structure.getKtModule import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.services.AssertionsService import org.jetbrains.kotlin.test.services.TestModuleStructure @@ -43,7 +46,10 @@ abstract class AbstractFirContextCollectionTest : AbstractLowLevelApiSingleFileT ) { resolveState -> check(resolveState is LLFirSourceModuleResolveState) - val fileStructure = resolveState.fileStructureCache.getFileStructure(ktFile, resolveState.cache) + val session = resolveState.getSessionFor(ktFile.getKtModule()) as LLFirResolvableModuleSession + val fileStructureCache = session.moduleComponents.fileStructureCache + + val fileStructure = fileStructureCache.getFileStructure(ktFile) val allStructureElements = fileStructure.getAllStructureElements() handler.elementsToCheckContext = allStructureElements.map { it.getFirDeclaration() } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/AbstractFileStructureTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/AbstractFileStructureTest.kt index 989b1e9cd30..1910dd8f573 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/AbstractFileStructureTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/AbstractFileStructureTest.kt @@ -11,7 +11,9 @@ import com.intellij.psi.PsiElementVisitor import com.intellij.psi.impl.source.tree.LeafPsiElement import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceModuleResolveState import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getResolveState +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest +import org.jetbrains.kotlin.analysis.project.structure.getKtModule import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.test.KotlinTestUtils @@ -86,10 +88,8 @@ abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() { private fun KtFile.getFileStructure(): FileStructure { val moduleResolveState = getResolveState() as LLFirSourceModuleResolveState - return moduleResolveState.fileStructureCache.getFileStructure( - ktFile = this, - moduleFileCache = moduleResolveState.cache - ) + val session = moduleResolveState.getSessionFor(getKtModule()) as LLFirResolvableModuleSession + return session.moduleComponents.fileStructureCache.getFileStructure(this) } @OptIn(ExperimentalStdlibApi::class)