K2: copy explicit receiver to dispatch receiver for static member accesses

Related to KT-55116
This commit is contained in:
Mikhail Glukhikh
2023-01-17 16:37:08 +01:00
committed by Space Team
parent 4167a69e30
commit 938e1d5ce8
5 changed files with 22 additions and 5 deletions
@@ -230,7 +230,7 @@ private fun FirCallableSymbol<*>.toSymbolForCall(
val fakeOverrideOwnerLookupTag = when { val fakeOverrideOwnerLookupTag = when {
// Static fake overrides // Static fake overrides
isStatic -> { isStatic -> {
((dispatchReceiver as? FirResolvedQualifier) ?: (explicitReceiver as? FirResolvedQualifier))?.toLookupTag(session) (dispatchReceiver as? FirResolvedQualifier)?.toLookupTag(session)
} }
// Member fake override or bound callable reference // Member fake override or bound callable reference
dispatchReceiver !is FirNoReceiverExpression -> { dispatchReceiver !is FirNoReceiverExpression -> {
@@ -13,12 +13,14 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.resolve.SupertypeSupplier import org.jetbrains.kotlin.fir.resolve.SupertypeSupplier
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
import org.jetbrains.kotlin.fir.resolve.isSubclassOf import org.jetbrains.kotlin.fir.resolve.isSubclassOf
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
@@ -41,7 +43,13 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
} else { } else {
val ownerLookupTag = symbol.getOwnerLookupTag() ?: return false val ownerLookupTag = symbol.getOwnerLookupTag() ?: return false
if (canSeeProtectedMemberOf( if (canSeeProtectedMemberOf(
symbol, containingDeclarations, dispatchReceiver, ownerLookupTag, session, symbol,
containingDeclarations,
// Note: dispatch receiver isn't relevant for Java protected static
// See e.g. diagnostics/tests/visibility/packagePrivateStatic.kt
dispatchReceiver.takeUnless { symbol is FirCallableSymbol && symbol.isStatic },
ownerLookupTag,
session,
isVariableOrNamedFunction = symbol.isVariableOrNamedFunction(), isVariableOrNamedFunction = symbol.isVariableOrNamedFunction(),
isSyntheticProperty = symbol.fir is FirSyntheticPropertyAccessor, isSyntheticProperty = symbol.fir is FirSyntheticPropertyAccessor,
supertypeSupplier supertypeSupplier
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.FirSuperReference
@@ -330,7 +331,10 @@ abstract class FirVisibilityChecker : FirSessionComponent {
) )
} }
if (dispatchReceiver != null) { // Note: private static symbols aren't accessible by use-site dispatch receiver
// See e.g. diagnostics/tests/scopes/inheritance/statics/hidePrivateByPublic.kt,
// private A.a becomes visible from outside without filtering static callables here
if (dispatchReceiver != null && (symbol !is FirCallableSymbol || !symbol.isStatic)) {
val fir = symbol.fir val fir = symbol.fir
val dispatchReceiverParameterClassSymbol = val dispatchReceiverParameterClassSymbol =
(fir as? FirCallableDeclaration) (fir as? FirCallableDeclaration)
@@ -33,7 +33,7 @@ fun FirVisibilityChecker.isVisible(
dispatchReceiverValue: ReceiverValue? dispatchReceiverValue: ReceiverValue?
): Boolean { ): Boolean {
val staticQualifierForCallable = runIf(declaration is FirCallableDeclaration && declaration.isStatic) { val staticQualifierForCallable = runIf(declaration is FirCallableDeclaration && declaration.isStatic) {
val explicitReceiver = callInfo.explicitReceiver ?: (dispatchReceiverValue as? ExpressionReceiverValue)?.explicitReceiver val explicitReceiver = (dispatchReceiverValue as? ExpressionReceiverValue)?.explicitReceiver
when (val classLikeSymbol = (explicitReceiver as? FirResolvedQualifier)?.symbol) { when (val classLikeSymbol = (explicitReceiver as? FirResolvedQualifier)?.symbol) {
is FirRegularClassSymbol -> classLikeSymbol.fir is FirRegularClassSymbol -> classLikeSymbol.fir
is FirTypeAliasSymbol -> classLikeSymbol.fullyExpandedClass(callInfo.session)?.fir is FirTypeAliasSymbol -> classLikeSymbol.fullyExpandedClass(callInfo.session)?.fir
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
@@ -382,7 +383,11 @@ class ScopeTowerLevel(
} }
} }
} }
if (candidate.isStatic && callInfo.explicitReceiver == null && candidate.isJavaOrEnhancement) { if (candidate.isStatic && candidate.isJavaOrEnhancement) {
val explicitReceiver = callInfo.explicitReceiver
if (explicitReceiver is FirResolvedQualifier) {
return ExpressionReceiverValue(explicitReceiver)
}
val lookupTag = candidate.fir.containingClassLookupTag() ?: return null val lookupTag = candidate.fir.containingClassLookupTag() ?: return null
val implicitDispatchReceiverValue = bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver { implicitReceiverValue -> val implicitDispatchReceiverValue = bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver { implicitReceiverValue ->
implicitReceiverValue is ImplicitDispatchReceiverValue && implicitReceiverValue.boundSymbol.fir.isSubclassOf( implicitReceiverValue is ImplicitDispatchReceiverValue && implicitReceiverValue.boundSymbol.fir.isSubclassOf(