[FIR] Extract function for receiver resolution

This commit is contained in:
Kirill Rakhman
2024-03-13 12:17:59 +01:00
committed by Space Team
parent ff981a49ad
commit 609906a0b1
2 changed files with 28 additions and 29 deletions
@@ -264,7 +264,7 @@ class FirCallResolver(
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val qualifiedAccess = qualifiedAccess.let(transformer::transformExplicitReceiver) val qualifiedAccess = qualifiedAccess.let(transformer::transformExplicitReceiverOf)
val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics
val basicResult by lazy(LazyThreadSafetyMode.NONE) { val basicResult by lazy(LazyThreadSafetyMode.NONE) {
@@ -199,8 +199,8 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
return result return result
} }
fun <Q : FirQualifiedAccessExpression> transformExplicitReceiver(qualifiedAccessExpression: Q): Q { fun <Q : FirQualifiedAccessExpression> transformExplicitReceiverOf(qualifiedAccessExpression: Q): Q {
val explicitReceiver = qualifiedAccessExpression.explicitReceiver as? FirQualifiedAccessExpression val explicitReceiver = qualifiedAccessExpression.explicitReceiver
if (explicitReceiver is FirQualifiedAccessExpression) { if (explicitReceiver is FirQualifiedAccessExpression) {
val superReference = explicitReceiver.calleeReference as? FirSuperReference val superReference = explicitReceiver.calleeReference as? FirSuperReference
if (superReference != null) { if (superReference != null) {
@@ -208,16 +208,26 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
return qualifiedAccessExpression return qualifiedAccessExpression
} }
} }
if (explicitReceiver is FirPropertyAccessExpression) {
if (explicitReceiver != null) {
qualifiedAccessExpression.replaceExplicitReceiver( qualifiedAccessExpression.replaceExplicitReceiver(
transformQualifiedAccessExpression( explicitReceiver.transformAsExplicitReceiver(ResolutionMode.ReceiverResolution, isUsedAsGetClassReceiver = false)
explicitReceiver, ResolutionMode.ReceiverResolution, isUsedAsReceiver = true, isUsedAsGetClassReceiver = false
)
) )
return qualifiedAccessExpression
} }
@Suppress("UNCHECKED_CAST")
return qualifiedAccessExpression.transformExplicitReceiver(transformer, ResolutionMode.ReceiverResolution) as Q return qualifiedAccessExpression
}
private fun FirExpression.transformAsExplicitReceiver(
resolutionMode: ResolutionMode,
isUsedAsGetClassReceiver: Boolean,
): FirExpression {
return when (this) {
is FirPropertyAccessExpression -> transformQualifiedAccessExpression(
this, resolutionMode, isUsedAsReceiver = true, isUsedAsGetClassReceiver = isUsedAsGetClassReceiver
)
else -> transformSingle(this@FirExpressionsResolveTransformer, resolutionMode)
}
} }
override fun transformPropertyAccessExpression( override fun transformPropertyAccessExpression(
@@ -456,7 +466,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
// and 'someDelegate' explicit receiver is resolved at 1st stage // and 'someDelegate' explicit receiver is resolved at 1st stage
// See also FirDeclarationsResolveTransformer.transformWrappedDelegateExpression // See also FirDeclarationsResolveTransformer.transformWrappedDelegateExpression
val withResolvedExplicitReceiver = val withResolvedExplicitReceiver =
if (callResolutionMode == CallResolutionMode.PROVIDE_DELEGATE) functionCall else transformExplicitReceiver(functionCall) if (callResolutionMode == CallResolutionMode.PROVIDE_DELEGATE) functionCall else transformExplicitReceiverOf(functionCall)
withResolvedExplicitReceiver.also { withResolvedExplicitReceiver.also {
it.replaceArgumentList(it.argumentList.transform(this, ResolutionMode.ContextDependent)) it.replaceArgumentList(it.argumentList.transform(this, ResolutionMode.ContextDependent))
dataFlowAnalyzer.exitCallArguments() dataFlowAnalyzer.exitCallArguments()
@@ -1101,18 +1111,13 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
callableReferenceAccess.transformAnnotations(transformer, data) callableReferenceAccess.transformAnnotations(transformer, data)
val explicitReceiver = callableReferenceAccess.explicitReceiver val explicitReceiver = callableReferenceAccess.explicitReceiver
val transformedLHS = when (explicitReceiver) { val transformedLHS = explicitReceiver
is FirPropertyAccessExpression -> ?.transformAsExplicitReceiver(ResolutionMode.ReceiverResolution.ForCallableReference, false)
transformQualifiedAccessExpression( .apply {
explicitReceiver, ResolutionMode.ReceiverResolution.ForCallableReference, isUsedAsReceiver = true, isUsedAsGetClassReceiver = false if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) {
) replaceIsNullableLHSForCallableReference(true)
else -> }
explicitReceiver?.transformSingle(this, ResolutionMode.ReceiverResolution.ForCallableReference)
}.apply {
if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) {
replaceIsNullableLHSForCallableReference(true)
} }
}
transformedLHS?.let { callableReferenceAccess.replaceExplicitReceiver(transformedLHS) } transformedLHS?.let { callableReferenceAccess.replaceExplicitReceiver(transformedLHS) }
@@ -1142,13 +1147,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val transformedGetClassCall = run { val transformedGetClassCall = run {
val argument = getClassCall.argument val argument = getClassCall.argument
val replacedArgument: FirExpression = val replacedArgument: FirExpression = argument.transformAsExplicitReceiver(dataForLhs, isUsedAsGetClassReceiver = true)
if (argument is FirPropertyAccessExpression)
transformQualifiedAccessExpression(
argument, dataForLhs, isUsedAsReceiver = true, isUsedAsGetClassReceiver = true
)
else
argument.transform(this, dataForLhs)
getClassCall.argumentList.transformArguments(object : FirTransformer<Nothing?>() { getClassCall.argumentList.transformArguments(object : FirTransformer<Nothing?>() {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")