FIR resolve: integrate receiverExpression inside ReceiverValue
This commit is contained in:
@@ -11,13 +11,10 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirImplicitThisReference
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
@@ -68,19 +65,11 @@ class Candidate(
|
||||
|
||||
fun dispatchReceiverExpression(): FirExpression = when (explicitReceiverKind) {
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> callInfo.explicitReceiver!!
|
||||
else -> dispatchReceiverValue?.let {
|
||||
FirThisReceiverExpressionImpl(null, FirImplicitThisReference(it.klassSymbol)).apply {
|
||||
typeRef = FirResolvedTypeRefImpl(null, it.type)
|
||||
}
|
||||
} ?: FirNoReceiverExpression
|
||||
else -> dispatchReceiverValue?.receiverExpression ?: FirNoReceiverExpression
|
||||
}
|
||||
|
||||
fun extensionReceiverExpression(): FirExpression = when (explicitReceiverKind) {
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> callInfo.explicitReceiver!!
|
||||
else -> implicitExtensionReceiverValue?.let {
|
||||
FirThisReceiverExpressionImpl(null, FirImplicitThisReference(it.boundSymbol)).apply {
|
||||
typeRef = FirResolvedTypeRefImpl(null, it.type)
|
||||
}
|
||||
} ?: FirNoReceiverExpression
|
||||
else -> implicitExtensionReceiverValue?.receiverExpression ?: FirNoReceiverExpression
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirImplicitThisReference
|
||||
import org.jetbrains.kotlin.fir.renderWithType
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
@@ -18,20 +20,30 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
|
||||
interface ReceiverValue {
|
||||
val type: ConeKotlinType
|
||||
|
||||
val receiverExpression: FirExpression
|
||||
|
||||
fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? =
|
||||
type.scope(useSiteSession, scopeSession)
|
||||
}
|
||||
|
||||
private fun receiverExpression(symbol: AbstractFirBasedSymbol<*>, type: ConeKotlinType): FirExpression =
|
||||
FirThisReceiverExpressionImpl(null, FirImplicitThisReference(symbol)).apply {
|
||||
typeRef = FirResolvedTypeRefImpl(null, type)
|
||||
}
|
||||
|
||||
class ClassDispatchReceiverValue(val klassSymbol: FirClassSymbol) : ReceiverValue {
|
||||
override val type: ConeKotlinType = ConeClassTypeImpl(
|
||||
klassSymbol.toLookupTag(),
|
||||
klassSymbol.fir.typeParameters.map { ConeStarProjection }.toTypedArray(),
|
||||
isNullable = false
|
||||
)
|
||||
|
||||
override val receiverExpression: FirExpression = receiverExpression(klassSymbol, type)
|
||||
}
|
||||
|
||||
class ExpressionReceiverValue(
|
||||
@@ -41,6 +53,9 @@ class ExpressionReceiverValue(
|
||||
override val type: ConeKotlinType
|
||||
get() = typeProvider(explicitReceiverExpression)?.coneTypeSafe()
|
||||
?: ConeKotlinErrorType("No type calculated for: ${explicitReceiverExpression.renderWithType()}") // TODO: assert here
|
||||
|
||||
override val receiverExpression: FirExpression
|
||||
get() = explicitReceiverExpression
|
||||
}
|
||||
|
||||
abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
||||
@@ -52,6 +67,8 @@ abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
||||
val implicitScope: FirScope? = type.scope(useSiteSession, scopeSession)
|
||||
|
||||
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? = implicitScope
|
||||
|
||||
override val receiverExpression: FirExpression = receiverExpression(boundSymbol, type)
|
||||
}
|
||||
|
||||
class ImplicitDispatchReceiverValue(
|
||||
|
||||
@@ -60,8 +60,8 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
return this == DISPATCH_RECEIVER || this == BOTH_RECEIVERS
|
||||
}
|
||||
|
||||
override fun Candidate.getReceiverValue(): ReceiverValue? {
|
||||
return dispatchReceiverValue
|
||||
override fun Candidate.getReceiverType(): ConeKotlinType? {
|
||||
return dispatchReceiverValue?.type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,35 +74,30 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
return this == EXTENSION_RECEIVER || this == BOTH_RECEIVERS
|
||||
}
|
||||
|
||||
override fun Candidate.getReceiverValue(): ReceiverValue? {
|
||||
override fun Candidate.getReceiverType(): ConeKotlinType? {
|
||||
val callableSymbol = symbol as? FirCallableSymbol<*> ?: return null
|
||||
val callable = callableSymbol.fir
|
||||
val type = (callable.receiverTypeRef as FirResolvedTypeRef?)?.type ?: return null
|
||||
return object : ReceiverValue {
|
||||
override val type: ConeKotlinType
|
||||
get() = type
|
||||
|
||||
}
|
||||
return (callable.receiverTypeRef as FirResolvedTypeRef?)?.type
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun Candidate.getReceiverValue(): ReceiverValue?
|
||||
abstract fun Candidate.getReceiverType(): ConeKotlinType?
|
||||
|
||||
abstract fun ExplicitReceiverKind.shouldBeCheckedAgainstExplicit(): Boolean
|
||||
|
||||
abstract fun ExplicitReceiverKind.shouldBeCheckedAgainstImplicit(): Boolean
|
||||
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val expectedReceiverParameterValue = candidate.getReceiverValue()
|
||||
val expectedReceiverType = candidate.getReceiverType()
|
||||
val explicitReceiverExpression = callInfo.explicitReceiver
|
||||
val explicitReceiverKind = candidate.explicitReceiverKind
|
||||
|
||||
if (expectedReceiverParameterValue != null) {
|
||||
if (expectedReceiverType != null) {
|
||||
if (explicitReceiverExpression != null && explicitReceiverKind.shouldBeCheckedAgainstExplicit()) {
|
||||
resolveArgumentExpression(
|
||||
candidate.csBuilder,
|
||||
argument = explicitReceiverExpression,
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverParameterValue.type),
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType),
|
||||
expectedTypeRef = explicitReceiverExpression.typeRef,
|
||||
sink = sink,
|
||||
isReceiver = true,
|
||||
@@ -117,7 +112,7 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
resolvePlainArgumentType(
|
||||
candidate.csBuilder,
|
||||
argumentType = argumentExtensionReceiverValue.type,
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverParameterValue.type),
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType.type),
|
||||
sink = sink,
|
||||
isReceiver = true,
|
||||
isSafeCall = callInfo.isSafeCall
|
||||
|
||||
Reference in New Issue
Block a user