Add selector and method bridge to relevant ObjCMethodSpec types
This helps to drop usages of obsolete "IrDeclaration.descriptor" from ObjCExportCodeGenerator
This commit is contained in:
committed by
Vasily Levchenko
parent
ccf8b570ca
commit
4080a852e1
+50
-47
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrClassReference
|
import org.jetbrains.kotlin.ir.expressions.IrClassReference
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrVararg
|
import org.jetbrains.kotlin.ir.expressions.IrVararg
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.konan.target.Family
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
@@ -373,8 +375,8 @@ internal class ObjCExportCodeGenerator(
|
|||||||
methods = listOf("equals", "hashCode", "toString").map { name ->
|
methods = listOf("equals", "hashCode", "toString").map { name ->
|
||||||
symbols.any.owner.simpleFunctions().single { it.name == Name.identifier(name) }
|
symbols.any.owner.simpleFunctions().single { it.name == Name.identifier(name) }
|
||||||
}.map {
|
}.map {
|
||||||
require(mapper.shouldBeExposed(it.descriptor))
|
val baseMethod = createObjCMethodSpecBaseMethod(mapper, namer, it.symbol, it.descriptor)
|
||||||
ObjCMethodForKotlinMethod(it.symbol)
|
ObjCMethodForKotlinMethod(baseMethod)
|
||||||
},
|
},
|
||||||
categoryMethods = emptyList(),
|
categoryMethods = emptyList(),
|
||||||
superClassNotAny = null
|
superClassNotAny = null
|
||||||
@@ -957,11 +959,11 @@ private fun ObjCExportCodeGenerator.generateObjCImpForArrayConstructor(
|
|||||||
// TODO: cache bridges.
|
// TODO: cache bridges.
|
||||||
private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
||||||
irFunction: IrFunction,
|
irFunction: IrFunction,
|
||||||
baseIrFunction: IrFunction
|
baseMethod: ObjCMethodSpec.BaseMethod<IrSimpleFunctionSymbol>
|
||||||
): ConstPointer {
|
): ConstPointer {
|
||||||
val baseMethod = baseIrFunction.descriptor
|
val baseIrFunction = baseMethod.symbol.owner
|
||||||
|
|
||||||
val methodBridge = mapper.bridgeMethod(baseMethod)
|
val methodBridge = baseMethod.bridge
|
||||||
|
|
||||||
val parameterToBase = irFunction.allParameters.zip(baseIrFunction.allParameters).toMap()
|
val parameterToBase = irFunction.allParameters.zip(baseIrFunction.allParameters).toMap()
|
||||||
|
|
||||||
@@ -991,7 +993,7 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
|
|
||||||
MethodBridgeReceiver.Instance -> kotlinReferenceToObjC(parameters[parameter]!!)
|
MethodBridgeReceiver.Instance -> kotlinReferenceToObjC(parameters[parameter]!!)
|
||||||
MethodBridgeSelector -> {
|
MethodBridgeSelector -> {
|
||||||
val selector = namer.getSelector(baseMethod)
|
val selector = baseMethod.selector
|
||||||
// Selector is referenced thus should be defined to avoid false positive non-public API rejection:
|
// Selector is referenced thus should be defined to avoid false positive non-public API rejection:
|
||||||
selectorsToDefine[selector] = methodBridge
|
selectorsToDefine[selector] = methodBridge
|
||||||
genSelector(selector)
|
genSelector(selector)
|
||||||
@@ -1022,7 +1024,7 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
|
|
||||||
val targetResult = callFromBridge(objcMsgSend, objCArgs)
|
val targetResult = callFromBridge(objcMsgSend, objCArgs)
|
||||||
|
|
||||||
assert(baseMethod !is ConstructorDescriptor)
|
assert(baseMethod.symbol !is IrConstructorSymbol)
|
||||||
|
|
||||||
fun rethrow() {
|
fun rethrow() {
|
||||||
val error = load(errorOutPtr!!)
|
val error = load(errorOutPtr!!)
|
||||||
@@ -1120,14 +1122,14 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createReverseAdapter(
|
private fun ObjCExportCodeGenerator.createReverseAdapter(
|
||||||
irFunction: IrFunction,
|
irFunction: IrFunction,
|
||||||
baseMethod: IrFunction,
|
baseMethod: ObjCMethodSpec.BaseMethod<IrSimpleFunctionSymbol>,
|
||||||
functionName: String,
|
functionName: String,
|
||||||
vtableIndex: Int?,
|
vtableIndex: Int?,
|
||||||
itablePlace: ClassLayoutBuilder.InterfaceTablePlace?
|
itablePlace: ClassLayoutBuilder.InterfaceTablePlace?
|
||||||
): ObjCExportCodeGenerator.KotlinToObjCMethodAdapter {
|
): ObjCExportCodeGenerator.KotlinToObjCMethodAdapter {
|
||||||
|
|
||||||
val nameSignature = functionName.localHash.value
|
val nameSignature = functionName.localHash.value
|
||||||
val selector = namer.getSelector(baseMethod.descriptor)
|
val selector = baseMethod.selector
|
||||||
|
|
||||||
val kotlinToObjC = generateKotlinToObjCBridge(
|
val kotlinToObjC = generateKotlinToObjCBridge(
|
||||||
irFunction,
|
irFunction,
|
||||||
@@ -1141,51 +1143,51 @@ private fun ObjCExportCodeGenerator.createReverseAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createMethodVirtualAdapter(
|
private fun ObjCExportCodeGenerator.createMethodVirtualAdapter(
|
||||||
baseMethod: IrFunction
|
baseMethod: ObjCMethodSpec.BaseMethod<IrSimpleFunctionSymbol>
|
||||||
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
||||||
assert(mapper.isBaseMethod(baseMethod.descriptor))
|
val selector = baseMethod.selector
|
||||||
|
val methodBridge = baseMethod.bridge
|
||||||
val selector = namer.getSelector(baseMethod.descriptor)
|
val irFunction = baseMethod.symbol.owner
|
||||||
|
val imp = generateObjCImp(irFunction, irFunction, methodBridge, isVirtual = true)
|
||||||
val methodBridge = mapper.bridgeMethod(baseMethod.descriptor)
|
|
||||||
val imp = generateObjCImp(baseMethod, baseMethod, methodBridge, isVirtual = true)
|
|
||||||
|
|
||||||
return objCToKotlinMethodAdapter(selector, methodBridge, imp)
|
return objCToKotlinMethodAdapter(selector, methodBridge, imp)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createMethodAdapter(
|
private fun ObjCExportCodeGenerator.createMethodAdapter(
|
||||||
implementation: IrFunction?,
|
implementation: IrFunction?,
|
||||||
baseMethod: IrFunction
|
baseMethod: ObjCMethodSpec.BaseMethod<*>
|
||||||
) = createMethodAdapter(DirectAdapterRequest(implementation, baseMethod))
|
) = createMethodAdapter(DirectAdapterRequest(implementation, baseMethod))
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createFinalMethodAdapter(
|
private fun ObjCExportCodeGenerator.createFinalMethodAdapter(
|
||||||
irFunction: IrSimpleFunction
|
baseMethod: ObjCMethodSpec.BaseMethod<IrSimpleFunctionSymbol>
|
||||||
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
||||||
|
val irFunction = baseMethod.symbol.owner
|
||||||
require(irFunction.modality == Modality.FINAL)
|
require(irFunction.modality == Modality.FINAL)
|
||||||
return createMethodAdapter(irFunction, irFunction)
|
return createMethodAdapter(irFunction, baseMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createMethodAdapter(
|
private fun ObjCExportCodeGenerator.createMethodAdapter(
|
||||||
request: DirectAdapterRequest
|
request: DirectAdapterRequest
|
||||||
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter = this.directMethodAdapters.getOrPut(request) {
|
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter = this.directMethodAdapters.getOrPut(request) {
|
||||||
|
|
||||||
val selectorName = namer.getSelector(request.base.descriptor)
|
val selectorName = request.base.selector
|
||||||
val methodBridge = mapper.bridgeMethod(request.base.descriptor)
|
val methodBridge = request.base.bridge
|
||||||
|
|
||||||
val imp = generateObjCImp(request.implementation, request.base, methodBridge)
|
val imp = generateObjCImp(request.implementation, request.base.symbol.owner, methodBridge)
|
||||||
|
|
||||||
objCToKotlinMethodAdapter(selectorName, methodBridge, imp)
|
objCToKotlinMethodAdapter(selectorName, methodBridge, imp)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createConstructorAdapter(
|
private fun ObjCExportCodeGenerator.createConstructorAdapter(
|
||||||
irConstructor: IrConstructor
|
baseMethod: ObjCMethodSpec.BaseMethod<IrConstructorSymbol>
|
||||||
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter = createMethodAdapter(irConstructor, irConstructor)
|
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter = createMethodAdapter(baseMethod.symbol.owner, baseMethod)
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createArrayConstructorAdapter(
|
private fun ObjCExportCodeGenerator.createArrayConstructorAdapter(
|
||||||
irConstructor: IrConstructor
|
baseMethod: ObjCMethodSpec.BaseMethod<IrConstructorSymbol>
|
||||||
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
||||||
val selectorName = namer.getSelector(irConstructor.descriptor)
|
val selectorName = baseMethod.selector
|
||||||
val methodBridge = mapper.bridgeMethod(irConstructor.descriptor)
|
val methodBridge = baseMethod.bridge
|
||||||
|
val irConstructor = baseMethod.symbol.owner
|
||||||
val imp = generateObjCImpForArrayConstructor(irConstructor, methodBridge)
|
val imp = generateObjCImpForArrayConstructor(irConstructor, methodBridge)
|
||||||
|
|
||||||
return objCToKotlinMethodAdapter(selectorName, methodBridge, imp)
|
return objCToKotlinMethodAdapter(selectorName, methodBridge, imp)
|
||||||
@@ -1217,7 +1219,7 @@ private fun ObjCExportCodeGenerator.createTypeAdapterForFileClass(
|
|||||||
): ObjCExportCodeGenerator.ObjCTypeAdapter {
|
): ObjCExportCodeGenerator.ObjCTypeAdapter {
|
||||||
val name = fileClass.binaryName
|
val name = fileClass.binaryName
|
||||||
|
|
||||||
val adapters = fileClass.methods.map { createFinalMethodAdapter(it.baseMethod.owner) }
|
val adapters = fileClass.methods.map { createFinalMethodAdapter(it.baseMethod) }
|
||||||
|
|
||||||
return ObjCTypeAdapter(
|
return ObjCTypeAdapter(
|
||||||
irClass = null,
|
irClass = null,
|
||||||
@@ -1246,10 +1248,10 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
|
|||||||
type.methods.forEach {
|
type.methods.forEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
is ObjCInitMethodForKotlinConstructor -> {
|
is ObjCInitMethodForKotlinConstructor -> {
|
||||||
adapters += createConstructorAdapter(it.irConstructorSymbol.owner)
|
adapters += createConstructorAdapter(it.baseMethod)
|
||||||
}
|
}
|
||||||
is ObjCFactoryMethodForKotlinArrayConstructor -> {
|
is ObjCFactoryMethodForKotlinArrayConstructor -> {
|
||||||
classAdapters += createArrayConstructorAdapter(it.irConstructorSymbol.owner)
|
classAdapters += createArrayConstructorAdapter(it.baseMethod)
|
||||||
}
|
}
|
||||||
is ObjCGetterForKotlinEnumEntry -> {
|
is ObjCGetterForKotlinEnumEntry -> {
|
||||||
classAdapters += createEnumEntryAdapter(it.irEnumEntrySymbol.owner, it.selector)
|
classAdapters += createEnumEntryAdapter(it.irEnumEntrySymbol.owner, it.selector)
|
||||||
@@ -1273,9 +1275,8 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
|
|||||||
if (type is ObjCClassForKotlinClass) {
|
if (type is ObjCClassForKotlinClass) {
|
||||||
|
|
||||||
type.categoryMethods.forEach {
|
type.categoryMethods.forEach {
|
||||||
val irFunction = it.baseMethod.owner
|
adapters += createFinalMethodAdapter(it.baseMethod)
|
||||||
adapters += createFinalMethodAdapter(irFunction)
|
reverseAdapters += nonOverridableAdapter(it.baseMethod.selector, hasSelectorAmbiguity = false)
|
||||||
reverseAdapters += nonOverridableAdapter(irFunction.descriptor, hasSelectorAmbiguity = false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
adapters += createDirectAdapters(type, superClass)
|
adapters += createDirectAdapters(type, superClass)
|
||||||
@@ -1283,9 +1284,11 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
|
|||||||
|
|
||||||
reverseAdapters += createReverseAdapters(type)
|
reverseAdapters += createReverseAdapters(type)
|
||||||
|
|
||||||
val virtualAdapters = type.kotlinMethods.map { it.baseMethod.owner }
|
val virtualAdapters = type.kotlinMethods
|
||||||
.filter { it.parentAsClass == irClass && it.isOverridable }
|
.filter {
|
||||||
.map { createMethodVirtualAdapter(it) }
|
val irFunction = it.baseMethod.symbol.owner
|
||||||
|
irFunction.parentAsClass == irClass && irFunction.isOverridable
|
||||||
|
}.map { createMethodVirtualAdapter(it.baseMethod) }
|
||||||
|
|
||||||
val typeInfo = constPointer(codegen.typeInfoValue(irClass))
|
val typeInfo = constPointer(codegen.typeInfoValue(irClass))
|
||||||
val objCName = type.binaryName
|
val objCName = type.binaryName
|
||||||
@@ -1336,13 +1339,13 @@ private fun ObjCExportCodeGenerator.createReverseAdapters(
|
|||||||
type: ObjCTypeForKotlinType
|
type: ObjCTypeForKotlinType
|
||||||
): List<ObjCExportCodeGenerator.KotlinToObjCMethodAdapter> {
|
): List<ObjCExportCodeGenerator.KotlinToObjCMethodAdapter> {
|
||||||
val result = mutableListOf<ObjCExportCodeGenerator.KotlinToObjCMethodAdapter>()
|
val result = mutableListOf<ObjCExportCodeGenerator.KotlinToObjCMethodAdapter>()
|
||||||
val allBaseMethods = type.kotlinMethods.map { it.baseMethod.owner }.toSet()
|
val allBaseMethodsByIr = type.kotlinMethods.map { it.baseMethod }.associateBy { it.symbol.owner }
|
||||||
|
|
||||||
for (method in type.irClassSymbol.owner.simpleFunctions()) {
|
for (method in type.irClassSymbol.owner.simpleFunctions()) {
|
||||||
val baseMethods = method.allOverriddenFunctions.filter { it in allBaseMethods }
|
val baseMethods = method.allOverriddenFunctions.mapNotNull { allBaseMethodsByIr[it] }
|
||||||
if (baseMethods.isEmpty()) continue
|
if (baseMethods.isEmpty()) continue
|
||||||
|
|
||||||
val hasSelectorAmbiguity = baseMethods.map { namer.getSelector(it.descriptor) }.distinct().size > 1
|
val hasSelectorAmbiguity = baseMethods.map { it.selector }.distinct().size > 1
|
||||||
|
|
||||||
if (method.isOverridable && !hasSelectorAmbiguity) {
|
if (method.isOverridable && !hasSelectorAmbiguity) {
|
||||||
val baseMethod = baseMethods.first()
|
val baseMethod = baseMethods.first()
|
||||||
@@ -1379,8 +1382,8 @@ private fun ObjCExportCodeGenerator.createReverseAdapters(
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Mark it as non-overridable:
|
// Mark it as non-overridable:
|
||||||
baseMethods.distinctBy { namer.getSelector(it.descriptor) }.forEach { baseMethod ->
|
baseMethods.map { it.selector }.distinct().forEach {
|
||||||
result += nonOverridableAdapter(baseMethod.descriptor, hasSelectorAmbiguity)
|
result += nonOverridableAdapter(it, hasSelectorAmbiguity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1389,10 +1392,10 @@ private fun ObjCExportCodeGenerator.createReverseAdapters(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.nonOverridableAdapter(
|
private fun ObjCExportCodeGenerator.nonOverridableAdapter(
|
||||||
baseMethod: FunctionDescriptor,
|
selector: String,
|
||||||
hasSelectorAmbiguity: Boolean
|
hasSelectorAmbiguity: Boolean
|
||||||
): ObjCExportCodeGenerator.KotlinToObjCMethodAdapter = KotlinToObjCMethodAdapter(
|
): ObjCExportCodeGenerator.KotlinToObjCMethodAdapter = KotlinToObjCMethodAdapter(
|
||||||
namer.getSelector(baseMethod),
|
selector,
|
||||||
-1,
|
-1,
|
||||||
vtableIndex = if (hasSelectorAmbiguity) -2 else -1, // Describes the reason.
|
vtableIndex = if (hasSelectorAmbiguity) -2 else -1, // Describes the reason.
|
||||||
kotlinImpl = NullPointer(int8Type),
|
kotlinImpl = NullPointer(int8Type),
|
||||||
@@ -1402,7 +1405,7 @@ private fun ObjCExportCodeGenerator.nonOverridableAdapter(
|
|||||||
private val ObjCTypeForKotlinType.kotlinMethods: List<ObjCMethodForKotlinMethod>
|
private val ObjCTypeForKotlinType.kotlinMethods: List<ObjCMethodForKotlinMethod>
|
||||||
get() = this.methods.filterIsInstance<ObjCMethodForKotlinMethod>()
|
get() = this.methods.filterIsInstance<ObjCMethodForKotlinMethod>()
|
||||||
|
|
||||||
internal data class DirectAdapterRequest(val implementation: IrFunction?, val base: IrFunction)
|
internal data class DirectAdapterRequest(val implementation: IrFunction?, val base: ObjCMethodSpec.BaseMethod<*>)
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createDirectAdapters(
|
private fun ObjCExportCodeGenerator.createDirectAdapters(
|
||||||
typeDeclaration: ObjCClassForKotlinClass,
|
typeDeclaration: ObjCClassForKotlinClass,
|
||||||
@@ -1411,15 +1414,15 @@ private fun ObjCExportCodeGenerator.createDirectAdapters(
|
|||||||
|
|
||||||
fun ObjCClassForKotlinClass.getAllRequiredDirectAdapters() = this.kotlinMethods.map { method ->
|
fun ObjCClassForKotlinClass.getAllRequiredDirectAdapters() = this.kotlinMethods.map { method ->
|
||||||
DirectAdapterRequest(
|
DirectAdapterRequest(
|
||||||
findImplementation(irClassSymbol.owner, method.baseMethod.owner, context),
|
findImplementation(irClassSymbol.owner, method.baseMethod.symbol.owner, context),
|
||||||
method.baseMethod.owner
|
method.baseMethod
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val inheritedAdapters = superClass?.getAllRequiredDirectAdapters().orEmpty()
|
val inheritedAdapters = superClass?.getAllRequiredDirectAdapters().orEmpty()
|
||||||
val requiredAdapters = typeDeclaration.getAllRequiredDirectAdapters() - inheritedAdapters
|
val requiredAdapters = typeDeclaration.getAllRequiredDirectAdapters() - inheritedAdapters
|
||||||
|
|
||||||
return requiredAdapters.distinctBy { namer.getSelector(it.base.descriptor) }.map { createMethodAdapter(it) }
|
return requiredAdapters.distinctBy { it.base.selector }.map { createMethodAdapter(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findImplementation(irClass: IrClass, method: IrSimpleFunction, context: Context): IrSimpleFunction? {
|
private fun findImplementation(irClass: IrClass, method: IrSimpleFunction, context: Context): IrSimpleFunction? {
|
||||||
|
|||||||
+35
-7
@@ -17,7 +17,14 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
|||||||
internal fun ObjCExportedInterface.createCodeSpec(symbolTable: SymbolTable): ObjCExportCodeSpec {
|
internal fun ObjCExportedInterface.createCodeSpec(symbolTable: SymbolTable): ObjCExportCodeSpec {
|
||||||
|
|
||||||
fun createObjCMethods(methods: List<FunctionDescriptor>) = methods.map {
|
fun createObjCMethods(methods: List<FunctionDescriptor>) = methods.map {
|
||||||
ObjCMethodForKotlinMethod(symbolTable.referenceSimpleFunction(it))
|
ObjCMethodForKotlinMethod(
|
||||||
|
createObjCMethodSpecBaseMethod(
|
||||||
|
mapper,
|
||||||
|
namer,
|
||||||
|
symbolTable.referenceSimpleFunction(it),
|
||||||
|
it
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<CallableMemberDescriptor>.toObjCMethods() = createObjCMethods(this.flatMap {
|
fun List<CallableMemberDescriptor>.toObjCMethods() = createObjCMethods(this.flatMap {
|
||||||
@@ -55,11 +62,12 @@ internal fun ObjCExportedInterface.createCodeSpec(symbolTable: SymbolTable): Obj
|
|||||||
} else {
|
} else {
|
||||||
descriptor.constructors.filter { mapper.shouldBeExposed(it) }.mapTo(methods) {
|
descriptor.constructors.filter { mapper.shouldBeExposed(it) }.mapTo(methods) {
|
||||||
val irConstructorSymbol = symbolTable.referenceConstructor(it)
|
val irConstructorSymbol = symbolTable.referenceConstructor(it)
|
||||||
|
val baseMethod = createObjCMethodSpecBaseMethod(mapper, namer, irConstructorSymbol, it)
|
||||||
|
|
||||||
if (descriptor.isArray) {
|
if (descriptor.isArray) {
|
||||||
ObjCFactoryMethodForKotlinArrayConstructor(irConstructorSymbol)
|
ObjCFactoryMethodForKotlinArrayConstructor(baseMethod)
|
||||||
} else {
|
} else {
|
||||||
ObjCInitMethodForKotlinConstructor(irConstructorSymbol)
|
ObjCInitMethodForKotlinConstructor(baseMethod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,19 +102,39 @@ internal fun ObjCExportedInterface.createCodeSpec(symbolTable: SymbolTable): Obj
|
|||||||
return ObjCExportCodeSpec(files, types)
|
return ObjCExportCodeSpec(files, types)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <S : IrFunctionSymbol> createObjCMethodSpecBaseMethod(
|
||||||
|
mapper: ObjCExportMapper,
|
||||||
|
namer: ObjCExportNamer,
|
||||||
|
symbol: S,
|
||||||
|
descriptor: FunctionDescriptor
|
||||||
|
): ObjCMethodSpec.BaseMethod<S> {
|
||||||
|
require(mapper.isBaseMethod(descriptor))
|
||||||
|
|
||||||
|
val selector = namer.getSelector(descriptor)
|
||||||
|
val bridge = mapper.bridgeMethod(descriptor)
|
||||||
|
|
||||||
|
return ObjCMethodSpec.BaseMethod(symbol, bridge, selector)
|
||||||
|
}
|
||||||
|
|
||||||
internal class ObjCExportCodeSpec(
|
internal class ObjCExportCodeSpec(
|
||||||
val files: List<ObjCClassForKotlinFile>,
|
val files: List<ObjCClassForKotlinFile>,
|
||||||
val types: List<ObjCTypeForKotlinType>
|
val types: List<ObjCTypeForKotlinType>
|
||||||
)
|
)
|
||||||
|
|
||||||
internal sealed class ObjCMethodSpec
|
internal sealed class ObjCMethodSpec {
|
||||||
|
/**
|
||||||
|
* Aggregates base method (as defined by [ObjCExportMapper.isBaseMethod])
|
||||||
|
* and details required to generate code for bridges between Kotlin and Obj-C methods.
|
||||||
|
*/
|
||||||
|
data class BaseMethod<out S : IrFunctionSymbol>(val symbol: S, val bridge: MethodBridge, val selector: String)
|
||||||
|
}
|
||||||
|
|
||||||
internal class ObjCMethodForKotlinMethod(val baseMethod: IrSimpleFunctionSymbol) : ObjCMethodSpec()
|
internal class ObjCMethodForKotlinMethod(val baseMethod: BaseMethod<IrSimpleFunctionSymbol>) : ObjCMethodSpec()
|
||||||
|
|
||||||
internal class ObjCInitMethodForKotlinConstructor(val irConstructorSymbol: IrConstructorSymbol) : ObjCMethodSpec()
|
internal class ObjCInitMethodForKotlinConstructor(val baseMethod: BaseMethod<IrConstructorSymbol>) : ObjCMethodSpec()
|
||||||
|
|
||||||
internal class ObjCFactoryMethodForKotlinArrayConstructor(
|
internal class ObjCFactoryMethodForKotlinArrayConstructor(
|
||||||
val irConstructorSymbol: IrConstructorSymbol
|
val baseMethod: BaseMethod<IrConstructorSymbol>
|
||||||
) : ObjCMethodSpec()
|
) : ObjCMethodSpec()
|
||||||
|
|
||||||
internal class ObjCGetterForKotlinEnumEntry(
|
internal class ObjCGetterForKotlinEnumEntry(
|
||||||
|
|||||||
Reference in New Issue
Block a user