From 1d18008449cdd5cd9369d33956d95576ef325db7 Mon Sep 17 00:00:00 2001 From: SvyatoslavScherbina Date: Fri, 25 Oct 2019 17:09:53 +0300 Subject: [PATCH] Make Objective-C blocks conform to kotlin.Function<*> interface (#3492) --- .../jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt | 2 +- backend.native/tests/framework/values/expectedLazy.h | 2 ++ backend.native/tests/framework/values/values.kt | 3 +++ backend.native/tests/framework/values/values.swift | 6 ++++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt index 66df8bb3a53..c79f89d5a48 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt @@ -451,7 +451,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val superClass = context.ir.symbols.any.owner assert(superClass.implementedInterfaces.isEmpty()) - val interfaces = listOf(irClass.typeInfoPtr) + val interfaces = (listOf(irClass) + irClass.implementedInterfaces).map { it.typeInfoPtr } val interfacesPtr = staticData.placeGlobalConstArray("", pointerType(runtime.typeInfoType), interfaces) diff --git a/backend.native/tests/framework/values/expectedLazy.h b/backend.native/tests/framework/values/expectedLazy.h index ac7763bbfb5..d3eb189ef24 100644 --- a/backend.native/tests/framework/values/expectedLazy.h +++ b/backend.native/tests/framework/values/expectedLazy.h @@ -1055,6 +1055,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:)"))); ++ (BOOL)isFunctionObj:(id _Nullable)obj __attribute__((swift_name("isFunction(obj:)"))); ++ (BOOL)isFunction0Obj:(id _Nullable)obj __attribute__((swift_name("isFunction0(obj:)"))); + (void)takeForwardDeclaredClassObj:(ForwardDeclaredClass *)obj __attribute__((swift_name("takeForwardDeclaredClass(obj:)"))); + (void)takeForwardDeclaredProtocolObj:(id)obj __attribute__((swift_name("takeForwardDeclaredProtocol(obj:)"))); + (void)error __attribute__((swift_name("error()"))) __attribute__((unavailable("error"))); diff --git a/backend.native/tests/framework/values/values.kt b/backend.native/tests/framework/values/values.kt index 83ca982afa1..224e185aa4b 100644 --- a/backend.native/tests/framework/values/values.kt +++ b/backend.native/tests/framework/values/values.kt @@ -432,6 +432,9 @@ object UnitBlockCoercionImpl : UnitBlockCoercion<() -> Unit> { override fun uncoerce(block: () -> Unit): () -> Unit = block } +fun isFunction(obj: Any?): Boolean = obj is Function<*> +fun isFunction0(obj: Any?): Boolean = obj is Function0<*> + abstract class MyAbstractList : List fun takeForwardDeclaredClass(obj: objcnames.classes.ForwardDeclaredClass) {} diff --git a/backend.native/tests/framework/values/values.swift b/backend.native/tests/framework/values/values.swift index 3a8dfbdeffc..1b43568752f 100644 --- a/backend.native/tests/framework/values/values.swift +++ b/backend.native/tests/framework/values/values.swift @@ -386,6 +386,12 @@ func testLambda() throws { } try assertTrue(uncoercedUnitBlock() == Void()) try assertEquals(actual: blockRuns, expected: 5) + + let blockMustBeFunction0: @convention(block) () -> AnyObject? = { return nil } + try assertTrue(ValuesKt.isFunction(obj: blockMustBeFunction0)) + try assertTrue(ValuesKt.isFunction0(obj: blockMustBeFunction0)) + try assertFalse(ValuesKt.isFunction(obj: NSObject())) + try assertFalse(ValuesKt.isFunction0(obj: NSObject())) } // -------- Tests for classes and interfaces -------