[Analysis API FIR] add check for public api
This commit is contained in:
committed by
Space Team
parent
34d695cc72
commit
29502ba126
+7
@@ -23,7 +23,9 @@ import org.jetbrains.kotlin.psi.KtExpression
|
|||||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
||||||
|
|
||||||
@@ -72,6 +74,11 @@ internal class KtFe10VisibilityChecker(
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isPublicApi(symbol: KtSymbolWithVisibility): Boolean {
|
||||||
|
val descriptor = getSymbolDescriptor(symbol) as? DeclarationDescriptorWithVisibility ?: return false
|
||||||
|
return descriptor.isEffectivelyPublicApi || descriptor.isPublishedApi()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findContainingNonLocalDeclaration(element: PsiElement): KtCallableDeclaration? {
|
private fun findContainingNonLocalDeclaration(element: PsiElement): KtCallableDeclaration? {
|
||||||
|
|||||||
+14
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.api.components.KtVisibilityChecker
|
|||||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirFileSymbol
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirFileSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
||||||
|
import org.jetbrains.kotlin.analysis.api.fir.utils.firSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
||||||
@@ -19,8 +20,12 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe
|
|||||||
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
|
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.publishedApiEffectiveVisibility
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
@@ -61,6 +66,15 @@ internal class KtFirVisibilityChecker(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isPublicApi(symbol: KtSymbolWithVisibility): Boolean {
|
||||||
|
require(symbol is KtFirSymbol<*>)
|
||||||
|
val declaration = symbol.firSymbol.fir as? FirMemberDeclaration ?: return false
|
||||||
|
|
||||||
|
// Inspecting visibility requires resolving to status
|
||||||
|
declaration.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||||
|
return declaration.effectiveVisibility.publicApi || declaration.publishedApiEffectiveVisibility?.publicApi == true
|
||||||
|
}
|
||||||
|
|
||||||
private fun collectContainingDeclarations(position: PsiElement): List<FirDeclaration> {
|
private fun collectContainingDeclarations(position: PsiElement): List<FirDeclaration> {
|
||||||
val nonLocalContainer = findContainingNonLocalDeclaration(position)
|
val nonLocalContainer = findContainingNonLocalDeclaration(position)
|
||||||
val nonLocalContainerFir = nonLocalContainer?.getOrBuildFirSafe<FirDeclaration>(analysisSession.firResolveSession)
|
val nonLocalContainerFir = nonLocalContainer?.getOrBuildFirSafe<FirDeclaration>(analysisSession.firResolveSession)
|
||||||
|
|||||||
+11
@@ -18,6 +18,8 @@ public abstract class KtVisibilityChecker : KtAnalysisSessionComponent() {
|
|||||||
position: PsiElement,
|
position: PsiElement,
|
||||||
receiverExpression: KtExpression?
|
receiverExpression: KtExpression?
|
||||||
): Boolean
|
): Boolean
|
||||||
|
|
||||||
|
public abstract fun isPublicApi(symbol: KtSymbolWithVisibility): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface KtVisibilityCheckerMixIn : KtAnalysisSessionMixIn {
|
public interface KtVisibilityCheckerMixIn : KtAnalysisSessionMixIn {
|
||||||
@@ -29,4 +31,13 @@ public interface KtVisibilityCheckerMixIn : KtAnalysisSessionMixIn {
|
|||||||
): Boolean = withValidityAssertion {
|
): Boolean = withValidityAssertion {
|
||||||
analysisSession.visibilityChecker.isVisible(candidateSymbol, useSiteFile, position, receiverExpression)
|
analysisSession.visibilityChecker.isVisible(candidateSymbol, useSiteFile, position, receiverExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true for effectively public symbols, including internal declarations with @PublishedApi annotation.
|
||||||
|
* In 'Explicit API' mode explicit visibility modifier and explicit return types are required for such symbols.
|
||||||
|
* See FirExplicitApiDeclarationChecker.kt
|
||||||
|
*/
|
||||||
|
public fun isPublicApi(symbol: KtSymbolWithVisibility): Boolean = withValidityAssertion {
|
||||||
|
analysisSession.visibilityChecker.isPublicApi(symbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user