[LL FIR] LLFirResolveMultiDesignationCollector: simplify code

We can unify all designation calculators and migrate from
`List<LLFirResolveTarget>` to `LLFirResolveTarget`

^KT-65563
This commit is contained in:
Dmitrii Gridin
2024-02-06 17:57:57 +01:00
committed by Space Team
parent c52b9032ce
commit 77c850f0d0
3 changed files with 51 additions and 62 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2024 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.
*/ */
@@ -35,7 +35,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
) { ) {
if (target.resolvePhase >= toPhase) return if (target.resolvePhase >= toPhase) return
lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationsToResolve) lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationToResolve)
} }
/** /**
@@ -50,7 +50,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
scopeSession: ScopeSession, scopeSession: ScopeSession,
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
) { ) {
lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationsToResolveWithCallableMembers) lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationToResolveWithCallableMembers)
} }
/** /**
@@ -65,28 +65,29 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
scopeSession: ScopeSession, scopeSession: ScopeSession,
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
) { ) {
lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationsToResolveRecursively) lazyResolve(target, scopeSession, toPhase, LLFirResolveMultiDesignationCollector::getDesignationToResolveRecursively)
} }
private inline fun <T : FirElementWithResolveState> lazyResolve( private inline fun <T : FirElementWithResolveState> lazyResolve(
target: T, targetElement: T,
scopeSession: ScopeSession, scopeSession: ScopeSession,
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
resolveTargets: (T) -> List<LLFirResolveTarget>, resolveTarget: (T) -> LLFirResolveTarget?,
) { ) {
val fromPhase = target.resolvePhase val fromPhase = targetElement.resolvePhase
try { try {
resolveContainingFileToImports(target) resolveContainingFileToImports(targetElement)
if (toPhase == FirResolvePhase.IMPORTS) return if (toPhase == FirResolvePhase.IMPORTS) return
val target = resolveTarget(targetElement) ?: return
lazyResolveTargets( lazyResolveTargets(
targets = resolveTargets(target), target,
scopeSession = scopeSession, scopeSession,
toPhase = toPhase, toPhase,
towerDataContextCollector = null, towerDataContextCollector = null,
) )
} catch (e: Exception) { } catch (e: Exception) {
handleExceptionFromResolve(e, target, fromPhase, toPhase) handleExceptionFromResolve(e, targetElement, fromPhase, toPhase)
} }
} }
@@ -108,7 +109,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
if (toPhase == FirResolvePhase.IMPORTS) return if (toPhase == FirResolvePhase.IMPORTS) return
lazyResolveTargets( lazyResolveTargets(
targets = listOf(target), target,
moduleComponents.scopeSessionProvider.getScopeSession(), moduleComponents.scopeSessionProvider.getScopeSession(),
toPhase, toPhase,
towerDataContextCollector, towerDataContextCollector,
@@ -131,13 +132,12 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
} }
private fun lazyResolveTargets( private fun lazyResolveTargets(
targets: List<LLFirResolveTarget>, target: LLFirResolveTarget,
scopeSession: ScopeSession, scopeSession: ScopeSession,
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
towerDataContextCollector: FirResolveContextCollector?, towerDataContextCollector: FirResolveContextCollector?,
) { ) {
if (targets.isEmpty()) return var currentPhase = getMinResolvePhase(target).coerceAtLeast(FirResolvePhase.IMPORTS)
var currentPhase = getMinResolvePhase(targets).coerceAtLeast(FirResolvePhase.IMPORTS)
if (currentPhase >= toPhase) return if (currentPhase >= toPhase) return
val lockProvider = moduleComponents.globalResolveComponents.lockProvider val lockProvider = moduleComponents.globalResolveComponents.lockProvider
@@ -149,25 +149,20 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
currentPhase = currentPhase.next currentPhase = currentPhase.next
checkCanceled() checkCanceled()
for (target in targets) { LLFirLazyResolverRunner.runLazyResolverByPhase(
LLFirLazyResolverRunner.runLazyResolverByPhase( currentPhase,
phase = currentPhase, target,
target = target, scopeSession,
scopeSession = scopeSession, lockProvider,
lockProvider = lockProvider, towerDataContextCollector,
towerDataContextCollector = towerDataContextCollector, )
)
}
} }
} }
private fun getMinResolvePhase(designations: List<LLFirResolveTarget>): FirResolvePhase { private fun getMinResolvePhase(designation: LLFirResolveTarget): FirResolvePhase {
var min = FirResolvePhase.BODY_RESOLVE var min = FirResolvePhase.BODY_RESOLVE
for (designation in designations) { designation.forEachTarget { target ->
if (min == FirResolvePhase.RAW_FIR) break min = minOf(min, target.resolvePhase)
designation.forEachTarget { target ->
min = minOf(min, target.resolvePhase)
}
} }
return min return min
@@ -8,12 +8,10 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
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
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignationWithFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
@@ -22,41 +20,37 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAcces
import org.jetbrains.kotlin.fir.isCopyCreatedInScope import org.jetbrains.kotlin.fir.isCopyCreatedInScope
internal object LLFirResolveMultiDesignationCollector { internal object LLFirResolveMultiDesignationCollector {
fun getDesignationsToResolve(target: FirElementWithResolveState): List<LLFirResolveTarget> = when (target) { fun getDesignationToResolve(target: FirElementWithResolveState): LLFirResolveTarget? {
is FirFile -> listOf(FirDesignation(target).asResolveTarget()) return getDesignationToResolve(target, FirDesignation::asResolveTarget)
is FirSyntheticPropertyAccessor, is FirSyntheticProperty -> errorWithFirSpecificEntries("Unsupported element", fir = target)
else -> listOfNotNull(getMainDesignationToResolve(target))
} }
fun getDesignationsToResolveWithCallableMembers(target: FirRegularClass): List<LLFirResolveTarget> { fun getDesignationToResolveWithCallableMembers(target: FirRegularClass): LLFirResolveTarget? {
val designation = target.tryCollectDesignationWithFile() ?: return emptyList() return getDesignationToResolve(target, ::LLFirClassWithAllCallablesResolveTarget)
val resolveTarget = LLFirClassWithAllCallablesResolveTarget(designation)
return listOf(resolveTarget)
} }
fun getDesignationsToResolveRecursively(target: FirElementWithResolveState): List<LLFirResolveTarget> { fun getDesignationToResolveRecursively(target: FirElementWithResolveState): LLFirResolveTarget? {
if (target is FirFile) return listOf(LLFirWholeElementResolveTarget(FirDesignation(target))) return getDesignationToResolve(target, ::LLFirWholeElementResolveTarget)
if (!target.shouldBeResolved()) return emptyList()
if (target is FirCallableDeclaration && target.isCopyCreatedInScope) {
return listOf(FirDesignation(target).asResolveTarget())
}
val designation = target.tryCollectDesignationWithFile() ?: return emptyList()
val resolveTarget = LLFirWholeElementResolveTarget(designation)
return listOf(resolveTarget)
} }
private fun getMainDesignationToResolve(target: FirElementWithResolveState): LLFirSingleResolveTarget? { private fun getDesignationToResolve(
require(target !is FirFile) target: FirElementWithResolveState,
resolveTarget: (FirDesignation) -> LLFirResolveTarget,
): LLFirResolveTarget? {
val designation = getFirDesignationToResolve(target) ?: return null
val llResolveTarget = resolveTarget(designation)
return llResolveTarget
}
private fun getFirDesignationToResolve(target: FirElementWithResolveState): FirDesignation? {
if (!target.shouldBeResolved()) return null if (!target.shouldBeResolved()) return null
return when { return when {
target is FirPropertyAccessor -> getMainDesignationToResolve(target.propertySymbol.fir) target is FirFile || target is FirCallableDeclaration && target.isCopyCreatedInScope -> FirDesignation(target)
target is FirBackingField -> getMainDesignationToResolve(target.propertySymbol.fir) target is FirPropertyAccessor -> getFirDesignationToResolve(target.propertySymbol.fir)
target is FirTypeParameter -> getMainDesignationToResolve(target.containingDeclarationSymbol.fir) target is FirBackingField -> getFirDesignationToResolve(target.propertySymbol.fir)
target is FirValueParameter -> getMainDesignationToResolve(target.containingFunctionSymbol.fir) target is FirTypeParameter -> getFirDesignationToResolve(target.containingDeclarationSymbol.fir)
target is FirCallableDeclaration && target.isCopyCreatedInScope -> FirDesignation(target).asResolveTarget() target is FirValueParameter -> getFirDesignationToResolve(target.containingFunctionSymbol.fir)
else -> target.tryCollectDesignationWithFile()?.asResolveTarget() else -> target.tryCollectDesignationWithFile()
} }
} }
@@ -41,8 +41,8 @@ abstract class AbstractFirLazyDeclarationResolveOverAllPhasesTest : AbstractFirL
testServices.allKtFiles().map(firResolveSession::getOrBuildFirFile) testServices.allKtFiles().map(firResolveSession::getOrBuildFirFile)
} else { } else {
val firFile = firResolveSession.getOrBuildFirFile(ktFile) val firFile = firResolveSession.getOrBuildFirFile(ktFile)
val designations = LLFirResolveMultiDesignationCollector.getDesignationsToResolve(elementToResolve) val designation = LLFirResolveMultiDesignationCollector.getDesignationToResolve(elementToResolve)
listOf(firFile).plus(designations.mapNotNull { it.firFile }).distinct() listOfNotNull(firFile, designation?.firFile).distinct()
} }
val basePhase = elementToResolve.resolvePhase val basePhase = elementToResolve.resolvePhase