Use compiler-generated C stubs to call Objective-C methods

Also
*   Use compiler-generated C stubs when overriding all Objective-C methods
*   Support block types in C stubs generator
This commit is contained in:
Svyatoslav Scherbina
2019-03-13 11:13:28 +03:00
committed by SvyatoslavScherbina
parent 68efc823f1
commit 54881b421c
24 changed files with 963 additions and 484 deletions
+62 -19
View File
@@ -18,6 +18,9 @@ fun run() {
testTypeOps()
testConversions()
testWeakRefs()
testExceptions()
testBlocks()
testCustomRetain()
assertEquals(2, ForwardDeclaredEnum.TWO.value)
@@ -88,24 +91,6 @@ fun run() {
override fun create() = autoreleasepool { NSObject() }
})
assertEquals(222, callProvidedBlock(object : NSObject(), BlockProviderProtocol {
override fun block(): (Int) -> Int = { it * 2 }
}, 111))
assertEquals(322, callPlusOneBlock(object : NSObject(), BlockConsumerProtocol {
override fun callBlock(block: ((Int) -> Int)?, argument: Int) = block!!(argument)
}, 321))
autoreleasepool {
useCustomRetainMethods(object : Foo(), CustomRetainMethodsProtocol {
override fun returnRetained(obj: Any?) = obj
override fun consume(obj: Any?) {}
override fun consumeSelf() {}
})
}
assertFalse(unexpectedDeallocation)
}
fun MutablePairProtocol.swap() {
@@ -185,7 +170,7 @@ fun testMethodsOfAny(kotlinObject: Any, equalNsObject: NSObject, otherObject: An
}
fun testWeakRefs() {
testWeakReference({ NSObject.new()!! })
testWeakReference({ createNSObject()!! })
createAndAbandonWeakRef(NSObject())
@@ -213,6 +198,64 @@ fun createAndAbandonWeakRef(obj: NSObject) {
WeakReference(obj)
}
fun testExceptions() {
assertFailsWith<MyException> {
ExceptionThrowerManager.throwExceptionWith(object : NSObject(), ExceptionThrowerProtocol {
override fun throwException() {
throw MyException()
}
})
}
}
fun testBlocks() {
assertTrue(Blocks.blockIsNull(null))
assertFalse(Blocks.blockIsNull({}))
assertEquals(null, Blocks.nullBlock)
assertNotEquals(null, Blocks.notNullBlock)
assertEquals(10, Blocks.same({ a, b, c, d -> a + b + c + d })!!(1, 2, 3, 4))
assertEquals(222, callProvidedBlock(object : NSObject(), BlockProviderProtocol {
override fun block(): (Int) -> Int = { it * 2 }
}, 111))
assertEquals(322, callPlusOneBlock(object : NSObject(), BlockConsumerProtocol {
override fun callBlock(block: ((Int) -> Int)?, argument: Int) = block!!(argument)
}, 321))
}
private lateinit var retainedMustNotBeDeallocated: MustNotBeDeallocated
fun testCustomRetain() {
fun test() {
useCustomRetainMethods(object : Foo(), CustomRetainMethodsProtocol {
override fun returnRetained(obj: Any?) = obj
override fun consume(obj: Any?) {}
override fun consumeSelf() {}
override fun returnRetainedBlock(block: (() -> Unit)?) = block
})
CustomRetainMethodsImpl().let {
it.returnRetained(Any())
retainedMustNotBeDeallocated = MustNotBeDeallocated() // Retain to detect possible over-release.
it.consume(retainedMustNotBeDeallocated)
it.consumeSelf()
it.returnRetainedBlock({})!!()
}
}
autoreleasepool {
test()
kotlin.native.internal.GC.collect()
}
assertFalse(unexpectedDeallocation)
}
private class MyException : Throwable()
fun nsArrayOf(vararg elements: Any): NSArray = NSMutableArray().apply {
elements.forEach {
this.addObject(it as ObjCObject)