[LL FIR] introduce lazyResolveRecursively API
FirFile after KT-56683 has its own phases and resolution logic, so we should have a separate API for lazy resolution for FirFile and for the entire file ^KT-61296 Fixed
This commit is contained in:
committed by
Space Team
parent
b77ae5d275
commit
31b36ee766
+2
-3
@@ -18,8 +18,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilt
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirWholeElementResolveTarget
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.resolve
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedId
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedId
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedValueAnalyzer
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedValueAnalyzer
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CompilationPeerCollector
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CompilationPeerCollector
|
||||||
@@ -51,6 +49,7 @@ import org.jetbrains.kotlin.fir.references.FirReference
|
|||||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
||||||
@@ -291,7 +290,7 @@ internal class KtFirCompilerFacility(
|
|||||||
|
|
||||||
private fun getFullyResolvedFirFile(file: KtFile): FirFile {
|
private fun getFullyResolvedFirFile(file: KtFile): FirFile {
|
||||||
val firFile = file.getOrBuildFirFile(firResolveSession)
|
val firFile = file.getOrBuildFirFile(firResolveSession)
|
||||||
LLFirWholeElementResolveTarget(firFile).resolve(FirResolvePhase.BODY_RESOLVE)
|
firFile.lazyResolveToPhaseRecursively(FirResolvePhase.BODY_RESOLVE)
|
||||||
return firFile
|
return firFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
|||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
@@ -30,9 +29,9 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
|||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedSymbolError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedSymbolError
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedTypeQualifierError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedTypeQualifierError
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
||||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.classId
|
import org.jetbrains.kotlin.fir.types.classId
|
||||||
@@ -59,7 +58,7 @@ internal class KtFirImportOptimizer(
|
|||||||
val existingImports = file.importDirectives
|
val existingImports = file.importDirectives
|
||||||
if (existingImports.isEmpty()) return KtImportOptimizerResult()
|
if (existingImports.isEmpty()) return KtImportOptimizerResult()
|
||||||
|
|
||||||
val firFile = file.getOrBuildFirFile(firResolveSession).apply { lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) }
|
val firFile = file.getOrBuildFirFile(firResolveSession).apply { lazyResolveToPhaseRecursively(FirResolvePhase.BODY_RESOLVE) }
|
||||||
|
|
||||||
val explicitlyImportedFqNames = existingImports
|
val explicitlyImportedFqNames = existingImports
|
||||||
.asSequence()
|
.asSequence()
|
||||||
|
|||||||
+12
@@ -41,4 +41,16 @@ internal class LLFirLazyDeclarationResolver : FirLazyDeclarationResolver() {
|
|||||||
toPhase = toPhase,
|
toPhase = toPhase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun lazyResolveToPhaseRecursively(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {
|
||||||
|
val fir = symbol.fir
|
||||||
|
val session = fir.moduleData.session
|
||||||
|
if (session !is LLFirResolvableModuleSession) return
|
||||||
|
val moduleComponents = session.moduleComponents
|
||||||
|
moduleComponents.firModuleLazyDeclarationResolver.lazyResolveRecursively(
|
||||||
|
target = fir,
|
||||||
|
scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(),
|
||||||
|
toPhase = toPhase,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -16,6 +16,8 @@ class LLFirSingleResolveTarget(
|
|||||||
containerClasses: List<FirRegularClass>,
|
containerClasses: List<FirRegularClass>,
|
||||||
target: FirElementWithResolveState,
|
target: FirElementWithResolveState,
|
||||||
) : LLFirResolveTarget(firFile, containerClasses, target) {
|
) : LLFirResolveTarget(firFile, containerClasses, target) {
|
||||||
|
constructor(firFile: FirFile) : this(firFile, emptyList(), firFile)
|
||||||
|
|
||||||
override fun visitTargetElement(
|
override fun visitTargetElement(
|
||||||
element: FirElementWithResolveState,
|
element: FirElementWithResolveState,
|
||||||
visitor: LLFirResolveTargetVisitor,
|
visitor: LLFirResolveTargetVisitor,
|
||||||
|
|||||||
+2
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
|||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
|
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||||
@@ -85,7 +86,7 @@ internal class FirElementBuilder(
|
|||||||
|
|
||||||
private fun getOrBuildFirForKtFile(ktFile: KtFile): FirFile {
|
private fun getOrBuildFirForKtFile(ktFile: KtFile): FirFile {
|
||||||
val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile)
|
val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile)
|
||||||
firFile.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
firFile.lazyResolveToPhaseRecursively(FirResolvePhase.BODY_RESOLVE)
|
||||||
return firFile
|
return firFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+31
-25
@@ -31,7 +31,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
|||||||
*
|
*
|
||||||
* Might resolve additional required declarations.
|
* Might resolve additional required declarations.
|
||||||
*
|
*
|
||||||
* Resolution is performed under the lock specific to each declaration which is going to be resolved.
|
* Resolution is performed under the lock specific to each declaration that is going to be resolved.
|
||||||
*
|
*
|
||||||
* Suitable for body resolve or/and on-air resolve.
|
* Suitable for body resolve or/and on-air resolve.
|
||||||
*/
|
*/
|
||||||
@@ -40,28 +40,8 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
|||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
toPhase: FirResolvePhase,
|
toPhase: FirResolvePhase,
|
||||||
) {
|
) {
|
||||||
val fromPhase = target.resolvePhase
|
if (target.resolvePhase >= toPhase) return
|
||||||
|
lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationsToResolve)
|
||||||
/**
|
|
||||||
* Currently [lazyResolve] on file means [LLFirWholeElementResolveTarget], but also [FirFile] itself
|
|
||||||
* has [resolvePhase] which does not match with the entire file resolution state.
|
|
||||||
* This additional [FirFile] condition can be dropped after KT-61296
|
|
||||||
*/
|
|
||||||
if (target !is FirFile && fromPhase >= toPhase) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
resolveContainingFileToImports(target)
|
|
||||||
if (toPhase == FirResolvePhase.IMPORTS) return
|
|
||||||
|
|
||||||
lazyResolveTargets(
|
|
||||||
targets = LLFirResolveMultiDesignationCollector.getDesignationsToResolve(target),
|
|
||||||
scopeSession = scopeSession,
|
|
||||||
toPhase = toPhase,
|
|
||||||
towerDataContextCollector = null,
|
|
||||||
)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
handleExceptionFromResolve(e, target, fromPhase, toPhase)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,7 +49,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
|||||||
*
|
*
|
||||||
* Might resolve additional required declarations.
|
* Might resolve additional required declarations.
|
||||||
*
|
*
|
||||||
* Resolution is performed under the lock specific to each declaration which is going to be resolved.
|
* Resolution is performed under the lock specific to each declaration that is going to be resolved.
|
||||||
*
|
*
|
||||||
* Suitable for body resolve or/and on-air resolve.
|
* Suitable for body resolve or/and on-air resolve.
|
||||||
*/
|
*/
|
||||||
@@ -77,6 +57,32 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
|||||||
target: FirRegularClass,
|
target: FirRegularClass,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
toPhase: FirResolvePhase,
|
toPhase: FirResolvePhase,
|
||||||
|
) {
|
||||||
|
lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationsToResolveWithCallableMembers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazily resolves the [target] with nested declarations to a given [toPhase] recursively.
|
||||||
|
*
|
||||||
|
* Might resolve additional required declarations.
|
||||||
|
*
|
||||||
|
* Resolution is performed under the lock specific to each declaration that is going to be resolved.
|
||||||
|
*
|
||||||
|
* Suitable for body resolve or/and on-air resolve.
|
||||||
|
*/
|
||||||
|
fun lazyResolveRecursively(
|
||||||
|
target: FirElementWithResolveState,
|
||||||
|
scopeSession: ScopeSession,
|
||||||
|
toPhase: FirResolvePhase,
|
||||||
|
) {
|
||||||
|
lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationsToResolveRecursively)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <T : FirElementWithResolveState> lazyResolve(
|
||||||
|
target: T,
|
||||||
|
scopeSession: ScopeSession,
|
||||||
|
toPhase: FirResolvePhase,
|
||||||
|
resolveTargets: (T) -> List<LLFirResolveTarget>,
|
||||||
) {
|
) {
|
||||||
val fromPhase = target.resolvePhase
|
val fromPhase = target.resolvePhase
|
||||||
try {
|
try {
|
||||||
@@ -84,7 +90,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
|||||||
if (toPhase == FirResolvePhase.IMPORTS) return
|
if (toPhase == FirResolvePhase.IMPORTS) return
|
||||||
|
|
||||||
lazyResolveTargets(
|
lazyResolveTargets(
|
||||||
targets = LLFirResolveMultiDesignationCollector.getDesignationsToResolveWithCallableMembers(target),
|
targets = resolveTargets(target),
|
||||||
scopeSession = scopeSession,
|
scopeSession = scopeSession,
|
||||||
toPhase = toPhase,
|
toPhase = toPhase,
|
||||||
towerDataContextCollector = null,
|
towerDataContextCollector = null,
|
||||||
|
|||||||
+13
-6
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignationWithFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignationWithFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirClassWithAllCallablesResolveTarget
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirClassWithAllCallablesResolveTarget
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
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.api.targets.LLFirWholeElementResolveTarget
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.asResolveTarget
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.asResolveTarget
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||||
@@ -19,12 +20,10 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
|||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
||||||
|
|
||||||
internal object LLFirResolveMultiDesignationCollector {
|
internal object LLFirResolveMultiDesignationCollector {
|
||||||
fun getDesignationsToResolve(target: FirElementWithResolveState): List<LLFirResolveTarget> {
|
fun getDesignationsToResolve(target: FirElementWithResolveState): List<LLFirResolveTarget> = when (target) {
|
||||||
return when (target) {
|
is FirFile -> listOf(LLFirSingleResolveTarget(target))
|
||||||
is FirFile -> listOf(LLFirWholeElementResolveTarget(target))
|
else -> getMainDesignationToResolve(target)?.withAnnotationContainer()
|
||||||
else -> getMainDesignationToResolve(target)?.withAnnotationContainer()
|
} ?: emptyList()
|
||||||
} ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getDesignationsToResolveWithCallableMembers(target: FirRegularClass): List<LLFirResolveTarget> {
|
fun getDesignationsToResolveWithCallableMembers(target: FirRegularClass): List<LLFirResolveTarget> {
|
||||||
val designation = target.tryCollectDesignationWithFile() ?: return emptyList()
|
val designation = target.tryCollectDesignationWithFile() ?: return emptyList()
|
||||||
@@ -32,6 +31,14 @@ internal object LLFirResolveMultiDesignationCollector {
|
|||||||
return resolveTarget.withAnnotationContainer()
|
return resolveTarget.withAnnotationContainer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getDesignationsToResolveRecursively(target: FirElementWithResolveState): List<LLFirResolveTarget> {
|
||||||
|
if (target is FirFile) return listOf(LLFirWholeElementResolveTarget(target))
|
||||||
|
|
||||||
|
val designation = target.tryCollectDesignationWithFile() ?: return emptyList()
|
||||||
|
val resolveTarget = LLFirWholeElementResolveTarget(designation.firFile, designation.path, target)
|
||||||
|
return resolveTarget.withAnnotationContainer()
|
||||||
|
}
|
||||||
|
|
||||||
private fun LLFirResolveTarget.withAnnotationContainer(): List<LLFirResolveTarget> {
|
private fun LLFirResolveTarget.withAnnotationContainer(): List<LLFirResolveTarget> {
|
||||||
val annotationsContainer = firFile.annotationsContainer
|
val annotationsContainer = firFile.annotationsContainer
|
||||||
if (annotationsContainer?.shouldBeResolved() != true) return listOf(this)
|
if (annotationsContainer?.shouldBeResolved() != true) return listOf(this)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
RAW_FIR:
|
RAW_FIR:
|
||||||
FILE: [ResolvedTo(IMPORTS)] fileElements.kt
|
FILE: [ResolvedTo(RAW_FIR)] fileElements.kt
|
||||||
@FILE:Deprecated[Unresolved](LAZY_EXPRESSION)
|
@FILE:Deprecated[Unresolved](LAZY_EXPRESSION)
|
||||||
@FILE:Anno[Unresolved](LAZY_EXPRESSION)
|
@FILE:Anno[Unresolved](LAZY_EXPRESSION)
|
||||||
[ResolvedTo(RAW_FIR)] annotations container
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
|||||||
+1
-5
@@ -51,11 +51,7 @@ abstract class AbstractFirLazyDeclarationResolveTest : AbstractFirLazyDeclaratio
|
|||||||
val session = firResolveSession.useSiteFirSession as LLFirResolvableModuleSession
|
val session = firResolveSession.useSiteFirSession as LLFirResolvableModuleSession
|
||||||
val file = session.moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile)
|
val file = session.moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile)
|
||||||
file to fun(phase: FirResolvePhase) {
|
file to fun(phase: FirResolvePhase) {
|
||||||
session.moduleComponents.firModuleLazyDeclarationResolver.lazyResolveTarget(
|
file.lazyResolveToPhase(phase)
|
||||||
LLFirSingleResolveTarget(file, emptyList(), file),
|
|
||||||
phase,
|
|
||||||
towerDataContextCollector = null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|||||||
+2
-2
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
|||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirScriptSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirScriptSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||||
@@ -83,7 +83,7 @@ abstract class AbstractFirLazyDeclarationResolveTestCase : AbstractLowLevelApiSi
|
|||||||
resolveWithClearCaches(ktFile) { llSession ->
|
resolveWithClearCaches(ktFile) { llSession ->
|
||||||
checkSession(llSession)
|
checkSession(llSession)
|
||||||
val firFile = llSession.getOrBuildFirFile(ktFile)
|
val firFile = llSession.getOrBuildFirFile(ktFile)
|
||||||
firFile.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
firFile.lazyResolveToPhaseRecursively(FirResolvePhase.BODY_RESOLVE)
|
||||||
if (resultBuilder.isNotEmpty()) {
|
if (resultBuilder.isNotEmpty()) {
|
||||||
resultBuilder.appendLine()
|
resultBuilder.appendLine()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
|
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
|
||||||
@@ -64,7 +64,7 @@ class SealedClassesInheritorsCaclulatorPreAnalysisHandler(
|
|||||||
firFiles: List<FirFile>,
|
firFiles: List<FirFile>,
|
||||||
tmpFirResolveSession: LLFirResolveSession
|
tmpFirResolveSession: LLFirResolveSession
|
||||||
): Map<ClassId, List<ClassId>> {
|
): Map<ClassId, List<ClassId>> {
|
||||||
firFiles.forEach { it.lazyResolveToPhase(FirResolvePhase.TYPES) }
|
firFiles.forEach { it.lazyResolveToPhaseRecursively(FirResolvePhase.TYPES) }
|
||||||
val inheritorsCollector = FirSealedClassInheritorsProcessor.InheritorsCollector(tmpFirResolveSession.useSiteFirSession)
|
val inheritorsCollector = FirSealedClassInheritorsProcessor.InheritorsCollector(tmpFirResolveSession.useSiteFirSession)
|
||||||
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
|
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
|
||||||
firFiles.forEach { it.accept(inheritorsCollector, sealedClassInheritorsMap) }
|
firFiles.forEach { it.accept(inheritorsCollector, sealedClassInheritorsMap) }
|
||||||
|
|||||||
+3
-3
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerPro
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
||||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||||
@@ -70,7 +70,7 @@ internal fun testInBlockModification(
|
|||||||
val declaration = elementToModify.getNonLocalContainingOrThisDeclaration() ?: file
|
val declaration = elementToModify.getNonLocalContainingOrThisDeclaration() ?: file
|
||||||
val firDeclarationBefore = declaration.getOrBuildFirOfType<FirDeclaration>(firSession)
|
val firDeclarationBefore = declaration.getOrBuildFirOfType<FirDeclaration>(firSession)
|
||||||
val declarationToRender = if (dumpFirFile) {
|
val declarationToRender = if (dumpFirFile) {
|
||||||
file.getOrBuildFirFile(firSession).also { it.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) }
|
file.getOrBuildFirFile(firSession).also { it.lazyResolveToPhaseRecursively(FirResolvePhase.BODY_RESOLVE) }
|
||||||
} else {
|
} else {
|
||||||
firDeclarationBefore
|
firDeclarationBefore
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ internal fun testInBlockModification(
|
|||||||
val textAfter = if (dumpFirFile) {
|
val textAfter = if (dumpFirFile) {
|
||||||
// we should resolve the entire file instead of the declaration to be sure that this declaration will be
|
// we should resolve the entire file instead of the declaration to be sure that this declaration will be
|
||||||
// resolved by file resolution as well
|
// resolved by file resolution as well
|
||||||
declarationToRender.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
declarationToRender.lazyResolveToPhaseRecursively(FirResolvePhase.BODY_RESOLVE)
|
||||||
declarationToRender.render()
|
declarationToRender.render()
|
||||||
} else {
|
} else {
|
||||||
declaration.getOrBuildFirOfType<FirDeclaration>(firSession)
|
declaration.getOrBuildFirOfType<FirDeclaration>(firSession)
|
||||||
|
|||||||
+1
@@ -16,4 +16,5 @@ object FirDummyCompilerLazyDeclarationResolver : FirLazyDeclarationResolver() {
|
|||||||
|
|
||||||
override fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {}
|
override fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {}
|
||||||
override fun lazyResolveToPhaseWithCallableMembers(symbol: FirClassSymbol<*>, toPhase: FirResolvePhase) {}
|
override fun lazyResolveToPhaseWithCallableMembers(symbol: FirClassSymbol<*>, toPhase: FirResolvePhase) {}
|
||||||
|
override fun lazyResolveToPhaseRecursively(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-1
@@ -40,8 +40,20 @@ abstract class FirLazyDeclarationResolver : FirSessionComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
|
*/
|
||||||
abstract fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase)
|
abstract fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseWithCallableMembers
|
||||||
|
*/
|
||||||
abstract fun lazyResolveToPhaseWithCallableMembers(symbol: FirClassSymbol<*>, toPhase: FirResolvePhase)
|
abstract fun lazyResolveToPhaseWithCallableMembers(symbol: FirClassSymbol<*>, toPhase: FirResolvePhase)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
||||||
|
*/
|
||||||
|
abstract fun lazyResolveToPhaseRecursively(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FirLazyResolveContractViolationException(
|
class FirLazyResolveContractViolationException(
|
||||||
@@ -104,7 +116,6 @@ fun FirDeclaration.lazyResolveToPhase(toPhase: FirResolvePhase) {
|
|||||||
*
|
*
|
||||||
* @see lazyResolveToPhase
|
* @see lazyResolveToPhase
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fun FirClassSymbol<*>.lazyResolveToPhaseWithCallableMembers(toPhase: FirResolvePhase) {
|
fun FirClassSymbol<*>.lazyResolveToPhaseWithCallableMembers(toPhase: FirResolvePhase) {
|
||||||
fir.lazyDeclarationResolver.lazyResolveToPhaseWithCallableMembers(this, toPhase)
|
fir.lazyDeclarationResolver.lazyResolveToPhaseWithCallableMembers(this, toPhase)
|
||||||
}
|
}
|
||||||
@@ -117,3 +128,31 @@ fun FirClassSymbol<*>.lazyResolveToPhaseWithCallableMembers(toPhase: FirResolveP
|
|||||||
fun FirClass.lazyResolveToPhaseWithCallableMembers(toPhase: FirResolvePhase) {
|
fun FirClass.lazyResolveToPhaseWithCallableMembers(toPhase: FirResolvePhase) {
|
||||||
symbol.lazyResolveToPhaseWithCallableMembers(toPhase)
|
symbol.lazyResolveToPhaseWithCallableMembers(toPhase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazy resolve [FirBasedSymbol] and all nested declarations to [FirResolvePhase].
|
||||||
|
*
|
||||||
|
* In the case of lazy resolution (inside Analysis API), it checks that the declaration phase `>= toPhase`.
|
||||||
|
* If not, it resolves the declaration for the requested phase.
|
||||||
|
*
|
||||||
|
* If the [lazyResolveToPhase] is called inside a fir transformer,
|
||||||
|
* it should always request the phase which is strictly lower than the current transformer phase,
|
||||||
|
* otherwise a deadlock/StackOverflow is possible.
|
||||||
|
*
|
||||||
|
* For the compiler mode, it does nothing, as the compiler is non-lazy.
|
||||||
|
*
|
||||||
|
* @receiver [FirBasedSymbol] which should be resolved
|
||||||
|
* @param toPhase the minimum phase, the declaration and all nested declarations should be resolved to after an execution of the [lazyResolveToPhase]
|
||||||
|
*/
|
||||||
|
fun FirBasedSymbol<*>.lazyResolveToPhaseRecursively(toPhase: FirResolvePhase) {
|
||||||
|
fir.lazyDeclarationResolver.lazyResolveToPhaseRecursively(this, toPhase)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazy resolve [FirDeclaration] and all nested declarations to [FirResolvePhase].
|
||||||
|
*
|
||||||
|
* @see lazyResolveToPhaseRecursively
|
||||||
|
*/
|
||||||
|
fun FirDeclaration.lazyResolveToPhaseRecursively(toPhase: FirResolvePhase) {
|
||||||
|
symbol.lazyResolveToPhaseRecursively(toPhase)
|
||||||
|
}
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_REVERSED_RESOLVE
|
// IGNORE_REVERSED_RESOLVE
|
||||||
// IGNORE_CONTRACT_VIOLATIONS
|
|
||||||
// FIR_IDENTICAL
|
// FIR_IDENTICAL
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
@Repeatable
|
@Repeatable
|
||||||
|
|||||||
+4
@@ -28,6 +28,10 @@ class FirCompilerLazyDeclarationResolverWithPhaseChecking : FirLazyDeclarationRe
|
|||||||
checkIfCanLazyResolveToPhase(toPhase)
|
checkIfCanLazyResolveToPhase(toPhase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun lazyResolveToPhaseRecursively(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {
|
||||||
|
checkIfCanLazyResolveToPhase(toPhase)
|
||||||
|
}
|
||||||
|
|
||||||
override fun startResolvingPhase(phase: FirResolvePhase) {
|
override fun startResolvingPhase(phase: FirResolvePhase) {
|
||||||
check(currentTransformerPhase == null)
|
check(currentTransformerPhase == null)
|
||||||
currentTransformerPhase = phase
|
currentTransformerPhase = phase
|
||||||
|
|||||||
Reference in New Issue
Block a user