diff --git a/backend.native/tests/objcexport/expectedLazy.h b/backend.native/tests/objcexport/expectedLazy.h index dc50e7fce28..71889ab6406 100644 --- a/backend.native/tests/objcexport/expectedLazy.h +++ b/backend.native/tests/objcexport/expectedLazy.h @@ -308,6 +308,40 @@ __attribute__((swift_name("CoroutinesKt"))) + (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)"))); @end; +__attribute__((swift_name("FHolder"))) +@interface KtFHolder : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +@property (readonly) id _Nullable value __attribute__((swift_name("value"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("F2Holder"))) +@interface KtF2Holder : KtFHolder +- (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); ++ (instancetype)new __attribute__((unavailable)); +@property (readonly) id _Nullable (^value)(id _Nullable, id _Nullable) __attribute__((swift_name("value"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("F32Holder"))) +@interface KtF32Holder : KtFHolder +- (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); ++ (instancetype)new __attribute__((unavailable)); +@property (readonly) id _Nullable (^value)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable) __attribute__((swift_name("value"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("F33Holder"))) +@interface KtF33Holder : KtFHolder +- (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); ++ (instancetype)new __attribute__((unavailable)); +@property (readonly) id value __attribute__((swift_name("value"))); +@end; + __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("FunctionalTypesKt"))) @interface KtFunctionalTypesKt : KtBase @@ -317,6 +351,16 @@ __attribute__((swift_name("FunctionalTypesKt"))) + (void)callStaticType32Fct:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))fct param:(id _Nullable)param __attribute__((swift_name("callStaticType32(fct:param:)"))); + (void)callDynType33List:(NSArray> *)list param:(id _Nullable)param __attribute__((swift_name("callDynType33(list:param:)"))); + (void)callStaticType33Fct:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))fct param:(id _Nullable)param __attribute__((swift_name("callStaticType33(fct:param:)"))); ++ (KtF2Holder *)getDynTypeLambda2 __attribute__((swift_name("getDynTypeLambda2()"))); ++ (id _Nullable (^)(id _Nullable, id _Nullable))getStaticLambda2 __attribute__((swift_name("getStaticLambda2()"))); ++ (KtF2Holder *)getDynTypeRef2 __attribute__((swift_name("getDynTypeRef2()"))); ++ (id _Nullable (^)(id _Nullable, id _Nullable))getStaticRef2 __attribute__((swift_name("getStaticRef2()"))); ++ (KtF32Holder *)getDynType32 __attribute__((swift_name("getDynType32()"))); ++ (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticType32 __attribute__((swift_name("getStaticType32()"))); ++ (KtF33Holder *)getDynTypeRef33 __attribute__((swift_name("getDynTypeRef33()"))); ++ (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticTypeRef33 __attribute__((swift_name("getStaticTypeRef33()"))); ++ (KtF33Holder *)getDynTypeLambda33 __attribute__((swift_name("getDynTypeLambda33()"))); ++ (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticTypeLambda33 __attribute__((swift_name("getStaticTypeLambda33()"))); @end; __attribute__((swift_name("GH4002ArgumentBase"))) diff --git a/backend.native/tests/objcexport/functionalTypes.kt b/backend.native/tests/objcexport/functionalTypes.kt index 46bc855f41e..695653764af 100644 --- a/backend.native/tests/objcexport/functionalTypes.kt +++ b/backend.native/tests/objcexport/functionalTypes.kt @@ -70,3 +70,56 @@ fun callStaticType33(fct: F33, param: AN) { ) assertEquals(param, ret) } + +abstract class FHolder { + abstract val value: Any? +} + +// Note: can't provoke dynamic function type conversion using list (as above) or generics +// due to Swift <-> Obj-C interop bugs/limitations. +// Use covariant return type instead: +class F2Holder(override val value: F2) : FHolder() + +fun getDynTypeLambda2(): F2Holder = F2Holder({ p1, _ -> p1 }) +fun getStaticLambda2(): F2 = { p1, _ -> p1 } + +private fun f2(p1: AN, p2: AN): AN = p1 + +fun getDynTypeRef2(): F2Holder = F2Holder(::f2) +fun getStaticRef2(): F2 = ::f2 + +private fun f32( + p1: AN, p2: AN, p3: AN, p4: AN, p5: AN, p6: AN, p7: AN, p8: AN, + p9: AN, p10: AN, p11: AN, p12: AN, p13: AN, p14: AN, p15: AN, p16: AN, + p17: AN, p18: AN, p19: AN, p20: AN, p21: AN, p22: AN, p23: AN, p24: AN, + p25: AN, p26: AN, p27: AN, p28: AN, p29: AN, p30: AN, p31: AN, p32: AN +): AN = p1 + +private fun f33( + p1: AN, p2: AN, p3: AN, p4: AN, p5: AN, p6: AN, p7: AN, p8: AN, + p9: AN, p10: AN, p11: AN, p12: AN, p13: AN, p14: AN, p15: AN, p16: AN, + p17: AN, p18: AN, p19: AN, p20: AN, p21: AN, p22: AN, p23: AN, p24: AN, + p25: AN, p26: AN, p27: AN, p28: AN, p29: AN, p30: AN, p31: AN, p32: AN, + p33: AN +): AN = p1 + +class F32Holder(override val value: F32) : FHolder() + +fun getDynType32(): F32Holder = F32Holder(::f32) +fun getStaticType32(): F32 = ::f32 + +class F33Holder(override val value: F33) : FHolder() + +fun getDynTypeRef33(): F33Holder = F33Holder(::f33) +fun getStaticTypeRef33(): F33 = ::f33 + +fun getDynTypeLambda33(): F33Holder = F33Holder(getStaticTypeLambda33()) +fun getStaticTypeLambda33(): F33 = { + p, + _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _ + -> + p +} diff --git a/backend.native/tests/objcexport/functionalTypes.swift b/backend.native/tests/objcexport/functionalTypes.swift index 8dce6099217..e00c8ceacee 100644 --- a/backend.native/tests/objcexport/functionalTypes.swift +++ b/backend.native/tests/objcexport/functionalTypes.swift @@ -32,11 +32,89 @@ private func test1() { FunctionalTypesKt.callDynType33(list: [ Foo33() ], param: "from swift") } +private func test2() throws { + try assertEquals(actual: FunctionalTypesKt.getDynTypeLambda2().value("one", nil) as? String, expected: "one") + try assertEquals(actual: FunctionalTypesKt.getStaticLambda2()("two", nil) as? String, expected: "two") + + try assertEquals(actual: FunctionalTypesKt.getDynTypeRef2().value("three", nil) as? String, expected: "three") + try assertEquals(actual: FunctionalTypesKt.getStaticRef2()("four", nil) as? String, expected: "four") + + // 32 params is mapped as regular; calling result as block is OK + try assertEquals( + actual: FunctionalTypesKt.getDynType32().value( + "five", + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil + ) as? String, + expected: "five" + ) + + try assertEquals( + actual: FunctionalTypesKt.getStaticType32()( + "six", + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil + ) as? String, + expected: "six" + ) + + // 33 params requires explicit invocation of KotlinFunction33.invoke + try assertEquals( + actual: FunctionalTypesKt.getDynTypeRef33().value.invoke( + p1: "seven", + p2: nil, p3: nil, p4: nil, p5: nil, p6: nil, p7: nil, p8: nil, p9: nil, + p10: nil, p11: nil, p12: nil, p13: nil, p14: nil, p15: nil, p16: nil, p17: nil, + p18: nil, p19: nil, p20: nil, p21: nil, p22: nil, p23: nil, p24: nil, p25: nil, + p26: nil, p27: nil, p28: nil, p29: nil, p30: nil, p31: nil, p32: nil, p33: nil + ) as? String, + expected: "seven" + ) + + // static conversion is ok though. + try assertEquals( + actual: FunctionalTypesKt.getStaticTypeRef33()( + "eight", + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil + ) as? String, + expected: "eight" + ) + + try assertEquals( + actual: FunctionalTypesKt.getDynTypeLambda33().value.invoke( + p1: "nine", + p2: nil, p3: nil, p4: nil, p5: nil, p6: nil, p7: nil, p8: nil, p9: nil, + p10: nil, p11: nil, p12: nil, p13: nil, p14: nil, p15: nil, p16: nil, p17: nil, + p18: nil, p19: nil, p20: nil, p21: nil, p22: nil, p23: nil, p24: nil, p25: nil, + p26: nil, p27: nil, p28: nil, p29: nil, p30: nil, p31: nil, p32: nil, p33: nil + ) as? String, + expected: "nine" + ) + + try assertEquals( + actual: FunctionalTypesKt.getStaticTypeLambda33()( + "ten", + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil + ) as? String, + expected: "ten" + ) +} + class FunctionalTypesTests : SimpleTestProvider { override init() { super.init() test("Test1", test1) + test("Test2", test2) } }