diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt index 0ca5eadd872..ea6d21812e8 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProviderByJavaPsi import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFile @OptIn(KtAnalysisApiInternals::class, KtAnalysisNonPublicApi::class) @Suppress("LeakingThis") @@ -79,8 +78,4 @@ class KtFe10AnalysisSession( @Suppress("AnalysisApiMissingLifetimeCheck") override val substitutorProviderImpl: KtSubstitutorProvider get() = throw NotSupportedForK1Exception() - - @Suppress("OVERRIDE_DEPRECATION") - override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession = - KtFe10AnalysisSession(originalKtFile.project, elementToReanalyze, token) } 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 7214c949eb1..36dad6ad395 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,7 +18,6 @@ import org.jetbrains.kotlin.analysis.api.impl.base.components.KtAnalysisScopePro import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.LLFirResolveExtensionTool import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.llResolveExtensionTool import org.jetbrains.kotlin.analysis.project.structure.KtModule @@ -35,8 +34,6 @@ 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 -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.utils.addIfNotNull @OptIn(KtAnalysisApiInternals::class, KtAnalysisNonPublicApi::class) @@ -135,26 +132,6 @@ private constructor( override val substitutorProviderImpl: KtSubstitutorProvider = KtFirSubstitutorProvider(this) - @Suppress("AnalysisApiMissingLifetimeCheck", "OVERRIDE_DEPRECATION") - override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession { - check(mode == AnalysisSessionMode.REGULAR) { - "Cannot create context-dependent copy of KtAnalysis session from a context dependent one" - } - - val contextFirResolveSession = LowLevelFirApiFacadeForResolveOnAir.getFirResolveSessionForDependentCopy( - originalFirResolveSession = firResolveSession, - originalKtFile = originalKtFile, - elementToAnalyze = elementToReanalyze - ) - - return KtFirAnalysisSession( - project, - contextFirResolveSession, - token, - AnalysisSessionMode.DEPENDENT_COPY - ) - } - internal val useSiteSession: FirSession get() = firResolveSession.useSiteFirSession internal val firSymbolProvider: FirSymbolProvider get() = useSiteSession.symbolProvider internal val targetPlatform: TargetPlatform get() = useSiteSession.moduleData.platform diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt index e00d4225297..49c02c71dd1 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt @@ -13,8 +13,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFile /** * [KtAnalysisSession] is the entry point to all frontend-related work. It has the following contracts: @@ -100,15 +98,6 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke override val analysisSession: KtAnalysisSession get() = this - /** - * Creates a new [KtAnalysisSession] which depends on this analysis session, but additionally provides its own symbols derived from - * analyzing [elementToReanalyze]. - * - * @see analyzeInDependedAnalysisSession - */ - @Deprecated("On-air analysis is obsolete. Use 'analyzeCopy()' instead") - public abstract fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession - internal val smartCastProvider: KtSmartCastProvider get() = smartCastProviderImpl protected abstract val smartCastProviderImpl: KtSmartCastProvider diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/analyze.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/analyze.kt index 6202b9df6a1..11723b4a94a 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/analyze.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/analyze.kt @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.KtModuleStructureInternals import org.jetbrains.kotlin.analysis.project.structure.withDanglingFileResolutionMode import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFile /** * Executes the given [action] in a [KtAnalysisSession] context. @@ -46,32 +45,6 @@ public inline fun analyze( return sessionProvider.analyze(useSiteKtModule, action) } -/** - * Executes the given [action] in the context of a [KtAnalysisSession] that depends on an original analysis session determined by - * [originalFile]. In addition to the symbols provided by the original analysis session, the dependent analysis session provides its own - * symbols derived from analyzing [elementToReanalyze]. This allows analyzing some new or copied (and modified) element in the larger - * context of the original analysis session. - * - * @see KtAnalysisSession.createContextDependentCopy - */ -@Deprecated( - "On-air analysis is obsolete. Use 'analyzeCopy()' instead", - ReplaceWith( - "analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE.SELF)", - imports = [ - "org.jetbrains.kotlin.analysis.api.analyzeCopy", - "org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode" - ] - ) -) -public inline fun analyzeInDependedAnalysisSession( - @Suppress("unused", "UNUSED_PARAMETER") originalFile: KtFile, - elementToReanalyze: KtElement, - crossinline action: KtAnalysisSession.() -> R -): R { - return analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE_SELF, action) -} - /** * Executes the given [action] in a [KtAnalysisSession] context. * Depending on the passed [resolutionMode], declarations inside a file copy will be treated in a specific way. diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/session/KtAnalysisSessionProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/session/KtAnalysisSessionProvider.kt index 9f82f10dceb..b5c324004df 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/session/KtAnalysisSessionProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/session/KtAnalysisSessionProvider.kt @@ -39,24 +39,6 @@ public abstract class KtAnalysisSessionProvider(public val project: Project) : D public abstract fun getAnalysisSessionByUseSiteKtModule(useSiteKtModule: KtModule): KtAnalysisSession - @Deprecated( - "On-air analysis is obsolete. Use 'analyzeCopy()' instead", - replaceWith = ReplaceWith( - "analyzeCopy(elementToReanalyze, DanglingFileAnalysisMode.IGNORE_SELF, action)", - imports = [ - "org.jetbrains.kotlin.analysis.api.analyzeCopy", - "org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode" - ] - ) - ) - public inline fun analyseInDependedAnalysisSession( - @Suppress("unused", "UNUSED_PARAMETER") originalFile: KtFile, - elementToReanalyze: KtElement, - crossinline action: KtAnalysisSession.() -> R, - ): R { - return analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE_SELF, action) - } - public inline fun analyse( useSiteKtElement: KtElement, action: KtAnalysisSession.() -> R, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveSessionDepended.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveSessionDepended.kt deleted file mode 100644 index 2913a900052..00000000000 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveSessionDepended.kt +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.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.LLFirResolveSession -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.file.structure.KtToFirMapping -import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession -import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLDiagnosticProvider -import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableResolveSession -import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLScopeSessionProvider -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.originalDeclaration -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 - -/** - * An [LLFirResolveSession] which *depends* on an [originalFirResolveSession], but can provide its own FIR elements and symbols selectively. - * The dependent session mostly provides FIR elements and symbols from the original resolve session, but additionally provides FIR elements - * (and their associated symbols) from its own [ktToFirMapping]. - * - * [LLFirResolveSessionDepended] is used by on-air resolve to provide FIR elements for a copied declaration in the larger context of the - * original resolve session. - */ -internal class LLFirResolveSessionDepended( - val originalFirResolveSession: LLFirResolvableResolveSession, - val towerProviderBuiltUponElement: FirTowerContextProvider, - private val ktToFirMapping: KtToFirMapping?, -) : LLFirResolveSession( - originalFirResolveSession.moduleProvider, - originalFirResolveSession.resolutionStrategyProvider, - originalFirResolveSession.sessionProvider, - LLDependedScopeSessionProvider(originalFirResolveSession.project), - LLDependedDiagnosticProvider -) { - override fun getOrBuildFirFor(element: KtElement): FirElement? { - val psi = FirElementBuilder.getPsiAsFirElementSource(element) ?: return null - ktToFirMapping?.getFir(psi)?.let { return it } - return originalFirResolveSession.getOrBuildFirFor(element = element) - } - - override fun getOrBuildFirFile(ktFile: KtFile): FirFile = - originalFirResolveSession.getOrBuildFirFile(ktFile) - - override fun resolveFirToPhase(declaration: FirDeclaration, toPhase: FirResolvePhase) { - originalFirResolveSession.resolveFirToPhase(declaration, toPhase) - } - - override fun resolveToFirSymbol(ktDeclaration: KtDeclaration, phase: FirResolvePhase): FirBasedSymbol<*> { - val declarationToResolve = ktDeclaration.originalDeclaration ?: ktDeclaration - ktToFirMapping?.getElement(declarationToResolve)?.let { it as? FirDeclaration }?.symbol?.let { return it } - - return originalFirResolveSession.resolveToFirSymbol(declarationToResolve, phase) - } - - override fun getTowerContextProvider(ktFile: KtFile): FirTowerContextProvider = - TowerProviderForElementForState(this) -} - -private object LLDependedDiagnosticProvider : LLDiagnosticProvider { - override fun collectDiagnostics(file: KtFile, filter: DiagnosticCheckerFilter): List { - throw NotImplementedError("Diagnostics are not implemented for depended state") - } - - override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List { - throw NotImplementedError("Diagnostics are not implemented for depended state") - } -} - -private class LLDependedScopeSessionProvider(private val project: Project) : LLScopeSessionProvider { - private val scopeSessionProviderCache = SoftCachedMap.create( - project, - SoftCachedMap.Kind.SOFT_KEYS_SOFT_VALUES, - listOf( - PsiModificationTracker.MODIFICATION_COUNT, - ProjectRootModificationTracker.getInstance(project) - ) - ) - - override fun getScopeSession(session: LLFirSession): ScopeSession { - return scopeSessionProviderCache - .getOrPut(session) { LLFirScopeSessionProvider.create(project, invalidationTrackers = emptyList()) } - .getScopeSession() - } -} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt index d572eed5fcd..3d89b915345 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt @@ -82,8 +82,6 @@ abstract class LLFirResolveSession( abstract fun resolveToFirSymbol(ktDeclaration: KtDeclaration, phase: FirResolvePhase): FirBasedSymbol<*> internal abstract fun resolveFirToPhase(declaration: FirDeclaration, toPhase: FirResolvePhase) - - abstract fun getTowerContextProvider(ktFile: KtFile): FirTowerContextProvider } fun LLFirResolveSession.getModule(element: PsiElement): KtModule { 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 deleted file mode 100644 index 69bd5ee1cde..00000000000 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright 2010-2023 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.api - -import com.intellij.psi.PsiElement -import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionDepended -import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FileTowerProvider -import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider -import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerDataContextAllElementsCollector -import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration -import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.isAutonomousDeclaration -import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.KtToFirMapping -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.RawFirNonLocalDeclarationBuilder -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.RawFirReplacement -import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.buildFileFirAnnotation -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.sessions.llFirSession -import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableResolveSession -import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder -import org.jetbrains.kotlin.analysis.low.level.api.fir.util.codeFragment -import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries -import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isElementWhichShouldBeResolvedAsPartOfScript -import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration -import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalKtFile -import org.jetbrains.kotlin.analysis.utils.printer.parentOfType -import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType -import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.builder.buildFileAnnotationsContainer -import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.expressions.FirAnnotation -import org.jetbrains.kotlin.fir.realPsi -import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector -import org.jetbrains.kotlin.fir.scopes.createImportingScopes -import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider -import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry -import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType -import org.jetbrains.kotlin.psi.psiUtil.isAncestor -import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf -import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment -import org.jetbrains.kotlin.utils.exceptions.withPsiEntry - -object LowLevelFirApiFacadeForResolveOnAir { - private fun KtDeclaration.isApplicableForOnAirResolve(): Boolean = when (this) { - is KtDestructuringDeclaration -> false - else -> true - } - - private fun PsiElement.getNonLocalContainingOrThisDeclarationCodeFragmentAware(predicate: (KtDeclaration) -> Boolean): KtAnnotated? { - return getNonLocalContainingOrThisDeclaration(predicate) ?: containingFile as? KtCodeFragment - } - - private fun PsiElement.onAirGetNonLocalContainingOrThisDeclaration(): KtElement? { - return getNonLocalContainingOrThisDeclarationCodeFragmentAware { declaration -> - declaration.isApplicableForOnAirResolve() && declaration.isAutonomousDeclaration - } - } - - private fun recordOriginalDeclaration(targetDeclaration: KtDeclaration, originalDeclaration: KtDeclaration) { - require(originalDeclaration.containingKtFile !== targetDeclaration.containingKtFile) - val originalDeclarationParents = originalDeclaration.parentsOfType().toList() - val fakeDeclarationParents = targetDeclaration.parentsOfType().toList() - originalDeclarationParents.zip(fakeDeclarationParents) { original, fake -> - fake.originalDeclaration = original - } - - /** - * We assume that [targetDeclaration] should have the same number of declarations - * - * @see restoreOriginalDeclarationsInScript - */ - if (targetDeclaration is KtScript && originalDeclaration is KtScript) { - val originalStatements = originalDeclaration.declarationSequence() - val newStatements = targetDeclaration.declarationSequence() - originalStatements.zip(newStatements) { original, fake -> - fake.originalDeclaration = original - } - } - } - - private fun KtScript.declarationSequence(): Sequence { - val sequence = blockExpression.statements.asSequence().filter { it !is KtScriptInitializer && it is KtDeclaration } - @Suppress("UNCHECKED_CAST") - return sequence as Sequence - } - - fun onAirResolveElement( - firResolveSession: LLFirResolveSession, - place: T, - elementToResolve: T, - ): FirElement { - require(firResolveSession is LLFirResolvableResolveSession) - - val declaration = runBodyResolveOnAir( - firResolveSession = firResolveSession, - originalPlace = place, - replacementElement = elementToResolve, - collector = null, - ) - - val expressionLocator = object : FirVisitorVoid() { - var result: FirElement? = null - private set - - override fun visitElement(element: FirElement) { - if (element.realPsi == elementToResolve) result = element - if (result != null) return - element.acceptChildren(this) - } - } - - declaration.accept(expressionLocator) - return expressionLocator.result ?: errorWithFirSpecificEntries("Resolved on-air element was not found in containing declaration") { - withPsiEntry("place", place) - withPsiEntry("elementToResolve", elementToResolve) - } - } - - fun getOnAirTowerDataContextProviderForTheWholeFile( - firResolveSession: LLFirResolveSession, - ktFile: KtFile, - ): FirTowerContextProvider { - val ktModule = firResolveSession.getModule(ktFile) - val session = firResolveSession.getSessionFor(ktModule) as LLFirResolvableModuleSession - val moduleComponents = session.moduleComponents - - val onAirFirFile = RawFirNonLocalDeclarationBuilder.buildNewFile(session, session.kotlinScopeProvider, ktFile) - val collector = FirTowerDataContextAllElementsCollector() - moduleComponents.firModuleLazyDeclarationResolver.runLazyDesignatedOnAirResolve( - FirDesignationWithFile(emptyList(), onAirFirFile, onAirFirFile), - collector, - ) - - return collector - } - - fun getOnAirGetTowerContextProvider( - firResolveSession: LLFirResolveSession, - place: KtElement, - ): FirTowerContextProvider { - require(firResolveSession is LLFirResolvableResolveSession) - - return if (place is KtFile) { - FileTowerProvider(place, onAirGetTowerContextForFile(firResolveSession, place)) - } else { - val validPlace = PsiTreeUtil.findFirstParent(place, false) { - it is KtElement && RawFirReplacement.isApplicableForReplacement(it) - } as KtElement - - FirTowerDataContextAllElementsCollector().also { - runBodyResolveOnAir( - firResolveSession = firResolveSession, - collector = it, - originalPlace = validPlace, - replacementElement = validPlace, - ) - } - } - } - - private fun onAirGetTowerContextForFile( - firResolveSession: LLFirResolvableResolveSession, - file: KtFile, - ): FirTowerDataContext { - val module = firResolveSession.getModule(file) - val session = firResolveSession.getSessionFor(module) as LLFirResolvableModuleSession - val moduleComponents = session.moduleComponents - - val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(file) - - val scopeSession = firResolveSession.getScopeSessionFor(session) - return firFile.createTowerDataContext(scopeSession) - } - - private fun FirFile.createTowerDataContext(scopeSession: ScopeSession): FirTowerDataContext { - val importingScopes = createImportingScopes(this, moduleData.session, scopeSession) - val fileScopeElements = importingScopes.map { it.asTowerDataElement(isLocal = false) } - return FirTowerDataContext().addNonLocalTowerDataElements(fileScopeElements) - } - - /** - * Makes a copy of the original fir declaration and resolves it to the minimum required phase - * depends on [elementToAnalyze] position inside a non-local containing declaration. - * - * If [elementToAnalyze] is non-local declaration then resolves it to [FirResolvePhase.BODY_RESOLVE]. - * - * Resulted [LLFirResolveSession] have [FirTowerDataContext] for elements from the copy. - */ - fun getFirResolveSessionForDependentCopy( - originalFirResolveSession: LLFirResolveSession, - originalKtFile: KtFile, - elementToAnalyze: KtElement, - ): LLFirResolveSession { - require(originalFirResolveSession is LLFirResolvableResolveSession) - require(elementToAnalyze !is KtFile) { "KtFile for dependency element not supported" } - - elementToAnalyze.containingKtFile.originalKtFile = originalKtFile - - val minimalCopiedDeclaration = elementToAnalyze.getNonLocalContainingOrThisDeclarationCodeFragmentAware { - it.isApplicableForOnAirResolve() - } - - val copiedNonLocalDeclaration = minimalCopiedDeclaration?.onAirGetNonLocalContainingOrThisDeclaration() - if (copiedNonLocalDeclaration == null) { - val towerDataContext = onAirGetTowerContextForFile(originalFirResolveSession, originalKtFile) - val fileTowerProvider = FileTowerProvider(elementToAnalyze.containingKtFile, towerDataContext) - return LLFirResolveSessionDepended(originalFirResolveSession, fileTowerProvider, ktToFirMapping = null) - } - - val originalNonLocalDeclaration = PsiTreeUtil.findSameElementInCopy(copiedNonLocalDeclaration, originalKtFile) - ?: errorWithAttachment("Cannot find original function matching") { - withPsiEntry("matchingPsi", elementToAnalyze) - withPsiEntry("originalFile", originalKtFile) - } - - if (copiedNonLocalDeclaration is KtNamedDeclaration && originalNonLocalDeclaration is KtNamedDeclaration) { - recordOriginalDeclaration( - targetDeclaration = copiedNonLocalDeclaration, - originalDeclaration = originalNonLocalDeclaration - ) - } - - val collector = FirTowerDataContextAllElementsCollector() - val copiedFirDeclaration = runBodyResolveOnAir( - originalFirResolveSession, - originalPlace = originalNonLocalDeclaration, - replacementElement = copiedNonLocalDeclaration, - collector = collector, - forcedResolvePhase = requiredResolvePhase(minimalCopiedDeclaration, elementToAnalyze), - ) - - val mapping = KtToFirMapping(copiedFirDeclaration) - return LLFirResolveSessionDepended(originalFirResolveSession, collector, mapping) - } - - private fun tryResolveAsFileAnnotation( - annotationEntry: KtAnnotationEntry, - replacement: RawFirReplacement, - firFile: FirFile, - collector: FirResolveContextCollector? = null, - firResolveSession: LLFirResolvableResolveSession, - ): FirAnnotation { - val annotationCall = buildFileFirAnnotation( - firFile = firFile, - fileAnnotation = annotationEntry, - replacement = replacement, - ) - - val fileAnnotationsContainer = buildFileAnnotationsContainer { - moduleData = firFile.moduleData - containingFileSymbol = firFile.symbol - annotations += annotationCall - } - - val llFirResolvableSession = firFile.llFirResolvableSession - ?: errorWithAttachment("FirFile session expected to be a resolvable session but was ${firFile.llFirSession::class.java}") { - withEntry("firSession", firFile.llFirSession) { it.toString() } - } - - val declarationResolver = llFirResolvableSession.moduleComponents.firModuleLazyDeclarationResolver - declarationResolver.runLazyDesignatedOnAirResolve( - FirDesignationWithFile(path = emptyList(), target = fileAnnotationsContainer, firFile), - collector, - ) - - collector?.addFileContext(firFile, firFile.createTowerDataContext(firResolveSession.getScopeSessionFor(llFirResolvableSession))) - - // We should return annotation from fileAnnotationsContainer because the original annotation can be replaced - return fileAnnotationsContainer.annotations.single() - } - - /** - * Creates a new fir declaration from closer non-local declaration based on [originalPlace] position. - * The resulted [FirResolvePhase] depends on [forcedResolvePhase] or the position of [originalPlace] inside the non-local declaration. - * - * Note: the new declaration and its content won't be rebinded to the original. - * - * @see requiredResolvePhase - */ - private fun runBodyResolveOnAir( - firResolveSession: LLFirResolvableResolveSession, - originalPlace: KtElement, - replacementElement: KtElement, - collector: FirResolveContextCollector?, - forcedResolvePhase: FirResolvePhase? = null, - ): FirElement { - val minimalOriginalDeclarationToReplace = originalPlace.getNonLocalContainingOrThisDeclarationCodeFragmentAware { - it.isApplicableForOnAirResolve() - } - - val originalFirFile = firResolveSession.getOrBuildFirFile(originalPlace.containingKtFile) - - val originalDeclaration = minimalOriginalDeclarationToReplace?.onAirGetNonLocalContainingOrThisDeclaration() - if (originalDeclaration == null) { - //It is possible that it is file annotation is going to resolve - val annotationCall = originalPlace.parentOfType(withSelf = true) - if (annotationCall != null) { - return tryResolveAsFileAnnotation( - annotationEntry = annotationCall, - replacement = RawFirReplacement(from = originalPlace, to = replacementElement), - firFile = originalFirFile, - collector = collector, - firResolveSession = firResolveSession, - ) - } else { - errorWithFirSpecificEntries( - "Cannot find enclosing declaration for ${originalPlace::class.simpleName}", - psi = originalPlace, - ) - } - } - - val originalDesignationPath = computeDesignation(originalDeclaration, originalFirFile) - ?: errorWithFirSpecificEntries(message = "Impossible to collect designation", fir = originalFirFile, psi = originalDeclaration) - - val originalFirDeclaration = originalDesignationPath.target - val session = originalFirDeclaration.llFirResolvableSession - ?: errorWithAttachment("Expected resolvable session, found ${originalFirDeclaration.llFirSession::class}") { - withFirEntry("sessionOwner", originalFirDeclaration) - } - - /** - * Special case for [getOnAirGetTowerContextProvider]. Can be dropped after KT-59498 - */ - val replacement = if (originalPlace === replacementElement) { - RawFirReplacement(from = originalDeclaration, to = originalDeclaration) - } else { - RawFirReplacement(from = originalPlace, to = replacementElement) - } - - val newFirDeclaration = RawFirNonLocalDeclarationBuilder.buildWithReplacement( - session = session, - scopeProvider = session.kotlinScopeProvider, - designation = FirDesignation(originalDesignationPath.path, originalFirDeclaration), - rootNonLocalDeclaration = originalDeclaration, - replacement = replacement, - ) - - /** - * We shouldn't touch script declarations because they're independent of a script - */ - if (newFirDeclaration is FirScript && originalFirDeclaration is FirScript) { - restoreOriginalDeclarationsInScript(originalScript = originalFirDeclaration, newScript = newFirDeclaration) - } - - session.moduleComponents.firModuleLazyDeclarationResolver.runLazyDesignatedOnAirResolve( - FirDesignationWithFile(originalDesignationPath.path, newFirDeclaration, originalFirFile), - collector, - forcedResolvePhase ?: requiredResolvePhase(minimalOriginalDeclarationToReplace, originalPlace), - ) - - return newFirDeclaration - } - - /** - * We assume that [newScript] has the same declarations as [originalScript] - */ - private fun restoreOriginalDeclarationsInScript(originalScript: FirScript, newScript: FirScript) { - val updatedDeclarations = ArrayList(newScript.declarations.size) - val originalDeclarations = originalScript.declarations.iterator() - for (recreatedDeclaration in newScript.declarations) { - updatedDeclarations += if (recreatedDeclaration.isElementWhichShouldBeResolvedAsPartOfScript) { - recreatedDeclaration - } else { - originalDeclarations.nextDeclaration() ?: scriptDeclarationInconsistencyError(originalScript, newScript) - } - } - - val nextDeclaration = originalDeclarations.nextDeclaration() - if (nextDeclaration != null) { - scriptDeclarationInconsistencyError(originalScript, newScript) - } - - newScript.replaceDeclarations(updatedDeclarations) - } - - private fun scriptDeclarationInconsistencyError(originalScript: FirScript, newScript: FirScript): Nothing { - val originalDeclarations = originalScript.declarations.filterNot(FirDeclaration::isElementWhichShouldBeResolvedAsPartOfScript) - val newDeclarations = newScript.declarations.filterNot(FirDeclaration::isElementWhichShouldBeResolvedAsPartOfScript) - errorWithAttachment("New script has ${if (newDeclarations.size > originalDeclarations.size) "more" else "less"} declarations") { - withFirEntry("originalScript", originalScript) - withFirEntry("newScript", newScript) - withEntryGroup("originalDeclarations") { - for ((index, declaration) in originalDeclarations.withIndex()) { - withFirEntry(index.toString(), declaration) - } - } - - withEntryGroup("newDeclarations") { - for ((index, declaration) in newDeclarations.withIndex()) { - withFirEntry(index.toString(), declaration) - } - } - } - } - - private fun Iterator.nextDeclaration(): FirDeclaration? { - while (hasNext()) { - val declaration = next() - if (declaration.isElementWhichShouldBeResolvedAsPartOfScript) continue - - return declaration - } - - return null - } - - private fun computeDesignation(originalDeclaration: KtElement, originalFirFile: FirFile): FirElementFinder.FirDeclarationDesignation? { - if (originalDeclaration is KtCodeFragment) { - val firCodeFragment = originalFirFile.codeFragment - return FirElementFinder.FirDeclarationDesignation(emptyList(), firCodeFragment) - } - - require(originalDeclaration is KtDeclaration) - return FirElementFinder.collectDesignationPath(originalFirFile, originalDeclaration) - } - - private fun requiredResolvePhase( - container: KtAnnotated, - elementToReplace: PsiElement, - ): FirResolvePhase { - assert(container is KtDeclaration || container is KtCodeFragment) - - return when { - container !is KtDeclaration -> FirResolvePhase.BODY_RESOLVE - bodyResolveRequired(container, elementToReplace) -> FirResolvePhase.BODY_RESOLVE - annotationMappingRequired(container, elementToReplace) -> FirResolvePhase.ANNOTATION_ARGUMENTS - else -> { - /** Currently it is a minimal phase there we can collect [FirResolveContextCollector] */ - FirResolvePhase.CONTRACTS - } - } - } - - private fun annotationMappingRequired( - container: KtDeclaration, - elementToReplace: PsiElement, - ): Boolean = elementToReplace.parentsWithSelf.takeWhile { it != container }.any { - it is KtAnnotationEntry - } || elementToReplace.anyDescendantOfType( - canGoInside = { - // We shouldn't go inside a class body, because class resolution won't process such elements - // In case of container is class, we are interested only in elements outside its body - it !is KtClassBody - }, - ) - - private fun bodyResolveRequired(container: KtDeclaration, elementToReplace: PsiElement): Boolean = when { - container == elementToReplace -> true - - container is KtDeclarationWithBody -> { - val bodyExpression = container.bodyExpression - val secondaryConstructorSuperCallArgs = (container as? KtSecondaryConstructor)?.getDelegationCallOrNull()?.valueArgumentList - - bodyExpression.isAncestor(elementToReplace) || secondaryConstructorSuperCallArgs.isAncestor(elementToReplace) - } - - container is KtProperty -> container.delegateExpressionOrInitializer.isAncestor(elementToReplace) - container is KtParameter -> container.defaultValue.isAncestor(elementToReplace) - - container is KtEnumEntry -> { - container.initializerList.isAncestor(elementToReplace) || container.body.isAncestor(elementToReplace) - } - - container is KtClassOrObject -> { - container.superTypeListEntries.any { superTypeEntry -> - when (superTypeEntry) { - is KtSuperTypeCallEntry -> superTypeEntry.valueArgumentList.isAncestor(elementToReplace) - is KtDelegatedSuperTypeEntry -> superTypeEntry.delegateExpression.isAncestor(elementToReplace) - else -> false - } - } - } - - container is KtScript || container is KtAnonymousInitializer -> true - else -> false - } -} 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 db19829241a..8d03e560750 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 @@ -6,14 +6,10 @@ 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.FirDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirSingleResolveTarget -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirWholeElementResolveTarget import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyResolverRunner -import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.withOnAirDesignation 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.fir.FirElementWithResolveState @@ -130,38 +126,6 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod } } - /** - * Resolve on-air created declaration in a context of real [FirDesignationWithFile.firFile] and [FirDesignationWithFile.path]. - * If target declaration is [FirFile] then the entire file will be resolved. - * The same for [FirRegularClass] if [resolvePhase] is [FirResolvePhase.BODY_RESOLVE]. - */ - fun runLazyDesignatedOnAirResolve( - designation: FirDesignationWithFile, - towerDataContextCollector: FirResolveContextCollector?, - resolvePhase: FirResolvePhase = FirResolvePhase.BODY_RESOLVE, - ) { - resolveFileToImportsWithLock(designation.firFile) - - val target = when { - designation.target is FirFile -> LLFirWholeElementResolveTarget(designation.firFile) - resolvePhase == FirResolvePhase.BODY_RESOLVE && designation.target is FirRegularClass -> { - LLFirWholeElementResolveTarget(designation.firFile, designation.path, designation.target) - } - - else -> LLFirSingleResolveTarget(designation.firFile, designation.path, designation.target) - } - - try { - withOnAirDesignation(designation) { - // New session to avoid garbage in the original session - val scopeSession = ScopeSession() - lazyResolveTargets(listOf(target), scopeSession, resolvePhase, towerDataContextCollector) - } - } catch (e: Exception) { - handleExceptionFromResolve(e, target, resolvePhase) - } - } - private fun resolveContainingFileToImports(target: FirElementWithResolveState) { if (target.resolvePhase >= FirResolvePhase.IMPORTS) return val firFile = target.getContainingFile() ?: return 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 70ce8832a72..a22e23fde2e 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,7 +5,6 @@ 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 @@ -20,8 +19,7 @@ internal class LLFirLibrarySessionProvider( override val symbolProvider: FirSymbolProvider ) : FirProvider() { override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? { - return SyntheticFirClassProvider.getInstance(symbolProvider.session).getFirClassifierByFqName(classId) - ?: symbolProvider.getClassLikeSymbolByClassId(classId)?.fir + return 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 93ea7872259..fa996ff0515 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 @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.providers import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession -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.NoMutableState @@ -62,8 +61,9 @@ internal class LLFirProvider( private fun getFirClassifierByFqNameAndDeclaration( classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration?, - ): FirClassLikeDeclaration? = SyntheticFirClassProvider.getInstance(session).getFirClassifierByFqName(classId) - ?: providerHelper.getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration) + ): FirClassLikeDeclaration? { + return providerHelper.getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration) + } override fun getFirClassifierContainerFile(fqName: ClassId): FirFile { return getFirClassifierContainerFileIfAny(fqName) @@ -73,8 +73,7 @@ internal class LLFirProvider( } override fun getFirClassifierContainerFileIfAny(fqName: ClassId): FirFile? { - return SyntheticFirClassProvider.getInstance(session).getFirClassifierContainerFileIfAny(fqName) - ?: getFirClassifierByFqName(fqName)?.let { moduleComponents.cache.getContainerFirFile(it) } + return getFirClassifierByFqName(fqName)?.let { moduleComponents.cache.getContainerFirFile(it) } } override fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile { @@ -85,13 +84,11 @@ internal class LLFirProvider( } override fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? { - return SyntheticFirClassProvider.getInstance(session).getFirClassifierContainerFileIfAny(symbol.classId) - ?: moduleComponents.cache.getContainerFirFile(symbol.fir) + return moduleComponents.cache.getContainerFirFile(symbol.fir) } override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? { - return symbol.callableId.classId?.let { SyntheticFirClassProvider.getInstance(session).getFirClassifierContainerFileIfAny(it) } - ?: moduleComponents.cache.getContainerFirFile(symbol.fir) + return moduleComponents.cache.getContainerFirFile(symbol.fir) } override fun getFirScriptContainerFile(symbol: FirScriptSymbol): FirFile? { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt index 6d5c91f42ec..e4170353534 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.state import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getModule -import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.util.* import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCompiledElementSearcher @@ -131,8 +130,4 @@ internal class LLFirResolvableResolveSession( override fun resolveFirToPhase(declaration: FirDeclaration, toPhase: FirResolvePhase) { declaration.lazyResolveToPhase(toPhase) } - - override fun getTowerContextProvider(ktFile: KtFile): FirTowerContextProvider { - return TowerProviderForElementForState(this) - } } \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/TowerProviderForElementForState.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/TowerProviderForElementForState.kt deleted file mode 100644 index 9724f79599b..00000000000 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/TowerProviderForElementForState.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.state - -import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionDepended -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir -import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider -import org.jetbrains.kotlin.fir.declarations.FirTowerDataContext -import org.jetbrains.kotlin.psi.KtElement - -internal class TowerProviderForElementForState(private val firResolveSession: LLFirResolveSession) : FirTowerContextProvider { - override fun getClosestAvailableParentContext(ktElement: KtElement): FirTowerDataContext? { - if (firResolveSession is LLFirResolveSessionDepended) { - firResolveSession.towerProviderBuiltUponElement - .getClosestAvailableParentContext(ktElement) - ?.let { return it } - - return LowLevelFirApiFacadeForResolveOnAir - .getOnAirGetTowerContextProvider(firResolveSession.originalFirResolveSession, ktElement) - .getClosestAvailableParentContext(ktElement) - } - return LowLevelFirApiFacadeForResolveOnAir - .getOnAirGetTowerContextProvider(firResolveSession, ktElement) - .getClosestAvailableParentContext(ktElement) - } -} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/StateKeeper.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/StateKeeper.kt index df999e7fb90..cc738a98b08 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/StateKeeper.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/StateKeeper.kt @@ -5,12 +5,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers -import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElementWithResolveState -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirDeclaration -import org.jetbrains.kotlin.fir.expressions.FirStatement -import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid @DslMarker internal annotation class StateKeeperDsl @@ -264,15 +259,6 @@ internal inline fun prepareTarget: (Target) -> Unit = {}, action: () -> Result, ): Result { - val onAirAnalysisTarget = target.moduleData.session.onAirAnalysisTarget - if (onAirAnalysisTarget != null && target in onAirAnalysisTarget) { - // Several arrangers reset declaration bodies to lazy ones, and then re-construct the FIR tree from the backing PSI. - // This won't work for on-air analysis, as the tree is manually modified. However, it doesn't seem that tree guards are needed - // in the first place, as results of the on-air analysis aren't going to be shared. - prepareTarget(target) - return action() - } - var preservedState: PreservedState? = null try { @@ -284,26 +270,4 @@ internal inline fun preservedState?.restore() throw e } -} - -private operator fun FirElementWithResolveState.contains(child: FirElementWithResolveState): Boolean { - if (this == child) { - return true - } - - var isFound = false - - accept(object : FirVisitorVoid() { - override fun visitElement(element: FirElement) { - if (!isFound) { - if (element == child) { - isFound = true - } else if (element is FirDeclaration || element !is FirStatement) { - element.acceptChildren(this) - } - } - } - }) - - return isFound } \ No newline at end of file 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 deleted file mode 100644 index c563135351d..00000000000 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/SyntheticFirClassProvider.kt +++ /dev/null @@ -1,91 +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.analysis.low.level.api.fir.api.FirDesignationWithFile -import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.FirElementWithResolveState -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 - -internal interface SyntheticFirClassProvider { - fun getFirClassifierContainerFileIfAny(classId: ClassId): FirFile? - fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? - - companion object { - fun getInstance(session: FirSession): SyntheticFirClassProvider { - return onAirProviderForThread.get()?.takeIf { it.session == session } ?: EmptySyntheticFirClassProvider - } - } -} - -internal val FirSession.onAirAnalysisTarget: FirElementWithResolveState? - get() = onAirProviderForThread.get()?.target - -/** - * Injects a designation-based class file provider to 'LLFirProvider'. - * Used for on-air analysis. - */ -internal fun withOnAirDesignation(designation: FirDesignationWithFile, block: () -> Unit) { - check(onAirProviderForThread.get() == null) { "Nested on-air analysis is not allowed" } - - try { - // Make additional classes available only inside a given `block`. - // The provider is stored inside a `ThreadLocal` value to avoid parallel analysis modification. - val provider = OnAirSyntheticFirClassProvider.create(designation) - onAirProviderForThread.set(provider) - block() - } finally { - onAirProviderForThread.remove() - } -} - -private class OnAirSyntheticFirClassProvider private constructor( - private val firFile: FirFile, - val target: FirElementWithResolveState, - private val classes: Map -) : SyntheticFirClassProvider { - val session: FirSession - get() = firFile.moduleData.session - - 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): OnAirSyntheticFirClassProvider { - 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 OnAirSyntheticFirClassProvider(firFile, designation.target, nodeInfoCollector.classes) - } - } -} - -private object EmptySyntheticFirClassProvider : SyntheticFirClassProvider { - override fun getFirClassifierContainerFileIfAny(classId: ClassId) = null - override fun getFirClassifierByFqName(classId: ClassId) = null -} - -private val onAirProviderForThread: ThreadLocal = ThreadLocal() \ No newline at end of file