Native: add tests for autorelease optimization in ObjCExport
The compiler should do its best to avoid putting objects to autorelease pools.
This commit is contained in:
committed by
Space
parent
8c923f6504
commit
b32ab48596
@@ -923,6 +923,116 @@ __attribute__((swift_name("ArraysInitBlock")))
|
||||
- (NSString *)log __attribute__((swift_name("log()")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("KotlinLivenessTracker")))
|
||||
@interface KtKotlinLivenessTracker : KtBase
|
||||
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
|
||||
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
|
||||
- (void)addObj:(id _Nullable)obj __attribute__((swift_name("add(obj:)")));
|
||||
- (BOOL)isEmpty __attribute__((swift_name("isEmpty()")));
|
||||
- (BOOL)objectsAreDead __attribute__((swift_name("objectsAreDead()")));
|
||||
@property (readonly) NSMutableArray<KtKotlinWeakReference<id> *> *weakRefs __attribute__((swift_name("weakRefs")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("KotlinObject")))
|
||||
@interface KtKotlinObject : KtBase
|
||||
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
|
||||
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
|
||||
@end;
|
||||
|
||||
__attribute__((swift_name("NoAutoreleaseSendHelper")))
|
||||
@protocol KtNoAutoreleaseSendHelper
|
||||
@required
|
||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||
@end;
|
||||
|
||||
__attribute__((swift_name("NoAutoreleaseReceiveHelper")))
|
||||
@protocol KtNoAutoreleaseReceiveHelper
|
||||
@required
|
||||
- (KtKotlinObject *)receiveKotlinObject __attribute__((swift_name("receiveKotlinObject()")));
|
||||
- (id)receiveSwiftObject __attribute__((swift_name("receiveSwiftObject()")));
|
||||
- (NSArray<id> *)receiveList __attribute__((swift_name("receiveList()")));
|
||||
- (NSString *)receiveString __attribute__((swift_name("receiveString()")));
|
||||
- (id)receiveNumber __attribute__((swift_name("receiveNumber()")));
|
||||
- (KtKotlinObject *(^)(void))receiveBlock __attribute__((swift_name("receiveBlock()")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseKotlinSendHelper")))
|
||||
@interface KtNoAutoreleaseKotlinSendHelper : KtBase <KtNoAutoreleaseSendHelper>
|
||||
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseKotlinReceiveHelper")))
|
||||
@interface KtNoAutoreleaseKotlinReceiveHelper : KtBase <KtNoAutoreleaseReceiveHelper>
|
||||
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
||||
- (KtKotlinObject *)receiveKotlinObject __attribute__((swift_name("receiveKotlinObject()")));
|
||||
- (id)receiveSwiftObject __attribute__((swift_name("receiveSwiftObject()")));
|
||||
- (NSArray<id> *)receiveList __attribute__((swift_name("receiveList()")));
|
||||
- (NSString *)receiveString __attribute__((swift_name("receiveString()")));
|
||||
- (id)receiveNumber __attribute__((swift_name("receiveNumber()")));
|
||||
- (KtKotlinObject *(^)(void))receiveBlock __attribute__((swift_name("receiveBlock()")));
|
||||
@property id swiftObject __attribute__((swift_name("swiftObject")));
|
||||
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseSingleton")))
|
||||
@interface KtNoAutoreleaseSingleton : KtBase
|
||||
+ (instancetype)alloc __attribute__((unavailable));
|
||||
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
|
||||
+ (instancetype)noAutoreleaseSingleton __attribute__((swift_name("init()")));
|
||||
@property (class, readonly, getter=shared) KtNoAutoreleaseSingleton *shared __attribute__((swift_name("shared")));
|
||||
@property (readonly) int32_t x __attribute__((swift_name("x")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseEnum")))
|
||||
@interface KtNoAutoreleaseEnum : KtKotlinEnum<KtNoAutoreleaseEnum *>
|
||||
+ (instancetype)alloc __attribute__((unavailable));
|
||||
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
|
||||
- (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
|
||||
@property (class, readonly) KtNoAutoreleaseEnum *entry __attribute__((swift_name("entry")));
|
||||
+ (KtKotlinArray<KtNoAutoreleaseEnum *> *)values __attribute__((swift_name("values()")));
|
||||
@property (readonly) int32_t x __attribute__((swift_name("x")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseKt")))
|
||||
@interface KtNoAutoreleaseKt : KtBase
|
||||
+ (void)gc __attribute__((swift_name("gc()")));
|
||||
+ (void)callSendKotlinObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendKotlinObject(helper:tracker:)")));
|
||||
+ (void)callSendSwiftObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker swiftObject:(id)swiftObject __attribute__((swift_name("callSendSwiftObject(helper:tracker:swiftObject:)")));
|
||||
+ (void)callSendListHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendList(helper:tracker:)")));
|
||||
+ (void)callSendStringHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendString(helper:tracker:)")));
|
||||
+ (void)callSendNumberHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendNumber(helper:tracker:)")));
|
||||
+ (void)callSendBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendBlock(helper:tracker:)")));
|
||||
+ (void)callReceiveKotlinObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveKotlinObject(helper:tracker:)")));
|
||||
+ (void)callReceiveSwiftObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveSwiftObject(helper:tracker:)")));
|
||||
+ (void)callReceiveListHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveList(helper:tracker:)")));
|
||||
+ (void)callReceiveStringHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveString(helper:tracker:)")));
|
||||
+ (void)callReceiveNumberHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveNumber(helper:tracker:)")));
|
||||
+ (void)callReceiveBlockHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveBlock(helper:tracker:)")));
|
||||
+ (void)callReceiveBlockAndCallHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveBlockAndCall(helper:tracker:)")));
|
||||
+ (void * _Nullable)objc_autoreleasePoolPush __attribute__((swift_name("objc_autoreleasePoolPush()")));
|
||||
+ (void)objc_autoreleasePoolPopHandle:(void * _Nullable)handle __attribute__((swift_name("objc_autoreleasePoolPop(handle:)")));
|
||||
+ (void)useIntArrayArray:(KtKotlinIntArray *)array __attribute__((swift_name("useIntArray(array:)")));
|
||||
@end;
|
||||
|
||||
__attribute__((swift_name("OverrideKotlinMethods2")))
|
||||
@protocol KtOverrideKotlinMethods2
|
||||
@required
|
||||
|
||||
@@ -865,6 +865,116 @@ __attribute__((swift_name("ArraysInitBlock")))
|
||||
- (NSString *)log __attribute__((swift_name("log()")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("KotlinLivenessTracker")))
|
||||
@interface KtKotlinLivenessTracker : KtBase
|
||||
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
|
||||
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
|
||||
- (void)addObj:(id _Nullable)obj __attribute__((swift_name("add(obj:)")));
|
||||
- (BOOL)isEmpty __attribute__((swift_name("isEmpty()")));
|
||||
- (BOOL)objectsAreDead __attribute__((swift_name("objectsAreDead()")));
|
||||
@property (readonly) NSMutableArray<KtKotlinWeakReference *> *weakRefs __attribute__((swift_name("weakRefs")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("KotlinObject")))
|
||||
@interface KtKotlinObject : KtBase
|
||||
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
|
||||
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
|
||||
@end;
|
||||
|
||||
__attribute__((swift_name("NoAutoreleaseSendHelper")))
|
||||
@protocol KtNoAutoreleaseSendHelper
|
||||
@required
|
||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||
@end;
|
||||
|
||||
__attribute__((swift_name("NoAutoreleaseReceiveHelper")))
|
||||
@protocol KtNoAutoreleaseReceiveHelper
|
||||
@required
|
||||
- (KtKotlinObject *)receiveKotlinObject __attribute__((swift_name("receiveKotlinObject()")));
|
||||
- (id)receiveSwiftObject __attribute__((swift_name("receiveSwiftObject()")));
|
||||
- (NSArray<id> *)receiveList __attribute__((swift_name("receiveList()")));
|
||||
- (NSString *)receiveString __attribute__((swift_name("receiveString()")));
|
||||
- (id)receiveNumber __attribute__((swift_name("receiveNumber()")));
|
||||
- (KtKotlinObject *(^)(void))receiveBlock __attribute__((swift_name("receiveBlock()")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseKotlinSendHelper")))
|
||||
@interface KtNoAutoreleaseKotlinSendHelper : KtBase <KtNoAutoreleaseSendHelper>
|
||||
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseKotlinReceiveHelper")))
|
||||
@interface KtNoAutoreleaseKotlinReceiveHelper : KtBase <KtNoAutoreleaseReceiveHelper>
|
||||
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
||||
- (KtKotlinObject *)receiveKotlinObject __attribute__((swift_name("receiveKotlinObject()")));
|
||||
- (id)receiveSwiftObject __attribute__((swift_name("receiveSwiftObject()")));
|
||||
- (NSArray<id> *)receiveList __attribute__((swift_name("receiveList()")));
|
||||
- (NSString *)receiveString __attribute__((swift_name("receiveString()")));
|
||||
- (id)receiveNumber __attribute__((swift_name("receiveNumber()")));
|
||||
- (KtKotlinObject *(^)(void))receiveBlock __attribute__((swift_name("receiveBlock()")));
|
||||
@property id swiftObject __attribute__((swift_name("swiftObject")));
|
||||
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseSingleton")))
|
||||
@interface KtNoAutoreleaseSingleton : KtBase
|
||||
+ (instancetype)alloc __attribute__((unavailable));
|
||||
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
|
||||
+ (instancetype)noAutoreleaseSingleton __attribute__((swift_name("init()")));
|
||||
@property (class, readonly, getter=shared) KtNoAutoreleaseSingleton *shared __attribute__((swift_name("shared")));
|
||||
@property (readonly) int32_t x __attribute__((swift_name("x")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseEnum")))
|
||||
@interface KtNoAutoreleaseEnum : KtKotlinEnum
|
||||
+ (instancetype)alloc __attribute__((unavailable));
|
||||
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
|
||||
- (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
|
||||
@property (class, readonly) KtNoAutoreleaseEnum *entry __attribute__((swift_name("entry")));
|
||||
+ (KtKotlinArray *)values __attribute__((swift_name("values()")));
|
||||
@property (readonly) int32_t x __attribute__((swift_name("x")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("NoAutoreleaseKt")))
|
||||
@interface KtNoAutoreleaseKt : KtBase
|
||||
+ (void)gc __attribute__((swift_name("gc()")));
|
||||
+ (void)callSendKotlinObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendKotlinObject(helper:tracker:)")));
|
||||
+ (void)callSendSwiftObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker swiftObject:(id)swiftObject __attribute__((swift_name("callSendSwiftObject(helper:tracker:swiftObject:)")));
|
||||
+ (void)callSendListHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendList(helper:tracker:)")));
|
||||
+ (void)callSendStringHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendString(helper:tracker:)")));
|
||||
+ (void)callSendNumberHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendNumber(helper:tracker:)")));
|
||||
+ (void)callSendBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendBlock(helper:tracker:)")));
|
||||
+ (void)callReceiveKotlinObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveKotlinObject(helper:tracker:)")));
|
||||
+ (void)callReceiveSwiftObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveSwiftObject(helper:tracker:)")));
|
||||
+ (void)callReceiveListHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveList(helper:tracker:)")));
|
||||
+ (void)callReceiveStringHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveString(helper:tracker:)")));
|
||||
+ (void)callReceiveNumberHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveNumber(helper:tracker:)")));
|
||||
+ (void)callReceiveBlockHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveBlock(helper:tracker:)")));
|
||||
+ (void)callReceiveBlockAndCallHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveBlockAndCall(helper:tracker:)")));
|
||||
+ (void * _Nullable)objc_autoreleasePoolPush __attribute__((swift_name("objc_autoreleasePoolPush()")));
|
||||
+ (void)objc_autoreleasePoolPopHandle:(void * _Nullable)handle __attribute__((swift_name("objc_autoreleasePoolPop(handle:)")));
|
||||
+ (void)useIntArrayArray:(KtKotlinIntArray *)array __attribute__((swift_name("useIntArray(array:)")));
|
||||
@end;
|
||||
|
||||
__attribute__((swift_name("OverrideKotlinMethods2")))
|
||||
@protocol KtOverrideKotlinMethods2
|
||||
@required
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
package noAutorelease
|
||||
|
||||
import kotlin.native.internal.NativePtr
|
||||
import kotlin.native.ref.WeakReference
|
||||
import kotlin.test.*
|
||||
|
||||
class KotlinLivenessTracker {
|
||||
val weakRefs = mutableListOf<WeakReference<Any>>()
|
||||
|
||||
fun add(obj: Any?) {
|
||||
assertNotNull(obj)
|
||||
weakRefs += WeakReference(obj)
|
||||
assertFalse(objectsAreDead())
|
||||
}
|
||||
|
||||
fun isEmpty() = weakRefs.isEmpty()
|
||||
fun objectsAreDead() = weakRefs.all { it.value === null }
|
||||
}
|
||||
|
||||
fun gc() = kotlin.native.internal.GC.collect()
|
||||
|
||||
class KotlinObject
|
||||
|
||||
interface NoAutoreleaseSendHelper {
|
||||
fun sendKotlinObject(kotlinObject: KotlinObject)
|
||||
fun sendSwiftObject(swiftObject: Any)
|
||||
fun sendList(list: List<*>)
|
||||
fun sendString(string: String)
|
||||
fun sendNumber(number: Any)
|
||||
fun sendBlock(block: () -> KotlinObject)
|
||||
}
|
||||
|
||||
interface NoAutoreleaseReceiveHelper {
|
||||
fun receiveKotlinObject(): KotlinObject
|
||||
fun receiveSwiftObject(): Any
|
||||
fun receiveList(): List<*>
|
||||
fun receiveString(): String
|
||||
fun receiveNumber(): Any
|
||||
fun receiveBlock(): () -> KotlinObject
|
||||
}
|
||||
|
||||
class NoAutoreleaseKotlinSendHelper(val kotlinLivenessTracker: KotlinLivenessTracker) : NoAutoreleaseSendHelper {
|
||||
override fun sendKotlinObject(kotlinObject: KotlinObject) = kotlinLivenessTracker.add(kotlinObject)
|
||||
override fun sendSwiftObject(swiftObject: Any) = kotlinLivenessTracker.add(swiftObject)
|
||||
override fun sendList(list: List<*>) = kotlinLivenessTracker.add(list)
|
||||
override fun sendString(string: String) = kotlinLivenessTracker.add(string)
|
||||
override fun sendNumber(number: Any) = kotlinLivenessTracker.add(number)
|
||||
override fun sendBlock(block: () -> KotlinObject) = kotlinLivenessTracker.add(block)
|
||||
}
|
||||
|
||||
class NoAutoreleaseKotlinReceiveHelper(val kotlinLivenessTracker: KotlinLivenessTracker) : NoAutoreleaseReceiveHelper {
|
||||
private val kotlinObject = KotlinObject()
|
||||
lateinit var swiftObject: Any
|
||||
private val list = listOf(Any())
|
||||
private val string = Any().toString()
|
||||
private val number = createKotlinNumber()
|
||||
private val block = createLambda()
|
||||
|
||||
override fun receiveKotlinObject(): KotlinObject = kotlinObject.also { kotlinLivenessTracker.add(it) }
|
||||
override fun receiveSwiftObject(): Any = swiftObject.also { kotlinLivenessTracker.add(it) }
|
||||
override fun receiveList(): List<*> = list.also { kotlinLivenessTracker.add(it) }
|
||||
override fun receiveString(): String = string.also { kotlinLivenessTracker.add(it) }
|
||||
override fun receiveNumber(): Any = number.also { kotlinLivenessTracker.add(it) }
|
||||
override fun receiveBlock(): () -> KotlinObject = block.also { kotlinLivenessTracker.add(it) }
|
||||
}
|
||||
|
||||
object NoAutoreleaseSingleton {
|
||||
val x = 1
|
||||
}
|
||||
enum class NoAutoreleaseEnum {
|
||||
ENTRY;
|
||||
|
||||
val x = 2
|
||||
}
|
||||
|
||||
fun callSendKotlinObject(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker) {
|
||||
val kotlinObject = KotlinObject()
|
||||
|
||||
// Repeating twice to cover possible fast paths after caching something for an object.
|
||||
helper.sendKotlinObject(kotlinObject)
|
||||
helper.sendKotlinObject(kotlinObject)
|
||||
tracker.add(kotlinObject)
|
||||
}
|
||||
|
||||
fun callSendSwiftObject(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker, swiftObject: Any) {
|
||||
helper.sendSwiftObject(swiftObject)
|
||||
helper.sendSwiftObject(swiftObject)
|
||||
tracker.add(swiftObject)
|
||||
}
|
||||
|
||||
fun callSendList(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker) {
|
||||
val list = listOf(Any())
|
||||
|
||||
helper.sendList(list)
|
||||
helper.sendList(list)
|
||||
tracker.add(list)
|
||||
}
|
||||
|
||||
fun callSendString(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker) {
|
||||
val string = Any().toString()
|
||||
|
||||
helper.sendString(string)
|
||||
helper.sendString(string)
|
||||
tracker.add(string)
|
||||
}
|
||||
|
||||
fun callSendNumber(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker) {
|
||||
val number = createKotlinNumber()
|
||||
|
||||
helper.sendNumber(number)
|
||||
helper.sendNumber(number)
|
||||
tracker.add(number)
|
||||
}
|
||||
|
||||
fun callSendBlock(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker) {
|
||||
val block = createLambda()
|
||||
|
||||
helper.sendBlock(block)
|
||||
helper.sendBlock(block)
|
||||
tracker.add(block)
|
||||
}
|
||||
|
||||
fun callReceiveKotlinObject(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
||||
tracker.add(helper.receiveKotlinObject())
|
||||
}
|
||||
|
||||
fun callReceiveSwiftObject(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
||||
tracker.add(helper.receiveSwiftObject())
|
||||
}
|
||||
|
||||
fun callReceiveList(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
||||
tracker.add(helper.receiveList())
|
||||
}
|
||||
|
||||
fun callReceiveString(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
||||
tracker.add(helper.receiveString())
|
||||
}
|
||||
|
||||
fun callReceiveNumber(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
||||
tracker.add(helper.receiveNumber())
|
||||
}
|
||||
|
||||
fun callReceiveBlock(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
||||
tracker.add(helper.receiveBlock())
|
||||
}
|
||||
|
||||
fun callReceiveBlockAndCall(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
||||
tracker.add(helper.receiveBlock()())
|
||||
}
|
||||
|
||||
fun objc_autoreleasePoolPush() = kotlinx.cinterop.objc_autoreleasePoolPush()
|
||||
fun objc_autoreleasePoolPop(handle: NativePtr) = kotlinx.cinterop.objc_autoreleasePoolPop(handle)
|
||||
|
||||
fun useIntArray(array: IntArray) {} // Just to make IntArray available from Swift.
|
||||
|
||||
private fun createLambda(): () -> KotlinObject {
|
||||
val lambdaResult = KotlinObject()
|
||||
return { lambdaResult } // make it capturing thus dynamic.
|
||||
}
|
||||
|
||||
private fun createKotlinNumber(): Any = (0.5 + Any().hashCode().toDouble()) // to make it dynamic.
|
||||
@@ -0,0 +1,458 @@
|
||||
import Kt
|
||||
|
||||
private class SwiftLivenessTracker {
|
||||
class SwiftWeakRef {
|
||||
weak var value: AnyObject?
|
||||
}
|
||||
|
||||
var weakRefs: [SwiftWeakRef] = []
|
||||
|
||||
func add(_ obj: AnyObject?) {
|
||||
try! assertTrue(obj != nil)
|
||||
|
||||
let weakRef = SwiftWeakRef()
|
||||
weakRef.value = obj
|
||||
weakRefs.append(weakRef)
|
||||
|
||||
try! assertFalse(objectsAreDead())
|
||||
}
|
||||
|
||||
func isEmpty() -> Bool {
|
||||
return weakRefs.isEmpty
|
||||
}
|
||||
|
||||
func objectsAreDead() -> Bool {
|
||||
for weakRef in weakRefs {
|
||||
if weakRef.value !== nil { return false }
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private class NoAutoreleaseSwiftHelper : NoAutoreleaseSendHelper, NoAutoreleaseReceiveHelper {
|
||||
fileprivate var swiftLivenessTracker: SwiftLivenessTracker
|
||||
|
||||
init(swiftLivenessTracker: SwiftLivenessTracker) {
|
||||
self.swiftLivenessTracker = swiftLivenessTracker
|
||||
}
|
||||
|
||||
func sendKotlinObject(kotlinObject: KotlinObject) {
|
||||
swiftLivenessTracker.add(kotlinObject)
|
||||
}
|
||||
|
||||
func sendSwiftObject(swiftObject: Any) {
|
||||
swiftLivenessTracker.add(swiftObject as AnyObject)
|
||||
}
|
||||
|
||||
func sendList(list: [Any]) {
|
||||
}
|
||||
|
||||
func sendString(string: String) {
|
||||
}
|
||||
|
||||
func sendNumber(number: Any) {
|
||||
swiftLivenessTracker.add(number as AnyObject)
|
||||
}
|
||||
|
||||
func sendBlock(block: @escaping () -> KotlinObject) {
|
||||
}
|
||||
|
||||
let kotlinObject = KotlinObject()
|
||||
let swiftObject = SwiftObject2()
|
||||
let list = createList()
|
||||
let string = createString()
|
||||
let number = createNumber()
|
||||
let block = createBlock()
|
||||
|
||||
func receiveKotlinObject() -> KotlinObject {
|
||||
let result = kotlinObject
|
||||
swiftLivenessTracker.add(result)
|
||||
return result
|
||||
}
|
||||
|
||||
func receiveSwiftObject() -> Any {
|
||||
let result = swiftObject
|
||||
swiftLivenessTracker.add(result)
|
||||
return result
|
||||
}
|
||||
|
||||
func receiveList() -> [Any] {
|
||||
return list
|
||||
}
|
||||
|
||||
func receiveString() -> String {
|
||||
return string
|
||||
}
|
||||
|
||||
func receiveNumber() -> Any {
|
||||
let result = number
|
||||
swiftLivenessTracker.add(result)
|
||||
return number
|
||||
}
|
||||
|
||||
func receiveBlock() -> (() -> KotlinObject) {
|
||||
return block
|
||||
}
|
||||
}
|
||||
|
||||
private struct TestFlags {
|
||||
var trackSwiftLifetime: Bool = true
|
||||
var checkAutorelease: Bool = true
|
||||
}
|
||||
|
||||
private func testOnce(flags: TestFlags, block: (KotlinLivenessTracker, SwiftLivenessTracker) throws -> Void) throws {
|
||||
try assertAutoreleasepoolNotUsed(flags: flags) { // Note: this assertion will also fail if something in the "test infra" below uses autoreleasepool.
|
||||
let kotlinLivenessTracker = KotlinLivenessTracker()
|
||||
let swiftLivenessTracker = SwiftLivenessTracker()
|
||||
|
||||
try assertTrue(kotlinLivenessTracker.isEmpty())
|
||||
try assertTrue(swiftLivenessTracker.isEmpty())
|
||||
|
||||
try block(kotlinLivenessTracker, swiftLivenessTracker)
|
||||
|
||||
NoAutoreleaseKt.gc()
|
||||
|
||||
try assertFalse(kotlinLivenessTracker.isEmpty())
|
||||
if flags.trackSwiftLifetime {
|
||||
try assertFalse(swiftLivenessTracker.isEmpty())
|
||||
} else {
|
||||
// Note: some of the tests don't actually add objects to the swiftLivenessTracker,
|
||||
// because e.g. Swift represents certain Obj-C classes as value types.
|
||||
try assertTrue(swiftLivenessTracker.isEmpty())
|
||||
}
|
||||
|
||||
#if !NOOP_GC
|
||||
// If something has "leaked" to autoreleasepool, one of the assertions below should fail:
|
||||
try assertTrue(kotlinLivenessTracker.objectsAreDead())
|
||||
try assertTrue(swiftLivenessTracker.objectsAreDead())
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private func test(flags: TestFlags, block: (KotlinLivenessTracker, SwiftLivenessTracker) -> Void) throws {
|
||||
for _ in 1...2 {
|
||||
// Repeating twice to cover possible fast paths after caching something for a type.
|
||||
try testOnce(flags: flags, block: block)
|
||||
}
|
||||
}
|
||||
|
||||
private func assertAutoreleasepoolNotUsed(flags: TestFlags = TestFlags(), block: () throws -> Void) throws {
|
||||
let poolBefore = NoAutoreleaseKt.objc_autoreleasePoolPush()
|
||||
NoAutoreleaseKt.objc_autoreleasePoolPop(handle: poolBefore)
|
||||
|
||||
try block()
|
||||
|
||||
let poolAfter = NoAutoreleaseKt.objc_autoreleasePoolPush()
|
||||
NoAutoreleaseKt.objc_autoreleasePoolPop(handle: poolAfter)
|
||||
|
||||
// autoreleasepool machinery is implemented as a stack.
|
||||
// So here we check that stack top after `block()` is the same as before.
|
||||
// Which means that no objects were added to this stack inbetween.
|
||||
if flags.checkAutorelease {
|
||||
try assertEquals(actual: poolAfter, expected: poolBefore)
|
||||
} else {
|
||||
// Just to ensure we disable the hack once it is not needed anymore:
|
||||
try assertFalse(poolAfter == poolBefore)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendToKotlin<T>(
|
||||
_ createObject: () -> T,
|
||||
flags: TestFlags = TestFlags(),
|
||||
sendObject: (NoAutoreleaseKotlinSendHelper, T) -> Void
|
||||
) throws {
|
||||
try test(flags: flags) { kotlinLivenessTracker, swiftLivenessTracker in
|
||||
let helper = NoAutoreleaseKotlinSendHelper(kotlinLivenessTracker: kotlinLivenessTracker)
|
||||
|
||||
let obj = createObject()
|
||||
if flags.trackSwiftLifetime {
|
||||
swiftLivenessTracker.add(obj as AnyObject)
|
||||
}
|
||||
|
||||
// Repeating twice to cover possible fast paths after caching something for an object.
|
||||
sendObject(helper, obj)
|
||||
sendObject(helper, obj)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveFromKotlin<T>(flags: TestFlags = TestFlags(), receiveObject: (NoAutoreleaseKotlinReceiveHelper) -> T) throws {
|
||||
try test(flags: flags) { kotlinLivenessTracker, swiftLivenessTracker in
|
||||
let helper = NoAutoreleaseKotlinReceiveHelper(kotlinLivenessTracker: kotlinLivenessTracker)
|
||||
|
||||
// Repeating twice to cover possible fast paths after caching something for an object.
|
||||
let obj1 = receiveObject(helper)
|
||||
let obj2 = receiveObject(helper)
|
||||
|
||||
if flags.trackSwiftLifetime {
|
||||
swiftLivenessTracker.add(obj1 as AnyObject)
|
||||
swiftLivenessTracker.add(obj2 as AnyObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func testCallToSwift(flags: TestFlags = TestFlags(), callKotlin: (NoAutoreleaseSwiftHelper, KotlinLivenessTracker) -> Void) throws {
|
||||
try test(flags: flags) { kotlinLivenessTracker, swiftLivenessTracker in
|
||||
let helper = NoAutoreleaseSwiftHelper(swiftLivenessTracker: swiftLivenessTracker)
|
||||
|
||||
callKotlin(helper, kotlinLivenessTracker)
|
||||
}
|
||||
}
|
||||
|
||||
private class SwiftObject1 {}
|
||||
private class SwiftObject2 {}
|
||||
private class SwiftObject3 {}
|
||||
private class SwiftObject4 {}
|
||||
|
||||
private func testSendKotlinObjectToKotlin() throws {
|
||||
try testSendToKotlin({ KotlinObject() }) {
|
||||
$0.sendKotlinObject(kotlinObject: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendSwiftObjectToKotlin() throws {
|
||||
try testSendToKotlin({ SwiftObject1() }) {
|
||||
$0.sendSwiftObject(swiftObject: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendListToKotlin() throws {
|
||||
try testSendToKotlin({ createList() }, flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
$0.sendList(list: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendStringToKotlin() throws {
|
||||
try testSendToKotlin({ createString() }, flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
$0.sendString(string: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendNumberToKotlin() throws {
|
||||
try testSendToKotlin({ createNumber() }) {
|
||||
$0.sendNumber(number: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendBlockToKotlin() throws {
|
||||
try testSendToKotlin({ createBlock() }, flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
$0.sendBlock(block: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveKotlinObjectFromKotlin() throws {
|
||||
try testReceiveFromKotlin {
|
||||
$0.receiveKotlinObject()
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveSwiftObjectFromKotlin() throws {
|
||||
try testReceiveFromKotlin { (helper: NoAutoreleaseKotlinReceiveHelper) -> Any in
|
||||
helper.swiftObject = SwiftObject3()
|
||||
return helper.receiveSwiftObject()
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveListFromKotlin() throws {
|
||||
// Swift conversion from NSArray to Swift Array uses non-optimized autorelease in the implementation,
|
||||
// So regardless of our efforts, passing List from Kotlin to Swift will use autoreleasepool.
|
||||
// Use `checkAutorelease: false` flag to disable the relevant check.
|
||||
try testReceiveFromKotlin(flags: TestFlags(trackSwiftLifetime: false, checkAutorelease: false)) {
|
||||
$0.receiveList()
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveStringFromKotlin() throws {
|
||||
try testReceiveFromKotlin(flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
$0.receiveString()
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveNumberFromKotlin() throws {
|
||||
try testReceiveFromKotlin {
|
||||
$0.receiveNumber()
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveBlockFromKotlin() throws {
|
||||
try testReceiveFromKotlin(flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
$0.receiveBlock()
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveBlockFromKotlinAndCall() throws {
|
||||
try testReceiveFromKotlin {
|
||||
$0.receiveBlock()()
|
||||
}
|
||||
}
|
||||
|
||||
private func testCreateKotlinArray() throws {
|
||||
try testReceiveFromKotlin { (helper: NoAutoreleaseKotlinReceiveHelper) -> KotlinIntArray in
|
||||
let array = KotlinIntArray(size: 2)
|
||||
helper.kotlinLivenessTracker.add(obj: array)
|
||||
return array
|
||||
}
|
||||
}
|
||||
|
||||
private func testGetKotlinUnit() throws {
|
||||
try assertAutoreleasepoolNotUsed {
|
||||
try assertSame(actual: KotlinUnit.shared, expected: KotlinUnit.shared)
|
||||
}
|
||||
}
|
||||
|
||||
private func testGetKotlinSingleton() throws {
|
||||
try assertAutoreleasepoolNotUsed {
|
||||
try assertEquals(actual: NoAutoreleaseSingleton.shared.x, expected: 1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testGetKotlinEnumEntry() throws {
|
||||
try assertAutoreleasepoolNotUsed {
|
||||
try assertEquals(actual: NoAutoreleaseEnum.entry.x, expected: 2)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendKotlinObjectToSwift() throws {
|
||||
try testCallToSwift {
|
||||
NoAutoreleaseKt.callSendKotlinObject(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendSwiftObjectToSwift() throws {
|
||||
try testCallToSwift {
|
||||
NoAutoreleaseKt.callSendSwiftObject(helper: $0, tracker: $1, swiftObject: SwiftObject4())
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendListToSwift() throws {
|
||||
// Swift conversion from NSArray to Swift Array uses non-optimized autorelease in the implementation,
|
||||
// So regardless of our efforts, passing List from Kotlin to Swift will use autoreleasepool.
|
||||
// Use `checkAutorelease: false` flag to disable the relevant check.
|
||||
try testCallToSwift(flags: TestFlags(trackSwiftLifetime: false, checkAutorelease: false)) {
|
||||
NoAutoreleaseKt.callSendList(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendStringToSwift() throws {
|
||||
try testCallToSwift(flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
NoAutoreleaseKt.callSendString(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendNumberToSwift() throws {
|
||||
try testCallToSwift {
|
||||
NoAutoreleaseKt.callSendNumber(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testSendBlockToSwift() throws {
|
||||
try testCallToSwift(flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
NoAutoreleaseKt.callSendBlock(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveKotlinObjectFromSwift() throws {
|
||||
try testCallToSwift {
|
||||
NoAutoreleaseKt.callReceiveKotlinObject(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveSwiftObjectFromSwift() throws {
|
||||
try testCallToSwift {
|
||||
NoAutoreleaseKt.callReceiveSwiftObject(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveListFromSwift() throws {
|
||||
try testCallToSwift(flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
NoAutoreleaseKt.callReceiveList(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveStringFromSwift() throws {
|
||||
try testCallToSwift(flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
NoAutoreleaseKt.callReceiveString(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveNumberFromSwift() throws {
|
||||
try testCallToSwift {
|
||||
NoAutoreleaseKt.callReceiveNumber(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveBlockFromSwift() throws {
|
||||
try testCallToSwift(flags: TestFlags(trackSwiftLifetime: false)) {
|
||||
NoAutoreleaseKt.callReceiveBlock(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func testReceiveBlockFromSwiftAndCall() throws {
|
||||
try testCallToSwift {
|
||||
NoAutoreleaseKt.callReceiveBlockAndCall(helper: $0, tracker: $1)
|
||||
}
|
||||
}
|
||||
|
||||
private func createList() -> [Any] {
|
||||
return [NSObject()]
|
||||
}
|
||||
|
||||
private func createBlock() -> () -> KotlinObject {
|
||||
let blockResult = KotlinObject()
|
||||
return { return blockResult } // Make capturing thus dynamic.
|
||||
}
|
||||
|
||||
private func createString() -> String {
|
||||
return NSObject().description // Make it dynamic.
|
||||
}
|
||||
|
||||
private func createNumber() -> NSNumber {
|
||||
return (0.5 + Double(NSObject().hash)) as NSNumber
|
||||
}
|
||||
|
||||
class NoAutoreleaseTests : SimpleTestProvider {
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
test("testSendKotlinObjectToKotlin", testSendKotlinObjectToKotlin)
|
||||
test("testSendSwiftObjectToKotlin", testSendSwiftObjectToKotlin)
|
||||
test("testSendListToKotlin", testSendListToKotlin)
|
||||
test("testSendStringToKotlin", testSendStringToKotlin)
|
||||
test("testSendNumberToKotlin", testSendNumberToKotlin)
|
||||
test("testSendBlockToKotlin", testSendBlockToKotlin)
|
||||
|
||||
test("testReceiveKotlinObjectFromKotlin", testReceiveKotlinObjectFromKotlin)
|
||||
test("testReceiveSwiftObjectFromKotlin", testReceiveSwiftObjectFromKotlin)
|
||||
test("testReceiveListFromKotlin", testReceiveListFromKotlin)
|
||||
test("testReceiveStringFromKotlin", testReceiveStringFromKotlin)
|
||||
test("testReceiveNumberFromKotlin", testReceiveNumberFromKotlin)
|
||||
test("testReceiveBlockFromKotlin", testReceiveBlockFromKotlin)
|
||||
test("testReceiveBlockFromKotlinAndCall", testReceiveBlockFromKotlinAndCall)
|
||||
|
||||
test("testCreateKotlinArray", testCreateKotlinArray)
|
||||
|
||||
test("testGetKotlinUnit", testGetKotlinUnit)
|
||||
test("testGetKotlinSingleton", testGetKotlinSingleton)
|
||||
test("testGetKotlinEnumEntry", testGetKotlinEnumEntry)
|
||||
|
||||
#if false
|
||||
test("testSendKotlinObjectToSwift", testSendKotlinObjectToSwift)
|
||||
#endif
|
||||
|
||||
test("testSendSwiftObjectToSwift", testSendSwiftObjectToSwift)
|
||||
|
||||
#if false
|
||||
test("testSendListToSwift", testSendListToSwift)
|
||||
test("testSendStringToSwift", testSendStringToSwift)
|
||||
test("testSendNumberToSwift", testSendNumberToSwift)
|
||||
test("testSendBlockToSwift", testSendBlockToSwift)
|
||||
|
||||
test("testReceiveKotlinObjectFromSwift", testReceiveKotlinObjectFromSwift)
|
||||
test("testReceiveSwiftObjectFromSwift", testReceiveSwiftObjectFromSwift)
|
||||
test("testReceiveListFromSwift", testReceiveListFromSwift)
|
||||
test("testReceiveStringFromSwift", testReceiveStringFromSwift)
|
||||
test("testReceiveNumberFromSwift", testReceiveNumberFromSwift)
|
||||
test("testReceiveBlockFromSwift", testReceiveBlockFromSwift)
|
||||
test("testReceiveBlockFromSwiftAndCall", testReceiveBlockFromSwiftAndCall)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user