ObjCExport: remove KotlinUnit from suspend funs returning Unit (#4635)
With `unitSuspendFunctionObjCExport=proper` binary option, for Unit-returning suspend functions ObjCExport now generates completion handlers without redundant `KotlinUnit*` result parameter. So Swift (5.5+) can import these functions as Void-returning async functions. ^KT-47399 Fixed
This commit is contained in:
+2
@@ -23,6 +23,8 @@ object BinaryOptions : BinaryOptionRegistry() {
|
|||||||
val sourceInfoType by option<SourceInfoType>()
|
val sourceInfoType by option<SourceInfoType>()
|
||||||
|
|
||||||
val androidProgramType by option<AndroidProgramType>()
|
val androidProgramType by option<AndroidProgramType>()
|
||||||
|
|
||||||
|
val unitSuspendFunctionObjCExport by option<UnitSuspendFunctionObjCExport>()
|
||||||
}
|
}
|
||||||
|
|
||||||
open class BinaryOption<T : Any>(
|
open class BinaryOption<T : Any>(
|
||||||
|
|||||||
+3
@@ -38,6 +38,9 @@ internal fun StorageComponentContainer.initContainer(config: KonanConfig) {
|
|||||||
|
|
||||||
override val objcGenerics: Boolean
|
override val objcGenerics: Boolean
|
||||||
get() = config.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS)
|
get() = config.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS)
|
||||||
|
|
||||||
|
override val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport
|
||||||
|
get() = config.unitSuspendFunctionObjCExport
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -303,6 +303,9 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
}
|
}
|
||||||
"Konan_main"
|
"Konan_main"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val unitSuspendFunctionObjCExport: UnitSuspendFunctionObjCExport
|
||||||
|
get() = configuration.get(BinaryOptions.unitSuspendFunctionObjCExport) ?: UnitSuspendFunctionObjCExport.LEGACY
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String)
|
fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String)
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
|
enum class UnitSuspendFunctionObjCExport {
|
||||||
|
/**
|
||||||
|
* In this mode suspend functions and methods with [Unit] return type are exported to Objective-C with an additional argument,
|
||||||
|
* continuation callback, with the following Objective-C signature: `(^)(KtKotlinUnit * _Nullable, NSError * _Nullable)`.
|
||||||
|
*/
|
||||||
|
LEGACY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In this mode suspend functions and methods with [Unit] return type are exported to Objective-C with an additional argument,
|
||||||
|
* continuation callback, with the following Objective-C signature: `(^)(NSError * _Nullable)`.
|
||||||
|
*
|
||||||
|
* Methods overriding superclass methods or implementing interface requirements narrowing down a more general return type
|
||||||
|
* to [Unit] are exported like in [LEGACY] mode.
|
||||||
|
*
|
||||||
|
* Note that in Swift 5.5 and higher suspend functions exported this way are transparently mapped to
|
||||||
|
* async functions with `Void` return type
|
||||||
|
*/
|
||||||
|
PROPER,
|
||||||
|
}
|
||||||
+1
@@ -503,6 +503,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) : Runti
|
|||||||
val Kotlin_ObjCExport_RethrowNSErrorAsException by lazyRtFunction
|
val Kotlin_ObjCExport_RethrowNSErrorAsException by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_AllocInstanceWithAssociatedObject by lazyRtFunction
|
val Kotlin_ObjCExport_AllocInstanceWithAssociatedObject by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_createContinuationArgument by lazyRtFunction
|
val Kotlin_ObjCExport_createContinuationArgument by lazyRtFunction
|
||||||
|
val Kotlin_ObjCExport_createUnitContinuationArgument by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_resumeContinuation by lazyRtFunction
|
val Kotlin_ObjCExport_resumeContinuation by lazyRtFunction
|
||||||
|
|
||||||
private val Kotlin_ObjCExport_NSIntegerTypeProvider by lazyRtFunction
|
private val Kotlin_ObjCExport_NSIntegerTypeProvider by lazyRtFunction
|
||||||
|
|||||||
+46
-7
@@ -243,6 +243,10 @@ internal class ObjCExportCodeGenerator(
|
|||||||
generateContinuationToRetainedCompletionConverter(blockGenerator)
|
generateContinuationToRetainedCompletionConverter(blockGenerator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val unitContinuationToRetainedCompletionConverter: LLVMValueRef by lazy {
|
||||||
|
generateUnitContinuationToRetainedCompletionConverter(blockGenerator)
|
||||||
|
}
|
||||||
|
|
||||||
fun meaningfulBridgeNameOrNull(irFunction: IrFunction?): String? {
|
fun meaningfulBridgeNameOrNull(irFunction: IrFunction?): String? {
|
||||||
if (!context.config.configuration.getBoolean(KonanConfigKeys.MEANINGFUL_BRIDGE_NAMES)) {
|
if (!context.config.configuration.getBoolean(KonanConfigKeys.MEANINGFUL_BRIDGE_NAMES)) {
|
||||||
return null
|
return null
|
||||||
@@ -771,7 +775,31 @@ private fun ObjCExportCodeGenerator.generateContinuationToRetainedCompletionConv
|
|||||||
invokeName = "invokeCompletion"
|
invokeName = "invokeCompletion"
|
||||||
) { continuation, arguments ->
|
) { continuation, arguments ->
|
||||||
check(arguments.size == 2)
|
check(arguments.size == 2)
|
||||||
callFromBridge(context.llvm.Kotlin_ObjCExport_resumeContinuation, listOf(continuation) + arguments)
|
|
||||||
|
val resultArgument = objCReferenceToKotlin(arguments[0], Lifetime.ARGUMENT)
|
||||||
|
val errorArgument = arguments[1]
|
||||||
|
|
||||||
|
callFromBridge(context.llvm.Kotlin_ObjCExport_resumeContinuation, listOf(continuation, resultArgument, errorArgument))
|
||||||
|
ret(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ObjCExportCodeGenerator.generateUnitContinuationToRetainedCompletionConverter(
|
||||||
|
blockGenerator: BlockGenerator
|
||||||
|
): LLVMValueRef = with(blockGenerator) {
|
||||||
|
generateWrapKotlinObjectToRetainedBlock(
|
||||||
|
BlockType(numberOfParameters = 1, returnsVoid = true),
|
||||||
|
convertName = "convertUnitContinuation",
|
||||||
|
invokeName = "invokeUnitCompletion"
|
||||||
|
) { continuation, arguments ->
|
||||||
|
check(arguments.size == 1)
|
||||||
|
|
||||||
|
val errorArgument = arguments[0]
|
||||||
|
val resultArgument = ifThenElse(icmpNe(errorArgument, kNullInt8Ptr), kNullObjHeaderPtr) {
|
||||||
|
codegen.theUnitInstanceRef.llvm
|
||||||
|
}
|
||||||
|
|
||||||
|
callFromBridge(context.llvm.Kotlin_ObjCExport_resumeContinuation, listOf(continuation, resultArgument, errorArgument))
|
||||||
ret(null)
|
ret(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -979,9 +1007,14 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> {
|
is MethodBridgeValueParameter.SuspendCompletion -> {
|
||||||
|
val createContinuationArgument = if (paramBridge.useUnitCompletion) {
|
||||||
|
context.llvm.Kotlin_ObjCExport_createUnitContinuationArgument
|
||||||
|
} else {
|
||||||
|
context.llvm.Kotlin_ObjCExport_createContinuationArgument
|
||||||
|
}
|
||||||
callFromBridge(
|
callFromBridge(
|
||||||
context.llvm.Kotlin_ObjCExport_createContinuationArgument,
|
createContinuationArgument,
|
||||||
listOf(parameter, generateExceptionTypeInfoArray(baseMethod!!)),
|
listOf(parameter, generateExceptionTypeInfoArray(baseMethod!!)),
|
||||||
Lifetime.ARGUMENT
|
Lifetime.ARGUMENT
|
||||||
).also {
|
).also {
|
||||||
@@ -1187,7 +1220,7 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
errorOutPtr = it
|
errorOutPtr = it
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> {
|
is MethodBridgeValueParameter.SuspendCompletion -> {
|
||||||
val continuation = param(irFunction.allParametersCount) // The last argument.
|
val continuation = param(irFunction.allParametersCount) // The last argument.
|
||||||
// TODO: consider placing interception into the converter to reduce code size.
|
// TODO: consider placing interception into the converter to reduce code size.
|
||||||
val intercepted = callFromBridge(
|
val intercepted = callFromBridge(
|
||||||
@@ -1195,7 +1228,13 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
listOf(continuation),
|
listOf(continuation),
|
||||||
Lifetime.ARGUMENT
|
Lifetime.ARGUMENT
|
||||||
)
|
)
|
||||||
val retainedCompletion = callFromBridge(continuationToRetainedCompletionConverter, listOf(intercepted))
|
|
||||||
|
val converter = if (bridge.useUnitCompletion) {
|
||||||
|
unitContinuationToRetainedCompletionConverter
|
||||||
|
} else {
|
||||||
|
continuationToRetainedCompletionConverter
|
||||||
|
}
|
||||||
|
val retainedCompletion = callFromBridge(converter, listOf(intercepted))
|
||||||
callFromBridge(objcAutorelease, listOf(retainedCompletion)) // TODO: use stack-allocated block here instead.
|
callFromBridge(objcAutorelease, listOf(retainedCompletion)) // TODO: use stack-allocated block here instead.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1771,7 +1810,7 @@ private fun MethodBridgeParameter.toLlvmParamType(): LlvmParamType = when (this)
|
|||||||
is MethodBridgeReceiver -> ReferenceBridge.toLlvmParamType()
|
is MethodBridgeReceiver -> ReferenceBridge.toLlvmParamType()
|
||||||
MethodBridgeSelector -> LlvmParamType(int8TypePtr)
|
MethodBridgeSelector -> LlvmParamType(int8TypePtr)
|
||||||
MethodBridgeValueParameter.ErrorOutParameter -> LlvmParamType(pointerType(ReferenceBridge.toLlvmParamType().llvmType))
|
MethodBridgeValueParameter.ErrorOutParameter -> LlvmParamType(pointerType(ReferenceBridge.toLlvmParamType().llvmType))
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> LlvmParamType(int8TypePtr)
|
is MethodBridgeValueParameter.SuspendCompletion -> LlvmParamType(int8TypePtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MethodBridge.ReturnValue.toLlvmRetType(
|
private fun MethodBridge.ReturnValue.toLlvmRetType(
|
||||||
@@ -1827,7 +1866,7 @@ private val MethodBridgeParameter.objCEncoding: String get() = when (this) {
|
|||||||
is MethodBridgeReceiver -> ReferenceBridge.objCEncoding
|
is MethodBridgeReceiver -> ReferenceBridge.objCEncoding
|
||||||
MethodBridgeSelector -> ":"
|
MethodBridgeSelector -> ":"
|
||||||
MethodBridgeValueParameter.ErrorOutParameter -> "^${ReferenceBridge.objCEncoding}"
|
MethodBridgeValueParameter.ErrorOutParameter -> "^${ReferenceBridge.objCEncoding}"
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> "@"
|
is MethodBridgeValueParameter.SuspendCompletion -> "@"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val TypeBridge.objCEncoding: String get() = when (this) {
|
private val TypeBridge.objCEncoding: String get() = when (this) {
|
||||||
|
|||||||
+3
-3
@@ -35,7 +35,7 @@ internal object MethodBridgeSelector : MethodBridgeParameter()
|
|||||||
internal sealed class MethodBridgeValueParameter : MethodBridgeParameter() {
|
internal sealed class MethodBridgeValueParameter : MethodBridgeParameter() {
|
||||||
data class Mapped(val bridge: TypeBridge) : MethodBridgeValueParameter()
|
data class Mapped(val bridge: TypeBridge) : MethodBridgeValueParameter()
|
||||||
object ErrorOutParameter : MethodBridgeValueParameter()
|
object ErrorOutParameter : MethodBridgeValueParameter()
|
||||||
object SuspendCompletion : MethodBridgeValueParameter()
|
data class SuspendCompletion(val useUnitCompletion: Boolean) : MethodBridgeValueParameter()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal data class MethodBridge(
|
internal data class MethodBridge(
|
||||||
@@ -92,7 +92,7 @@ internal fun MethodBridge.valueParametersAssociated(
|
|||||||
when (it) {
|
when (it) {
|
||||||
is MethodBridgeValueParameter.Mapped -> it to kotlinParameters.next()
|
is MethodBridgeValueParameter.Mapped -> it to kotlinParameters.next()
|
||||||
|
|
||||||
MethodBridgeValueParameter.SuspendCompletion,
|
is MethodBridgeValueParameter.SuspendCompletion,
|
||||||
is MethodBridgeValueParameter.ErrorOutParameter -> it to null
|
is MethodBridgeValueParameter.ErrorOutParameter -> it to null
|
||||||
}
|
}
|
||||||
}.also { assert(!kotlinParameters.hasNext()) }
|
}.also { assert(!kotlinParameters.hasNext()) }
|
||||||
@@ -108,7 +108,7 @@ internal fun MethodBridge.parametersAssociated(
|
|||||||
is MethodBridgeValueParameter.Mapped, MethodBridgeReceiver.Instance ->
|
is MethodBridgeValueParameter.Mapped, MethodBridgeReceiver.Instance ->
|
||||||
it to kotlinParameters.next()
|
it to kotlinParameters.next()
|
||||||
|
|
||||||
MethodBridgeValueParameter.SuspendCompletion,
|
is MethodBridgeValueParameter.SuspendCompletion,
|
||||||
MethodBridgeReceiver.Static, MethodBridgeSelector, MethodBridgeValueParameter.ErrorOutParameter ->
|
MethodBridgeReceiver.Static, MethodBridgeSelector, MethodBridgeValueParameter.ErrorOutParameter ->
|
||||||
it to null
|
it to null
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -56,7 +56,8 @@ internal class ObjCExport(val context: Context, symbolTable: SymbolTable) {
|
|||||||
val produceFramework = context.config.produce == CompilerOutputKind.FRAMEWORK
|
val produceFramework = context.config.produce == CompilerOutputKind.FRAMEWORK
|
||||||
|
|
||||||
return if (produceFramework) {
|
return if (produceFramework) {
|
||||||
val mapper = ObjCExportMapper(context.frontendServices.deprecationResolver)
|
val unitSuspendFunctionExport = context.config.unitSuspendFunctionObjCExport
|
||||||
|
val mapper = ObjCExportMapper(context.frontendServices.deprecationResolver, unitSuspendFunctionExport = unitSuspendFunctionExport)
|
||||||
val moduleDescriptors = listOf(context.moduleDescriptor) + context.getExportedDependencies()
|
val moduleDescriptors = listOf(context.moduleDescriptor) + context.getExportedDependencies()
|
||||||
val objcGenerics = context.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS)
|
val objcGenerics = context.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS)
|
||||||
val namer = ObjCExportNamerImpl(
|
val namer = ObjCExportNamerImpl(
|
||||||
@@ -86,7 +87,7 @@ internal class ObjCExport(val context: Context, symbolTable: SymbolTable) {
|
|||||||
|
|
||||||
if (!context.config.produce.isFinalBinary) return // TODO: emit RTTI to the same modules as classes belong to.
|
if (!context.config.produce.isFinalBinary) return // TODO: emit RTTI to the same modules as classes belong to.
|
||||||
|
|
||||||
val mapper = exportedInterface?.mapper ?: ObjCExportMapper()
|
val mapper = exportedInterface?.mapper ?: ObjCExportMapper(unitSuspendFunctionExport = context.config.unitSuspendFunctionObjCExport)
|
||||||
namer = exportedInterface?.namer ?: ObjCExportNamerImpl(
|
namer = exportedInterface?.namer ?: ObjCExportNamerImpl(
|
||||||
setOf(codegen.context.moduleDescriptor),
|
setOf(codegen.context.moduleDescriptor),
|
||||||
context.moduleDescriptor.builtIns,
|
context.moduleDescriptor.builtIns,
|
||||||
|
|||||||
+10
-6
@@ -644,7 +644,7 @@ internal class ObjCExportTranslatorImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
MethodBridgeValueParameter.ErrorOutParameter -> "error"
|
MethodBridgeValueParameter.ErrorOutParameter -> "error"
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
|
is MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
|
||||||
}
|
}
|
||||||
|
|
||||||
val uniqueName = unifyName(candidateName, usedNames)
|
val uniqueName = unifyName(candidateName, usedNames)
|
||||||
@@ -655,14 +655,18 @@ internal class ObjCExportTranslatorImpl(
|
|||||||
MethodBridgeValueParameter.ErrorOutParameter ->
|
MethodBridgeValueParameter.ErrorOutParameter ->
|
||||||
ObjCPointerType(ObjCNullableReferenceType(ObjCClassType("NSError")), nullable = true)
|
ObjCPointerType(ObjCNullableReferenceType(ObjCClassType("NSError")), nullable = true)
|
||||||
|
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> {
|
is MethodBridgeValueParameter.SuspendCompletion -> {
|
||||||
val resultType = when (val it = mapReferenceType(method.returnType!!, objCExportScope)) {
|
val resultType = if (bridge.useUnitCompletion) {
|
||||||
is ObjCNonNullReferenceType -> ObjCNullableReferenceType(it, isNullableResult = false)
|
null
|
||||||
is ObjCNullableReferenceType -> ObjCNullableReferenceType(it.nonNullType, isNullableResult = true)
|
} else {
|
||||||
|
when (val it = mapReferenceType(method.returnType!!, objCExportScope)) {
|
||||||
|
is ObjCNonNullReferenceType -> ObjCNullableReferenceType(it, isNullableResult = false)
|
||||||
|
is ObjCNullableReferenceType -> ObjCNullableReferenceType(it.nonNullType, isNullableResult = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ObjCBlockPointerType(
|
ObjCBlockPointerType(
|
||||||
returnType = ObjCVoidType,
|
returnType = ObjCVoidType,
|
||||||
parameterTypes = listOf(
|
parameterTypes = listOfNotNull(
|
||||||
resultType,
|
resultType,
|
||||||
ObjCNullableReferenceType(ObjCClassType("NSError"))
|
ObjCNullableReferenceType(ObjCClassType("NSError"))
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.konan.objcexport
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
|
import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport
|
||||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -43,6 +44,7 @@ interface ObjCExportLazy {
|
|||||||
fun isIncluded(moduleInfo: ModuleInfo): Boolean
|
fun isIncluded(moduleInfo: ModuleInfo): Boolean
|
||||||
fun getCompilerModuleName(moduleInfo: ModuleInfo): String
|
fun getCompilerModuleName(moduleInfo: ModuleInfo): String
|
||||||
val objcGenerics: Boolean
|
val objcGenerics: Boolean
|
||||||
|
val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateBase(): List<ObjCTopLevel<*>>
|
fun generateBase(): List<ObjCTopLevel<*>>
|
||||||
@@ -86,7 +88,7 @@ internal class ObjCExportLazyImpl(
|
|||||||
|
|
||||||
private val nameTranslator: ObjCExportNameTranslator = ObjCExportNameTranslatorImpl(namerConfiguration)
|
private val nameTranslator: ObjCExportNameTranslator = ObjCExportNameTranslatorImpl(namerConfiguration)
|
||||||
|
|
||||||
private val mapper = ObjCExportMapper(deprecationResolver, local = true)
|
private val mapper = ObjCExportMapper(deprecationResolver, local = true, configuration.unitSuspendFunctionExport)
|
||||||
|
|
||||||
private val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, local = true)
|
private val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, local = true)
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -25,7 +25,8 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
|
|||||||
|
|
||||||
internal class ObjCExportMapper(
|
internal class ObjCExportMapper(
|
||||||
internal val deprecationResolver: DeprecationResolver? = null,
|
internal val deprecationResolver: DeprecationResolver? = null,
|
||||||
private val local: Boolean = false
|
private val local: Boolean = false,
|
||||||
|
internal val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport
|
||||||
) {
|
) {
|
||||||
fun getCustomTypeMapper(descriptor: ClassDescriptor): CustomTypeMapper? = CustomTypeMappers.getMapper(descriptor)
|
fun getCustomTypeMapper(descriptor: ClassDescriptor): CustomTypeMapper? = CustomTypeMappers.getMapper(descriptor)
|
||||||
|
|
||||||
@@ -331,7 +332,8 @@ private fun ObjCExportMapper.bridgeMethodImpl(descriptor: FunctionDescriptor): M
|
|||||||
val returnBridge = bridgeReturnType(descriptor, convertExceptionsToErrors)
|
val returnBridge = bridgeReturnType(descriptor, convertExceptionsToErrors)
|
||||||
|
|
||||||
if (descriptor.isSuspend) {
|
if (descriptor.isSuspend) {
|
||||||
valueParameters += MethodBridgeValueParameter.SuspendCompletion
|
val useUnitCompletion = (unitSuspendFunctionExport == UnitSuspendFunctionObjCExport.PROPER) && (descriptor.returnType!!.isUnit())
|
||||||
|
valueParameters += MethodBridgeValueParameter.SuspendCompletion(useUnitCompletion)
|
||||||
} else if (convertExceptionsToErrors) {
|
} else if (convertExceptionsToErrors) {
|
||||||
// Add error out parameter before tail block parameters. The convention allows this.
|
// Add error out parameter before tail block parameters. The convention allows this.
|
||||||
// Placing it after would trigger https://bugs.swift.org/browse/SR-12201
|
// Placing it after would trigger https://bugs.swift.org/browse/SR-12201
|
||||||
@@ -349,7 +351,7 @@ private fun MethodBridgeValueParameter.isBlockPointer(): Boolean = when (this) {
|
|||||||
is BlockPointerBridge -> true
|
is BlockPointerBridge -> true
|
||||||
}
|
}
|
||||||
MethodBridgeValueParameter.ErrorOutParameter -> false
|
MethodBridgeValueParameter.ErrorOutParameter -> false
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> true
|
is MethodBridgeValueParameter.SuspendCompletion -> true
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ObjCExportMapper.bridgePropertyType(descriptor: PropertyDescriptor): TypeBridge {
|
internal fun ObjCExportMapper.bridgePropertyType(descriptor: PropertyDescriptor): TypeBridge {
|
||||||
|
|||||||
+4
-3
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.konan.objcexport
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.findSourceFile
|
import org.jetbrains.kotlin.backend.common.serialization.findSourceFile
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport
|
||||||
import org.jetbrains.kotlin.backend.konan.cKeywords
|
import org.jetbrains.kotlin.backend.konan.cKeywords
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isArray
|
import org.jetbrains.kotlin.backend.konan.descriptors.isArray
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
|
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
|
||||||
@@ -89,7 +90,7 @@ fun createNamer(
|
|||||||
): ObjCExportNamer = ObjCExportNamerImpl(
|
): ObjCExportNamer = ObjCExportNamerImpl(
|
||||||
(exportedDependencies + moduleDescriptor).toSet(),
|
(exportedDependencies + moduleDescriptor).toSet(),
|
||||||
moduleDescriptor.builtIns,
|
moduleDescriptor.builtIns,
|
||||||
ObjCExportMapper(local = true),
|
ObjCExportMapper(local = true, unitSuspendFunctionExport = UnitSuspendFunctionObjCExport.LEGACY),
|
||||||
topLevelNamePrefix,
|
topLevelNamePrefix,
|
||||||
local = true
|
local = true
|
||||||
)
|
)
|
||||||
@@ -472,7 +473,7 @@ internal class ObjCExportNamerImpl(
|
|||||||
else -> it!!.name.asString().toIdentifier()
|
else -> it!!.name.asString().toIdentifier()
|
||||||
}
|
}
|
||||||
MethodBridgeValueParameter.ErrorOutParameter -> "error"
|
MethodBridgeValueParameter.ErrorOutParameter -> "error"
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
|
is MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
@@ -525,7 +526,7 @@ internal class ObjCExportNamerImpl(
|
|||||||
else -> it!!.name.asString().toIdentifier()
|
else -> it!!.name.asString().toIdentifier()
|
||||||
}
|
}
|
||||||
MethodBridgeValueParameter.ErrorOutParameter -> continue@parameters
|
MethodBridgeValueParameter.ErrorOutParameter -> continue@parameters
|
||||||
MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
|
is MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
|
||||||
}
|
}
|
||||||
|
|
||||||
append(label)
|
append(label)
|
||||||
|
|||||||
+3
-3
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|||||||
|
|
||||||
class ObjCExportTranslatorMobile internal constructor(private val delegate: ObjCExportTranslatorImpl) : ObjCExportTranslator by delegate {
|
class ObjCExportTranslatorMobile internal constructor(private val delegate: ObjCExportTranslatorImpl) : ObjCExportTranslator by delegate {
|
||||||
companion object {
|
companion object {
|
||||||
fun create(namer: ObjCExportNamer): ObjCExportTranslatorMobile {
|
fun create(namer: ObjCExportNamer, configuration: ObjCExportLazy.Configuration): ObjCExportTranslatorMobile {
|
||||||
val mapper = ObjCExportMapper(local = true)
|
val mapper = ObjCExportMapper(local = true, unitSuspendFunctionExport = configuration.unitSuspendFunctionExport)
|
||||||
return ObjCExportTranslatorMobile(ObjCExportTranslatorImpl(null, mapper, namer, ObjCExportProblemCollector.SILENT, false))
|
return ObjCExportTranslatorMobile(ObjCExportTranslatorImpl(null, mapper, namer, ObjCExportProblemCollector.SILENT, configuration.objcGenerics))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ class ObjcExportHeaderGeneratorMobile internal constructor(
|
|||||||
deprecationResolver: DeprecationResolver? = null,
|
deprecationResolver: DeprecationResolver? = null,
|
||||||
local: Boolean = false,
|
local: Boolean = false,
|
||||||
restrictToLocalModules: Boolean = false): ObjCExportHeaderGenerator {
|
restrictToLocalModules: Boolean = false): ObjCExportHeaderGenerator {
|
||||||
val mapper = ObjCExportMapper(deprecationResolver, local)
|
val mapper = ObjCExportMapper(deprecationResolver, local, configuration.unitSuspendFunctionExport)
|
||||||
val namerConfiguration = createNamerConfiguration(configuration)
|
val namerConfiguration = createNamerConfiguration(configuration)
|
||||||
val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, local)
|
val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, local)
|
||||||
|
|
||||||
|
|||||||
@@ -5321,7 +5321,7 @@ if (isAppleTarget(project)) {
|
|||||||
framework(frameworkName) {
|
framework(frameworkName) {
|
||||||
sources = ['objcexport']
|
sources = ['objcexport']
|
||||||
library = libraryName
|
library = libraryName
|
||||||
opts = ["-Xemit-lazy-objc-header=$lazyHeader", "-Xexport-kdoc", "-Xbundle-id=foo.bar"]
|
opts = ["-Xemit-lazy-objc-header=$lazyHeader", "-Xexport-kdoc", "-Xbundle-id=foo.bar", "-Xbinary=unitSuspendFunctionObjCExport=proper"]
|
||||||
}
|
}
|
||||||
swiftSources = ['objcexport']
|
swiftSources = ['objcexport']
|
||||||
if (isNoopGC) {
|
if (isNoopGC) {
|
||||||
@@ -5375,7 +5375,7 @@ if (isAppleTarget(project)) {
|
|||||||
sources = ['objcexport']
|
sources = ['objcexport']
|
||||||
artifact = frameworkArtifactName
|
artifact = frameworkArtifactName
|
||||||
library = libraryName
|
library = libraryName
|
||||||
opts = ["-Xemit-lazy-objc-header=$lazyHeader", "-Xno-objc-generics"]
|
opts = ["-Xemit-lazy-objc-header=$lazyHeader", "-Xno-objc-generics", "-Xbinary=unitSuspendFunctionObjCExport=proper"]
|
||||||
}
|
}
|
||||||
swiftSources = ['objcexport']
|
swiftSources = ['objcexport']
|
||||||
swiftExtraOpts = [ '-D', 'NO_GENERICS' ]
|
swiftExtraOpts = [ '-D', 'NO_GENERICS' ]
|
||||||
@@ -5384,6 +5384,61 @@ if (isAppleTarget(project)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frameworkTest('testObjCExportLegacySuspendUnit') {
|
||||||
|
final String frameworkName = 'KtLegacySuspendUnit'
|
||||||
|
final String frameworkArtifactName = 'Kt'
|
||||||
|
final String dir = "$testOutputFramework/testObjCExportLegacySuspendUnit"
|
||||||
|
final File lazyHeader = file("$dir/$target-lazy.h")
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
final String expectedLazyHeaderName = "expectedLazyLegacySuspendUnit.h"
|
||||||
|
final String expectedLazyHeaderDir = file("objcexport/")
|
||||||
|
final File expectedLazyHeader = new File(expectedLazyHeaderDir, expectedLazyHeaderName)
|
||||||
|
|
||||||
|
if (expectedLazyHeader.readLines() != lazyHeader.readLines()) {
|
||||||
|
exec {
|
||||||
|
commandLine 'diff', '-u', expectedLazyHeader, lazyHeader
|
||||||
|
ignoreExitValue = true
|
||||||
|
}
|
||||||
|
|
||||||
|
copy {
|
||||||
|
from(lazyHeader)
|
||||||
|
into(expectedLazyHeaderDir)
|
||||||
|
rename { expectedLazyHeaderName }
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("$expectedLazyHeader file patched;\nre-run the test and don't forget to commit the patch")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def libraryName = frameworkName + "Library"
|
||||||
|
konanArtifacts {
|
||||||
|
library(libraryName, targets: [target.name]) {
|
||||||
|
srcDir "objcexport/library"
|
||||||
|
artifactName "test-library"
|
||||||
|
|
||||||
|
if (!useCustomDist) {
|
||||||
|
dependsOn ":${target.name}CrossDistRuntime", ':distCompiler'
|
||||||
|
}
|
||||||
|
|
||||||
|
extraOpts "-Xshort-module-name=MyLibrary"
|
||||||
|
extraOpts "-module-name", "org.jetbrains.kotlin.native.test-library"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
framework(frameworkName) {
|
||||||
|
sources = ['objcexport']
|
||||||
|
artifact = frameworkArtifactName
|
||||||
|
library = libraryName
|
||||||
|
opts = ["-Xemit-lazy-objc-header=$lazyHeader"]
|
||||||
|
}
|
||||||
|
swiftSources = ['objcexport']
|
||||||
|
swiftExtraOpts = [ '-D', 'LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT' ]
|
||||||
|
if (isNoopGC) {
|
||||||
|
swiftExtraOpts += ["-D", "NOOP_GC"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
frameworkTest('testObjCExportStatic') {
|
frameworkTest('testObjCExportStatic') {
|
||||||
final String frameworkName = 'KtStatic'
|
final String frameworkName = 'KtStatic'
|
||||||
final String frameworkArtifactName = 'Kt'
|
final String frameworkArtifactName = 'Kt'
|
||||||
@@ -5410,6 +5465,7 @@ if (isAppleTarget(project)) {
|
|||||||
artifact = frameworkArtifactName
|
artifact = frameworkArtifactName
|
||||||
library = libraryName
|
library = libraryName
|
||||||
isStatic = true
|
isStatic = true
|
||||||
|
opts = ["-Xbinary=unitSuspendFunctionObjCExport=proper"]
|
||||||
}
|
}
|
||||||
swiftSources = ['objcexport']
|
swiftSources = ['objcexport']
|
||||||
if (isNoopGC) {
|
if (isNoopGC) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import kotlin.test.*
|
|||||||
class CoroutineException : Throwable()
|
class CoroutineException : Throwable()
|
||||||
|
|
||||||
suspend fun suspendFun() = 42
|
suspend fun suspendFun() = 42
|
||||||
|
suspend fun unitSuspendFun() = Unit
|
||||||
|
|
||||||
@Throws(CoroutineException::class, CancellationException::class)
|
@Throws(CoroutineException::class, CancellationException::class)
|
||||||
suspend fun suspendFun(result: Any?, doSuspend: Boolean, doThrow: Boolean): Any? {
|
suspend fun suspendFun(result: Any?, doSuspend: Boolean, doThrow: Boolean): Any? {
|
||||||
@@ -30,6 +31,18 @@ suspend fun suspendFun(result: Any?, doSuspend: Boolean, doThrow: Boolean): Any?
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws(CoroutineException::class, CancellationException::class)
|
||||||
|
suspend fun unitSuspendFun(doSuspend: Boolean, doThrow: Boolean) {
|
||||||
|
if (doSuspend) {
|
||||||
|
suspendCoroutineUninterceptedOrReturn<Unit> {
|
||||||
|
it.resume(Unit)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doThrow) throw CoroutineException()
|
||||||
|
}
|
||||||
|
|
||||||
class ContinuationHolder<T> {
|
class ContinuationHolder<T> {
|
||||||
internal lateinit var continuation: Continuation<T>
|
internal lateinit var continuation: Continuation<T>
|
||||||
|
|
||||||
@@ -96,6 +109,7 @@ interface SuspendBridge<T> {
|
|||||||
|
|
||||||
suspend fun unit(value: T): Unit
|
suspend fun unit(value: T): Unit
|
||||||
suspend fun unitAsAny(value: T): Any?
|
suspend fun unitAsAny(value: T): Any?
|
||||||
|
suspend fun nullableUnit(value: T): Unit?
|
||||||
|
|
||||||
@Throws(Throwable::class) suspend fun nothing(value: T): Nothing
|
@Throws(Throwable::class) suspend fun nothing(value: T): Nothing
|
||||||
@Throws(Throwable::class) suspend fun nothingAsInt(value: T): Int
|
@Throws(Throwable::class) suspend fun nothingAsInt(value: T): Int
|
||||||
@@ -106,7 +120,9 @@ interface SuspendBridge<T> {
|
|||||||
abstract class AbstractSuspendBridge : SuspendBridge<Int> {
|
abstract class AbstractSuspendBridge : SuspendBridge<Int> {
|
||||||
override suspend fun intAsAny(value: Int): Int = TODO()
|
override suspend fun intAsAny(value: Int): Int = TODO()
|
||||||
|
|
||||||
|
override suspend fun unit(value: Int): Unit = TODO()
|
||||||
override suspend fun unitAsAny(value: Int): Unit = TODO()
|
override suspend fun unitAsAny(value: Int): Unit = TODO()
|
||||||
|
override suspend fun nullableUnit(value: Int): Unit? = TODO()
|
||||||
|
|
||||||
override suspend fun nothingAsInt(value: Int): Nothing = TODO()
|
override suspend fun nothingAsInt(value: Int): Nothing = TODO()
|
||||||
override suspend fun nothingAsAny(value: Int): Nothing = TODO()
|
override suspend fun nothingAsAny(value: Int): Nothing = TODO()
|
||||||
@@ -116,21 +132,25 @@ abstract class AbstractSuspendBridge : SuspendBridge<Int> {
|
|||||||
private suspend fun callSuspendBridgeImpl(bridge: SuspendBridge<Int>) {
|
private suspend fun callSuspendBridgeImpl(bridge: SuspendBridge<Int>) {
|
||||||
assertEquals(1, bridge.intAsAny(1))
|
assertEquals(1, bridge.intAsAny(1))
|
||||||
|
|
||||||
assertSame(Unit, bridge.unitAsAny(2))
|
assertSame(Unit, bridge.unit(2))
|
||||||
|
assertSame(Unit, bridge.unitAsAny(3))
|
||||||
|
assertSame(Unit, bridge.nullableUnit(4))
|
||||||
|
|
||||||
assertFailsWith<ObjCErrorException> { bridge.nothingAsInt(3) }
|
assertFailsWith<ObjCErrorException> { bridge.nothingAsInt(5) }
|
||||||
assertFailsWith<ObjCErrorException> { bridge.nothingAsAny(4) }
|
assertFailsWith<ObjCErrorException> { bridge.nothingAsAny(6) }
|
||||||
assertFailsWith<ObjCErrorException> { bridge.nothingAsUnit(5) }
|
assertFailsWith<ObjCErrorException> { bridge.nothingAsUnit(7) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun callAbstractSuspendBridgeImpl(bridge: AbstractSuspendBridge) {
|
private suspend fun callAbstractSuspendBridgeImpl(bridge: AbstractSuspendBridge) {
|
||||||
assertEquals(6, bridge.intAsAny(6))
|
assertEquals(8, bridge.intAsAny(8))
|
||||||
|
|
||||||
assertSame(Unit, bridge.unitAsAny(7))
|
assertSame(Unit, bridge.unit(9))
|
||||||
|
assertSame(Unit, bridge.unitAsAny(10))
|
||||||
|
assertSame(Unit, bridge.nullableUnit(11))
|
||||||
|
|
||||||
assertFailsWith<ObjCErrorException> { bridge.nothingAsInt(8) }
|
assertFailsWith<ObjCErrorException> { bridge.nothingAsInt(12) }
|
||||||
assertFailsWith<ObjCErrorException> { bridge.nothingAsAny(9) }
|
assertFailsWith<ObjCErrorException> { bridge.nothingAsAny(13) }
|
||||||
assertFailsWith<ObjCErrorException> { bridge.nothingAsUnit(10) }
|
assertFailsWith<ObjCErrorException> { bridge.nothingAsUnit(14) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Throwable::class)
|
@Throws(Throwable::class)
|
||||||
|
|||||||
@@ -21,6 +21,33 @@ private func testCallSimple() throws {
|
|||||||
try assertNil(error)
|
try assertNil(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func testUnitCallSimple() throws {
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
var result: KotlinUnit? = nil
|
||||||
|
#endif
|
||||||
|
var error: Error? = nil
|
||||||
|
var completionCalled = 0
|
||||||
|
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
CoroutinesKt.unitSuspendFun { _result, _error in
|
||||||
|
completionCalled += 1
|
||||||
|
result = _result
|
||||||
|
error = _error
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
CoroutinesKt.unitSuspendFun { _error in
|
||||||
|
completionCalled += 1
|
||||||
|
error = _error
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
try assertSame(actual: result, expected: KotlinUnit.shared)
|
||||||
|
#endif
|
||||||
|
try assertEquals(actual: completionCalled, expected: 1)
|
||||||
|
try assertNil(error)
|
||||||
|
}
|
||||||
|
|
||||||
private func testCallSuspendFun(doSuspend: Bool, doThrow: Bool) throws {
|
private func testCallSuspendFun(doSuspend: Bool, doThrow: Bool) throws {
|
||||||
class C {}
|
class C {}
|
||||||
let expectedResult = C()
|
let expectedResult = C()
|
||||||
@@ -46,6 +73,39 @@ private func testCallSuspendFun(doSuspend: Bool, doThrow: Bool) throws {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func testCallUnitSuspendFun(doSuspend: Bool, doThrow: Bool) throws {
|
||||||
|
var completionCalled = 0
|
||||||
|
var result: AnyObject? = nil
|
||||||
|
var error: Error? = nil
|
||||||
|
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
CoroutinesKt.unitSuspendFun(doSuspend: doSuspend, doThrow: doThrow) { _result, _error in
|
||||||
|
completionCalled += 1
|
||||||
|
result = _result as AnyObject?
|
||||||
|
error = _error
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
CoroutinesKt.unitSuspendFun(doSuspend: doSuspend, doThrow: doThrow) { _error in
|
||||||
|
completionCalled += 1
|
||||||
|
error = _error
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try assertEquals(actual: completionCalled, expected: 1)
|
||||||
|
|
||||||
|
if doThrow {
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
try assertNil(result)
|
||||||
|
#endif
|
||||||
|
try assertTrue(error?.kotlinException is CoroutineException)
|
||||||
|
} else {
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
try assertSame(actual: result, expected: KotlinUnit.shared)
|
||||||
|
#endif
|
||||||
|
try assertNil(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func testSuspendFuncAsync(doThrow: Bool) throws {
|
private func testSuspendFuncAsync(doThrow: Bool) throws {
|
||||||
var completionCalled = 0
|
var completionCalled = 0
|
||||||
var result: AnyObject? = nil
|
var result: AnyObject? = nil
|
||||||
@@ -91,6 +151,11 @@ private func testCall() throws {
|
|||||||
try testCallSuspendFun(doSuspend: true, doThrow: true)
|
try testCallSuspendFun(doSuspend: true, doThrow: true)
|
||||||
try testCallSuspendFun(doSuspend: false, doThrow: true)
|
try testCallSuspendFun(doSuspend: false, doThrow: true)
|
||||||
|
|
||||||
|
try testCallUnitSuspendFun(doSuspend: true, doThrow: false)
|
||||||
|
try testCallUnitSuspendFun(doSuspend: false, doThrow: false)
|
||||||
|
try testCallUnitSuspendFun(doSuspend: true, doThrow: true)
|
||||||
|
try testCallUnitSuspendFun(doSuspend: false, doThrow: true)
|
||||||
|
|
||||||
try testSuspendFuncAsync(doThrow: false)
|
try testSuspendFuncAsync(doThrow: false)
|
||||||
try testSuspendFuncAsync(doThrow: true)
|
try testSuspendFuncAsync(doThrow: true)
|
||||||
}
|
}
|
||||||
@@ -237,10 +302,24 @@ private class SwiftSuspendBridge : AbstractSuspendBridge {
|
|||||||
completionHandler(value, nil)
|
completionHandler(value, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
override func unit(value: KotlinInt, completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
|
||||||
|
completionHandler(KotlinUnit(), nil)
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
override func unit(value: KotlinInt, completionHandler: @escaping (Error?) -> Void) {
|
||||||
|
completionHandler(nil)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
override func unitAsAny(value: KotlinInt, completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
|
override func unitAsAny(value: KotlinInt, completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
|
||||||
completionHandler(KotlinUnit(), nil)
|
completionHandler(KotlinUnit(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func nullableUnit(value: KotlinInt, completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
|
||||||
|
completionHandler(KotlinUnit(), nil)
|
||||||
|
}
|
||||||
|
|
||||||
override func nothingAsInt(value: KotlinInt, completionHandler: @escaping (KotlinNothing?, Error?) -> Void) {
|
override func nothingAsInt(value: KotlinInt, completionHandler: @escaping (KotlinNothing?, Error?) -> Void) {
|
||||||
completionHandler(nil, E())
|
completionHandler(nil, E())
|
||||||
}
|
}
|
||||||
@@ -249,9 +328,15 @@ private class SwiftSuspendBridge : AbstractSuspendBridge {
|
|||||||
completionHandler(nil, E())
|
completionHandler(nil, E())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
override func nothingAsUnit(value: KotlinInt, completionHandler: @escaping (KotlinNothing?, Error?) -> Void) {
|
override func nothingAsUnit(value: KotlinInt, completionHandler: @escaping (KotlinNothing?, Error?) -> Void) {
|
||||||
completionHandler(nil, E())
|
completionHandler(nil, E())
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
override func nothingAsUnit(value: KotlinInt, completionHandler: @escaping (Error?) -> Void) {
|
||||||
|
completionHandler(E())
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private func testBridges() throws {
|
private func testBridges() throws {
|
||||||
@@ -268,34 +353,52 @@ private func testBridges() throws {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func testImplicitThrows1() throws {
|
private func testImplicitThrows1() throws {
|
||||||
var result: KotlinUnit? = nil
|
|
||||||
var error: Error? = nil
|
var error: Error? = nil
|
||||||
var completionCalled = 0
|
var completionCalled = 0
|
||||||
|
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
var result: KotlinUnit? = nil
|
||||||
|
|
||||||
CoroutinesKt.throwCancellationException { _result, _error in
|
CoroutinesKt.throwCancellationException { _result, _error in
|
||||||
completionCalled += 1
|
completionCalled += 1
|
||||||
result = _result
|
result = _result
|
||||||
error = _error
|
error = _error
|
||||||
}
|
}
|
||||||
|
|
||||||
try assertEquals(actual: completionCalled, expected: 1)
|
|
||||||
try assertNil(result)
|
try assertNil(result)
|
||||||
|
#else
|
||||||
|
CoroutinesKt.throwCancellationException { _error in
|
||||||
|
completionCalled += 1
|
||||||
|
error = _error
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try assertEquals(actual: completionCalled, expected: 1)
|
||||||
try assertTrue(error?.kotlinException is KotlinCancellationException)
|
try assertTrue(error?.kotlinException is KotlinCancellationException)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func testImplicitThrows2() throws {
|
private func testImplicitThrows2() throws {
|
||||||
var result: KotlinUnit? = nil
|
|
||||||
var error: Error? = nil
|
var error: Error? = nil
|
||||||
var completionCalled = 0
|
var completionCalled = 0
|
||||||
|
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
|
var result: KotlinUnit? = nil
|
||||||
|
|
||||||
ThrowCancellationExceptionImpl().throwCancellationException { _result, _error in
|
ThrowCancellationExceptionImpl().throwCancellationException { _result, _error in
|
||||||
completionCalled += 1
|
completionCalled += 1
|
||||||
result = _result
|
result = _result
|
||||||
error = _error
|
error = _error
|
||||||
}
|
}
|
||||||
|
|
||||||
try assertEquals(actual: completionCalled, expected: 1)
|
|
||||||
try assertNil(result)
|
try assertNil(result)
|
||||||
|
#else
|
||||||
|
ThrowCancellationExceptionImpl().throwCancellationException { _error in
|
||||||
|
completionCalled += 1
|
||||||
|
error = _error
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try assertEquals(actual: completionCalled, expected: 1)
|
||||||
try assertTrue(error?.kotlinException is KotlinCancellationException)
|
try assertTrue(error?.kotlinException is KotlinCancellationException)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,6 +472,7 @@ class CoroutinesTests : SimpleTestProvider {
|
|||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
test("TestCallSimple", testCallSimple)
|
test("TestCallSimple", testCallSimple)
|
||||||
|
test("TestCallUnitSimple", testUnitCallSimple)
|
||||||
test("TestCall", testCall)
|
test("TestCall", testCall)
|
||||||
test("TestCallChain", testCallChain)
|
test("TestCallChain", testCallChain)
|
||||||
test("TestOverride", testOverride)
|
test("TestOverride", testOverride)
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ __attribute__((swift_name("SuspendBridge")))
|
|||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
- (void)unitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unit(value:completionHandler:)")));
|
- (void)unitValue:(id _Nullable)value completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unit(value:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
@@ -188,6 +188,12 @@ __attribute__((swift_name("SuspendBridge")))
|
|||||||
*/
|
*/
|
||||||
- (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
|
- (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)nullableUnitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("nullableUnit(value:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts all Kotlin exceptions to errors.
|
@note This method converts all Kotlin exceptions to errors.
|
||||||
*/
|
*/
|
||||||
@@ -206,7 +212,7 @@ __attribute__((swift_name("SuspendBridge")))
|
|||||||
/**
|
/**
|
||||||
@note This method converts all Kotlin exceptions to errors.
|
@note This method converts all Kotlin exceptions to errors.
|
||||||
*/
|
*/
|
||||||
- (void)nothingAsUnitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)")));
|
- (void)nothingAsUnitValue:(id _Nullable)value completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((swift_name("AbstractSuspendBridge")))
|
__attribute__((swift_name("AbstractSuspendBridge")))
|
||||||
@@ -220,12 +226,24 @@ __attribute__((swift_name("AbstractSuspendBridge")))
|
|||||||
*/
|
*/
|
||||||
- (void)intAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)")));
|
- (void)intAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)unitValue:(KtInt *)value completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unit(value:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
- (void)unitAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
|
- (void)unitAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)nullableUnitValue:(KtInt *)value completionHandler:(void (^)(KtKotlinUnit * _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("nullableUnit(value:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts all Kotlin exceptions to errors.
|
@note This method converts all Kotlin exceptions to errors.
|
||||||
*/
|
*/
|
||||||
@@ -239,7 +257,7 @@ __attribute__((swift_name("AbstractSuspendBridge")))
|
|||||||
/**
|
/**
|
||||||
@note This method converts all Kotlin exceptions to errors.
|
@note This method converts all Kotlin exceptions to errors.
|
||||||
*/
|
*/
|
||||||
- (void)nothingAsUnitValue:(KtInt *)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)")));
|
- (void)nothingAsUnitValue:(KtInt *)value completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((swift_name("ThrowCancellationException")))
|
__attribute__((swift_name("ThrowCancellationException")))
|
||||||
@@ -258,7 +276,7 @@ __attribute__((swift_name("ThrowCancellationExceptionImpl")))
|
|||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
- (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)")));
|
- (void)throwCancellationExceptionWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((objc_subclassing_restricted))
|
__attribute__((objc_subclassing_restricted))
|
||||||
@@ -271,12 +289,24 @@ __attribute__((swift_name("CoroutinesKt")))
|
|||||||
*/
|
*/
|
||||||
+ (void)suspendFunWithCompletionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(completionHandler:)")));
|
+ (void)suspendFunWithCompletionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
+ (void)unitSuspendFunWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unitSuspendFun(completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts instances of CoroutineException, CancellationException to errors.
|
@note This method converts instances of CoroutineException, CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
+ (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)")));
|
+ (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CoroutineException, CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
+ (void)unitSuspendFunDoSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unitSuspendFun(doSuspend:doThrow:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts instances of CoroutineException, CancellationException to errors.
|
@note This method converts instances of CoroutineException, CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
@@ -305,7 +335,7 @@ __attribute__((swift_name("CoroutinesKt")))
|
|||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
+ (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)")));
|
+ (void)throwCancellationExceptionWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)")));
|
||||||
+ (id<KtKotlinSuspendFunction0>)getSuspendLambda0 __attribute__((swift_name("getSuspendLambda0()")));
|
+ (id<KtKotlinSuspendFunction0>)getSuspendLambda0 __attribute__((swift_name("getSuspendLambda0()")));
|
||||||
+ (id<KtKotlinSuspendFunction0>)getSuspendCallableReference0 __attribute__((swift_name("getSuspendCallableReference0()")));
|
+ (id<KtKotlinSuspendFunction0>)getSuspendCallableReference0 __attribute__((swift_name("getSuspendCallableReference0()")));
|
||||||
+ (id<KtKotlinSuspendFunction1>)getSuspendLambda1 __attribute__((swift_name("getSuspendLambda1()")));
|
+ (id<KtKotlinSuspendFunction1>)getSuspendLambda1 __attribute__((swift_name("getSuspendLambda1()")));
|
||||||
@@ -1191,7 +1221,7 @@ __attribute__((swift_name("ThrowsThrowableAsErrorSuspend")))
|
|||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
- (void)throwErrorWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwError(completionHandler:)")));
|
- (void)throwErrorWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("throwError(completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((objc_subclassing_restricted))
|
__attribute__((objc_subclassing_restricted))
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -180,7 +180,7 @@ __attribute__((swift_name("SuspendBridge")))
|
|||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
- (void)unitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unit(value:completionHandler:)")));
|
- (void)unitValue:(id _Nullable)value completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unit(value:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
@@ -188,6 +188,12 @@ __attribute__((swift_name("SuspendBridge")))
|
|||||||
*/
|
*/
|
||||||
- (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
|
- (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)nullableUnitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("nullableUnit(value:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts all Kotlin exceptions to errors.
|
@note This method converts all Kotlin exceptions to errors.
|
||||||
*/
|
*/
|
||||||
@@ -206,7 +212,7 @@ __attribute__((swift_name("SuspendBridge")))
|
|||||||
/**
|
/**
|
||||||
@note This method converts all Kotlin exceptions to errors.
|
@note This method converts all Kotlin exceptions to errors.
|
||||||
*/
|
*/
|
||||||
- (void)nothingAsUnitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)")));
|
- (void)nothingAsUnitValue:(id _Nullable)value completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((swift_name("AbstractSuspendBridge")))
|
__attribute__((swift_name("AbstractSuspendBridge")))
|
||||||
@@ -220,12 +226,24 @@ __attribute__((swift_name("AbstractSuspendBridge")))
|
|||||||
*/
|
*/
|
||||||
- (void)intAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)")));
|
- (void)intAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)unitValue:(KtInt *)value completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unit(value:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
- (void)unitAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
|
- (void)unitAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)nullableUnitValue:(KtInt *)value completionHandler:(void (^)(KtKotlinUnit * _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("nullableUnit(value:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts all Kotlin exceptions to errors.
|
@note This method converts all Kotlin exceptions to errors.
|
||||||
*/
|
*/
|
||||||
@@ -239,7 +257,7 @@ __attribute__((swift_name("AbstractSuspendBridge")))
|
|||||||
/**
|
/**
|
||||||
@note This method converts all Kotlin exceptions to errors.
|
@note This method converts all Kotlin exceptions to errors.
|
||||||
*/
|
*/
|
||||||
- (void)nothingAsUnitValue:(KtInt *)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)")));
|
- (void)nothingAsUnitValue:(KtInt *)value completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((swift_name("ThrowCancellationException")))
|
__attribute__((swift_name("ThrowCancellationException")))
|
||||||
@@ -258,7 +276,7 @@ __attribute__((swift_name("ThrowCancellationExceptionImpl")))
|
|||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
- (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)")));
|
- (void)throwCancellationExceptionWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((objc_subclassing_restricted))
|
__attribute__((objc_subclassing_restricted))
|
||||||
@@ -271,12 +289,24 @@ __attribute__((swift_name("CoroutinesKt")))
|
|||||||
*/
|
*/
|
||||||
+ (void)suspendFunWithCompletionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(completionHandler:)")));
|
+ (void)suspendFunWithCompletionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
+ (void)unitSuspendFunWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unitSuspendFun(completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts instances of CoroutineException, CancellationException to errors.
|
@note This method converts instances of CoroutineException, CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
+ (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)")));
|
+ (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CoroutineException, CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
+ (void)unitSuspendFunDoSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("unitSuspendFun(doSuspend:doThrow:completionHandler:)")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@note This method converts instances of CoroutineException, CancellationException to errors.
|
@note This method converts instances of CoroutineException, CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
@@ -305,7 +335,7 @@ __attribute__((swift_name("CoroutinesKt")))
|
|||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
+ (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)")));
|
+ (void)throwCancellationExceptionWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)")));
|
||||||
+ (id<KtKotlinSuspendFunction0>)getSuspendLambda0 __attribute__((swift_name("getSuspendLambda0()")));
|
+ (id<KtKotlinSuspendFunction0>)getSuspendLambda0 __attribute__((swift_name("getSuspendLambda0()")));
|
||||||
+ (id<KtKotlinSuspendFunction0>)getSuspendCallableReference0 __attribute__((swift_name("getSuspendCallableReference0()")));
|
+ (id<KtKotlinSuspendFunction0>)getSuspendCallableReference0 __attribute__((swift_name("getSuspendCallableReference0()")));
|
||||||
+ (id<KtKotlinSuspendFunction1>)getSuspendLambda1 __attribute__((swift_name("getSuspendLambda1()")));
|
+ (id<KtKotlinSuspendFunction1>)getSuspendLambda1 __attribute__((swift_name("getSuspendLambda1()")));
|
||||||
@@ -1133,7 +1163,7 @@ __attribute__((swift_name("ThrowsThrowableAsErrorSuspend")))
|
|||||||
@note This method converts instances of CancellationException to errors.
|
@note This method converts instances of CancellationException to errors.
|
||||||
Other uncaught Kotlin exceptions are fatal.
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
*/
|
*/
|
||||||
- (void)throwErrorWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwError(completionHandler:)")));
|
- (void)throwErrorWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler __attribute__((swift_name("throwError(completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((objc_subclassing_restricted))
|
__attribute__((objc_subclassing_restricted))
|
||||||
|
|||||||
@@ -38,9 +38,15 @@ private class ThrowsThrowableAsErrorSuspendImpl : ThrowsThrowableAsErrorSuspend
|
|||||||
self.throwable = throwable
|
self.throwable = throwable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LEGACY_SUSPEND_UNIT_FUNCTION_EXPORT
|
||||||
func throwError(completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
|
func throwError(completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
|
||||||
completionHandler(nil, throwable.asError())
|
completionHandler(nil, throwable.asError())
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
func throwError(completionHandler: @escaping (Error?) -> Void) {
|
||||||
|
completionHandler(throwable.asError())
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThrowableAsErrorTests : SimpleTestProvider {
|
class ThrowableAsErrorTests : SimpleTestProvider {
|
||||||
|
|||||||
@@ -48,12 +48,21 @@ extern "C" OBJ_GETTER(Kotlin_ObjCExport_createContinuationArgument, id completio
|
|||||||
RETURN_RESULT_OF(Kotlin_ObjCExport_createContinuationArgumentImpl, completionHolder, exceptionTypes);
|
RETURN_RESULT_OF(Kotlin_ObjCExport_createContinuationArgumentImpl, completionHolder, exceptionTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" OBJ_GETTER(Kotlin_ObjCExport_createUnitContinuationArgument, id completion, const TypeInfo** exceptionTypes) {
|
||||||
|
void (^typedCompletion)(NSError * _Nullable) = completion;
|
||||||
|
Completion twoArgumentCompletion = ^(_Nullable id result, NSError* _Nullable error) {
|
||||||
|
// typedCompletion will be retained by the containing block when the latter is copied
|
||||||
|
// from stack to heap via objc_retainBlock.
|
||||||
|
typedCompletion(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
RETURN_RESULT_OF(Kotlin_ObjCExport_createContinuationArgument, twoArgumentCompletion, exceptionTypes);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void Kotlin_ObjCExport_resumeContinuationSuccess(KRef continuation, KRef result);
|
extern "C" void Kotlin_ObjCExport_resumeContinuationSuccess(KRef continuation, KRef result);
|
||||||
extern "C" void Kotlin_ObjCExport_resumeContinuationFailure(KRef continuation, KRef exception);
|
extern "C" void Kotlin_ObjCExport_resumeContinuationFailure(KRef continuation, KRef exception);
|
||||||
|
|
||||||
extern "C" void Kotlin_ObjCExport_resumeContinuation(KRef continuation, id result, id error) {
|
extern "C" void Kotlin_ObjCExport_resumeContinuation(KRef continuation, KRef result, id error) {
|
||||||
ObjHolder holder;
|
|
||||||
|
|
||||||
if (error != nullptr) {
|
if (error != nullptr) {
|
||||||
if (result != nullptr) {
|
if (result != nullptr) {
|
||||||
[NSException raise:NSGenericException
|
[NSException raise:NSGenericException
|
||||||
@@ -61,11 +70,12 @@ extern "C" void Kotlin_ObjCExport_resumeContinuation(KRef continuation, id resul
|
|||||||
result, error];
|
result, error];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjHolder holder;
|
||||||
|
|
||||||
KRef exception = Kotlin_ObjCExport_NSErrorAsException(error, holder.slot());
|
KRef exception = Kotlin_ObjCExport_NSErrorAsException(error, holder.slot());
|
||||||
Kotlin_ObjCExport_resumeContinuationFailure(continuation, exception);
|
Kotlin_ObjCExport_resumeContinuationFailure(continuation, exception);
|
||||||
} else {
|
} else {
|
||||||
KRef kotlinResult = Kotlin_ObjCExport_refFromObjC(result, holder.slot());
|
Kotlin_ObjCExport_resumeContinuationSuccess(continuation, result);
|
||||||
Kotlin_ObjCExport_resumeContinuationSuccess(continuation, kotlinResult);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ extern "C" const char* Kotlin_callsCheckerGoodFunctionNames[] = {
|
|||||||
"CFStringCreateCopy",
|
"CFStringCreateCopy",
|
||||||
"CFStringGetCharacters",
|
"CFStringGetCharacters",
|
||||||
"CFStringGetLength",
|
"CFStringGetLength",
|
||||||
|
"_Block_object_assign",
|
||||||
"class_addIvar",
|
"class_addIvar",
|
||||||
"class_addMethod",
|
"class_addMethod",
|
||||||
"class_addProtocol",
|
"class_addProtocol",
|
||||||
|
|||||||
Reference in New Issue
Block a user