diff --git a/kotlin-native/backend.native/tests/objcexport/coroutines.kt b/kotlin-native/backend.native/tests/objcexport/coroutines.kt index 6c5cc00c7c7..d3db90c58f5 100644 --- a/kotlin-native/backend.native/tests/objcexport/coroutines.kt +++ b/kotlin-native/backend.native/tests/objcexport/coroutines.kt @@ -63,6 +63,13 @@ suspend fun suspendFunAsync(result: Any?, continuationHolder: ContinuationHolder COROUTINE_SUSPENDED } ?: result +@Throws(CoroutineException::class, CancellationException::class) +suspend fun unitSuspendFunAsync(continuationHolder: ContinuationHolder): Unit = + suspendCoroutineUninterceptedOrReturn { + continuationHolder.continuation = it + COROUTINE_SUSPENDED + } + @Throws(CoroutineException::class, CancellationException::class) fun throwException(exception: Throwable) { throw exception diff --git a/kotlin-native/backend.native/tests/objcexport/coroutines.swift b/kotlin-native/backend.native/tests/objcexport/coroutines.swift index 5342ec4af86..fdf9a5c9e47 100644 --- a/kotlin-native/backend.native/tests/objcexport/coroutines.swift +++ b/kotlin-native/backend.native/tests/objcexport/coroutines.swift @@ -145,6 +145,54 @@ private func testSuspendFuncAsync(doThrow: Bool) throws { } } +private func testUnitSuspendFuncAsync(doThrow: Bool) throws { + var completionCalled = 0 + var result: AnyObject? = nil + var error: Error? = nil + +#if NO_GENERICS + let continuationHolder = ContinuationHolder() +#else + let continuationHolder = ContinuationHolder() +#endif + +#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT + CoroutinesKt.unitSuspendFunAsync(continuationHolder: continuationHolder) { _result, _error in + completionCalled += 1 + result = _result as AnyObject? + error = _error + } +#else + CoroutinesKt.unitSuspendFunAsync(continuationHolder: continuationHolder) { _error in + completionCalled += 1 + error = _error + } +#endif + + try assertEquals(actual: completionCalled, expected: 0) + + if doThrow { + let exception = CoroutineException() + continuationHolder.resumeWithException(exception: exception) + + try assertEquals(actual: completionCalled, expected: 1) + +#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT + try assertNil(result) +#endif + try assertSame(actual: error?.kotlinException as AnyObject?, expected: exception) + } else { + continuationHolder.resume(value: KotlinUnit.shared) + + try assertEquals(actual: completionCalled, expected: 1) + +#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT + try assertSame(actual: result, expected: KotlinUnit.shared) +#endif + try assertNil(error) + } +} + private func testCall() throws { try testCallSuspendFun(doSuspend: true, doThrow: false) try testCallSuspendFun(doSuspend: false, doThrow: false) @@ -158,6 +206,9 @@ private func testCall() throws { try testSuspendFuncAsync(doThrow: false) try testSuspendFuncAsync(doThrow: true) + + try testUnitSuspendFuncAsync(doThrow: false) + try testUnitSuspendFuncAsync(doThrow: true) } private func testCallSuspendFunChain(doSuspend: Bool, doThrow: Bool) throws { diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h index 692afa4a7f8..d36d054b056 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h @@ -339,6 +339,12 @@ __attribute__((swift_name("CoroutinesKt"))) */ + (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)"))); +/** + @note This method converts instances of CoroutineException, CancellationException to errors. + Other uncaught Kotlin exceptions are fatal. +*/ ++ (void)unitSuspendFunAsyncContinuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unitSuspendFunAsync(continuationHolder:completionHandler:)"))); + /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h b/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h index f180b6934b0..42f57026261 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h @@ -339,6 +339,12 @@ __attribute__((swift_name("CoroutinesKt"))) */ + (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)"))); +/** + @note This method converts instances of CoroutineException, CancellationException to errors. + Other uncaught Kotlin exceptions are fatal. +*/ ++ (void)unitSuspendFunAsyncContinuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitSuspendFunAsync(continuationHolder:completionHandler:)"))); + /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h b/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h index b550a276e67..a7f6b121d4b 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h @@ -339,6 +339,12 @@ __attribute__((swift_name("CoroutinesKt"))) */ + (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)"))); +/** + @note This method converts instances of CoroutineException, CancellationException to errors. + Other uncaught Kotlin exceptions are fatal. +*/ ++ (void)unitSuspendFunAsyncContinuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unitSuspendFunAsync(continuationHolder:completionHandler:)"))); + /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal.