From 4cd60090e0ace4b88e30e3a09fc66e63f97ca67d Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Wed, 26 Jan 2022 18:23:04 +0300 Subject: [PATCH] ObjCExport: fix replacing Kotlin class methods by Swift extensions ^KT-49937 Fixed --- .../tests/objcexport/expectedLazy.h | 8 ++++++ .../expectedLazyLegacySuspendUnit.h | 8 ++++++ .../tests/objcexport/expectedLazyNoGenerics.h | 8 ++++++ .../tests/objcexport/kt49937.kt | 14 ++++++++++ .../tests/objcexport/kt49937.swift | 27 +++++++++++++++++++ .../runtime/src/main/cpp/ObjCExport.mm | 8 +++--- 6 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 kotlin-native/backend.native/tests/objcexport/kt49937.kt create mode 100644 kotlin-native/backend.native/tests/objcexport/kt49937.swift diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h index 7a6a71e082b..c761abde108 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h @@ -958,6 +958,14 @@ __attribute__((swift_name("Kt46431Kt"))) + (id)createAbstractHost __attribute__((swift_name("createAbstractHost()"))); @end; +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("KT49937"))) +@interface KtKT49937 : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +- (NSString *)description __attribute__((swift_name("description()"))); +@end; + __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("LibraryKt"))) @interface KtLibraryKt : KtBase diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h b/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h index 92c3ac6692c..4cb084445e1 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h @@ -900,6 +900,14 @@ __attribute__((swift_name("Kt46431Kt"))) + (id)createAbstractHost __attribute__((swift_name("createAbstractHost()"))); @end; +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("KT49937"))) +@interface KtKT49937 : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +- (NSString *)description __attribute__((swift_name("description()"))); +@end; + __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("LibraryKt"))) @interface KtLibraryKt : KtBase diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h b/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h index 5474544e019..f03b5b2398b 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h @@ -900,6 +900,14 @@ __attribute__((swift_name("Kt46431Kt"))) + (id)createAbstractHost __attribute__((swift_name("createAbstractHost()"))); @end; +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("KT49937"))) +@interface KtKT49937 : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +- (NSString *)description __attribute__((swift_name("description()"))); +@end; + __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("LibraryKt"))) @interface KtLibraryKt : KtBase diff --git a/kotlin-native/backend.native/tests/objcexport/kt49937.kt b/kotlin-native/backend.native/tests/objcexport/kt49937.kt new file mode 100644 index 00000000000..c79c467f309 --- /dev/null +++ b/kotlin-native/backend.native/tests/objcexport/kt49937.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package kt49937 + +// Based on https://youtrack.jetbrains.com/issue/KT-49937 + +final class KT49937 { + override fun toString(): String { + return "KT49937" + } +} diff --git a/kotlin-native/backend.native/tests/objcexport/kt49937.swift b/kotlin-native/backend.native/tests/objcexport/kt49937.swift new file mode 100644 index 00000000000..273ea833f2b --- /dev/null +++ b/kotlin-native/backend.native/tests/objcexport/kt49937.swift @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +import Kt + +// Based on https://youtrack.jetbrains.com/issue/KT-49937. + +public extension KT49937 { + override var description: String { "KT49937Swift" } +} + +private func test1() throws { + try assertEquals(actual: KT49937().description, expected: "KT49937Swift") + + let nsObject: NSObject = KT49937() + try assertEquals(actual: nsObject.description, expected: "KT49937Swift") +} + +class Kt49937Tests : SimpleTestProvider { + override init() { + super.init() + + test("Test1", test1) + } +} diff --git a/kotlin-native/runtime/src/main/cpp/ObjCExport.mm b/kotlin-native/runtime/src/main/cpp/ObjCExport.mm index dbc309d714a..2dce12a0239 100644 --- a/kotlin-native/runtime/src/main/cpp/ObjCExport.mm +++ b/kotlin-native/runtime/src/main/cpp/ObjCExport.mm @@ -307,15 +307,15 @@ extern "C" void Kotlin_ObjCExport_initializeClass(Class clazz) { for (int i = 0; i < typeAdapter->directAdapterNum; ++i) { const ObjCToKotlinMethodAdapter* adapter = typeAdapter->directAdapters + i; SEL selector = sel_registerName(adapter->selector); - BOOL added = class_addMethod(clazz, selector, adapter->imp, adapter->encoding); - RuntimeAssert(added, "Unexpected selector clash"); + class_addMethod(clazz, selector, adapter->imp, adapter->encoding); + // The method above may fail if there is a matching Swift/Obj-C extension method for this Kotlin class. + // This is pretty much ok, and we shouldn't replace that method with our own. } for (int i = 0; i < typeAdapter->classAdapterNum; ++i) { const ObjCToKotlinMethodAdapter* adapter = typeAdapter->classAdapters + i; SEL selector = sel_registerName(adapter->selector); - BOOL added = class_addMethod(object_getClass(clazz), selector, adapter->imp, adapter->encoding); - RuntimeAssert(added, "Unexpected selector clash"); + class_addMethod(object_getClass(clazz), selector, adapter->imp, adapter->encoding); } if (isClassForPackage) return;