[K/N] A bit more KDocs in ObjCExport

This commit is contained in:
Sergey Bogolepov
2022-07-05 12:12:13 +03:00
committed by Space
parent 730f9b4b91
commit 6a8d7ed043
2 changed files with 63 additions and 0 deletions
@@ -386,6 +386,9 @@ internal class ObjCExportCodeGenerator(
this.needsRuntimeInit = true
}
/**
* Convert [genValue] of Kotlin type from [actualType] to [expectedType] in a bridge method.
*/
inline fun ObjCExportFunctionGenerationContext.convertKotlin(
genValue: (Lifetime) -> LLVMValueRef,
actualType: IrType,
@@ -1451,6 +1454,28 @@ private fun MethodBridge.ReturnValue.isAutoreleasedObjCReference(): Boolean = wh
is MethodBridge.ReturnValue.WithError.ZeroForError -> this.successBridge.isAutoreleasedObjCReference()
}
/**
* Reverse adapters are required when Kotlin code invokes virtual method which might be overriden on Objective-C side.
* Example:
*
* ```kotlin
* interface I {
* fun foo()
* }
*
* fun usage(i: I) {
* i.foo() // Here we invoke
* }
* ```
*
* ```swift
* class C : I {
* override func foo() { ... }
* }
*
* FileKt.usage(C()) // C.foo is invoked via reverse method adapter.
* ```
*/
private fun ObjCExportCodeGenerator.createReverseAdapter(
irFunction: IrFunction,
baseMethod: ObjCMethodSpec.BaseMethod<IrSimpleFunctionSymbol>,
@@ -1471,6 +1496,28 @@ private fun ObjCExportCodeGenerator.createReverseAdapter(
kotlinToObjC)
}
/**
* We need to generate indirect version of a method for a cases
* when it is called on an object of non-exported type.
*
* Consider the following example:
* file.kt:
* ```
* open class Foo {
* open fun foo() {}
* }
* private class Bar : Foo() {
* override fun foo() {}
* }
*
* fun createBar(): Foo = Bar()
* ```
* file.swift:
* ```
* FileKt.createBar().foo()
* ```
* There is no Objective-C typeinfo for `Bar`, thus `foo` will be called via method lookup.
*/
private fun ObjCExportCodeGenerator.createMethodVirtualAdapter(
baseMethod: ObjCMethodSpec.BaseMethod<IrSimpleFunctionSymbol>
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
@@ -151,6 +151,22 @@ private fun ObjCExportMapper.isBase(descriptor: CallableMemberDescriptor): Boole
descriptor.overriddenDescriptors.all { !shouldBeExposed(it) }
// e.g. it is not `override`, or overrides only unexposed methods.
/**
* Check that given [descriptor] is a so-called "base method", i.e. method
* that doesn't override anything in a generated Objective-C interface.
* Note that it does not mean that it has no "override" keyword.
* Consider example:
* ```kotlin
* private interface I {
* fun f()
* }
*
* class C : I {
* override fun f() {}
* }
* ```
* Interface `I` is not exposed to the generated header, so C#f is considered to be a base method even though it has an "override" keyword.
*/
internal fun ObjCExportMapper.isBaseMethod(descriptor: FunctionDescriptor) =
this.isBase(descriptor)