[FIR] Allow accessing protected members via local inheritors
^KT-65058 Fixed
This commit is contained in:
committed by
Space Team
parent
b6e913cde7
commit
4ee03a3a0c
+3
-1
@@ -19,7 +19,9 @@ object FirInlineBodyResolvedQualifierChecker : FirResolvedQualifierChecker(MppCh
|
||||
val accessedClass = expression.symbol ?: return
|
||||
val source = expression.source ?: return
|
||||
if (accessedClass.isCompanion) {
|
||||
inlineFunctionBodyContext.checkAccessedDeclaration(source, accessedClass, accessedClass.visibility, context, reporter)
|
||||
inlineFunctionBodyContext.checkAccessedDeclaration(
|
||||
source, expression, accessedClass, accessedClass.visibility, context, reporter,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+19
-6
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
||||
|
||||
@@ -65,6 +66,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
|
||||
|
||||
internal fun checkAccessedDeclaration(
|
||||
source: KtSourceElement,
|
||||
accessExpression: FirStatement,
|
||||
accessedSymbol: FirBasedSymbol<*>,
|
||||
declarationVisibility: Visibility,
|
||||
context: CheckerContext,
|
||||
@@ -76,12 +78,10 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
|
||||
else -> shouldNotBeCalled()
|
||||
}
|
||||
|
||||
val accessedDeclarationEffectiveVisibility = recordedEffectiveVisibility.let {
|
||||
if (it == EffectiveVisibility.Local) {
|
||||
EffectiveVisibility.Public
|
||||
} else {
|
||||
it
|
||||
}
|
||||
val accessedDeclarationEffectiveVisibility = when {
|
||||
recordedEffectiveVisibility.isReachableDueToLocalDispatchReceiver(accessExpression, context) -> EffectiveVisibility.Public
|
||||
recordedEffectiveVisibility == EffectiveVisibility.Local -> EffectiveVisibility.Public
|
||||
else -> recordedEffectiveVisibility
|
||||
}
|
||||
val isCalledFunPublicOrPublishedApi = accessedDeclarationEffectiveVisibility.publicApi
|
||||
val isInlineFunPublicOrPublishedApi = inlineFunEffectiveVisibility.publicApi
|
||||
@@ -106,6 +106,18 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
|
||||
)
|
||||
}
|
||||
|
||||
private fun EffectiveVisibility.isReachableDueToLocalDispatchReceiver(access: FirStatement, context: CheckerContext): Boolean {
|
||||
val receiverType = access.localDispatchReceiver(context) ?: return false
|
||||
val receiverProtected = EffectiveVisibility.Protected(receiverType.typeConstructor(context.session.typeContext))
|
||||
val relation = receiverProtected.relation(this, context.session.typeContext)
|
||||
return relation == EffectiveVisibility.Permissiveness.SAME || relation == EffectiveVisibility.Permissiveness.LESS
|
||||
}
|
||||
|
||||
private fun FirStatement.localDispatchReceiver(context: CheckerContext): ConeKotlinType? =
|
||||
(this as? FirQualifiedAccessExpression)?.dispatchReceiver?.resolvedType?.takeIf {
|
||||
(it.toSymbol(context.session) as? FirClassLikeSymbol<*>)?.effectiveVisibility == EffectiveVisibility.Local
|
||||
}
|
||||
|
||||
internal data class AccessedDeclarationVisibilityData(
|
||||
val isInlineFunPublicOrPublishedApi: Boolean,
|
||||
val isCalledFunPublicOrPublishedApi: Boolean,
|
||||
@@ -239,6 +251,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
|
||||
}
|
||||
val (isInlineFunPublicOrPublishedApi, isCalledFunPublicOrPublishedApi, calledFunEffectiveVisibility) = checkAccessedDeclaration(
|
||||
source,
|
||||
accessExpression,
|
||||
calledDeclaration,
|
||||
calledDeclaration.visibility,
|
||||
context,
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// ISSUE: KT-65058
|
||||
|
||||
open class A {
|
||||
protected fun foo() {
|
||||
}
|
||||
}
|
||||
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun bar() = object : A() {
|
||||
fun baz() {
|
||||
<!PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR!>foo<!>()
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-65058
|
||||
|
||||
open class A {
|
||||
|
||||
Reference in New Issue
Block a user