Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ internal fun ObjCExportedInterface.createCodeSpec(symbolTable: SymbolTable): Obj

if (descriptor.kind == ClassKind.ENUM_CLASS) {
descriptor.enumEntries.mapTo(methods) {
ObjCGetterForKotlinEnumEntry(symbolTable.descriptorExtension.referenceEnumEntry(it), namer.getEnumEntrySelector(it))
ObjCGetterForKotlinEnumEntry(
symbolTable.descriptorExtension.referenceEnumEntry(it),
namer.getEnumEntryName(it).objCName)
}

descriptor.getEnumValuesFunctionDescriptor()?.let {
Expand Down Expand Up @@ -133,7 +135,7 @@ internal fun <S : IrFunctionSymbol> createObjCMethodSpecBaseMethod(
): ObjCMethodSpec.BaseMethod<S> {
require(mapper.isBaseMethod(descriptor))

val selector = namer.getSelector(descriptor)
val selector = namer.getFunctionName(descriptor).objCName
val bridge = mapper.bridgeMethod(descriptor)

return ObjCMethodSpec.BaseMethod(symbol, bridge, selector)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ interface ObjCExportNamer {
override val objCName: String,
) : ObjCExportPropertyName

data class FunctionName(
override val swiftName: String,
override val objCName: String,
) : ObjCExportFunctionName

data class EnumEntryName(
override val swiftName: String,
override val objCName: String,
) : ObjCExportEnumEntryName

interface Configuration {
val topLevelNamePrefix: String
fun getAdditionalPrefix(module: ModuleDescriptor): String?
Expand All @@ -77,13 +87,11 @@ interface ObjCExportNamer {

fun getFileClassName(file: SourceFile): ClassOrProtocolName
fun getClassOrProtocolName(descriptor: ClassDescriptor): ClassOrProtocolName
fun getSelector(method: FunctionDescriptor): String
fun getParameterName(parameter: ParameterDescriptor): String
fun getSwiftName(method: FunctionDescriptor): String
fun getFunctionName(method: FunctionDescriptor): FunctionName
fun getPropertyName(property: PropertyDescriptor): PropertyName
fun getObjectInstanceSelector(descriptor: ClassDescriptor): String
fun getEnumEntrySelector(descriptor: ClassDescriptor): String
fun getEnumEntrySwiftName(descriptor: ClassDescriptor): String
fun getEnumEntryName(descriptor: ClassDescriptor) : EnumEntryName
fun getEnumStaticMemberSelector(descriptor: CallableMemberDescriptor): String
fun getTypeParameterName(typeParameterDescriptor: TypeParameterDescriptor): String

Expand Down Expand Up @@ -543,92 +551,98 @@ class ObjCExportNamerImpl(

override fun getParameterName(parameter: ParameterDescriptor): String = parameter.getObjCName().asString(forSwift = false)

override fun getSelector(method: FunctionDescriptor): String = methodSelectors.getOrPut(method) {
assert(mapper.isBaseMethod(method))
override fun getFunctionName(method: FunctionDescriptor): ObjCExportNamer.FunctionName {
fun swiftName(method: FunctionDescriptor): String = methodSwiftNames.getOrPut(method) {
assert(mapper.isBaseMethod(method))

getPredefined(method, Predefined.anyMethodSelectors)?.let { return it }
getPredefined(method, Predefined.anyMethodSwiftNames)?.let { return it }

val parameters = mapper.bridgeMethod(method).valueParametersAssociated(method)
val parameters = mapper.bridgeMethod(method).valueParametersAssociated(method)

StringBuilder().apply {
append(method.getMangledName(forSwift = false))

parameters.forEachIndexed { index, (bridge, it) ->
val name = when (bridge) {
is MethodBridgeValueParameter.Mapped -> when {
it is ReceiverParameterDescriptor -> it.getObjCName().asIdentifier(false) { "" }
method is PropertySetterDescriptor -> when (parameters.size) {
1 -> ""
else -> "value"
StringBuilder().apply {
append(method.getMangledName(forSwift = true))
append("(")

parameters@ for ((bridge, it) in parameters) {
val label = when (bridge) {
is MethodBridgeValueParameter.Mapped -> when {
it is ReceiverParameterDescriptor -> it.getObjCName().asIdentifier(true) { "_" }
method is PropertySetterDescriptor -> when (parameters.size) {
1 -> "_"
else -> "value"
}
else -> it!!.getObjCName().asIdentifier(true)
}
else -> it!!.getObjCName().asIdentifier(false)
MethodBridgeValueParameter.ErrorOutParameter -> continue@parameters
is MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
}
MethodBridgeValueParameter.ErrorOutParameter -> "error"
is MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
}

if (index == 0) {
append(
when {
bridge is MethodBridgeValueParameter.ErrorOutParameter -> "AndReturn"
bridge is MethodBridgeValueParameter.SuspendCompletion -> "With"
method is ConstructorDescriptor -> "With"
else -> ""
}
)
append(name.replaceFirstChar(Char::uppercaseChar))
} else {
append(name)
append(label)
append(":")
}

append(':')
}
}.mangledSequence {
if (parameters.isNotEmpty()) {
// "foo:" -> "foo_:"
insert(lastIndex, '_')
} else {
// "foo" -> "foo_"
append("_")
append(")")
}.mangledSequence {
// "foo(label:)" -> "foo(label_:)"
// "foo()" -> "foo_()"
insert(lastIndex - 1, '_')
}
}
}

override fun getSwiftName(method: FunctionDescriptor): String = methodSwiftNames.getOrPut(method) {
assert(mapper.isBaseMethod(method))
fun objCName(method: FunctionDescriptor): String = methodSelectors.getOrPut(method) {
assert(mapper.isBaseMethod(method))

getPredefined(method, Predefined.anyMethodSwiftNames)?.let { return it }
getPredefined(method, Predefined.anyMethodSelectors)?.let { return it }

val parameters = mapper.bridgeMethod(method).valueParametersAssociated(method)
val parameters = mapper.bridgeMethod(method).valueParametersAssociated(method)

StringBuilder().apply {
append(method.getMangledName(forSwift = true))
append("(")

parameters@ for ((bridge, it) in parameters) {
val label = when (bridge) {
is MethodBridgeValueParameter.Mapped -> when {
it is ReceiverParameterDescriptor -> it.getObjCName().asIdentifier(true) { "_" }
method is PropertySetterDescriptor -> when (parameters.size) {
1 -> "_"
else -> "value"
StringBuilder().apply {
append(method.getMangledName(forSwift = false))

parameters.forEachIndexed { index, (bridge, it) ->
val name = when (bridge) {
is MethodBridgeValueParameter.Mapped -> when {
it is ReceiverParameterDescriptor -> it.getObjCName().asIdentifier(false) { "" }
method is PropertySetterDescriptor -> when (parameters.size) {
1 -> ""
else -> "value"
}
else -> it!!.getObjCName().asIdentifier(false)
}
else -> it!!.getObjCName().asIdentifier(true)
MethodBridgeValueParameter.ErrorOutParameter -> "error"
is MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
}
MethodBridgeValueParameter.ErrorOutParameter -> continue@parameters
is MethodBridgeValueParameter.SuspendCompletion -> "completionHandler"
}

append(label)
append(":")
}
if (index == 0) {
append(
when {
bridge is MethodBridgeValueParameter.ErrorOutParameter -> "AndReturn"
bridge is MethodBridgeValueParameter.SuspendCompletion -> "With"
method is ConstructorDescriptor -> "With"
else -> ""
}
)
append(name.replaceFirstChar(Char::uppercaseChar))
} else {
append(name)
}

append(")")
}.mangledSequence {
// "foo(label:)" -> "foo(label_:)"
// "foo()" -> "foo_()"
insert(lastIndex - 1, '_')
append(':')
}
}.mangledSequence {
if (parameters.isNotEmpty()) {
// "foo:" -> "foo_:"
insert(lastIndex, '_')
} else {
// "foo" -> "foo_"
append("_")
}
}
}
return ObjCExportNamer.FunctionName(
swiftName = swiftName(method),
objCName = objCName(method)
)
}

private fun <T : Any> getPredefined(method: FunctionDescriptor, predefinedForAny: Map<Name, T>): T? {
Expand Down Expand Up @@ -677,20 +691,18 @@ class ObjCExportNamerImpl(
return StringBuilder(name).mangledBySuffixUnderscores()
}

override fun getEnumEntrySelector(descriptor: ClassDescriptor): String {
override fun getEnumEntryName(descriptor: ClassDescriptor): ObjCExportNamer.EnumEntryName {
assert(descriptor.kind == ClassKind.ENUM_ENTRY)

return enumClassSelectors.getOrPut(descriptor) {
descriptor.getEnumEntryName(false)
}
}

override fun getEnumEntrySwiftName(descriptor: ClassDescriptor): String {
assert(descriptor.kind == ClassKind.ENUM_ENTRY)
return ObjCExportNamer.EnumEntryName(
swiftName = enumClassSwiftNames.getOrPut(descriptor) {
descriptor.getEnumEntryName(true)
},
objCName = enumClassSwiftNames.getOrPut(descriptor) {
descriptor.getEnumEntryName(false)
}

return enumClassSwiftNames.getOrPut(descriptor) {
descriptor.getEnumEntryName(true)
}
)
}

override fun getEnumStaticMemberSelector(descriptor: CallableMemberDescriptor): String {
Expand Down
Loading