提交 0b0e2c3a 编写于 作者: D Dmitriy Novozhilov

[TD] Create real helpers files for coroutines checkers

上级 710c5ec8
package helpers
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
import kotlin.coroutines.jvm.internal.*
fun <T> handleResultContinuation(x: (T) -> Unit): Continuation<T> = object: Continuation<T> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<T>) {
x(result.getOrThrow())
}
}
fun handleExceptionContinuation(x: (Throwable) -> Unit): Continuation<Any?> = object: Continuation<Any?> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<Any?>) {
result.exceptionOrNull()?.let(x)
}
}
open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation<Any?> {
companion object : EmptyContinuation()
override fun resumeWith(result: Result<Any?>) {
result.getOrThrow()
}
}
class ResultContinuation : Continuation<Any?> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<Any?>) {
this.result = result.getOrThrow()
}
var result: Any? = null
}
abstract class ContinuationAdapter<in T> : Continuation<T> {
override val context: CoroutineContext = EmptyCoroutineContext
override fun resumeWith(result: Result<T>) {
if (result.isSuccess) {
resume(result.getOrThrow())
} else {
resumeWithException(result.exceptionOrNull()!!)
}
}
abstract fun resumeWithException(exception: Throwable)
abstract fun resume(value: T)
}
package helpers
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
import kotlin.coroutines.jvm.internal.*
class StateMachineCheckerClass {
private var counter = 0
var finished = false
var proceed: () -> Unit = {}
fun reset() {
counter = 0
finished = false
proceed = {}
}
suspend fun suspendHere() = suspendCoroutine<Unit> { c ->
counter++
proceed = { c.resume(Unit) }
}
fun check(numberOfSuspensions: Int, checkFinished: Boolean = true) {
for (i in 1..numberOfSuspensions) {
if (counter != i) error("Wrong state-machine generated: suspendHere should be called exactly once in one state. Expected " + i + ", got " + counter)
proceed()
}
if (counter != numberOfSuspensions)
error("Wrong state-machine generated: wrong number of overall suspensions. Expected " + numberOfSuspensions + ", got " + counter)
if (finished) error("Wrong state-machine generated: it is finished early")
proceed()
if (checkFinished && !finished) error("Wrong state-machine generated: it is not finished yet")
}
}
val StateMachineChecker = StateMachineCheckerClass()
object CheckStateMachineContinuation: ContinuationAdapter<Unit>() {
override val context: CoroutineContext
get() = EmptyCoroutineContext
override fun resume(value: Unit) {
StateMachineChecker.proceed = {
StateMachineChecker.finished = true
}
}
override fun resumeWithException(exception: Throwable) {
throw exception
}
}
package helpers
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
import kotlin.coroutines.jvm.internal.*
class TailCallOptimizationCheckerClass {
private val stackTrace = arrayListOf<StackTraceElement?>()
suspend fun saveStackTrace() = suspendCoroutineUninterceptedOrReturn<Unit> {
saveStackTrace(it)
}
fun saveStackTrace(c: Continuation<*>) {
if (c !is CoroutineStackFrame) error("Continuation " + c + " is not subtype of CoroutineStackFrame")
stackTrace.clear()
var csf: CoroutineStackFrame? = c
while (csf != null) {
stackTrace.add(csf.getStackTraceElement())
csf = csf.callerFrame
}
}
fun checkNoStateMachineIn(method: String) {
stackTrace.find { it?.methodName?.startsWith(method) == true }?.let { error("tail-call optimization miss: method at " + it + " has state-machine " +
stackTrace.joinToString(separator = "\n")) }
}
fun checkStateMachineIn(method: String) {
stackTrace.find { it?.methodName?.startsWith(method) == true } ?: error("tail-call optimization hit: method " + method + " has no state-machine " +
stackTrace.joinToString(separator = "\n"))
}
}
val TailCallOptimizationChecker = TailCallOptimizationCheckerClass()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册