Improve ObjCExport type mapping

Support Class type and forward declarations
This commit is contained in:
Svyatoslav Scherbina
2019-05-30 10:29:08 +03:00
committed by SvyatoslavScherbina
parent ed3f3f976e
commit 77e69f5a3f
5 changed files with 16 additions and 2 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
import org.jetbrains.kotlin.backend.konan.descriptors.getArgumentValueOrNull
import org.jetbrains.kotlin.backend.konan.descriptors.getStringValue
import org.jetbrains.kotlin.backend.konan.descriptors.getStringValueOrNull
@@ -34,6 +35,7 @@ internal val externalObjCClassFqName = interopPackageName.child(Name.identifier(
private val objCMethodFqName = interopPackageName.child(Name.identifier("ObjCMethod"))
private val objCConstructorFqName = FqName("kotlinx.cinterop.ObjCConstructor")
private val objCFactoryFqName = interopPackageName.child(Name.identifier("ObjCFactory"))
private val objcnamesForwardDeclarationsPackageName = Name.identifier("objcnames")
@Deprecated("Use IR version rather than descriptor version")
fun ClassDescriptor.isObjCClass(): Boolean =
@@ -61,6 +63,9 @@ fun IrClass.isExternalObjCClass(): Boolean = this.isObjCClass() &&
it.descriptor.annotations.hasAnnotation(externalObjCClassFqName)
}
fun ClassDescriptor.isObjCForwardDeclaration(): Boolean =
this.findPackage().fqName.startsWith(objcnamesForwardDeclarationsPackageName)
fun ClassDescriptor.isObjCMetaClass(): Boolean = this.getAllSuperClassifiers().any {
it.fqNameSafe == objCClassFqName
}
@@ -800,9 +800,9 @@ internal class ObjCExportTranslatorImpl(
private tailrec fun mapObjCObjectReferenceTypeIgnoringNullability(descriptor: ClassDescriptor): ObjCNonNullReferenceType {
// TODO: more precise types can be used.
if (descriptor.isObjCMetaClass()) return ObjCIdType
if (descriptor.isObjCMetaClass()) return ObjCMetaClassType
if (descriptor.isExternalObjCClass()) {
if (descriptor.isExternalObjCClass() || descriptor.isObjCForwardDeclaration()) {
return if (descriptor.isInterface) {
val name = descriptor.name.asString().removeSuffix("Protocol")
generator?.referenceProtocol(name)
@@ -89,6 +89,10 @@ class ObjCBlockPointerType(
})
}
object ObjCMetaClassType : ObjCNonNullReferenceType() {
override fun render(attrsAndName: String): String = "Class".withAttrsAndName(attrsAndName)
}
class ObjCPrimitiveType(
val cName: String
) : ObjCType() {
@@ -600,6 +600,8 @@ __attribute__((swift_name("ValuesKt")))
+ (void (^)(void))asNothingBlockBlock:(id _Nullable (^)(void))block __attribute__((swift_name("asNothingBlock(block:)")));
+ (void (^ _Nullable)(void))getNullBlock __attribute__((swift_name("getNullBlock()")));
+ (BOOL)isBlockNullBlock:(void (^ _Nullable)(void))block __attribute__((swift_name("isBlockNull(block:)")));
+ (void)takeForwardDeclaredClassObj:(ForwardDeclaredClass *)obj __attribute__((swift_name("takeForwardDeclaredClass(obj:)")));
+ (void)takeForwardDeclaredProtocolObj:(id<ForwardDeclared>)obj __attribute__((swift_name("takeForwardDeclaredProtocol(obj:)")));
@property (class, readonly) double dbl __attribute__((swift_name("dbl")));
@property (class, readonly) float flt __attribute__((swift_name("flt")));
@property (class, readonly) int32_t integer __attribute__((swift_name("integer")));
@@ -423,3 +423,6 @@ object UnitBlockCoercionImpl : UnitBlockCoercion<() -> Unit> {
}
abstract class MyAbstractList : List<Any?>
fun takeForwardDeclaredClass(obj: objcnames.classes.ForwardDeclaredClass) {}
fun takeForwardDeclaredProtocol(obj: objcnames.protocols.ForwardDeclaredProtocol) {}