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 34e2ac89920..4bb358b76de 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -41,7 +41,8 @@ class FirCallResolver( private val scopes: List, private val localScopes: List, private val implicitReceiverStack: List, - private val qualifiedResolver: FirQualifiedNameResolver + private val qualifiedResolver: FirQualifiedNameResolver, + private val resolutionStageRunner: ResolutionStageRunner ) : BodyResolveComponents by transformer { fun resolveCallAndSelectCandidate(functionCall: FirFunctionCall, expectedTypeRef: FirTypeRef?, file: FirFile): FirFunctionCall { @@ -66,7 +67,7 @@ class FirCallResolver( file, transformer.container ) { it.resultType } - val resolver = CallResolver(returnTypeCalculator, inferenceComponents) + val resolver = CallResolver(returnTypeCalculator, inferenceComponents, resolutionStageRunner) resolver.callInfo = info resolver.scopes = (scopes + localScopes).asReversed() @@ -156,7 +157,7 @@ class FirCallResolver( file, transformer.container ) { it.resultType } - val resolver = CallResolver(returnTypeCalculator, inferenceComponents) + val resolver = CallResolver(returnTypeCalculator, inferenceComponents, resolutionStageRunner) resolver.callInfo = info resolver.scopes = (scopes + localScopes).asReversed() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt index 57b68a39e19..fdc963b6f07 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt @@ -14,7 +14,11 @@ enum class TowerDataKind { TOWER_LEVEL } -class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: InferenceComponents) { +class CallResolver( + val typeCalculator: ReturnTypeCalculator, + val components: InferenceComponents, + val resolutionStageRunner: ResolutionStageRunner +) { var callInfo: CallInfo? = null var scopes: List? = null @@ -51,7 +55,7 @@ class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: Inf return group } - val collector by lazy { CandidateCollector(components) } + val collector by lazy { CandidateCollector(components, resolutionStageRunner) } lateinit var towerDataConsumer: TowerDataConsumer private lateinit var implicitReceiverValues: List diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt index f8cdf57390f..dec06ea4d4d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt @@ -9,14 +9,11 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImp import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol import org.jetbrains.kotlin.util.OperatorNameConventions -import kotlin.coroutines.Continuation -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.EmptyCoroutineContext -import kotlin.coroutines.intrinsics.createCoroutineUnintercepted -import kotlin.coroutines.resume - -open class CandidateCollector(val components: InferenceComponents) { +open class CandidateCollector( + val components: InferenceComponents, + val resolutionStageRunner: ResolutionStageRunner +) { val groupNumbers = mutableListOf() val candidates = mutableListOf() @@ -28,37 +25,8 @@ open class CandidateCollector(val components: InferenceComponents) { currentApplicability = CandidateApplicability.HIDDEN } - private fun getApplicability( - group: Int, - candidate: Candidate - ): CandidateApplicability { - val sink = CheckerSinkImpl(components) - var finished = false - sink.continuation = suspend { - for (stage in candidate.callInfo.callKind.sequence()) { - stage.check(candidate, sink, candidate.callInfo) - } - }.createCoroutineUnintercepted(completion = object : Continuation { - override val context: CoroutineContext - get() = EmptyCoroutineContext - - override fun resumeWith(result: Result) { - result.exceptionOrNull()?.let { throw it } - finished = true - } - }) - - while (!finished) { - sink.continuation!!.resume(Unit) - if (sink.current < CandidateApplicability.SYNTHETIC_RESOLVED) { - break - } - } - return sink.current - } - open fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability { - val applicability = getApplicability(group, candidate) + val applicability = resolutionStageRunner.processCandidate(candidate) if (applicability > currentApplicability) { groupNumbers.clear() @@ -103,8 +71,9 @@ class InvokeReceiverCandidateCollector( val callResolver: CallResolver, val invokeCallInfo: CallInfo, components: InferenceComponents, - val invokeConsumer: AccumulatingTowerDataConsumer -) : CandidateCollector(components) { + val invokeConsumer: AccumulatingTowerDataConsumer, + resolutionStageRunner: ResolutionStageRunner +) : CandidateCollector(components, resolutionStageRunner) { override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability { val applicability = super.consumeCandidate(group, candidate) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt index c44b2723920..61f5a82e079 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt @@ -94,7 +94,8 @@ fun createFunctionConsumer( callResolver, invokeCallInfo = callInfo, components = inferenceComponents, - invokeConsumer = this + invokeConsumer = this, + resolutionStageRunner = resultCollector.resolutionStageRunner ) ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStageRunner.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStageRunner.kt new file mode 100644 index 00000000000..f600dcd60a0 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStageRunner.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.calls + +import kotlin.coroutines.Continuation +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.coroutines.intrinsics.createCoroutineUnintercepted +import kotlin.coroutines.resume + +class ResolutionStageRunner(val components: InferenceComponents) { + fun processCandidate(candidate: Candidate): CandidateApplicability { + val sink = CheckerSinkImpl(components) + var finished = false + sink.continuation = suspend { + for (stage in candidate.callInfo.callKind.sequence()) { + stage.check(candidate, sink, candidate.callInfo) + } + }.createCoroutineUnintercepted(completion = object : Continuation { + override val context: CoroutineContext + get() = EmptyCoroutineContext + + override fun resumeWith(result: Result) { + result.exceptionOrNull()?.let { throw it } + finished = true + } + }) + + while (!finished) { + sink.continuation!!.resume(Unit) + if (sink.current < CandidateApplicability.SYNTHETIC_RESOLVED) { + break + } + } + return sink.current + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt index 60da548916d..da101f5e061 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt @@ -71,7 +71,16 @@ open class FirBodyResolveTransformer( private val callCompleter: FirCallCompleter = FirCallCompleter(this, inferenceComponents) private val qualifiedResolver: FirQualifiedNameResolver = FirQualifiedNameResolver(this) - private val callResolver: FirCallResolver = FirCallResolver(this, inferenceComponents, scopes, localScopes, implicitReceiverStack, qualifiedResolver) + private val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents) + private val callResolver: FirCallResolver = FirCallResolver( + this, + inferenceComponents, + scopes, + localScopes, + implicitReceiverStack, + qualifiedResolver, + resolutionStageRunner + ) override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult { packageFqName = file.packageFqName