From e5cbe79027546457256bb081a935a0affb30fd23 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 13 Jan 2023 02:51:07 +0900 Subject: [PATCH] [LL API] Encapsulate on-air class provider logic in LLFirProvider The old 'FirProviderInterceptor' is too invasive, ad-hoc, and only a few places in the compiler are aware of it. This fixes the test 'FirOnAirResolveTestGenerated#testOnAirTypesResolve' which started failing after the designation path collection refactoring. The newly appeared class existence check started to fail: ``` val declaration = firProvider.getFirClassifierByFqName(classId) check(declaration != null) ``` --- .../LLFirModuleLazyDeclarationResolver.kt | 46 ++++---- .../providers/LLFirLibrarySessionProvider.kt | 7 +- .../level/api/fir/providers/LLFirProvider.kt | 18 +-- .../LLFirDesignatedBodyResolveTransformer.kt | 7 +- ...rDesignatedSupertypeResolverTransformer.kt | 6 +- .../LLFirFirProviderInterceptor.kt | 49 -------- .../LLFirLazyTransformerExecutor.kt | 7 +- .../transformers/LazyTransformerFactory.kt | 10 +- .../transformers/SyntheticFirClassProvider.kt | 105 ++++++++++++++++++ .../transformers/FirSupertypesResolution.kt | 23 +--- ...bstractBodyResolveTransformerDispatcher.kt | 11 -- .../body/resolve/FirBodyResolveTransformer.kt | 7 +- .../FirDeclarationsResolveTransformer.kt | 24 +--- .../body/resolve/LocalClassesResolution.kt | 5 +- 14 files changed, 164 insertions(+), 161 deletions(-) delete mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirFirProviderInterceptor.kt create mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/SyntheticFirClassProvider.kt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirModuleLazyDeclarationResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirModuleLazyDeclarationResolver.kt index 5510a430790..e4ea16912a0 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirModuleLazyDeclarationResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirModuleLazyDeclarationResolver.kt @@ -12,8 +12,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionInvalidator import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession -import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirFirProviderInterceptor import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformerExecutor +import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.withSyntheticClasses import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry @@ -163,8 +163,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod scopeSession = scopeSession, phaseRunner = moduleComponents.globalResolveComponents.phaseRunner, lockProvider = moduleComponents.globalResolveComponents.lockProvider, - towerDataContextCollector = null, - firProviderInterceptor = null, + towerDataContextCollector = null ) } } @@ -175,31 +174,30 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod towerDataContextCollector: FirTowerDataContextCollector?, ) { resolveFileToImportsWithoutLock(designation.firFile) - var currentPhase = maxOf(designation.target.resolvePhase, FirResolvePhase.IMPORTS) - val scopeSession = ScopeSession() + fun runTransformation() { + val scopeSession = ScopeSession() + var currentPhase = maxOf(designation.target.resolvePhase, FirResolvePhase.IMPORTS) - val firProviderInterceptor = if (onAirCreatedDeclaration) { - LLFirFirProviderInterceptor.createForFirElement( - session = designation.firFile.moduleData.session, - firFile = designation.firFile, - element = designation.target - ) - } else null + while (currentPhase < FirResolvePhase.BODY_RESOLVE) { + currentPhase = currentPhase.next + checkCanceled() - while (currentPhase < FirResolvePhase.BODY_RESOLVE) { - currentPhase = currentPhase.next - checkCanceled() + LLFirLazyTransformerExecutor.execute( + phase = currentPhase, + designation = designation, + scopeSession = scopeSession, + phaseRunner = moduleComponents.globalResolveComponents.phaseRunner, + lockProvider = moduleComponents.globalResolveComponents.lockProvider, + towerDataContextCollector = towerDataContextCollector + ) + } + } - LLFirLazyTransformerExecutor.execute( - phase = currentPhase, - designation = designation, - scopeSession = scopeSession, - phaseRunner = moduleComponents.globalResolveComponents.phaseRunner, - lockProvider = moduleComponents.globalResolveComponents.lockProvider, - towerDataContextCollector = towerDataContextCollector, - firProviderInterceptor = firProviderInterceptor, - ) + if (onAirCreatedDeclaration) { + withSyntheticClasses(designation, ::runTransformation) + } else { + runTransformation() } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirLibrarySessionProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirLibrarySessionProvider.kt index d208f3547d7..a16f1e18b3c 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirLibrarySessionProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirLibrarySessionProvider.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.providers +import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.SyntheticFirClassProvider import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.resolve.providers.FirProvider @@ -17,8 +18,10 @@ import org.jetbrains.kotlin.name.Name internal class LLFirLibrarySessionProvider( override val symbolProvider: FirSymbolProvider ) : FirProvider() { - override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? = - symbolProvider.getClassLikeSymbolByClassId(classId)?.fir + override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? { + return SyntheticFirClassProvider.getInstance(symbolProvider.session).getFirClassifierByFqName(classId) + ?: symbolProvider.getClassLikeSymbolByClassId(classId)?.fir + } override fun getFirClassifierContainerFile(fqName: ClassId): FirFile = shouldNotBeCalled() 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 5692d7f8079..a4f001fef2e 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 @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.providers import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents +import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.SyntheticFirClassProvider import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider import org.jetbrains.kotlin.fir.FirSession @@ -44,8 +45,10 @@ internal class LLFirProvider( override val isPhasedFirAllowed: Boolean get() = true - override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? = - providerHelper.getFirClassifierByFqName(classId) + override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? { + return SyntheticFirClassProvider.getInstance(session).getFirClassifierByFqName(classId) + ?: providerHelper.getFirClassifierByFqName(classId) + } override fun getFirClassifierContainerFile(fqName: ClassId): FirFile { return getFirClassifierContainerFileIfAny(fqName) @@ -53,8 +56,8 @@ internal class LLFirProvider( } override fun getFirClassifierContainerFileIfAny(fqName: ClassId): FirFile? { - val fir = getFirClassifierByFqName(fqName) ?: return null // Necessary to ensure cacheProvider contains this classifier - return moduleComponents.cache.getContainerFirFile(fir) + return SyntheticFirClassProvider.getInstance(session).getFirClassifierContainerFileIfAny(fqName) + ?: getFirClassifierByFqName(fqName)?.let { moduleComponents.cache.getContainerFirFile(it) } } override fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile { @@ -62,9 +65,10 @@ internal class LLFirProvider( ?: error("Couldn't find container for ${symbol.classId}") } - override fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? = - moduleComponents.cache.getContainerFirFile(symbol.fir) - + override fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? { + return SyntheticFirClassProvider.getInstance(session).getFirClassifierContainerFileIfAny(symbol.classId) + ?: moduleComponents.cache.getContainerFirFile(symbol.fir) + } override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? { symbol.fir.originalForSubstitutionOverride?.symbol?.let { originalSymbol -> diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedBodyResolveTransformer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedBodyResolveTransformer.kt index 308a8157823..044f23255d1 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedBodyResolveTransformer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedBodyResolveTransformer.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.ImplicitBodyResolveComputationSession @@ -28,8 +27,7 @@ internal class LLFirDesignatedBodyResolveTransformer( private val designation: FirDesignationWithFile, session: FirSession, scopeSession: ScopeSession, - towerDataContextCollector: FirTowerDataContextCollector?, - firProviderInterceptor: FirProviderInterceptor?, + towerDataContextCollector: FirTowerDataContextCollector? ) : LLFirLazyTransformer, FirBodyResolveTransformer( session, phase = FirResolvePhase.BODY_RESOLVE, @@ -40,8 +38,7 @@ internal class LLFirDesignatedBodyResolveTransformer( ImplicitBodyResolveComputationSession(), ::LLFirEnsureBasedTransformerForReturnTypeCalculator ), - firTowerDataContextCollector = towerDataContextCollector, - firProviderInterceptor = firProviderInterceptor, + firTowerDataContextCollector = towerDataContextCollector ) { private val ideDeclarationTransformer = LLFirDeclarationTransformer(designation) 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 a2fca947cd4..5fa7c485128 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 @@ -35,8 +35,7 @@ internal class LLFirDesignatedSupertypeResolverTransformer( private val designation: FirDesignationWithFile, private val session: FirSession, private val scopeSession: ScopeSession, - private val lockProvider: LLFirLockProvider, - private val firProviderInterceptor: FirProviderInterceptor?, + private val lockProvider: LLFirLockProvider ) : LLFirLazyTransformer { private val supertypeComputationSession = SupertypeComputationSession() @@ -47,8 +46,7 @@ internal class LLFirDesignatedSupertypeResolverTransformer( supertypeComputationSession = supertypeComputationSession, scopeSession = scopeSession, scopeForLocalClass = null, - localClassesNavigationInfo = null, - firProviderInterceptor = firProviderInterceptor, + localClassesNavigationInfo = null ) { val declarationTransformer = LLFirDeclarationTransformer(classDesignation) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirFirProviderInterceptor.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirFirProviderInterceptor.kt deleted file mode 100644 index 9a52609b451..00000000000 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirFirProviderInterceptor.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2010-2021 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.transformers - -import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration -import org.jetbrains.kotlin.fir.declarations.FirFile -import org.jetbrains.kotlin.fir.resolve.providers.firProvider -import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor -import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol -import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid -import org.jetbrains.kotlin.name.ClassId - -internal class LLFirFirProviderInterceptor private constructor( - private val firFile: FirFile, - private val session: FirSession, - private val symbolSet: Set>, - private val classIdToElementMap: Map -) : FirProviderInterceptor { - - override fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? = - if (symbolSet.contains(symbol)) firFile else session.firProvider.getFirClassifierContainerFileIfAny(symbol) - - override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? = - classIdToElementMap[classId] ?: session.firProvider.getFirClassifierByFqName(classId) - - companion object { - fun createForFirElement(session: FirSession, firFile: FirFile, element: FirElement): FirProviderInterceptor { - val nodeInfoCollector = object : FirVisitorVoid() { - val symbolSet = mutableSetOf>() - val classIdToElementMap = mutableMapOf() - override fun visitElement(element: FirElement) { - if (element is FirClassLikeDeclaration) { - symbolSet.add(element.symbol) - classIdToElementMap[element.symbol.classId] = element - } - element.acceptChildren(this) - } - } - nodeInfoCollector.visitElement(element) - - return LLFirFirProviderInterceptor(firFile, session, nodeInfoCollector.symbolSet, nodeInfoCollector.classIdToElementMap) - } - } -} diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyTransformerExecutor.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyTransformerExecutor.kt index d2a37379392..1a110225131 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyTransformerExecutor.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyTransformerExecutor.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFil import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector internal class LLFirLazyTransformerExecutor { @@ -21,8 +20,7 @@ internal class LLFirLazyTransformerExecutor { scopeSession: ScopeSession, phaseRunner: LLFirPhaseRunner, lockProvider: LLFirLockProvider, - towerDataContextCollector: FirTowerDataContextCollector?, - firProviderInterceptor: FirProviderInterceptor?, + towerDataContextCollector: FirTowerDataContextCollector? ) { val lazyTransformer = LazyTransformerFactory.createLazyTransformer( @@ -30,8 +28,7 @@ internal class LLFirLazyTransformerExecutor { designation, scopeSession, lockProvider, - towerDataContextCollector, - firProviderInterceptor, + towerDataContextCollector ) lazyTransformer.transformDeclaration(phaseRunner) } 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 1b8ddf352aa..88302588f28 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 @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFil import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector internal object LazyTransformerFactory { @@ -18,8 +17,7 @@ internal object LazyTransformerFactory { designation: FirDesignationWithFile, scopeSession: ScopeSession, lockProvider: LLFirLockProvider, - towerDataContextCollector: FirTowerDataContextCollector?, - firProviderInterceptor: FirProviderInterceptor?, + towerDataContextCollector: FirTowerDataContextCollector? ): LLFirLazyTransformer = when (phase) { FirResolvePhase.COMPANION_GENERATION -> LLFirDesignatedGeneratedCompanionObjectResolveTransformer( designation = designation, @@ -30,8 +28,7 @@ internal object LazyTransformerFactory { designation = designation, session = designation.firFile.moduleData.session, scopeSession = scopeSession, - lockProvider = lockProvider, - firProviderInterceptor = firProviderInterceptor, + lockProvider = lockProvider ) FirResolvePhase.TYPES -> LLFirDesignatedTypeResolverTransformer( designation, @@ -73,8 +70,7 @@ internal object LazyTransformerFactory { designation, designation.firFile.moduleData.session, scopeSession, - towerDataContextCollector, - firProviderInterceptor, + towerDataContextCollector ) FirResolvePhase.EXPECT_ACTUAL_MATCHING -> LLFirDesignatedExpectActualMatcherTransformer( designation, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/SyntheticFirClassProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/SyntheticFirClassProvider.kt new file mode 100644 index 00000000000..5aba792a8c5 --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/SyntheticFirClassProvider.kt @@ -0,0 +1,105 @@ +/* + * Copyright 2010-2021 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.transformers + +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid +import org.jetbrains.kotlin.name.ClassId +import java.util.WeakHashMap + +internal interface SyntheticFirClassProvider { + fun getFirClassifierContainerFileIfAny(classId: ClassId): FirFile? + fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? + + companion object { + fun getInstance(session: FirSession): SyntheticFirClassProvider { + return providersForThread.get()[session] ?: EmptySyntheticFirClassProvider + } + } +} + +internal fun withSyntheticClasses(designation: FirDesignationWithFile, block: () -> Unit) { + val firSession = designation.firFile.moduleData.session + + val compoundProvider = providersForThread.get() + .getOrPut(firSession) { CompoundSyntheticFirClassProvider() } + + val provider = StaticSyntheticFirClassProvider.create(designation) + + try { + compoundProvider.push(provider) + block() + } finally { + compoundProvider.pop(provider) + } +} + +private class StaticSyntheticFirClassProvider private constructor( + private val firFile: FirFile, + private val classes: Map +) : SyntheticFirClassProvider { + override fun getFirClassifierContainerFileIfAny(classId: ClassId): FirFile? { + return if (classId in classes) firFile else null + } + + override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? { + return classes[classId] + } + + companion object { + fun create(designation: FirDesignationWithFile): SyntheticFirClassProvider { + val firFile = designation.firFile + val firElement = designation.target + + val nodeInfoCollector = object : FirVisitorVoid() { + val classes = mutableMapOf() + override fun visitElement(element: FirElement) { + if (element is FirClassLikeDeclaration) { + classes[element.symbol.classId] = element + } + element.acceptChildren(this) + } + } + + nodeInfoCollector.visitElement(firElement) + return StaticSyntheticFirClassProvider(firFile, nodeInfoCollector.classes) + } + } +} + +private class CompoundSyntheticFirClassProvider : SyntheticFirClassProvider { + private val providers = ArrayDeque() + + fun push(provider: SyntheticFirClassProvider) { + providers.addFirst(provider) + } + + fun pop(provider: SyntheticFirClassProvider) { + assert(providers.removeFirst() === provider) + } + + override fun getFirClassifierContainerFileIfAny(classId: ClassId): FirFile? { + return providers.asReversed() + .firstNotNullOfOrNull { it.getFirClassifierContainerFileIfAny(classId) } + } + + override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? { + return providers.asReversed() + .firstNotNullOfOrNull { it.getFirClassifierByFqName(classId) } + } +} + +private object EmptySyntheticFirClassProvider : SyntheticFirClassProvider { + override fun getFirClassifierContainerFileIfAny(classId: ClassId) = null + override fun getFirClassifierByFqName(classId: ClassId) = null +} + +private val providersForThread: ThreadLocal> = + ThreadLocal.withInitial { WeakHashMap() } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt index 841c238c611..896ef46c1b9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt @@ -50,14 +50,6 @@ class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSess override val transformer = FirSupertypeResolverTransformer(session, scopeSession) } -/** - * Interceptor needed by IDE to resolve in-air created declarations. - */ -interface FirProviderInterceptor { - fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? - fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? -} - open class FirSupertypeResolverTransformer( final override val session: FirSession, scopeSession: ScopeSession @@ -84,7 +76,6 @@ fun F.runSupertypeResolvePhaseForLocalClass( scopeSession: ScopeSession, currentScopeList: List, localClassesNavigationInfo: LocalClassesNavigationInfo, - firProviderInterceptor: FirProviderInterceptor?, useSiteFile: FirFile, containingDeclarations: List, ): F { @@ -93,7 +84,6 @@ fun F.runSupertypeResolvePhaseForLocalClass( session, supertypeComputationSession, scopeSession, currentScopeList.toPersistentList(), localClassesNavigationInfo, - firProviderInterceptor, useSiteFile, containingDeclarations, ) @@ -220,7 +210,6 @@ open class FirSupertypeResolverVisitor( private val scopeSession: ScopeSession, private val scopeForLocalClass: PersistentList? = null, private val localClassesNavigationInfo: LocalClassesNavigationInfo? = null, - private val firProviderInterceptor: FirProviderInterceptor? = null, @property:PrivateForInline var useSiteFile: FirFile? = null, containingDeclarations: List = emptyList(), ) : FirDefaultVisitor() { @@ -246,13 +235,13 @@ open class FirSupertypeResolverVisitor( } } - private fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? = - if (firProviderInterceptor != null) firProviderInterceptor.getFirClassifierContainerFileIfAny(symbol) - else symbol.moduleData.session.firProvider.getFirClassifierContainerFileIfAny(symbol.classId) + private fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? { + return symbol.moduleData.session.firProvider.getFirClassifierContainerFileIfAny(symbol.classId) + } - private fun getFirClassifierByFqName(moduleSession: FirSession, classId: ClassId): FirClassLikeDeclaration? = - if (firProviderInterceptor != null) firProviderInterceptor.getFirClassifierByFqName(classId) - else moduleSession.firProvider.getFirClassifierByFqName(classId) + private fun getFirClassifierByFqName(moduleSession: FirSession, classId: ClassId): FirClassLikeDeclaration? { + return moduleSession.firProvider.getFirClassifierByFqName(classId) + } override fun visitElement(element: FirElement, data: Any?) {} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt index 7f920e02f1b..08ade393beb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt @@ -10,19 +10,9 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext -import org.jetbrains.kotlin.fir.resolve.calls.ResolutionStageRunner import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext -import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer -import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter -import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents -import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents -import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.transformers.* -import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef import org.jetbrains.kotlin.fir.visitors.FirTransformer abstract class FirAbstractBodyResolveTransformerDispatcher( @@ -33,7 +23,6 @@ abstract class FirAbstractBodyResolveTransformerDispatcher( val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve, outerBodyResolveContext: BodyResolveContext? = null, val firTowerDataContextCollector: FirTowerDataContextCollector? = null, - val firProviderInterceptor: FirProviderInterceptor? = null, ) : FirAbstractBodyResolveTransformer(phase) { final override val context: BodyResolveContext = diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index 8fc02b0fb83..eb9b1dcac1e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve @@ -19,8 +18,7 @@ open class FirBodyResolveTransformer( scopeSession: ScopeSession, returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve, outerBodyResolveContext: BodyResolveContext? = null, - firTowerDataContextCollector: FirTowerDataContextCollector? = null, - firProviderInterceptor: FirProviderInterceptor? = null, + firTowerDataContextCollector: FirTowerDataContextCollector? = null ) : FirAbstractBodyResolveTransformerDispatcher( session, phase, @@ -28,8 +26,7 @@ open class FirBodyResolveTransformer( scopeSession, returnTypeCalculator, outerBodyResolveContext, - firTowerDataContextCollector, - firProviderInterceptor, + firTowerDataContextCollector ) { final override val expressionsTransformer = FirExpressionsResolveTransformer(this) final override val declarationsTransformer = FirDeclarationsResolveTransformer(this) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 2ac3c150577..6a2a8b0f25c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -493,13 +493,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement = whileAnalysing(session, regularClass) { return context.withContainingClass(regularClass) { if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) { - return regularClass.runAllPhasesForLocalClass( - transformer, - components, - data, - transformer.firTowerDataContextCollector, - transformer.firProviderInterceptor - ) + return regularClass.runAllPhasesForLocalClass(transformer, components, data, transformer.firTowerDataContextCollector) } doTransformTypeParameters(regularClass) @@ -519,13 +513,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve override fun transformTypeAlias(typeAlias: FirTypeAlias, data: ResolutionMode): FirTypeAlias = whileAnalysing(session, typeAlias) { if (typeAlias.isLocal && typeAlias !in context.targetedLocalClasses) { - return typeAlias.runAllPhasesForLocalClass( - transformer, - components, - data, - transformer.firTowerDataContextCollector, - transformer.firProviderInterceptor - ) + return typeAlias.runAllPhasesForLocalClass(transformer, components, data, transformer.firTowerDataContextCollector) } doTransformTypeParameters(typeAlias) typeAlias.transformAnnotations(transformer, data) @@ -554,13 +542,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve data: ResolutionMode ): FirStatement = whileAnalysing(session, anonymousObject) { if (anonymousObject !in context.targetedLocalClasses) { - return anonymousObject.runAllPhasesForLocalClass( - transformer, - components, - data, - transformer.firTowerDataContextCollector, - transformer.firProviderInterceptor - ) + return anonymousObject.runAllPhasesForLocalClass(transformer, components, data, transformer.firTowerDataContextCollector) } // TODO: why would there be a graph already? val buildGraph = !implicitTypeOnly && anonymousObject.controlFlowGraphReference == null diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt index 95917bce13f..994bdde957e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.createCurrentScopeList -import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor import org.jetbrains.kotlin.fir.resolve.transformers.plugin.runCompilerRequiredAnnotationsResolvePhaseForLocalClass import org.jetbrains.kotlin.fir.resolve.transformers.plugin.runCompanionGenerationPhaseForLocalClass import org.jetbrains.kotlin.fir.resolve.transformers.runStatusResolveForLocalClass @@ -19,8 +18,7 @@ fun F.runAllPhasesForLocalClass( transformer: FirAbstractBodyResolveTransformer, components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents, resolutionMode: ResolutionMode, - firTowerDataContextCollector: FirTowerDataContextCollector?, - firProviderInterceptor: FirProviderInterceptor?, + firTowerDataContextCollector: FirTowerDataContextCollector? ): F { if (status is FirResolvedDeclarationStatus) return this if (this is FirRegularClass) { @@ -47,7 +45,6 @@ fun F.runAllPhasesForLocalClass( components.scopeSession, components.createCurrentScopeList(), localClassesNavigationInfo, - firProviderInterceptor, components.file, components.containingDeclarations, )