[FIR] Split Receiver/ReceiverValue, QualifierReceiver/ExpressionReceiver

This commit is contained in:
Mikhail Glukhikh
2020-01-15 16:16:29 +03:00
parent 42ba54fffd
commit aaace40912
4 changed files with 33 additions and 19 deletions
@@ -103,7 +103,7 @@ fun createSimpleConsumer(
val factory = CandidateFactory(bodyResolveComponents, callInfo) val factory = CandidateFactory(bodyResolveComponents, callInfo)
val explicitReceiver = callInfo.explicitReceiver val explicitReceiver = callInfo.explicitReceiver
return if (explicitReceiver != null) { return if (explicitReceiver != null) {
ExplicitReceiverTowerDataConsumer(session, name, token, ExpressionReceiverValue(explicitReceiver), factory, resultCollector) ExplicitReceiverTowerDataConsumer(session, name, token, qualifierOrExpressionReceiver(explicitReceiver), factory, resultCollector)
} else { } else {
NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector) NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector)
} }
@@ -29,12 +29,16 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
interface ReceiverValue { interface Receiver {
fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope?
}
interface ReceiverValue : Receiver {
val type: ConeKotlinType val type: ConeKotlinType
val receiverExpression: FirExpression val receiverExpression: FirExpression
fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? = override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? =
type.scope(useSiteSession, scopeSession) type.scope(useSiteSession, scopeSession)
} }
@@ -53,16 +57,24 @@ class ClassDispatchReceiverValue(klassSymbol: FirClassSymbol<*>) : ReceiverValue
override val receiverExpression: FirExpression = receiverExpression(klassSymbol, type) override val receiverExpression: FirExpression = receiverExpression(klassSymbol, type)
} }
class ExpressionReceiverValue( // TODO: should inherit just Receiver, not ReceiverValue
val explicitReceiverExpression: FirExpression abstract class AbstractExplicitReceiver<E : FirExpression> : ReceiverValue {
) : ReceiverValue { abstract val explicitReceiver: FirExpression
override val type: ConeKotlinType override val type: ConeKotlinType
get() = explicitReceiverExpression.typeRef.coneTypeSafe() get() = explicitReceiver.typeRef.coneTypeSafe()
?: ConeKotlinErrorType("No type calculated for: ${explicitReceiverExpression.renderWithType()}") // TODO: assert here ?: ConeKotlinErrorType("No type calculated for: ${explicitReceiver.renderWithType()}") // TODO: assert here
override val receiverExpression: FirExpression 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<FirResolvedQualifier>() {
private fun getClassSymbolWithCallablesScope( private fun getClassSymbolWithCallablesScope(
classId: ClassId, classId: ClassId,
useSiteSession: FirSession, useSiteSession: FirSession,
@@ -94,7 +106,7 @@ class ExpressionReceiverValue(
} }
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
val qualifiedReceiver = explicitReceiverExpression as? FirResolvedQualifier val qualifiedReceiver = explicitReceiver as? FirResolvedQualifier
?: return super.scope(useSiteSession, scopeSession) ?: return super.scope(useSiteSession, scopeSession)
val classId = qualifiedReceiver.classId ?: return null val classId = qualifiedReceiver.classId ?: return null
@@ -118,6 +130,10 @@ class ExpressionReceiverValue(
} }
} }
private class ExpressionReceiverValue(
override val explicitReceiver: FirExpression
) : AbstractExplicitReceiver<FirExpression>(), ReceiverValue
abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>( abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
val boundSymbol: S, val boundSymbol: S,
type: ConeKotlinType, type: ConeKotlinType,
@@ -111,7 +111,7 @@ class ExplicitReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
val session: FirSession, val session: FirSession,
val name: Name, val name: Name,
val token: TowerScopeLevel.Token<T>, val token: TowerScopeLevel.Token<T>,
val explicitReceiver: ExpressionReceiverValue, val explicitReceiver: AbstractExplicitReceiver<*>,
val candidateFactory: CandidateFactory, val candidateFactory: CandidateFactory,
override val resultCollector: CandidateCollector override val resultCollector: CandidateCollector
) : TowerDataConsumer() { ) : TowerDataConsumer() {
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.isStatic import org.jetbrains.kotlin.fir.declarations.isStatic
import org.jetbrains.kotlin.fir.expressions.FirExpression 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.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
@@ -40,7 +39,7 @@ interface TowerScopeLevel {
fun <T : AbstractFirBasedSymbol<*>> processElementsByName( fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: Token<T>, token: Token<T>,
name: Name, name: Name,
explicitReceiver: ExpressionReceiverValue?, explicitReceiver: AbstractExplicitReceiver<*>?,
processor: TowerScopeLevelProcessor<T> processor: TowerScopeLevelProcessor<T>
): ProcessorAction ): ProcessorAction
@@ -57,7 +56,7 @@ interface TowerScopeLevel {
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName( override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: Token<T>, token: Token<T>,
name: Name, name: Name,
explicitReceiver: ExpressionReceiverValue?, explicitReceiver: AbstractExplicitReceiver<*>?,
processor: TowerScopeLevelProcessor<T> processor: TowerScopeLevelProcessor<T>
): ProcessorAction = ProcessorAction.NEXT ): ProcessorAction = ProcessorAction.NEXT
} }
@@ -102,7 +101,7 @@ class MemberScopeTowerLevel(
) : SessionBasedTowerLevel(session) { ) : SessionBasedTowerLevel(session) {
private fun <T : AbstractFirBasedSymbol<*>> processMembers( private fun <T : AbstractFirBasedSymbol<*>> processMembers(
output: TowerScopeLevel.TowerScopeLevelProcessor<T>, output: TowerScopeLevel.TowerScopeLevelProcessor<T>,
explicitExtensionReceiver: ExpressionReceiverValue?, explicitExtensionReceiver: AbstractExplicitReceiver<*>?,
processScopeMembers: FirScope.(processor: (T) -> ProcessorAction) -> ProcessorAction processScopeMembers: FirScope.(processor: (T) -> ProcessorAction) -> ProcessorAction
): ProcessorAction { ): ProcessorAction {
if (implicitExtensionReceiver != null && explicitExtensionReceiver != null) return ProcessorAction.NEXT if (implicitExtensionReceiver != null && explicitExtensionReceiver != null) return ProcessorAction.NEXT
@@ -146,7 +145,7 @@ class MemberScopeTowerLevel(
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName( override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: TowerScopeLevel.Token<T>, token: TowerScopeLevel.Token<T>,
name: Name, name: Name,
explicitReceiver: ExpressionReceiverValue?, explicitReceiver: AbstractExplicitReceiver<*>?,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T> processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
): ProcessorAction { ): ProcessorAction {
val isInvoke = name == OperatorNameConventions.INVOKE && token == TowerScopeLevel.Token.Functions val isInvoke = name == OperatorNameConventions.INVOKE && token == TowerScopeLevel.Token.Functions
@@ -154,8 +153,7 @@ class MemberScopeTowerLevel(
return ProcessorAction.NEXT return ProcessorAction.NEXT
} }
val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver
val noInnerConstructors = val noInnerConstructors = dispatchReceiver is QualifierReceiver
dispatchReceiver is ExpressionReceiverValue && dispatchReceiver.explicitReceiverExpression is FirResolvedQualifier
return when (token) { return when (token) {
TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver) { symbol -> TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver) { symbol ->
this.processPropertiesByName(name, symbol.cast()) this.processPropertiesByName(name, symbol.cast())
@@ -195,7 +193,7 @@ class ScopeTowerLevel(
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName( override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: TowerScopeLevel.Token<T>, token: TowerScopeLevel.Token<T>,
name: Name, name: Name,
explicitReceiver: ExpressionReceiverValue?, explicitReceiver: AbstractExplicitReceiver<*>?,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T> processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
): ProcessorAction { ): ProcessorAction {
if (explicitReceiver != null && implicitExtensionReceiver != null) { if (explicitReceiver != null && implicitExtensionReceiver != null) {