// WITH_STDLIB // WITH_COROUTINES import kotlin.test.* import kotlin.coroutines.* // To be tested with -g. // https://youtrack.jetbrains.com/issue/KT-49360 class Block(val block: () -> Int) // The Flow code below is taken from kotlinx.coroutines (some unrelated details removed). interface FlowCollector { suspend fun emit(value: T) } interface Flow { suspend fun collect(collector: FlowCollector) } suspend inline fun Flow.collect(crossinline action: suspend (value: T) -> Unit): Unit = collect(object : FlowCollector { override suspend fun emit(value: T) = action(value) }) inline fun unsafeFlow(crossinline block: suspend FlowCollector.() -> Unit): Flow { return object : Flow { override suspend fun collect(collector: FlowCollector) { collector.block() } } } inline fun Flow.unsafeTransform( crossinline transform: suspend FlowCollector.(value: T) -> Unit ): Flow = unsafeFlow { collect { value -> return@collect transform(value) } } inline fun Flow.mapNotNull(crossinline transform: suspend (value: T) -> R?): Flow = unsafeTransform { value -> val transformed = transform(value) ?: return@unsafeTransform return@unsafeTransform emit(transformed) } fun flowOf(value: T): Flow = unsafeFlow { emit(value) } suspend fun Flow.toList(): List { val result = mutableListOf() collect { result.add(it) } return result } // Close to https://youtrack.jetbrains.com/issue/KT-49360: fun testWithFlowMapNotNull(flow: Flow): Flow { return flow.mapNotNull { if (it) Block({ 333 }) else null } } fun box(): String { lateinit var list1: List lateinit var list2: List builder { list1 = testWithFlowMapNotNull(flowOf(true)).toList() list2 = testWithFlowMapNotNull(flowOf(false)).toList() } assertEquals(1, list1.size) assertEquals(333, list1.single().block()) assertEquals(0, list2.size) return "OK" } open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) }