[FIR] Use yieldIfNeed instead of yield

This commit is contained in:
Simon Ogorodnik
2019-12-09 22:10:07 +03:00
parent 81759e8c55
commit 5de69471b0
2 changed files with 31 additions and 18 deletions
@@ -7,33 +7,46 @@ package org.jetbrains.kotlin.fir.resolve.calls
import kotlin.coroutines.Continuation
interface CheckerSink {
fun reportApplicability(new: CandidateApplicability)
suspend fun yield()
suspend fun yieldApplicability(new: CandidateApplicability) {
reportApplicability(new)
yield()
}
abstract class CheckerSink {
abstract fun reportApplicability(new: CandidateApplicability)
val components: InferenceComponents
abstract val components: InferenceComponents
suspend fun yieldIfNeed()
abstract val needYielding: Boolean
@Deprecated(
"This function yields unconditionally, exposed only for yieldIfNeed",
level = DeprecationLevel.WARNING,
replaceWith = ReplaceWith("yieldIfNeed")
)
abstract suspend fun yield()
}
class CheckerSinkImpl(override val components: InferenceComponents, var continuation: Continuation<Unit>? = null) : CheckerSink {
suspend inline fun CheckerSink.yieldIfNeed() {
if (needYielding) {
@Suppress("DEPRECATION")
yield()
}
}
suspend inline fun CheckerSink.yieldApplicability(new: CandidateApplicability) {
reportApplicability(new)
yieldIfNeed()
}
class CheckerSinkImpl(override val components: InferenceComponents, var continuation: Continuation<Unit>? = null) : CheckerSink() {
var current = CandidateApplicability.RESOLVED
override fun reportApplicability(new: CandidateApplicability) {
if (new < current) current = new
}
@Suppress("OverridingDeprecatedMember")
override suspend fun yield() = kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn<Unit> {
continuation = it
kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
}
override suspend fun yieldIfNeed() {
if (current < CandidateApplicability.SYNTHETIC_RESOLVED) {
yield()
}
}
override val needYielding: Boolean
get() = current < CandidateApplicability.SYNTHETIC_RESOLVED
}
@@ -112,7 +112,7 @@ internal sealed class CheckReceivers : ResolutionStage() {
isSafeCall = callInfo.isSafeCall,
typeProvider = callInfo.typeProvider
)
sink.yield()
sink.yieldIfNeed()
} else {
val argumentExtensionReceiverValue = candidate.implicitExtensionReceiverValue
if (argumentExtensionReceiverValue != null && explicitReceiverKind.shouldBeCheckedAgainstImplicit()) {
@@ -125,7 +125,7 @@ internal sealed class CheckReceivers : ResolutionStage() {
isDispatch = this is Dispatch,
isSafeCall = callInfo.isSafeCall
)
sink.yield()
sink.yieldIfNeed()
}
}
}
@@ -161,7 +161,7 @@ internal object CheckArguments : CheckerStage() {
if (candidate.system.hasContradiction) {
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE)
}
sink.yield()
sink.yieldIfNeed()
}
}
}