@@ -10,41 +10,36 @@ import kotlin.coroutines.intrinsics.*
10
10
import kotlin.coroutines.jvm.internal.*
11
11
12
12
@Suppress(" UNCHECKED_CAST" )
13
+ private val emitFun =
14
+ FlowCollector <Any ?>::emit as Function3 <FlowCollector <Any ?>, Any? , Continuation <Unit >, Any? >
15
+ /*
16
+ * Implementor of ContinuationImpl (that will be preserved as ABI nearly forever)
17
+ * in order to properly control 'intercepted()' lifecycle.
18
+ */
19
+ @Suppress(" CANNOT_OVERRIDE_INVISIBLE_MEMBER" , " INVISIBLE_MEMBER" , " INVISIBLE_REFERENCE" , " UNCHECKED_CAST" )
13
20
internal actual class SafeCollector <T > actual constructor(
14
21
@JvmField internal actual val collector : FlowCollector <T >,
15
22
@JvmField internal actual val collectContext : CoroutineContext
16
- ) : FlowCollector<T> {
23
+ ) : FlowCollector<T>, ContinuationImpl( NoOpContinuation , EmptyCoroutineContext ) {
17
24
18
25
@JvmField // Note, it is non-capturing lambda, so no extra allocation during init of SafeCollector
19
26
internal actual val collectContextSize = collectContext.fold(0 ) { count, _ -> count + 1 }
20
27
private var lastEmissionContext: CoroutineContext ? = null
21
- private var intercepted: InterceptedContinuationOwner = InterceptedContinuationOwner ()
22
- private val emitFun = run {
23
- collector::emit as Function2 <T , Continuation <Unit >, Any? >
24
- }
28
+ private var completion: Continuation <Unit >? = null
25
29
26
- /*
27
- * Implementor of ContinuationImpl (that will be preserved by ABI implementation nearly forever)
28
- * in order to properly control 'intercepted()' lifecycle.
29
- */
30
- @Suppress(" CANNOT_OVERRIDE_INVISIBLE_MEMBER" , " INVISIBLE_MEMBER" , " INVISIBLE_REFERENCE" )
31
- private inner class InterceptedContinuationOwner : ContinuationImpl (NoOpContinuation , EmptyCoroutineContext ) {
32
- @JvmField
33
- public var realCompletion: Continuation <Unit >? = null
34
-
35
- override val context: CoroutineContext
36
- get() = realCompletion?.context ? : EmptyCoroutineContext
37
-
38
- override fun invokeSuspend (result : Result <Any ?>): Any? {
39
- result.onFailure { lastEmissionContext = DownstreamExceptionElement (it) }
40
- realCompletion?.resumeWith(result as Result <Unit >)
41
- return COROUTINE_SUSPENDED
42
- }
30
+ // ContinuationImpl
31
+ override val context: CoroutineContext
32
+ get() = completion?.context ? : EmptyCoroutineContext
43
33
44
- // Escalate visibility to manually release intercepted continuation
45
- public override fun releaseIntercepted () {
46
- super .releaseIntercepted()
47
- }
34
+ override fun invokeSuspend (result : Result <Any ?>): Any? {
35
+ result.onFailure { lastEmissionContext = DownstreamExceptionElement (it) }
36
+ completion?.resumeWith(result as Result <Unit >)
37
+ return COROUTINE_SUSPENDED
38
+ }
39
+
40
+ // Escalate visibility to manually release intercepted continuation
41
+ public actual override fun releaseIntercepted () {
42
+ super .releaseIntercepted()
48
43
}
49
44
50
45
/* *
@@ -72,8 +67,8 @@ internal actual class SafeCollector<T> actual constructor(
72
67
if (previousContext != = currentContext) {
73
68
checkContext(currentContext, previousContext, value)
74
69
}
75
- intercepted.realCompletion = uCont
76
- return emitFun(value, intercepted as Continuation <Unit >)
70
+ completion = uCont
71
+ return emitFun(collector as FlowCollector < Any ?>, value, this as Continuation <Unit >)
77
72
}
78
73
79
74
private fun checkContext (
@@ -88,10 +83,6 @@ internal actual class SafeCollector<T> actual constructor(
88
83
lastEmissionContext = currentContext
89
84
}
90
85
91
- public actual fun release () {
92
- intercepted.releaseIntercepted()
93
- }
94
-
95
86
private fun exceptionTransparencyViolated (exception : DownstreamExceptionElement , value : Any? ) {
96
87
/*
97
88
* Exception transparency ensures that if a `collect` block or any intermediate operator
0 commit comments