From b306ed53aa34ae44161affbb6204adb06e5e29af Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Tue, 21 Feb 2023 14:10:16 +0100 Subject: [PATCH] [K/N] Support Enum entries in objc export ^KT-53653 --- .../objcexport/ObjCExportCodeGenerator.kt | 10 +-- .../konan/objcexport/ObjCExportCodeSpec.kt | 12 ++- .../objcexport/ObjCExportHeaderGenerator.kt | 19 ++++- .../konan/objcexport/ObjCExportMapper.kt | 9 +++ .../konan/objcexport/ObjCExportNamer.kt | 7 +- .../backend.native/tests/build.gradle | 15 +++- .../tests/objcexport/enumValues.kt | 11 ++- .../tests/objcexport/enumValues.swift | 75 ++++++++++++++++++- .../tests/objcexport/expectedLazy.h | 18 +++++ .../expectedLazyLegacySuspendUnit.h | 18 +++++ .../tests/objcexport/expectedLazyNoGenerics.h | 18 +++++ .../objcexport/noEnumEntries/testEnum.kt | 12 +++ 12 files changed, 205 insertions(+), 19 deletions(-) create mode 100644 kotlin-native/backend.native/tests/objcexport/noEnumEntries/testEnum.kt diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index a34c295eff5..bb302ef448a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -1601,8 +1601,8 @@ private fun ObjCExportCodeGenerator.createTypeAdapter( is ObjCGetterForKotlinEnumEntry -> { classAdapters += createEnumEntryAdapter(it.irEnumEntrySymbol.owner, it.selector) } - is ObjCClassMethodForKotlinEnumValues -> { - classAdapters += createEnumValuesAdapter(it.valuesFunctionSymbol.owner, it.selector) + is ObjCClassMethodForKotlinEnumValuesOrEntries -> { + classAdapters += createEnumValuesOrEntriesAdapter(it.valuesFunctionSymbol.owner, it.selector) } is ObjCGetterForObjectInstance -> { classAdapters += if (it.classSymbol.owner.isUnit()) { @@ -1892,8 +1892,8 @@ private fun ObjCExportCodeGenerator.createEnumEntryAdapter( } } -private fun ObjCExportCodeGenerator.createEnumValuesAdapter( - valuesFunction: IrFunction, +private fun ObjCExportCodeGenerator.createEnumValuesOrEntriesAdapter( + function: IrFunction, selector: String ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { val methodBridge = MethodBridge( @@ -1902,7 +1902,7 @@ private fun ObjCExportCodeGenerator.createEnumValuesAdapter( valueParameters = emptyList() ) - val imp = generateObjCImp(valuesFunction, valuesFunction, methodBridge, isVirtual = false) + val imp = generateObjCImp(function, function, methodBridge, isVirtual = false) return objCToKotlinMethodAdapter(selector, methodBridge, imp) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportCodeSpec.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportCodeSpec.kt index ac3a8b9dc81..d1cecb14f7a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportCodeSpec.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportCodeSpec.kt @@ -88,9 +88,15 @@ internal fun ObjCExportedInterface.createCodeSpec(symbolTable: SymbolTable): Obj } descriptor.getEnumValuesFunctionDescriptor()?.let { - methods += ObjCClassMethodForKotlinEnumValues( + methods += ObjCClassMethodForKotlinEnumValuesOrEntries( symbolTable.referenceSimpleFunction(it), - namer.getEnumValuesSelector(it) + namer.getEnumStaticMemberSelector(it) + ) + } + descriptor.getEnumEntriesPropertyDescriptor()?.let { + methods += ObjCClassMethodForKotlinEnumValuesOrEntries( + symbolTable.referenceSimpleFunction(it.getter!!), + namer.getEnumStaticMemberSelector(it) ) } } @@ -165,7 +171,7 @@ internal class ObjCGetterForKotlinEnumEntry( "ObjC spec of getter `$selector` for `$irEnumEntrySymbol`" } -internal class ObjCClassMethodForKotlinEnumValues( +internal class ObjCClassMethodForKotlinEnumValuesOrEntries( val valuesFunctionSymbol: IrFunctionSymbol, val selector: String ) : ObjCMethodSpec() { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt index b23f1236d53..f6c21fb42c5 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt @@ -400,6 +400,9 @@ internal class ObjCExportTranslatorImpl( descriptor.getEnumValuesFunctionDescriptor()?.let { enumValues -> add { buildEnumValuesMethod(enumValues, genericExportScope) } } + descriptor.getEnumEntriesPropertyDescriptor()?.let { enumEntries -> + add { buildEnumEntriesProperty(enumEntries, genericExportScope) } + } } else -> { // Nothing special. @@ -463,7 +466,7 @@ internal class ObjCExportTranslatorImpl( enumValues: SimpleFunctionDescriptor, genericExportScope: ObjCExportScope ): ObjCMethod { - val selector = namer.getEnumValuesSelector(enumValues) + val selector = namer.getEnumStaticMemberSelector(enumValues) return ObjCMethod( enumValues, isInstanceMethod = false, @@ -474,6 +477,20 @@ internal class ObjCExportTranslatorImpl( ) } + private fun buildEnumEntriesProperty( + enumEntries: PropertyDescriptor, + genericExportScope: ObjCExportScope + ): ObjCProperty { + val selector = namer.getEnumStaticMemberSelector(enumEntries) + return ObjCProperty( + selector, + enumEntries, + type = mapReferenceType(enumEntries.type, genericExportScope), + propertyAttributes = listOf("class", "readonly"), + declarationAttributes = listOf(swiftNameAttribute("$selector")) + ) + } + private fun ClassDescriptor.getExposedMembers(): List = this.unsubstitutedMemberScope.getContributedDescriptors() .asSequence() diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt index 1952e2d9f89..949eb4e9434 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt @@ -240,6 +240,15 @@ internal fun ClassDescriptor.getEnumValuesFunctionDescriptor(): SimpleFunctionDe ).singleOrNull { it.extensionReceiverParameter == null && it.valueParameters.size == 0 } } +internal fun ClassDescriptor.getEnumEntriesPropertyDescriptor(): PropertyDescriptor? { + require(this.kind == ClassKind.ENUM_CLASS) + + return this.staticScope.getContributedVariables( + StandardNames.ENUM_ENTRIES, + NoLookupLocation.FROM_BACKEND + ).singleOrNull { it.extensionReceiverParameter == null } +} + internal fun ObjCExportMapper.doesThrow(method: FunctionDescriptor): Boolean = method.allOverriddenDescriptors.any { it.overriddenDescriptors.isEmpty() && it.annotations.hasAnnotation(KonanFqNames.throws) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt index 8e3d90b37b1..7f964495aed 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.driver.PhaseContext import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.konan.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -72,7 +71,7 @@ interface ObjCExportNamer { fun getObjectInstanceSelector(descriptor: ClassDescriptor): String fun getEnumEntrySelector(descriptor: ClassDescriptor): String fun getEnumEntrySwiftName(descriptor: ClassDescriptor): String - fun getEnumValuesSelector(descriptor: FunctionDescriptor): String + fun getEnumStaticMemberSelector(descriptor: CallableMemberDescriptor): String fun getTypeParameterName(typeParameterDescriptor: TypeParameterDescriptor): String fun numberBoxName(classId: ClassId): ClassOrProtocolName @@ -647,13 +646,11 @@ internal class ObjCExportNamerImpl( } } - override fun getEnumValuesSelector(descriptor: FunctionDescriptor): String { + override fun getEnumStaticMemberSelector(descriptor: CallableMemberDescriptor): String { val containingDeclaration = descriptor.containingDeclaration require(containingDeclaration is ClassDescriptor && containingDeclaration.kind == ClassKind.ENUM_CLASS) - require(descriptor.name == StandardNames.ENUM_VALUES) require(descriptor.dispatchReceiverParameter == null) { "must be static" } require(descriptor.extensionReceiverParameter == null) { "must be static" } - require(descriptor.valueParameters.isEmpty()) return enumClassSelectors.getOrPut(descriptor) { StringBuilder(descriptor.name.asString()).mangledBySuffixUnderscores() diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index 3ef76a317ee..c6d6eb4a595 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -5676,6 +5676,7 @@ Task objcExportTest( } def libraryName = frameworkName + "Library" + def noEnumEntriesLibraryName = frameworkName + "NoEnumEntriesLibrary" konanArtifacts { library(libraryName, targets: [target.name]) { srcDir "objcexport/library" @@ -5687,13 +5688,23 @@ Task objcExportTest( extraOpts "-Xshort-module-name=MyLibrary" extraOpts "-module-name", "org.jetbrains.kotlin.native.test-library" } + library(noEnumEntriesLibraryName, targets: [target.name]) { + srcDir "objcexport/noEnumEntries" + artifactName "test-no-enum-entries-$libraryName" + delegate.getByTarget(target.name).configure{ + UtilsKt.dependsOnDist(it) + } + extraOpts "-Xshort-module-name=NoEnumEntriesLibrary" + extraOpts "-module-name", "org.jetbrains.kotlin.native.test-no-enum-entries-library" + extraOpts "-XXLanguage:-EnumEntries" + } } codesign = !isStaticFramework framework(frameworkName) { enabled = !isK2(project) // KT-56182 sources = ['objcexport'] - libraries = [libraryName] + libraries = [libraryName, noEnumEntriesLibraryName] artifact = 'Kt' bitcode = !isStaticFramework isStatic = isStaticFramework @@ -5703,6 +5714,7 @@ Task objcExportTest( opts += [ "-Xexport-kdoc", "-Xbinary=bundleId=foo.bar", + "-Xexport-library=test-no-enum-entries-${libraryName}.klib" ] opts += frameworkOpts } @@ -5773,6 +5785,7 @@ if (isAppleTarget(project)) { false ) + frameworkTest('testValuesGenericsFramework') { framework('ValuesGenerics') { sources = ['objcexport/values.kt', 'framework/values_generics'] diff --git a/kotlin-native/backend.native/tests/objcexport/enumValues.kt b/kotlin-native/backend.native/tests/objcexport/enumValues.kt index 87eea28cd89..17dd77bd5e9 100644 --- a/kotlin-native/backend.native/tests/objcexport/enumValues.kt +++ b/kotlin-native/backend.native/tests/objcexport/enumValues.kt @@ -1,16 +1,23 @@ package enumValues +import noEnumEntries.* + enum class EnumLeftRightUpDown { LEFT, RIGHT, UP, DOWN } enum class EnumOneTwoThreeValues { - ONE, TWO, THREE, VALUES + ONE, TWO, THREE, VALUES, ENTRIES } enum class EnumValuesValues_ { - VALUES, VALUES_ + VALUES, VALUES_, ENTRIES, ENTRIES_ } enum class EmptyEnum { } + + +fun dceAvoidance() : NoEnumEntriesEnum { + return NoEnumEntriesEnum.ONE +} \ No newline at end of file diff --git a/kotlin-native/backend.native/tests/objcexport/enumValues.swift b/kotlin-native/backend.native/tests/objcexport/enumValues.swift index 17b140702ea..f309b328058 100644 --- a/kotlin-native/backend.native/tests/objcexport/enumValues.swift +++ b/kotlin-native/backend.native/tests/objcexport/enumValues.swift @@ -14,27 +14,93 @@ private func testEnumValues() throws { private func testEnumValuesMangled() throws { let values = EnumOneTwoThreeValues.values_() - try assertEquals(actual: values.size, expected: 4) + try assertEquals(actual: values.size, expected: 5) try assertSame(actual: values.get(index: 0) as AnyObject, expected: EnumOneTwoThreeValues.one) try assertSame(actual: values.get(index: 1) as AnyObject, expected: EnumOneTwoThreeValues.two) try assertSame(actual: values.get(index: 2) as AnyObject, expected: EnumOneTwoThreeValues.three) try assertSame(actual: values.get(index: 3) as AnyObject, expected: EnumOneTwoThreeValues.values) + try assertSame(actual: values.get(index: 4) as AnyObject, expected: EnumOneTwoThreeValues.entries) } private func testEnumValuesMangledTwice() throws { let values = EnumValuesValues_.values__() - try assertEquals(actual: values.size, expected: 2) + try assertEquals(actual: values.size, expected: 4) try assertSame(actual: values.get(index: 0) as AnyObject, expected: EnumValuesValues_.values) try assertSame(actual: values.get(index: 1) as AnyObject, expected: EnumValuesValues_.values_) + try assertSame(actual: values.get(index: 2) as AnyObject, expected: EnumValuesValues_.entries) + try assertSame(actual: values.get(index: 3) as AnyObject, expected: EnumValuesValues_.entries_) } private func testEnumValuesEmpty() throws { try assertEquals(actual: EmptyEnum.values().size, expected: 0) } +extension NSObject { + + // convert to dictionary + static func toDictionary(from classType: AnyClass) -> [String: Any] { + + var propertiesCount : CUnsignedInt = 0 + let propertiesInAClass = class_copyMethodList(classType, &propertiesCount) + var propertiesDictionary = [String:Any]() + + for i in 0 ..< Int(propertiesCount) { + if let property = propertiesInAClass?[i], + let strKey = NSString(utf8String: sel_getName(method_getName(property))) as String? { + propertiesDictionary[strKey] = value(forKey: strKey) + } + } + return propertiesDictionary + } +} + + +private func testNoEnumEntries() throws { + try assertTrue(class_respondsToSelector(object_getClass(EnumLeftRightUpDown.self), NSSelectorFromString("entries"))); + try assertFalse(class_respondsToSelector(object_getClass(NoEnumEntriesEnum.self), NSSelectorFromString("entries"))); +} + +private func testEnumEntries() throws { + let entries = EnumLeftRightUpDown.entries + + try assertEquals(actual: entries.count, expected: 4) + + try assertSame(actual: entries[0] as AnyObject, expected: EnumLeftRightUpDown.left) + try assertSame(actual: entries[1] as AnyObject, expected: EnumLeftRightUpDown.right) + try assertSame(actual: entries[2] as AnyObject, expected: EnumLeftRightUpDown.up) + try assertSame(actual: entries[3] as AnyObject, expected: EnumLeftRightUpDown.down) +} + +private func testEnumEntriesMangled() throws { + let entries = EnumOneTwoThreeValues.entries_ + + try assertEquals(actual: entries.count, expected: 5) + + try assertSame(actual: entries[0] as AnyObject, expected: EnumOneTwoThreeValues.one) + try assertSame(actual: entries[1] as AnyObject, expected: EnumOneTwoThreeValues.two) + try assertSame(actual: entries[2] as AnyObject, expected: EnumOneTwoThreeValues.three) + try assertSame(actual: entries[3] as AnyObject, expected: EnumOneTwoThreeValues.values) + try assertSame(actual: entries[4] as AnyObject, expected: EnumOneTwoThreeValues.entries) +} + +private func testEnumEntriesMangledTwice() throws { + let entries = EnumValuesValues_.entries__ + + try assertEquals(actual: entries.count, expected: 4) + + try assertSame(actual: entries[0] as AnyObject, expected: EnumValuesValues_.values) + try assertSame(actual: entries[1] as AnyObject, expected: EnumValuesValues_.values_) + try assertSame(actual: entries[2] as AnyObject, expected: EnumValuesValues_.entries) + try assertSame(actual: entries[3] as AnyObject, expected: EnumValuesValues_.entries_) +} + +private func testEnumEntriesEmpty() throws { + try assertEquals(actual: EmptyEnum.entries.count, expected: 0) +} + class EnumValuesTests : SimpleTestProvider { override init() { super.init() @@ -43,5 +109,10 @@ class EnumValuesTests : SimpleTestProvider { test("TestEnumValuesMangled", testEnumValuesMangled) test("TestEnumValuesMangledTwice", testEnumValuesMangledTwice) test("TestEnumValuesEmpty", testEnumValuesEmpty) + test("TestNoEnumEntries", testNoEnumEntries) + test("TestEnumEntries", testEnumEntries) + test("TestEnumEntriesMangled", testEnumEntriesMangled) + test("TestEnumEntriesMangledTwice", testEnumEntriesMangledTwice) + test("TestEnumEntriesEmpty", testEnumEntriesEmpty) } } diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h index f02a3429475..bd23619939c 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h @@ -481,6 +481,7 @@ __attribute__((swift_name("EnumLeftRightUpDown"))) @property (class, readonly) KtEnumLeftRightUpDown *up __attribute__((swift_name("up"))); @property (class, readonly) KtEnumLeftRightUpDown *down __attribute__((swift_name("down"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -493,7 +494,9 @@ __attribute__((swift_name("EnumOneTwoThreeValues"))) @property (class, readonly) KtEnumOneTwoThreeValues *two __attribute__((swift_name("two"))); @property (class, readonly) KtEnumOneTwoThreeValues *three __attribute__((swift_name("three"))); @property (class, readonly) KtEnumOneTwoThreeValues *values __attribute__((swift_name("values"))); +@property (class, readonly) KtEnumOneTwoThreeValues *entries __attribute__((swift_name("entries"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -504,7 +507,10 @@ __attribute__((swift_name("EnumValuesValues_"))) - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); +@property (class, readonly) KtEnumValuesValues_ *entries __attribute__((swift_name("entries"))); +@property (class, readonly) KtEnumValuesValues_ *entries __attribute__((swift_name("entries"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -514,6 +520,13 @@ __attribute__((swift_name("EmptyEnum"))) + (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)); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); +@end + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("EnumValuesKt"))) +@interface KtEnumValuesKt : KtBase ++ (KtNoEnumEntriesEnum *)dceAvoidance __attribute__((swift_name("dceAvoidance()"))); @end __attribute__((swift_name("FunInterface"))) @@ -1030,6 +1043,7 @@ __attribute__((swift_name("KT43780Enum"))) @property (class, readonly) KtKT43780Enum *otherEntry __attribute__((swift_name("otherEntry"))); @property (class, readonly) KtKT43780Enum *companion __attribute__((swift_name("companion"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -1308,6 +1322,7 @@ __attribute__((swift_name("NoAutoreleaseEnum"))) - (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 (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t x __attribute__((swift_name("x"))); @end @@ -1443,6 +1458,7 @@ __attribute__((swift_name("ObjCNameSwiftEnum"))) @property (class, readonly) KtObjCNameObjCEnum *objcTwo __attribute__((swift_name("companion"))); @property (class, readonly) KtObjCNameObjCEnum *objcThree __attribute__((swift_name("swiftThree"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -1808,6 +1824,7 @@ __attribute__((swift_name("Enumeration"))) @property (class, readonly) KtEnumeration *year __attribute__((swift_name("year"))); @property (class, readonly) KtEnumeration *temperature __attribute__((swift_name("temperature"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t enumValue __attribute__((swift_name("enumValue"))); @end @@ -2502,6 +2519,7 @@ __attribute__((swift_name("TestInvalidIdentifiers.E"))) @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t value __attribute__((swift_name("value"))); @end diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h b/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h index 98bcc3fddde..1eb42394bff 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h @@ -481,6 +481,7 @@ __attribute__((swift_name("EnumLeftRightUpDown"))) @property (class, readonly) KtEnumLeftRightUpDown *up __attribute__((swift_name("up"))); @property (class, readonly) KtEnumLeftRightUpDown *down __attribute__((swift_name("down"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -493,7 +494,9 @@ __attribute__((swift_name("EnumOneTwoThreeValues"))) @property (class, readonly) KtEnumOneTwoThreeValues *two __attribute__((swift_name("two"))); @property (class, readonly) KtEnumOneTwoThreeValues *three __attribute__((swift_name("three"))); @property (class, readonly) KtEnumOneTwoThreeValues *values __attribute__((swift_name("values"))); +@property (class, readonly) KtEnumOneTwoThreeValues *entries __attribute__((swift_name("entries"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -504,7 +507,10 @@ __attribute__((swift_name("EnumValuesValues_"))) - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); +@property (class, readonly) KtEnumValuesValues_ *entries __attribute__((swift_name("entries"))); +@property (class, readonly) KtEnumValuesValues_ *entries __attribute__((swift_name("entries"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -514,6 +520,13 @@ __attribute__((swift_name("EmptyEnum"))) + (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)); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); +@end + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("EnumValuesKt"))) +@interface KtEnumValuesKt : KtBase ++ (KtNoEnumEntriesEnum *)dceAvoidance __attribute__((swift_name("dceAvoidance()"))); @end __attribute__((swift_name("FunInterface"))) @@ -1030,6 +1043,7 @@ __attribute__((swift_name("KT43780Enum"))) @property (class, readonly) KtKT43780Enum *otherEntry __attribute__((swift_name("otherEntry"))); @property (class, readonly) KtKT43780Enum *companion __attribute__((swift_name("companion"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -1308,6 +1322,7 @@ __attribute__((swift_name("NoAutoreleaseEnum"))) - (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 (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t x __attribute__((swift_name("x"))); @end @@ -1443,6 +1458,7 @@ __attribute__((swift_name("ObjCNameSwiftEnum"))) @property (class, readonly) KtObjCNameObjCEnum *objcTwo __attribute__((swift_name("companion"))); @property (class, readonly) KtObjCNameObjCEnum *objcThree __attribute__((swift_name("swiftThree"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -1808,6 +1824,7 @@ __attribute__((swift_name("Enumeration"))) @property (class, readonly) KtEnumeration *year __attribute__((swift_name("year"))); @property (class, readonly) KtEnumeration *temperature __attribute__((swift_name("temperature"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t enumValue __attribute__((swift_name("enumValue"))); @end @@ -2502,6 +2519,7 @@ __attribute__((swift_name("TestInvalidIdentifiers.E"))) @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t value __attribute__((swift_name("value"))); @end diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h b/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h index 9336225d7b6..1293266c9b0 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h @@ -481,6 +481,7 @@ __attribute__((swift_name("EnumLeftRightUpDown"))) @property (class, readonly) KtEnumLeftRightUpDown *up __attribute__((swift_name("up"))); @property (class, readonly) KtEnumLeftRightUpDown *down __attribute__((swift_name("down"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -493,7 +494,9 @@ __attribute__((swift_name("EnumOneTwoThreeValues"))) @property (class, readonly) KtEnumOneTwoThreeValues *two __attribute__((swift_name("two"))); @property (class, readonly) KtEnumOneTwoThreeValues *three __attribute__((swift_name("three"))); @property (class, readonly) KtEnumOneTwoThreeValues *values __attribute__((swift_name("values"))); +@property (class, readonly) KtEnumOneTwoThreeValues *entries __attribute__((swift_name("entries"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -504,7 +507,10 @@ __attribute__((swift_name("EnumValuesValues_"))) - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); +@property (class, readonly) KtEnumValuesValues_ *entries __attribute__((swift_name("entries"))); +@property (class, readonly) KtEnumValuesValues_ *entries __attribute__((swift_name("entries"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -514,6 +520,13 @@ __attribute__((swift_name("EmptyEnum"))) + (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)); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); +@end + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("EnumValuesKt"))) +@interface KtEnumValuesKt : KtBase ++ (KtNoEnumEntriesEnum *)dceAvoidance __attribute__((swift_name("dceAvoidance()"))); @end __attribute__((swift_name("FunInterface"))) @@ -1030,6 +1043,7 @@ __attribute__((swift_name("KT43780Enum"))) @property (class, readonly) KtKT43780Enum *otherEntry __attribute__((swift_name("otherEntry"))); @property (class, readonly) KtKT43780Enum *companion __attribute__((swift_name("companion"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -1308,6 +1322,7 @@ __attribute__((swift_name("NoAutoreleaseEnum"))) - (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 (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t x __attribute__((swift_name("x"))); @end @@ -1443,6 +1458,7 @@ __attribute__((swift_name("ObjCNameSwiftEnum"))) @property (class, readonly) KtObjCNameObjCEnum *objcTwo __attribute__((swift_name("companion"))); @property (class, readonly) KtObjCNameObjCEnum *objcThree __attribute__((swift_name("swiftThree"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @end __attribute__((objc_subclassing_restricted)) @@ -1808,6 +1824,7 @@ __attribute__((swift_name("Enumeration"))) @property (class, readonly) KtEnumeration *year __attribute__((swift_name("year"))); @property (class, readonly) KtEnumeration *temperature __attribute__((swift_name("temperature"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t enumValue __attribute__((swift_name("enumValue"))); @end @@ -2502,6 +2519,7 @@ __attribute__((swift_name("TestInvalidIdentifiers.E"))) @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); +@property (class, readonly) NSArray *entries __attribute__((swift_name("entries"))); @property (readonly) int32_t value __attribute__((swift_name("value"))); @end diff --git a/kotlin-native/backend.native/tests/objcexport/noEnumEntries/testEnum.kt b/kotlin-native/backend.native/tests/objcexport/noEnumEntries/testEnum.kt new file mode 100644 index 00000000000..7ff97ce38e4 --- /dev/null +++ b/kotlin-native/backend.native/tests/objcexport/noEnumEntries/testEnum.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package noEnumEntries + +enum class NoEnumEntriesEnum { + ONE, + TWO, + THREE +} \ No newline at end of file