[FIR] Code refactoring: InvokeReceiverCandidateCollector
This commit is contained in:
@@ -43,6 +43,12 @@ class CallInfo(
|
|||||||
) {
|
) {
|
||||||
val argumentCount get() = arguments.size
|
val argumentCount get() = arguments.size
|
||||||
|
|
||||||
|
fun replaceExplicitReceiver(explicitReceiver: FirExpression): CallInfo =
|
||||||
|
CallInfo(
|
||||||
|
callKind, explicitReceiver, arguments,
|
||||||
|
isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs
|
||||||
|
)
|
||||||
|
|
||||||
fun withReceiverAsArgument(receiverExpression: FirExpression): CallInfo =
|
fun withReceiverAsArgument(receiverExpression: FirExpression): CallInfo =
|
||||||
CallInfo(
|
CallInfo(
|
||||||
callKind, explicitReceiver,
|
callKind, explicitReceiver,
|
||||||
|
|||||||
+23
-28
@@ -80,52 +80,47 @@ class InvokeReceiverCandidateCollector(
|
|||||||
private val invokeConsumer: AccumulatingTowerDataConsumer,
|
private val invokeConsumer: AccumulatingTowerDataConsumer,
|
||||||
resolutionStageRunner: ResolutionStageRunner
|
resolutionStageRunner: ResolutionStageRunner
|
||||||
) : CandidateCollector(components, resolutionStageRunner) {
|
) : CandidateCollector(components, resolutionStageRunner) {
|
||||||
|
private fun createBoundInvokeConsumer(boundInvokeCallInfo: CallInfo): TowerDataConsumer {
|
||||||
|
return createSimpleFunctionConsumer(
|
||||||
|
components.session, OperatorNameConventions.INVOKE,
|
||||||
|
boundInvokeCallInfo, components, towerResolver.collector
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createExplicitReceiverForInvoke(candidate: Candidate): FirQualifiedAccessExpressionImpl {
|
||||||
|
val symbol = candidate.symbol as FirCallableSymbol<*>
|
||||||
|
return FirQualifiedAccessExpressionImpl(null).apply {
|
||||||
|
calleeReference = FirNamedReferenceWithCandidate(
|
||||||
|
null,
|
||||||
|
symbol.callableId.callableName,
|
||||||
|
candidate
|
||||||
|
)
|
||||||
|
dispatchReceiver = candidate.dispatchReceiverExpression()
|
||||||
|
typeRef = towerResolver.typeCalculator.tryCalculateReturnType(symbol.firUnsafe())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
||||||
val applicability = super.consumeCandidate(group, candidate)
|
val applicability = super.consumeCandidate(group, candidate)
|
||||||
|
|
||||||
if (applicability >= CandidateApplicability.SYNTHETIC_RESOLVED) {
|
if (applicability >= CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||||
val session = components.session
|
|
||||||
val symbol = candidate.symbol as FirCallableSymbol<*>
|
val symbol = candidate.symbol as FirCallableSymbol<*>
|
||||||
val extensionReceiverExpression = candidate.extensionReceiverExpression()
|
val extensionReceiverExpression = candidate.extensionReceiverExpression()
|
||||||
val useExtensionReceiverAsArgument =
|
val useExtensionReceiverAsArgument =
|
||||||
symbol.fir.receiverTypeRef == null &&
|
symbol.fir.receiverTypeRef == null &&
|
||||||
candidate.explicitReceiverKind == ExplicitReceiverKind.EXTENSION_RECEIVER &&
|
candidate.explicitReceiverKind == ExplicitReceiverKind.EXTENSION_RECEIVER &&
|
||||||
symbol.fir.returnTypeRef.isExtensionFunctionType()
|
symbol.fir.returnTypeRef.isExtensionFunctionType()
|
||||||
val explicitReceiver = FirQualifiedAccessExpressionImpl(null).apply {
|
val explicitReceiver = createExplicitReceiverForInvoke(candidate).apply {
|
||||||
calleeReference = FirNamedReferenceWithCandidate(
|
|
||||||
null,
|
|
||||||
symbol.callableId.callableName,
|
|
||||||
candidate
|
|
||||||
)
|
|
||||||
dispatchReceiver = candidate.dispatchReceiverExpression()
|
|
||||||
extensionReceiver = extensionReceiverExpression.takeIf { !useExtensionReceiverAsArgument } ?: FirNoReceiverExpression
|
extensionReceiver = extensionReceiverExpression.takeIf { !useExtensionReceiverAsArgument } ?: FirNoReceiverExpression
|
||||||
typeRef = towerResolver.typeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe())
|
|
||||||
}.let {
|
}.let {
|
||||||
components.transformQualifiedAccessUsingSmartcastInfo(it)
|
components.transformQualifiedAccessUsingSmartcastInfo(it)
|
||||||
}
|
}
|
||||||
val boundInvokeCallInfo = CallInfo(
|
val boundInvokeCallInfo = invokeCallInfo.replaceExplicitReceiver(explicitReceiver).let {
|
||||||
invokeCallInfo.callKind,
|
|
||||||
explicitReceiver,
|
|
||||||
invokeCallInfo.arguments,
|
|
||||||
invokeCallInfo.isSafeCall,
|
|
||||||
invokeCallInfo.typeArguments,
|
|
||||||
session,
|
|
||||||
invokeCallInfo.containingFile,
|
|
||||||
invokeCallInfo.implicitReceiverStack,
|
|
||||||
invokeCallInfo.expectedType,
|
|
||||||
invokeCallInfo.outerCSBuilder,
|
|
||||||
invokeCallInfo.lhs
|
|
||||||
).let {
|
|
||||||
if (useExtensionReceiverAsArgument) it.withReceiverAsArgument(extensionReceiverExpression)
|
if (useExtensionReceiverAsArgument) it.withReceiverAsArgument(extensionReceiverExpression)
|
||||||
else it
|
else it
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeConsumer.addConsumerAndProcessAccumulatedData(
|
invokeConsumer.addConsumerAndProcessAccumulatedData(createBoundInvokeConsumer(boundInvokeCallInfo))
|
||||||
createSimpleFunctionConsumer(
|
|
||||||
session, OperatorNameConventions.INVOKE,
|
|
||||||
boundInvokeCallInfo, towerResolver.components, towerResolver.collector
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return applicability
|
return applicability
|
||||||
|
|||||||
Reference in New Issue
Block a user