[AA FIR] KtFirVisibilityChecker: drop redundant resolve

We can collect a designation path by psi declaration without resolution

^KT-59454 Fixed
This commit is contained in:
Dmitrii Gridin
2023-06-26 17:09:48 +02:00
committed by Space Team
parent ca521a81f8
commit 94d727a9ce
@@ -15,12 +15,10 @@ import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.collectContainingDeclarationsIfNonLocal
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
@@ -30,7 +28,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.publishedApiEffectiveVisibi
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.visibilityChecker
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.utils.addToStdlib.runIf
internal class KtFirVisibilityChecker(
@@ -52,7 +49,7 @@ internal class KtFirVisibilityChecker(
}
val useSiteFirFile = useSiteFile.firSymbol.fir
val containers = collectContainingDeclarations(position)
val containers = position.collectContainingDeclarationsIfNonLocal(analysisSession.firResolveSession).orEmpty()
val dispatchReceiverCanBeExplicit = candidateSymbol is KtCallableSymbol && !candidateSymbol.isExtension
val explicitDispatchReceiver = runIf(dispatchReceiverCanBeExplicit) {
@@ -61,6 +58,7 @@ internal class KtFirVisibilityChecker(
val candidateFirSymbol = candidateSymbol.firSymbol.fir as FirMemberDeclaration
val rootModuleSession = rootModuleSession
return rootModuleSession.visibilityChecker.isVisible(
candidateFirSymbol,
rootModuleSession,
@@ -112,28 +110,4 @@ internal class KtFirVisibilityChecker(
declaration.lazyResolveToPhase(FirResolvePhase.STATUS)
return declaration.effectiveVisibility.publicApi || declaration.publishedApiEffectiveVisibility?.publicApi == true
}
private fun collectContainingDeclarations(position: PsiElement): List<FirDeclaration> {
val nonLocalContainer = findContainingNonLocalDeclaration(position)
val nonLocalContainerFir = nonLocalContainer?.getOrBuildFirSafe<FirDeclaration>(analysisSession.firResolveSession)
?: return emptyList()
val designation = nonLocalContainerFir.collectDesignation()
return designation
.toSequence(includeTarget = true) // we include the starting declaration in case it is a class or an object
.filterIsInstance<FirDeclaration>()
.toList()
}
private fun findContainingNonLocalDeclaration(element: PsiElement): KtDeclaration? {
return element
.parentsOfType<KtDeclaration>()
.firstOrNull { it.isNotLocal }
}
private val KtDeclaration.isNotLocal
get() = this is KtNamedFunction && (isTopLevel || containingClassOrObject?.isLocal == false) ||
this is KtProperty && (isTopLevel || containingClassOrObject?.isLocal == false) ||
this is KtClassOrObject && (isTopLevel() || !isLocal)
}