Remove suspending function migration adapters for 1.3-M1
This commit is contained in:
-76
@@ -12,54 +12,6 @@ import kotlin.coroutines.experimental.EmptyCoroutineContext as ExperimentalEmpty
|
||||
import kotlin.coroutines.experimental.ContinuationInterceptor as ExperimentalContinuationInterceptor
|
||||
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED as EXPERIMENTAL_COROUTINE_SUSPENDED
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
|
||||
/**
|
||||
* Adapter to invoke experimental suspending function.
|
||||
*
|
||||
* To invoke experimental suspending function `foo(args)` that returns value of some type `Result`
|
||||
* from Kotlin 1.3 use the following code:
|
||||
*
|
||||
* ```
|
||||
* invokeExperimentalSuspend<Result> { foo(args, it) }
|
||||
* ```
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
public suspend inline fun <T> invokeExperimentalSuspend(crossinline invocation: (ExperimentalContinuation<T>) -> Any?): T =
|
||||
suspendCoroutineUninterceptedOrReturn { continuation ->
|
||||
val result = invocation(continuation.toExperimentalContinuation())
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
if (result === EXPERIMENTAL_COROUTINE_SUSPENDED) COROUTINE_SUSPENDED else result as T
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverts reference to suspending function to experimental suspending function.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
public fun <T> (suspend () -> T).toExperimentalSuspendFunction(): (ExperimentalContinuation<T>) -> Any? =
|
||||
ExperimentalSuspendFunction0Migration(this)
|
||||
|
||||
/**
|
||||
* Coverts reference to experimental suspending function to suspending function.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
public fun <T> ((ExperimentalContinuation<T>) -> Any?).toSuspendFunction(): suspend () -> T =
|
||||
(this as? ExperimentalSuspendFunction0Migration)?.function ?: SuspendFunction0Migration(this)::invoke
|
||||
|
||||
/**
|
||||
* Coverts reference to suspending function with receiver to experimental suspending function.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
public fun <R, T> (suspend (R) -> T).toExperimentalSuspendFunction(): (R, ExperimentalContinuation<T>) -> Any? =
|
||||
ExperimentalSuspendFunction1Migration(this)
|
||||
|
||||
/**
|
||||
* Coverts reference to experimental suspending function with receiver to suspending function.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
public fun <R, T> ((R, ExperimentalContinuation<T>) -> Any?).toSuspendFunction(): suspend (R) -> T =
|
||||
(this as? ExperimentalSuspendFunction1Migration)?.function ?: SuspendFunction1Migration(this)::invoke
|
||||
|
||||
/**
|
||||
* Converts [Continuation] to [ExperimentalContinuation].
|
||||
@@ -118,34 +70,6 @@ public fun ExperimentalContinuationInterceptor.toContinuationInterceptor(): Cont
|
||||
// ------------------ converter classes ------------------
|
||||
// Their name starts with "Experimental" if they implement the corresponding Experimental interfaces
|
||||
|
||||
private class ExperimentalSuspendFunction0Migration<T>(val function: suspend () -> T) : (ExperimentalContinuation<T>) -> Any? {
|
||||
override fun invoke(continuation: ExperimentalContinuation<T>): Any? {
|
||||
val result = function.startCoroutineUninterceptedOrReturn(continuation.toContinuation())
|
||||
return if (result === COROUTINE_SUSPENDED) EXPERIMENTAL_COROUTINE_SUSPENDED else result
|
||||
}
|
||||
}
|
||||
|
||||
private class SuspendFunction0Migration<T>(val function: (ExperimentalContinuation<T>) -> Any?) {
|
||||
suspend fun invoke(): T = suspendCoroutineUninterceptedOrReturn { continuation ->
|
||||
val result = function(continuation.toExperimentalContinuation())
|
||||
if (result === EXPERIMENTAL_COROUTINE_SUSPENDED) COROUTINE_SUSPENDED else result
|
||||
}
|
||||
}
|
||||
|
||||
private class ExperimentalSuspendFunction1Migration<R, T>(val function: suspend (R) -> T) : (R, ExperimentalContinuation<T>) -> Any? {
|
||||
override fun invoke(receiver: R, continuation: ExperimentalContinuation<T>): Any? {
|
||||
val result = function.startCoroutineUninterceptedOrReturn(receiver, continuation.toContinuation())
|
||||
return if (result === COROUTINE_SUSPENDED) EXPERIMENTAL_COROUTINE_SUSPENDED else result
|
||||
}
|
||||
}
|
||||
|
||||
private class SuspendFunction1Migration<R, T>(val function: (R, ExperimentalContinuation<T>) -> Any?) {
|
||||
suspend fun invoke(receiver: R): T = suspendCoroutineUninterceptedOrReturn { continuation ->
|
||||
val result = function(receiver, continuation.toExperimentalContinuation())
|
||||
if (result === EXPERIMENTAL_COROUTINE_SUSPENDED) COROUTINE_SUSPENDED else result
|
||||
}
|
||||
}
|
||||
|
||||
private class ExperimentalContinuationMigration<T>(val continuation: Continuation<T>): ExperimentalContinuation<T> {
|
||||
override val context = continuation.context.toExperimentalCoroutineContext()
|
||||
override fun resume(value: T) = continuation.resume(value)
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
package test.kotlin.coroutines.experimental.migration
|
||||
|
||||
import test.kotlin.coroutines.TestDispatcher
|
||||
import java.util.concurrent.Semaphore
|
||||
import kotlin.coroutines.experimental.buildSequence as experimentalBuildSequence
|
||||
import kotlin.coroutines.experimental.SequenceBuilder as ExperimentalSequenceBuilder
|
||||
import kotlin.coroutines.experimental.Continuation as ExperimentalContinuation
|
||||
@@ -19,8 +17,6 @@ import kotlin.coroutines.experimental.ContinuationInterceptor as ExperimentalCon
|
||||
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED as EXPERIMENTAL_COROUTINE_SUSPENDED
|
||||
import kotlin.coroutines.experimental.migration.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.experimental.startCoroutine
|
||||
import kotlin.coroutines.jvm.internal.runSuspend
|
||||
import kotlin.test.*
|
||||
|
||||
/**
|
||||
@@ -47,86 +43,6 @@ class CoroutinesMigrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFunctionMigration() {
|
||||
var fooCnt = 0
|
||||
suspend fun foo() {
|
||||
fooCnt++
|
||||
}
|
||||
runSuspend {
|
||||
foo()
|
||||
}
|
||||
assertEquals(1, fooCnt)
|
||||
val foo2 = ::foo.toExperimentalSuspendFunction().toSuspendFunction()
|
||||
runSuspend {
|
||||
foo2()
|
||||
}
|
||||
assertEquals(2, fooCnt)
|
||||
var barCnt = 0
|
||||
suspend fun bar(x: Int) {
|
||||
barCnt += x
|
||||
}
|
||||
runSuspend {
|
||||
bar(2)
|
||||
}
|
||||
assertEquals(2, barCnt)
|
||||
val bar2 = ::bar.toExperimentalSuspendFunction().toSuspendFunction()
|
||||
runSuspend {
|
||||
bar2(3)
|
||||
}
|
||||
assertEquals(5, barCnt)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInvokeExperimental0() {
|
||||
testInvokeExperimentalImpl(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInvokeExperimental1() {
|
||||
testInvokeExperimentalImpl(true)
|
||||
}
|
||||
|
||||
private fun testInvokeExperimentalImpl(shallSuspend: Boolean) {
|
||||
TestDispatcher("testInvokeExperimental").use { dispatcher ->
|
||||
val semaphore = Semaphore(0)
|
||||
val foo: suspend (Int) -> String = {
|
||||
dispatcher.assertThread()
|
||||
if (shallSuspend) {
|
||||
dispatcher.yield()
|
||||
}
|
||||
"OK$it"
|
||||
}
|
||||
val fooExp = foo.toExperimentalSuspendFunction()
|
||||
val testCode: suspend () -> String = {
|
||||
dispatcher.assertThread()
|
||||
val result = invokeExperimentalSuspend<String> {
|
||||
fooExp(42, it)
|
||||
}
|
||||
assertEquals("OK42", result)
|
||||
dispatcher.assertThread()
|
||||
"DONE"
|
||||
}
|
||||
testCode.startCoroutine(Continuation(dispatcher) { result ->
|
||||
dispatcher.assertThread()
|
||||
assertEquals("DONE", result.getOrThrow())
|
||||
semaphore.release()
|
||||
})
|
||||
semaphore.acquire()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExperimentalBuildSequence() {
|
||||
suspend fun action(builder: ExperimentalSequenceBuilder<Int>) {
|
||||
invokeExperimentalSuspend<Unit> { builder.yield(1, it) }
|
||||
invokeExperimentalSuspend<Unit> { builder.yield(2, it) }
|
||||
invokeExperimentalSuspend<Unit> { builder.yield(3, it) }
|
||||
}
|
||||
val seq = experimentalBuildSequence(::action.toExperimentalSuspendFunction())
|
||||
assertEquals(listOf(1, 2, 3), seq.toList())
|
||||
}
|
||||
|
||||
class MyElement : AbstractCoroutineContextElement(Key) {
|
||||
companion object Key : CoroutineContext.Key<MyElement>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user