diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt index 5b80e6656d2..a83db76d7cb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt @@ -103,7 +103,7 @@ fun createSimpleConsumer( val factory = CandidateFactory(bodyResolveComponents, callInfo) val explicitReceiver = callInfo.explicitReceiver return if (explicitReceiver != null) { - ExplicitReceiverTowerDataConsumer(session, name, token, ExpressionReceiverValue(explicitReceiver), factory, resultCollector) + ExplicitReceiverTowerDataConsumer(session, name, token, qualifierOrExpressionReceiver(explicitReceiver), factory, resultCollector) } else { NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt index cff32feca05..66fe55efa75 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt @@ -29,12 +29,16 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.name.ClassId -interface ReceiverValue { +interface Receiver { + fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? +} + +interface ReceiverValue : Receiver { val type: ConeKotlinType val receiverExpression: FirExpression - fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? = + override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? = type.scope(useSiteSession, scopeSession) } @@ -53,16 +57,24 @@ class ClassDispatchReceiverValue(klassSymbol: FirClassSymbol<*>) : ReceiverValue override val receiverExpression: FirExpression = receiverExpression(klassSymbol, type) } -class ExpressionReceiverValue( - val explicitReceiverExpression: FirExpression -) : ReceiverValue { +// TODO: should inherit just Receiver, not ReceiverValue +abstract class AbstractExplicitReceiver : ReceiverValue { + abstract val explicitReceiver: FirExpression + override val type: ConeKotlinType - get() = explicitReceiverExpression.typeRef.coneTypeSafe() - ?: ConeKotlinErrorType("No type calculated for: ${explicitReceiverExpression.renderWithType()}") // TODO: assert here + get() = explicitReceiver.typeRef.coneTypeSafe() + ?: ConeKotlinErrorType("No type calculated for: ${explicitReceiver.renderWithType()}") // TODO: assert here override val receiverExpression: FirExpression - get() = explicitReceiverExpression + get() = explicitReceiver +} +fun qualifierOrExpressionReceiver(explicitReceiver: FirExpression): AbstractExplicitReceiver<*> { + if (explicitReceiver is FirResolvedQualifier) return QualifierReceiver(explicitReceiver) + return ExpressionReceiverValue(explicitReceiver) +} + +class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : AbstractExplicitReceiver() { private fun getClassSymbolWithCallablesScope( classId: ClassId, useSiteSession: FirSession, @@ -94,7 +106,7 @@ class ExpressionReceiverValue( } override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { - val qualifiedReceiver = explicitReceiverExpression as? FirResolvedQualifier + val qualifiedReceiver = explicitReceiver as? FirResolvedQualifier ?: return super.scope(useSiteSession, scopeSession) val classId = qualifiedReceiver.classId ?: return null @@ -118,6 +130,10 @@ class ExpressionReceiverValue( } } +private class ExpressionReceiverValue( + override val explicitReceiver: FirExpression +) : AbstractExplicitReceiver(), ReceiverValue + abstract class ImplicitReceiverValue>( val boundSymbol: S, type: ConeKotlinType, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt index a7fb1b8e64e..94ab40d11f8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt @@ -111,7 +111,7 @@ class ExplicitReceiverTowerDataConsumer>( val session: FirSession, val name: Name, val token: TowerScopeLevel.Token, - val explicitReceiver: ExpressionReceiverValue, + val explicitReceiver: AbstractExplicitReceiver<*>, val candidateFactory: CandidateFactory, override val resultCollector: CandidateCollector ) : TowerDataConsumer() { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt index f624c1d5592..4a729dff622 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.isStatic import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.firSymbolProvider @@ -40,7 +39,7 @@ interface TowerScopeLevel { fun > processElementsByName( token: Token, name: Name, - explicitReceiver: ExpressionReceiverValue?, + explicitReceiver: AbstractExplicitReceiver<*>?, processor: TowerScopeLevelProcessor ): ProcessorAction @@ -57,7 +56,7 @@ interface TowerScopeLevel { override fun > processElementsByName( token: Token, name: Name, - explicitReceiver: ExpressionReceiverValue?, + explicitReceiver: AbstractExplicitReceiver<*>?, processor: TowerScopeLevelProcessor ): ProcessorAction = ProcessorAction.NEXT } @@ -102,7 +101,7 @@ class MemberScopeTowerLevel( ) : SessionBasedTowerLevel(session) { private fun > processMembers( output: TowerScopeLevel.TowerScopeLevelProcessor, - explicitExtensionReceiver: ExpressionReceiverValue?, + explicitExtensionReceiver: AbstractExplicitReceiver<*>?, processScopeMembers: FirScope.(processor: (T) -> ProcessorAction) -> ProcessorAction ): ProcessorAction { if (implicitExtensionReceiver != null && explicitExtensionReceiver != null) return ProcessorAction.NEXT @@ -146,7 +145,7 @@ class MemberScopeTowerLevel( override fun > processElementsByName( token: TowerScopeLevel.Token, name: Name, - explicitReceiver: ExpressionReceiverValue?, + explicitReceiver: AbstractExplicitReceiver<*>?, processor: TowerScopeLevel.TowerScopeLevelProcessor ): ProcessorAction { val isInvoke = name == OperatorNameConventions.INVOKE && token == TowerScopeLevel.Token.Functions @@ -154,8 +153,7 @@ class MemberScopeTowerLevel( return ProcessorAction.NEXT } val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver - val noInnerConstructors = - dispatchReceiver is ExpressionReceiverValue && dispatchReceiver.explicitReceiverExpression is FirResolvedQualifier + val noInnerConstructors = dispatchReceiver is QualifierReceiver return when (token) { TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver) { symbol -> this.processPropertiesByName(name, symbol.cast()) @@ -195,7 +193,7 @@ class ScopeTowerLevel( override fun > processElementsByName( token: TowerScopeLevel.Token, name: Name, - explicitReceiver: ExpressionReceiverValue?, + explicitReceiver: AbstractExplicitReceiver<*>?, processor: TowerScopeLevel.TowerScopeLevelProcessor ): ProcessorAction { if (explicitReceiver != null && implicitExtensionReceiver != null) {