[Analysis API] Support dangling file copies in 'KtFirVisibilityChecker'
Dangling files are copies of files in the context module, or just depend on it. In any way, dangling file modules see all internals of the context module.
This commit is contained in:
+22
-11
@@ -16,7 +16,9 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
|||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
|
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.collectContainingDeclarationsIfNonLocal
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.collectUseSiteContainers
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtDanglingFileModule
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities
|
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
@@ -48,22 +50,31 @@ internal class KtFirVisibilityChecker(
|
|||||||
candidateSymbol.isVisibleByPsi(useSiteFile)?.let { return it }
|
candidateSymbol.isVisibleByPsi(useSiteFile)?.let { return it }
|
||||||
}
|
}
|
||||||
|
|
||||||
val useSiteFirFile = useSiteFile.firSymbol.fir
|
|
||||||
val containers = position.collectContainingDeclarationsIfNonLocal(analysisSession.firResolveSession).orEmpty()
|
|
||||||
|
|
||||||
val dispatchReceiverCanBeExplicit = candidateSymbol is KtCallableSymbol && !candidateSymbol.isExtension
|
val dispatchReceiverCanBeExplicit = candidateSymbol is KtCallableSymbol && !candidateSymbol.isExtension
|
||||||
val explicitDispatchReceiver = runIf(dispatchReceiverCanBeExplicit) {
|
val explicitDispatchReceiver = runIf(dispatchReceiverCanBeExplicit) {
|
||||||
receiverExpression?.getOrBuildFirSafe<FirExpression>(analysisSession.firResolveSession)
|
receiverExpression?.getOrBuildFirSafe<FirExpression>(analysisSession.firResolveSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
val candidateFirSymbol = candidateSymbol.firSymbol.fir as FirMemberDeclaration
|
val candidateDeclaration = candidateSymbol.firSymbol.fir as FirMemberDeclaration
|
||||||
|
|
||||||
val rootModuleSession = rootModuleSession
|
val positionModule = firResolveSession.moduleProvider.getModule(position)
|
||||||
return rootModuleSession.visibilityChecker.isVisible(
|
val candidateModule = candidateDeclaration.llFirModuleData.ktModule
|
||||||
candidateFirSymbol,
|
|
||||||
rootModuleSession,
|
val effectiveSession = if (positionModule is KtDanglingFileModule && candidateModule != positionModule) {
|
||||||
useSiteFirFile,
|
@Suppress("USELESS_CAST") // Smart cast is only available in K2
|
||||||
containers,
|
val contextModule = (positionModule as KtDanglingFileModule).contextModule
|
||||||
|
firResolveSession.getSessionFor(contextModule)
|
||||||
|
} else {
|
||||||
|
firResolveSession.getSessionFor(positionModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
val effectiveContainers = collectUseSiteContainers(position, firResolveSession).orEmpty()
|
||||||
|
|
||||||
|
return effectiveSession.visibilityChecker.isVisible(
|
||||||
|
candidateDeclaration,
|
||||||
|
effectiveSession,
|
||||||
|
useSiteFile.firSymbol.fir,
|
||||||
|
effectiveContainers,
|
||||||
explicitDispatchReceiver
|
explicitDispatchReceiver
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -90,11 +90,11 @@ internal fun KtDeclaration.findSourceNonLocalFirDeclaration(firFile: FirFile, pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@KtAnalysisApiInternals
|
@KtAnalysisApiInternals
|
||||||
fun PsiElement.collectContainingDeclarationsIfNonLocal(session: LLFirResolveSession): List<FirDeclaration>? {
|
fun collectUseSiteContainers(element: PsiElement, resolveSession: LLFirResolveSession): List<FirDeclaration>? {
|
||||||
val ktFile = containingFile as? KtFile ?: return null
|
val containingDeclaration = element.getNonLocalContainingOrThisDeclaration { !it.canBePartOfParentDeclaration } ?: return null
|
||||||
val ktDeclaration = getNonLocalContainingOrThisDeclaration { !it.canBePartOfParentDeclaration } ?: return null
|
val containingFile = containingDeclaration.containingKtFile
|
||||||
val firFile = session.getOrBuildFirFile(ktFile)
|
val firFile = resolveSession.getOrBuildFirFile(containingFile)
|
||||||
return FirElementFinder.findPathToDeclarationWithTarget(firFile, ktDeclaration)
|
return FirElementFinder.findPathToDeclarationWithTarget(firFile, containingDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KtElement.findSourceByTraversingWholeTree(
|
internal fun KtElement.findSourceByTraversingWholeTree(
|
||||||
|
|||||||
Reference in New Issue
Block a user