diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index fcd014f4601..ea2e3d9bf4b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -40,7 +40,6 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind -import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST class FirCallResolver( components: BodyResolveComponents, @@ -118,7 +117,6 @@ class FirCallResolver( val explicitReceiver = functionCall.explicitReceiver val arguments = functionCall.arguments val typeArguments = functionCall.typeArguments - val name = functionCall.calleeReference.name val info = CallInfo( CallKind.Function, @@ -131,13 +129,10 @@ class FirCallResolver( transformer.components.implicitReceiverStack ) towerResolver.reset() - - val consumer = createFunctionConsumer(session, name, info, this, towerResolver.collector, towerResolver) val result = towerResolver.runResolver( - consumer, implicitReceiverStack.receiversAsReversed(), - shouldProcessExtensionsBeforeMembers = name in HIDES_MEMBERS_NAME_LIST, - shouldProcessExplicitReceiverScopeOnly = explicitReceiver?.typeRef?.coneTypeSafe() != null + functionCall.calleeReference.name, + info ) val bestCandidates = result.bestCandidates() val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) { @@ -168,14 +163,11 @@ class FirCallResolver( transformer.components.implicitReceiverStack ) towerResolver.reset() - - val consumer = createVariableAndObjectConsumer( - session, + val result = towerResolver.runResolver( + implicitReceiverStack.receiversAsReversed(), callee.name, - info, this, - towerResolver.collector + info ) - val result = towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed()) val bestCandidates = result.bestCandidates() val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) { @@ -247,15 +239,17 @@ class FirCallResolver( val coneSubstitutor = constraintSystemBuilder.buildCurrentSubstitutor() as ConeSubstitutor val expectedType = resolvedCallableReferenceAtom.expectedType?.let(coneSubstitutor::substituteOrSelf) - val result = CandidateCollector(this, resolutionStageRunner) - val consumer = - createCallableReferencesConsumerForLHS( - callableReferenceAccess, lhs, - result, expectedType, - constraintSystemBuilder - ) - - towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed()) + val info = createCallableReferencesInfoForLHS( + callableReferenceAccess, lhs, + expectedType, constraintSystemBuilder + ) + // No reset here! + val result = towerResolver.runResolver( + implicitReceiverStack.receiversAsReversed(), + callableReferenceAccess.calleeReference.name, + info, + collector = CandidateCollector(this, resolutionStageRunner) + ) val bestCandidates = result.bestCandidates() val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED val reducedCandidates = if (noSuccessfulCandidates) { @@ -336,79 +330,29 @@ class FirCallResolver( return call.transformCalleeReference(StoreNameReference, nameReference) as T } - private fun createCallableReferencesConsumerForLHS( + private fun createCallableReferencesInfoForLHS( callableReferenceAccess: FirCallableReferenceAccess, lhs: DoubleColonLHS?, - resultCollector: CandidateCollector, expectedType: ConeKotlinType?, outerConstraintSystemBuilder: ConstraintSystemBuilder? - ): TowerDataConsumer { - val name = callableReferenceAccess.calleeReference.name - - return when (lhs) { - is DoubleColonLHS.Expression, null -> createCallableReferencesConsumerForReceiver( - name, resultCollector, callableReferenceAccess.explicitReceiver, expectedType, outerConstraintSystemBuilder, - lhs - ) - is DoubleColonLHS.Type -> createCallableReferencesConsumerForReceivers( - name, - resultCollector, - expectedType, - outerConstraintSystemBuilder, - lhs, - FirExpressionStub(callableReferenceAccess.source).apply { replaceTypeRef(FirResolvedTypeRefImpl(null, lhs.type)) }, - callableReferenceAccess.explicitReceiver - ) - } - } - - private fun createCallableReferencesConsumerForReceivers( - name: Name, - resultCollector: CandidateCollector, - expectedType: ConeKotlinType?, - outerConstraintSystemBuilder: ConstraintSystemBuilder?, - lhs: DoubleColonLHS?, - vararg receivers: FirExpression? - ): TowerDataConsumer { - if (receivers.size == 1) { - return createCallableReferencesConsumerForReceiver( - name, resultCollector, receivers[0], expectedType, outerConstraintSystemBuilder, lhs - ) - } - - return PrioritizedTowerDataConsumer( - resultCollector, - *Array(receivers.size) { index -> - createCallableReferencesConsumerForReceiver( - name, resultCollector, receivers[index], expectedType, outerConstraintSystemBuilder, lhs - ) - } - ) - } - - private fun createCallableReferencesConsumerForReceiver( - name: Name, - resultCollector: CandidateCollector, - receiver: FirExpression?, - expectedType: ConeKotlinType?, - outerConstraintSystemBuilder: ConstraintSystemBuilder?, - lhs: DoubleColonLHS? - ): TowerDataConsumer { - val info = CallInfo( + ): CallInfo { + return CallInfo( CallKind.CallableReference, - receiver, + callableReferenceAccess.explicitReceiver, emptyList(), false, emptyList(), session, file, transformer.components.implicitReceiverStack, + // Additional things for callable reference resolve expectedType, outerConstraintSystemBuilder, - lhs + lhs, + stubReceiver = if (lhs !is DoubleColonLHS.Type) null else FirExpressionStub(callableReferenceAccess.source).apply { + replaceTypeRef(FirResolvedTypeRefImpl(null, lhs.type)) + } ) - - return createCallableReferencesConsumer(session, name, info, this, resultCollector) } private fun createResolvedNamedReference( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt index a4b26d5bd75..3c5927433f3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt @@ -36,10 +36,11 @@ class CallInfo( val containingFile: FirFile, val implicitReceiverStack: ImplicitReceiverStack, - // Three properties for callable references only + // Four properties for callable references only val expectedType: ConeKotlinType? = null, val outerCSBuilder: ConstraintSystemBuilder? = null, - val lhs: DoubleColonLHS? = null + val lhs: DoubleColonLHS? = null, + val stubReceiver: FirExpression? = null ) { val argumentCount get() = arguments.size diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt index 21e51c70ccd..4fb95ed1cef 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt @@ -14,6 +14,10 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NONE import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope +import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType +import org.jetbrains.kotlin.fir.types.coneTypeSafe +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST enum class TowerDataKind { EMPTY, // Corresponds to stub tower level which is replaced by receiver-related level @@ -199,13 +203,38 @@ class FirTowerResolver( private lateinit var implicitReceiverValues: List> fun runResolver( - consumer: TowerDataConsumer, - implicitReceiverValues: List>, - shouldProcessExtensionsBeforeMembers: Boolean = false, - shouldProcessExplicitReceiverScopeOnly: Boolean = false + implicitReceiverValues: List>, name: Name, info: CallInfo, + collector: CandidateCollector = this.collector ): CandidateCollector { this.implicitReceiverValues = implicitReceiverValues - towerDataConsumer = consumer + towerDataConsumer = when (info.callKind) { + CallKind.VariableAccess -> { + createVariableAndObjectConsumer(session, name, info, components, collector) + } + CallKind.Function -> { + createFunctionConsumer(session, name, info, components, collector, this) + } + CallKind.CallableReference -> { + if (info.stubReceiver == null) { + createCallableReferencesConsumer(session, name, info, components, collector) + } else { + PrioritizedTowerDataConsumer( + collector, + createCallableReferencesConsumer( + session, name, info.replaceExplicitReceiver(info.stubReceiver), components, collector + ), + createCallableReferencesConsumer( + session, name, info, components, collector + ) + ) + } + } + else -> throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}") + } + val shouldProcessExtensionsBeforeMembers = + info.callKind == CallKind.Function && name in HIDES_MEMBERS_NAME_LIST + val shouldProcessExplicitReceiverScopeOnly = + info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe() != null var group = 0