From 676f1c82a62280d44272136981d793d6ad0c844e Mon Sep 17 00:00:00 2001 From: SvyatoslavScherbina Date: Thu, 23 Jul 2020 17:20:03 +0700 Subject: [PATCH] Fix KT-38641 Use 'description_' instead of 'description' as property name in ObjCExport, as the latter clashes with 'NSObject.description'. --- .../konan/objcexport/ObjCExportNamer.kt | 7 +- .../tests/objcexport/expectedLazy.h | 61 ++++++++++++++++ backend.native/tests/objcexport/kt38641.kt | 36 ++++++++++ backend.native/tests/objcexport/kt38641.swift | 72 +++++++++++++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 backend.native/tests/objcexport/kt38641.kt create mode 100644 backend.native/tests/objcexport/kt38641.swift diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt index 873dee49a6f..67d7f57df29 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt @@ -308,7 +308,7 @@ internal class ObjCExportNamerImpl( } private val propertyNames = object : Mapping() { - override fun reserved(name: String) = name in cKeywords + override fun reserved(name: String) = name in Reserved.propertyNames override fun conflict(first: PropertyDescriptor, second: PropertyDescriptor): Boolean = !mapper.canHaveSameName(first, second) @@ -626,6 +626,11 @@ internal class ObjCExportNamerImpl( ).mapKeys { Name.identifier(it.key) } } + private object Reserved { + val propertyNames = cKeywords + + setOf("description") // https://youtrack.jetbrains.com/issue/KT-38641 + } + private fun FunctionDescriptor.getMangledName(forSwift: Boolean): String { if (this is ConstructorDescriptor) { return if (this.constructedClass.isArray && !forSwift) "array" else "init" diff --git a/backend.native/tests/objcexport/expectedLazy.h b/backend.native/tests/objcexport/expectedLazy.h index b2b45666a16..f67022271e7 100644 --- a/backend.native/tests/objcexport/expectedLazy.h +++ b/backend.native/tests/objcexport/expectedLazy.h @@ -442,6 +442,67 @@ __attribute__((swift_name("Kt35940Kt"))) + (NSString *)testKt35940 __attribute__((swift_name("testKt35940()"))); @end; +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("KT38641"))) +@interface KtKT38641 : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("KT38641.IntType"))) +@interface KtKT38641IntType : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +@property (getter=description, setter=setDescription:) int32_t description_ __attribute__((swift_name("description_"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("KT38641.Val"))) +@interface KtKT38641Val : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +@property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("KT38641.Var"))) +@interface KtKT38641Var : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +@property (getter=description, setter=setDescription:) NSString *description_ __attribute__((swift_name("description_"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("KT38641.TwoProperties"))) +@interface KtKT38641TwoProperties : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +@property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); +@property (readonly) NSString *description_ __attribute__((swift_name("description_"))); +@end; + +__attribute__((swift_name("KT38641.OverrideVal"))) +@interface KtKT38641OverrideVal : KtBase +- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); ++ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); +@property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); +@end; + +__attribute__((swift_name("KT38641OverrideVar"))) +@protocol KtKT38641OverrideVar +@required +@property (getter=description, setter=setDescription:) NSString *description_ __attribute__((swift_name("description_"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("Kt38641Kt"))) +@interface KtKt38641Kt : KtBase ++ (NSString *)getOverrideValDescriptionImpl:(KtKT38641OverrideVal *)impl __attribute__((swift_name("getOverrideValDescription(impl:)"))); ++ (NSString *)getOverrideVarDescriptionImpl:(id)impl __attribute__((swift_name("getOverrideVarDescription(impl:)"))); ++ (void)setOverrideVarDescriptionImpl:(id)impl newValue:(NSString *)newValue __attribute__((swift_name("setOverrideVarDescription(impl:newValue:)"))); +@end; + __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("LibraryKt"))) @interface KtLibraryKt : KtBase diff --git a/backend.native/tests/objcexport/kt38641.kt b/backend.native/tests/objcexport/kt38641.kt new file mode 100644 index 00000000000..18c3a74dcfe --- /dev/null +++ b/backend.native/tests/objcexport/kt38641.kt @@ -0,0 +1,36 @@ +package kt38641 + +// See https://youtrack.jetbrains.com/issue/KT-38641. +class KT38641 { + class IntType { + var description = 42 + } + + class Val { + val description = "val" + } + + class Var { + var description = "var" + } + + class TwoProperties { + val description = "description" + val description_ = "description_" + } + + abstract class OverrideVal { + abstract val description: String + } + + interface OverrideVar { + var description: String + } +} + +fun getOverrideValDescription(impl: KT38641.OverrideVal) = impl.description + +fun getOverrideVarDescription(impl: KT38641.OverrideVar) = impl.description +fun setOverrideVarDescription(impl: KT38641.OverrideVar, newValue: String) { + impl.description = newValue +} diff --git a/backend.native/tests/objcexport/kt38641.swift b/backend.native/tests/objcexport/kt38641.swift new file mode 100644 index 00000000000..871f23f23d6 --- /dev/null +++ b/backend.native/tests/objcexport/kt38641.swift @@ -0,0 +1,72 @@ +/* + * Copyright 2010-2020 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 + +private func testIntType() throws { + let i = KT38641.IntType() + + try assertEquals(actual: i.description_, expected: 42) + + i.description_ = 17 + try assertEquals(actual: i.description_, expected: 17) +} + +private func testVal() throws { + try assertEquals(actual: KT38641.Val().description_, expected: "val") +} + +private func testVar() throws { + let v = KT38641.Var() + + try assertEquals(actual: v.description_, expected: "var") + + v.description_ = "newValue" + try assertEquals(actual: v.description_, expected: "newValue") +} + +private func testTwoProperties() throws { + let t = KT38641.TwoProperties() + try assertEquals(actual: t.description_, expected: "description") + try assertEquals(actual: t.description__, expected: "description_") +} + +private func testOverrideVal() throws { + try assertEquals(actual: Kt38641Kt.getOverrideValDescription(impl: KT38641OverrideValImpl()), expected: "description_") +} + +class KT38641OverrideValImpl : KT38641.OverrideVal { + override var description_: String { + get { + return "description_" + } + } +} + +private func testOverrideVar() throws { + let impl = KT38641OverrideVarImpl() + + try assertEquals(actual: Kt38641Kt.getOverrideVarDescription(impl: impl), expected: "description_") + + Kt38641Kt.setOverrideVarDescription(impl: impl, newValue: "d") + try assertEquals(actual: Kt38641Kt.getOverrideVarDescription(impl: impl), expected: "d") +} + +class KT38641OverrideVarImpl : KT38641OverrideVar { + var description_: String = "description_" +} + +class Kt38641Tests : SimpleTestProvider { + override init() { + super.init() + + test("TestIntType", testIntType) + test("TestVal", testVal) + test("TestVar", testVar) + test("TestTwoProperties", testTwoProperties) + test("TestOverrideVal", testOverrideVal) + test("TestOverrideVar", testOverrideVar) + } +} \ No newline at end of file