Improve interop with headers generated by Swift

Support `objc_runtime_name` attribute on Objective-C classes
thus enabling interop with `@objc` Swift classes without
explicitly specified name.

See https://github.com/JetBrains/kotlin-native/issues/1841#issuecomment-411346727
This commit is contained in:
Svyatoslav Scherbina
2018-09-17 10:16:37 +03:00
committed by SvyatoslavScherbina
parent 4ec1ec05cf
commit 803620f423
8 changed files with 59 additions and 23 deletions
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
import org.jetbrains.kotlin.backend.konan.descriptors.findPackageView
import org.jetbrains.kotlin.backend.konan.descriptors.getStringValue
import org.jetbrains.kotlin.backend.konan.descriptors.getStringValueOrNull
import org.jetbrains.kotlin.backend.konan.irasdescriptors.constructedClass
import org.jetbrains.kotlin.backend.konan.irasdescriptors.getExternalObjCMethodInfo
import org.jetbrains.kotlin.backend.konan.irasdescriptors.isReal
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
import org.jetbrains.kotlin.resolve.constants.BooleanValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
@@ -229,4 +228,15 @@ fun inferObjCSelector(descriptor: FunctionDescriptor): String = if (descriptor.v
append(':')
}
}
}
}
fun ClassDescriptor.getExternalObjCClassBinaryName(): String =
this.getExplicitExternalObjCClassBinaryName()
?: this.name.asString()
fun ClassDescriptor.getExternalObjCMetaClassBinaryName(): String =
this.getExplicitExternalObjCClassBinaryName()
?: this.name.asString().removeSuffix("Meta")
private fun ClassDescriptor.getExplicitExternalObjCClassBinaryName() =
this.annotations.findAnnotation(externalObjCClassFqName)!!.getStringValueOrNull("binaryName")
@@ -754,7 +754,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
context.llvm.imports.add(irClass.llvmSymbolOrigin)
if (irClass.isObjCMetaClass()) {
val name = irClass.name.asString().removeSuffix("Meta")
val name = irClass.descriptor.getExternalObjCMetaClassBinaryName()
val objCClass = load(codegen.objCDataGenerator!!.genClassRef(name).llvm)
@@ -766,7 +766,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
call(getClass, listOf(objCClass), exceptionHandler = exceptionHandler)
} else {
load(codegen.objCDataGenerator!!.genClassRef(irClass.name.asString()).llvm)
load(codegen.objCDataGenerator!!.genClassRef(irClass.descriptor.getExternalObjCClassBinaryName()).llvm)
}
} else {
if (irClass.isObjCMetaClass()) {
@@ -31,7 +31,7 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con
val superclassName = irClass.getSuperClassNotAny()!!.let {
context.llvm.imports.add(it.llvmSymbolOrigin)
it.name.asString()
it.descriptor.getExternalObjCClassBinaryName()
}
val protocolNames = irClass.getSuperInterfaces().map {
context.llvm.imports.add(it.llvmSymbolOrigin)