[FIR] Make extensionReceiver and dispatchReceiver nullable
Get rid of FirNoReceiverExpression ^KT-59650 Fixed
This commit is contained in:
committed by
Space Team
parent
585c3fe4b5
commit
f203681ffa
+75
-27
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.realPsi
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
@@ -58,6 +57,7 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirSymbolEntry
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -70,8 +70,10 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.rethrowExceptionWithDetails
|
||||
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
|
||||
|
||||
internal class KtFirCallResolver(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -391,8 +393,8 @@ internal class KtFirCallResolver(
|
||||
} ?: KtSubstitutor.Empty(token)
|
||||
|
||||
fun createKtPartiallyAppliedSymbolForImplicitInvoke(
|
||||
dispatchReceiver: FirExpression,
|
||||
extensionReceiver: FirExpression,
|
||||
dispatchReceiver: FirExpression?,
|
||||
extensionReceiver: FirExpression?,
|
||||
explicitReceiverKind: ExplicitReceiverKind
|
||||
): KtPartiallyAppliedSymbol<KtCallableSymbol, KtCallableSignature<KtCallableSymbol>> {
|
||||
isImplicitInvoke = true
|
||||
@@ -413,24 +415,54 @@ internal class KtFirCallResolver(
|
||||
}
|
||||
|
||||
// Specially handle @ExtensionFunctionType
|
||||
if (dispatchReceiver.coneTypeSafe<ConeKotlinType>()?.isExtensionFunctionType == true) {
|
||||
if (dispatchReceiver?.coneTypeSafe<ConeKotlinType>()?.isExtensionFunctionType == true) {
|
||||
firstArgIsExtensionReceiver = true
|
||||
}
|
||||
|
||||
val dispatchReceiverValue: KtReceiverValue?
|
||||
val extensionReceiverValue: KtReceiverValue?
|
||||
if (explicitReceiverKind == ExplicitReceiverKind.DISPATCH_RECEIVER) {
|
||||
dispatchReceiverValue =
|
||||
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.resolvedType.asKtType(), false, token)
|
||||
if (firstArgIsExtensionReceiver) {
|
||||
extensionReceiverValue = (fir as FirFunctionCall).arguments.firstOrNull()?.toKtReceiverValue()
|
||||
} else {
|
||||
extensionReceiverValue = extensionReceiver.toKtReceiverValue()
|
||||
when (explicitReceiverKind) {
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER -> {
|
||||
checkWithAttachment(
|
||||
dispatchReceiver != null,
|
||||
{ "Dispatch receiver must be not null if explicitReceiverKind is DISPATCH_RECEIVER" }
|
||||
) {
|
||||
withPsiEntry("explicitReceiverPsi", explicitReceiverPsi)
|
||||
extensionReceiver?.let { withFirEntry("extensionReceiver", it) }
|
||||
withFirSymbolEntry("target", targetSymbol)
|
||||
}
|
||||
dispatchReceiverValue =
|
||||
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.resolvedType.asKtType(), false, token)
|
||||
if (firstArgIsExtensionReceiver) {
|
||||
extensionReceiverValue = (fir as FirFunctionCall).arguments.firstOrNull()?.toKtReceiverValue()
|
||||
} else {
|
||||
extensionReceiverValue = extensionReceiver?.toKtReceiverValue()
|
||||
}
|
||||
}
|
||||
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER -> {
|
||||
checkWithAttachment(
|
||||
extensionReceiver != null,
|
||||
{ "Extension receiver must be not null if explicitReceiverKind is EXTENSION_RECEIVER" }
|
||||
) {
|
||||
withPsiEntry("explicitReceiverPsi", explicitReceiverPsi)
|
||||
dispatchReceiver?.let { withFirEntry("dispatchReceiver", it) }
|
||||
withFirSymbolEntry("target", targetSymbol)
|
||||
}
|
||||
|
||||
dispatchReceiverValue = dispatchReceiver?.toKtReceiverValue()
|
||||
extensionReceiverValue =
|
||||
KtExplicitReceiverValue(explicitReceiverPsi, extensionReceiver.resolvedType.asKtType(), false, token)
|
||||
}
|
||||
|
||||
else -> {
|
||||
errorWithAttachment("Implicit invoke call can not have no explicit receiver") {
|
||||
withPsiEntry("explicitReceiverPsi", explicitReceiverPsi)
|
||||
withFirSymbolEntry("targetSymbol", targetSymbol)
|
||||
dispatchReceiver?.let { withFirEntry("dispatchReceiver", it) }
|
||||
extensionReceiver?.let { withFirEntry("extensionReceiver", it) }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dispatchReceiverValue = dispatchReceiver.toKtReceiverValue()
|
||||
extensionReceiverValue =
|
||||
KtExplicitReceiverValue(explicitReceiverPsi, extensionReceiver.resolvedType.asKtType(), false, token)
|
||||
}
|
||||
return KtPartiallyAppliedSymbol(
|
||||
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
|
||||
@@ -445,8 +477,8 @@ 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.dispatchReceiver ?: FirNoReceiverExpression,
|
||||
candidate.chosenExtensionReceiver ?: FirNoReceiverExpression,
|
||||
candidate.dispatchReceiver,
|
||||
candidate.chosenExtensionReceiver,
|
||||
candidate.explicitReceiverKind
|
||||
)
|
||||
} else {
|
||||
@@ -466,14 +498,14 @@ internal class KtFirCallResolver(
|
||||
} else if (fir is FirQualifiedAccessExpression) {
|
||||
KtPartiallyAppliedSymbol(
|
||||
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
|
||||
fir.dispatchReceiver.toKtReceiverValue(),
|
||||
fir.extensionReceiver.toKtReceiverValue()
|
||||
fir.dispatchReceiver?.toKtReceiverValue(),
|
||||
fir.extensionReceiver?.toKtReceiverValue()
|
||||
)
|
||||
} else if (fir is FirVariableAssignment) {
|
||||
KtPartiallyAppliedSymbol(
|
||||
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
|
||||
fir.dispatchReceiver.toKtReceiverValue(),
|
||||
fir.extensionReceiver.toKtReceiverValue()
|
||||
fir.dispatchReceiver?.toKtReceiverValue(),
|
||||
fir.extensionReceiver?.toKtReceiverValue()
|
||||
)
|
||||
} else {
|
||||
KtPartiallyAppliedSymbol(unsubstitutedKtSignature, _dispatchReceiver = null, _extensionReceiver = null)
|
||||
@@ -765,8 +797,8 @@ internal class KtFirCallResolver(
|
||||
val ktSignature = variableSymbol.toKtSignature()
|
||||
return KtPartiallyAppliedSymbol(
|
||||
with(analysisSession) { ktSignature.substitute(substitutor.toKtSubstitutor()) },
|
||||
dispatchReceiver.toKtReceiverValue(),
|
||||
extensionReceiver.toKtReceiverValue(),
|
||||
dispatchReceiver?.toKtReceiverValue(),
|
||||
extensionReceiver?.toKtReceiverValue(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -776,15 +808,31 @@ internal class KtFirCallResolver(
|
||||
val operationSymbol =
|
||||
(calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol ?: return null
|
||||
val substitutor = createConeSubstitutorFromTypeArguments() ?: return null
|
||||
val explicitReceiver = this.explicitReceiver
|
||||
val dispatchReceiver = this.dispatchReceiver
|
||||
val extensionReceiver = this.extensionReceiver
|
||||
|
||||
checkWithAttachment(
|
||||
(explicitReceiver != null) == (explicitReceiverPsiSupplement != null),
|
||||
{ "FIR and PSI for explicit receiver are inconsistent (one of them is null)" }
|
||||
) {
|
||||
withPsiEntry("explicitReceiverPsi", explicitReceiverPsiSupplement)
|
||||
if (explicitReceiver != null) {
|
||||
withFirEntry("explicitReceiverFir", explicitReceiver)
|
||||
} else {
|
||||
withEntry("explicitReceiverFir", "null")
|
||||
}
|
||||
}
|
||||
|
||||
val dispatchReceiverValue = if (explicitReceiverPsiSupplement != null && explicitReceiver == dispatchReceiver) {
|
||||
explicitReceiverPsiSupplement.toExplicitReceiverValue(dispatchReceiver.resolvedType.asKtType())
|
||||
explicitReceiverPsiSupplement.toExplicitReceiverValue(dispatchReceiver!!.resolvedType.asKtType())
|
||||
} else {
|
||||
dispatchReceiver.toKtReceiverValue()
|
||||
dispatchReceiver?.toKtReceiverValue()
|
||||
}
|
||||
val extensionReceiverValue = if (explicitReceiverPsiSupplement != null && explicitReceiver == extensionReceiver) {
|
||||
explicitReceiverPsiSupplement.toExplicitReceiverValue(extensionReceiver.resolvedType.asKtType())
|
||||
explicitReceiverPsiSupplement.toExplicitReceiverValue(extensionReceiver!!.resolvedType.asKtType())
|
||||
} else {
|
||||
extensionReceiver.toKtReceiverValue()
|
||||
extensionReceiver?.toKtReceiverValue()
|
||||
}
|
||||
val ktSignature = operationSymbol.toKtSignature()
|
||||
return KtPartiallyAppliedSymbol(
|
||||
|
||||
+1
-1
@@ -391,7 +391,7 @@ private val FirQualifiedAccessExpression.dispatchedWithoutImport: Boolean
|
||||
get() = when {
|
||||
isQualifiedWithPackage -> true
|
||||
dispatchReceiver is FirThisReceiverExpression -> true
|
||||
dispatchReceiver == explicitReceiver -> true
|
||||
explicitReceiver != null && dispatchReceiver == explicitReceiver -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.java.scopes.JavaClassMembersEnhancementScope
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
@@ -1103,7 +1102,7 @@ private class ElementsToShortenCollector(
|
||||
if (qualifiedAccess.explicitReceiver !is FirResolvedQualifier) return false
|
||||
|
||||
// if there is no extension receiver necessary, then it can be removed
|
||||
return qualifiedAccess.extensionReceiver is FirNoReceiverExpression
|
||||
return qualifiedAccess.extensionReceiver == null
|
||||
}
|
||||
|
||||
private fun findUnambiguousReferencedCallableId(namedReference: FirNamedReference): FirCallableSymbol<*>? {
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ internal class KtFirSmartcastProvider(
|
||||
KtImplicitReceiverSmartCastKind.EXTENSION -> firExpression.extensionReceiver
|
||||
}
|
||||
|
||||
if (receiver == firExpression.explicitReceiver) return null
|
||||
if (receiver == null || receiver == firExpression.explicitReceiver) return null
|
||||
if (!receiver.isStableSmartcast()) return null
|
||||
|
||||
val type = receiver.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return null
|
||||
|
||||
+1
-1
@@ -422,7 +422,7 @@ internal object FirReferenceResolveHelper {
|
||||
// accessing the `super` property on `this`, hence this weird looking if condition. In addition, the current class type is available
|
||||
// from the dispatch receiver `this`.
|
||||
if (expression is KtLabelReferenceExpression && fir is FirPropertyAccessExpression && fir.calleeReference is FirSuperReference) {
|
||||
return listOfNotNull(fir.dispatchReceiver.coneTypeOrNull?.toTargetSymbol(session, symbolBuilder))
|
||||
return listOfNotNull(fir.dispatchReceiver?.coneTypeOrNull?.toTargetSymbol(session, symbolBuilder))
|
||||
}
|
||||
val receiverOrImplicitInvoke = if (fir is FirImplicitInvokeCall) {
|
||||
fir.explicitReceiver?.unwrapSmartcastExpression()
|
||||
|
||||
Reference in New Issue
Block a user