FIR: Add preliminary support for context receivers in resolution

This commit is contained in:
Denis.Zharkov
2022-03-09 14:36:20 +03:00
committed by teamcity
parent 588dd23fd9
commit ef84dddc88
39 changed files with 688 additions and 133 deletions
@@ -335,14 +335,14 @@ internal class KtFirCallResolver(
// Implicit invoke (e.g., `x()`) will have a different callee symbol (e.g., `x`) than the candidate (e.g., `invoke`).
createKtPartiallyAppliedSymbolForImplicitInvoke(
candidate.dispatchReceiverValue?.receiverExpression ?: FirNoReceiverExpression,
candidate.extensionReceiverValue?.receiverExpression ?: FirNoReceiverExpression,
candidate.chosenExtensionReceiverValue?.receiverExpression ?: FirNoReceiverExpression,
candidate.explicitReceiverKind
)
} else {
KtPartiallyAppliedSymbol(
unsubstitutedKtSignature.substitute(substitutor),
candidate.dispatchReceiverValue?.receiverExpression?.toKtReceiverValue(),
candidate.extensionReceiverValue?.receiverExpression?.toKtReceiverValue(),
candidate.chosenExtensionReceiverValue?.receiverExpression?.toKtReceiverValue(),
)
}
} else if (fir is FirQualifiedAccess) {
@@ -1608,6 +1608,32 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.NO_CONTEXT_RECEIVER) { firDiagnostic ->
NoContextReceiverImpl(
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.MULTIPLE_ARGUMENTS_APPLICABLE_FOR_CONTEXT_RECEIVER) { firDiagnostic ->
MultipleArgumentsApplicableForContextReceiverImpl(
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER) { firDiagnostic ->
AmbiguousCallWithImplicitContextReceiverImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.UNSUPPORTED_CONTEXTUAL_DECLARATION_CALL) { firDiagnostic ->
UnsupportedContextualDeclarationCallImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.RECURSION_IN_IMPLICIT_TYPES) { firDiagnostic ->
RecursionInImplicitTypesImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -1145,6 +1145,24 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val candidates: List<KtSymbol>
}
abstract class NoContextReceiver : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = NoContextReceiver::class
abstract val contextReceiverRepresentation: KtType
}
abstract class MultipleArgumentsApplicableForContextReceiver : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = MultipleArgumentsApplicableForContextReceiver::class
abstract val contextReceiverRepresentation: KtType
}
abstract class AmbiguousCallWithImplicitContextReceiver : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = AmbiguousCallWithImplicitContextReceiver::class
}
abstract class UnsupportedContextualDeclarationCall : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = UnsupportedContextualDeclarationCall::class
}
abstract class RecursionInImplicitTypes : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = RecursionInImplicitTypes::class
}
@@ -1373,6 +1373,28 @@ internal class NextAmbiguityImpl(
override val token: ValidityToken,
) : KtFirDiagnostic.NextAmbiguity(), KtAbstractFirDiagnostic<PsiElement>
internal class NoContextReceiverImpl(
override val contextReceiverRepresentation: KtType,
override val firDiagnostic: KtPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.NoContextReceiver(), KtAbstractFirDiagnostic<KtElement>
internal class MultipleArgumentsApplicableForContextReceiverImpl(
override val contextReceiverRepresentation: KtType,
override val firDiagnostic: KtPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.MultipleArgumentsApplicableForContextReceiver(), KtAbstractFirDiagnostic<KtElement>
internal class AmbiguousCallWithImplicitContextReceiverImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.AmbiguousCallWithImplicitContextReceiver(), KtAbstractFirDiagnostic<KtElement>
internal class UnsupportedContextualDeclarationCallImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.UnsupportedContextualDeclarationCall(), KtAbstractFirDiagnostic<KtElement>
internal class RecursionInImplicitTypesImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: ValidityToken,
@@ -53,11 +53,12 @@ class SingleCandidateResolver(
resolutionParameters.callableSymbol,
explicitReceiverKind = explicitReceiverKind,
dispatchReceiverValue = dispatchReceiverValue,
extensionReceiverValue =
if (explicitReceiverKind.isExtensionReceiver)
callInfo.explicitReceiver?.let { ExpressionReceiverValue(it) }
else
implicitExtensionReceiverValue,
givenExtensionReceiverOptions = listOfNotNull(
if (explicitReceiverKind.isExtensionReceiver)
callInfo.explicitReceiver?.let { ExpressionReceiverValue(it) }
else
implicitExtensionReceiverValue
),
scope = null,
)