diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index 2d997aa6186..52b92313de9 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -229,13 +229,18 @@ internal class ObjCExportCodeGenerator( return callFromBridge(conversion.owner.llvmFunction, listOf(value), resultLifetime) } - private fun generateTypeAdapters(spec: ObjCExportCodeSpec?) { - val objCTypeAdapters = mutableListOf() + private fun generateTypeAdaptersForKotlinTypes(spec: ObjCExportCodeSpec?): List { + val types = spec?.types.orEmpty() + objCClassForAny - objCTypeAdapters += createTypeAdapter(objCClassForAny, superClass = null) + val allReverseAdapters = createReverseAdapters(types) + + return types.map { + val reverseAdapters = allReverseAdapters.getValue(it) + when (it) { + objCClassForAny -> { + createTypeAdapter(it, superClass = null, reverseAdapters) + } - spec?.types?.forEach { - objCTypeAdapters += when (it) { is ObjCClassForKotlinClass -> { val superClass = it.superClassNotAny ?: objCClassForAny @@ -243,12 +248,18 @@ internal class ObjCExportCodeGenerator( // Note: it is generated only to be visible for linker. // Methods will be added at runtime. - createTypeAdapter(it, superClass) + createTypeAdapter(it, superClass, reverseAdapters) } - is ObjCProtocolForKotlinInterface -> createTypeAdapter(it, superClass = null) + is ObjCProtocolForKotlinInterface -> createTypeAdapter(it, superClass = null, reverseAdapters) } } + } + + private fun generateTypeAdapters(spec: ObjCExportCodeSpec?) { + val objCTypeAdapters = mutableListOf() + + objCTypeAdapters += generateTypeAdaptersForKotlinTypes(spec) spec?.files?.forEach { objCTypeAdapters += createTypeAdapterForFileClass(it) @@ -1247,7 +1258,8 @@ private fun ObjCExportCodeGenerator.createTypeAdapterForFileClass( private fun ObjCExportCodeGenerator.createTypeAdapter( type: ObjCTypeForKotlinType, - superClass: ObjCClassForKotlinClass? + superClass: ObjCClassForKotlinClass?, + reverseAdapters: List ): ObjCExportCodeGenerator.ObjCTypeAdapter { val irClass = type.irClassSymbol.owner val adapters = mutableListOf() @@ -1278,20 +1290,18 @@ private fun ObjCExportCodeGenerator.createTypeAdapter( }.let {} // Force exhaustive. } - val reverseAdapters = mutableListOf() + val additionalReverseAdapters = mutableListOf() if (type is ObjCClassForKotlinClass) { type.categoryMethods.forEach { adapters += createFinalMethodAdapter(it.baseMethod) - reverseAdapters += nonOverridableAdapter(it.baseMethod.selector, hasSelectorAmbiguity = false) + additionalReverseAdapters += nonOverridableAdapter(it.baseMethod.selector, hasSelectorAmbiguity = false) } adapters += createDirectAdapters(type, superClass) } - reverseAdapters += createReverseAdapters(type) - val virtualAdapters = type.kotlinMethods .filter { val irFunction = it.baseMethod.symbol.owner @@ -1339,10 +1349,16 @@ private fun ObjCExportCodeGenerator.createTypeAdapter( adapters, classAdapters, virtualAdapters, - reverseAdapters + reverseAdapters + additionalReverseAdapters ) } +private fun ObjCExportCodeGenerator.createReverseAdapters( + types: List +): Map> { + return types.associateWith { createReverseAdapters(it) } +} + private fun ObjCExportCodeGenerator.createReverseAdapters( type: ObjCTypeForKotlinType ): List {