diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt index 80320e0865b..e158d188c92 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt @@ -185,14 +185,6 @@ internal class ObjCExportTranslatorImpl( return listOf("unavailable(\"$message\")") } - private fun genericExportScope(classDescriptor: DeclarationDescriptor): ObjCExportScope { - return if(objcGenerics && classDescriptor is ClassDescriptor && !classDescriptor.isInterface) { - ObjCClassExportScope(classDescriptor, namer) - } else { - ObjCNoneExportScope - } - } - private fun referenceClass(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName { fun forwardDeclarationObjcClassName(objcGenerics: Boolean, descriptor: ClassDescriptor, namer:ObjCExportNamer): String { val className = translateClassOrInterfaceName(descriptor) @@ -291,7 +283,11 @@ internal class ObjCExportTranslatorImpl( return translateUnexposedClassAsUnavailableStub(descriptor) } - val genericExportScope = genericExportScope(descriptor) + val genericExportScope = if (objcGenerics) { + ObjCClassExportScope(descriptor, namer) + } else { + ObjCNoneExportScope + } fun superClassGenerics(genericExportScope: ObjCExportScope): List { val parentType = computeSuperClassType(descriptor) @@ -379,7 +375,7 @@ internal class ObjCExportTranslatorImpl( } } - translateClassMembers(descriptor) + translateClassMembers(descriptor, genericExportScope) } val attributes = if (descriptor.isFinalOrEnum) listOf(OBJC_SUBCLASSING_RESTRICTED) else emptyList() @@ -419,9 +415,9 @@ internal class ObjCExportTranslatorImpl( .filter { mapper.shouldBeExposed(it) } .toList() - private fun StubBuilder.translateClassMembers(descriptor: ClassDescriptor) { + private fun StubBuilder.translateClassMembers(descriptor: ClassDescriptor, objCExportScope: ObjCExportScope) { require(!descriptor.isInterface) - translateClassMembers(descriptor.getExposedMembers()) + translateClassMembers(descriptor.getExposedMembers(), objCExportScope) } private fun StubBuilder.translateInterfaceMembers(descriptor: ClassDescriptor) { @@ -429,25 +425,6 @@ internal class ObjCExportTranslatorImpl( translateBaseMembers(descriptor.getExposedMembers()) } - private class RenderedStub>(val stub: T) { - private val presentation: String by lazy(LazyThreadSafetyMode.NONE) { - val listOfLines = StubRenderer.render(stub) - assert(listOfLines.size == 1) - listOfLines[0] - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - return other is RenderedStub<*> && presentation == other.presentation - } - - override fun hashCode(): Int { - return presentation.hashCode() - } - } - private fun List.toObjCMembers( methodsBuffer: MutableList, propertiesBuffer: MutableList @@ -464,7 +441,10 @@ internal class ObjCExportTranslatorImpl( } } - private fun StubBuilder.translateClassMembers(members: List) { + private fun StubBuilder.translateClassMembers( + members: List, + objCExportScope: ObjCExportScope + ) { // TODO: add some marks about modality. val methods = mutableListOf() @@ -474,8 +454,22 @@ internal class ObjCExportTranslatorImpl( methods.forEach { exportThrown(it) } - collectMethodsOrProperties(methods) { it -> buildAsDeclaredOrInheritedMethods(it.original) } - collectMethodsOrProperties(properties) { it -> buildAsDeclaredOrInheritedProperties(it.original) } + methods.retainAll { it.kind.isReal } + properties.retainAll { it.kind.isReal } + + methods.forEach { method -> + mapper.getBaseMethods(method) + .asSequence() + .distinctBy { namer.getSelector(it) } + .forEach { base -> +buildMethod(method, base, objCExportScope) } + } + + properties.forEach { property -> + mapper.getBaseProperties(property) + .asSequence() + .distinctBy { namer.getPropertyName(it) } + .forEach { base -> +buildProperty(property, base, objCExportScope) } + } } private fun StubBuilder.translateBaseMembers(members: List) { @@ -517,57 +511,6 @@ internal class ObjCExportTranslatorImpl( methods.forEach { +buildMethod(it, it, objCExportScope) } properties.forEach { +buildProperty(it, it, objCExportScope) } } - - private fun > StubBuilder.collectMethodsOrProperties( - members: List, - converter: (D) -> Set>) { - members.forEach { member -> - val memberStubs = converter(member).asSequence() - - val filteredMemberStubs = if (member.kind.isReal) { - memberStubs - } else { - val superMembers: Set> = (member.overriddenDescriptors as Collection) - .asSequence() - .filter { mapper.shouldBeExposed(it) } - .flatMap { converter(it).asSequence() } - .toSet() - - memberStubs.filterNot { superMembers.contains(it) } - } - - this += filteredMemberStubs - .map { rendered -> rendered.stub } - .toList() - } - } - - private fun buildAsDeclaredOrInheritedMethods( - method: FunctionDescriptor - ): Set> { - val isInterface = (method.containingDeclaration as ClassDescriptor).isInterface - - return mapper.getBaseMethods(method) - .asSequence() - .distinctBy { namer.getSelector(it) } - .map { base -> buildMethod((if (isInterface) base else method), base, genericExportScope(method.containingDeclaration)) } - .map { RenderedStub(it) } - .toSet() - } - - private fun buildAsDeclaredOrInheritedProperties( - property: PropertyDescriptor - ): Set> { - val isInterface = (property.containingDeclaration as ClassDescriptor).isInterface - - return mapper.getBaseProperties(property) - .asSequence() - .distinctBy { namer.getPropertyName(it) } - .map { base -> buildProperty((if (isInterface) base else property), base, genericExportScope(property.containingDeclaration)) } - .map { RenderedStub(it) } - .toSet() - } - // TODO: consider checking that signatures for bases with same selector/name are equal. private fun getSelector(method: FunctionDescriptor): String { diff --git a/backend.native/tests/framework/values/expectedLazy.h b/backend.native/tests/framework/values/expectedLazy.h index 6e6cac264c2..3c500bfa927 100644 --- a/backend.native/tests/framework/values/expectedLazy.h +++ b/backend.native/tests/framework/values/expectedLazy.h @@ -193,7 +193,6 @@ __attribute__((swift_name("Enumeration"))) @property (class, readonly) ValuesEnumeration *answer __attribute__((swift_name("answer"))); @property (class, readonly) ValuesEnumeration *year __attribute__((swift_name("year"))); @property (class, readonly) ValuesEnumeration *temperature __attribute__((swift_name("temperature"))); -- (int32_t)compareToOther:(ValuesEnumeration *)other __attribute__((swift_name("compareTo(other:)"))); @property (readonly) int32_t enumValue __attribute__((swift_name("enumValue"))); @end; @@ -407,7 +406,6 @@ __attribute__((swift_name("TransformInheritingDefault"))) @interface ValuesTransformInheritingDefault : ValuesBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); -- (T _Nullable)mapValue:(T _Nullable)value __attribute__((swift_name("map(value:)"))); @end; __attribute__((swift_name("TransformIntString"))) @@ -636,7 +634,6 @@ __attribute__((swift_name("TestInvalidIdentifiers.E"))) @property (class, readonly) ValuesTestInvalidIdentifiersE *_5_ __attribute__((swift_name("_5_"))); @property (class, readonly) ValuesTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); @property (class, readonly) ValuesTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); -- (int32_t)compareToOther:(ValuesTestInvalidIdentifiersE *)other __attribute__((swift_name("compareTo(other:)"))); @property (readonly) int32_t value __attribute__((swift_name("value"))); @end;