[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 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)
}
@@ -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<E : FirExpression> : 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<FirResolvedQualifier>() {
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<FirExpression>(), ReceiverValue
abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
val boundSymbol: S,
type: ConeKotlinType,
@@ -111,7 +111,7 @@ class ExplicitReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
val session: FirSession,
val name: Name,
val token: TowerScopeLevel.Token<T>,
val explicitReceiver: ExpressionReceiverValue,
val explicitReceiver: AbstractExplicitReceiver<*>,
val candidateFactory: CandidateFactory,
override val resultCollector: CandidateCollector
) : 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.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 <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: Token<T>,
name: Name,
explicitReceiver: ExpressionReceiverValue?,
explicitReceiver: AbstractExplicitReceiver<*>?,
processor: TowerScopeLevelProcessor<T>
): ProcessorAction
@@ -57,7 +56,7 @@ interface TowerScopeLevel {
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: Token<T>,
name: Name,
explicitReceiver: ExpressionReceiverValue?,
explicitReceiver: AbstractExplicitReceiver<*>?,
processor: TowerScopeLevelProcessor<T>
): ProcessorAction = ProcessorAction.NEXT
}
@@ -102,7 +101,7 @@ class MemberScopeTowerLevel(
) : SessionBasedTowerLevel(session) {
private fun <T : AbstractFirBasedSymbol<*>> processMembers(
output: TowerScopeLevel.TowerScopeLevelProcessor<T>,
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 <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: TowerScopeLevel.Token<T>,
name: Name,
explicitReceiver: ExpressionReceiverValue?,
explicitReceiver: AbstractExplicitReceiver<*>?,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
): 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 <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: TowerScopeLevel.Token<T>,
name: Name,
explicitReceiver: ExpressionReceiverValue?,
explicitReceiver: AbstractExplicitReceiver<*>?,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
): ProcessorAction {
if (explicitReceiver != null && implicitExtensionReceiver != null) {