From b5bcfaa2e34def2a9dcc16e4835dec538b6c36b8 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Thu, 14 Dec 2023 13:39:32 +0100 Subject: [PATCH] [ObjCExport] translateToObjCProtocol: Support building members KT-64226 --- .../kotlin/objcexport/translateToObjCHeader.kt | 4 +++- .../objcexport/translateToObjCProperty.kt | 18 ++++++++++++++++++ .../objcexport/translateToObjCProtocol.kt | 16 +++++++++++----- .../konan/objcexport/ObjCExportTranslator.kt | 5 ++--- .../objcexport/ObjCExportBaseDeclarations.kt | 8 -------- .../backend/konan/objcexport/ObjCExportName.kt | 9 +++++++++ 6 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProperty.kt diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt index 6741f44ae06..794ddb6cd00 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.scopes.KtScope import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind.INTERFACE import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportStub import org.jetbrains.kotlin.backend.konan.objcexport.ObjCHeader @@ -33,9 +34,10 @@ fun KtScope.translateToObjCHeader(): ObjCHeader { } context(KtAnalysisSession, KtObjCExportSession) -private fun KtSymbol.translateToObjCExportStubOrNull(): ObjCExportStub? { +internal fun KtSymbol.translateToObjCExportStubOrNull(): ObjCExportStub? { return when { this is KtClassOrObjectSymbol && classKind == INTERFACE -> translateToObjCProtocol() + this is KtPropertySymbol -> translateToObjCProperty() else -> null } } diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProperty.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProperty.kt new file mode 100644 index 00000000000..62b9434c68f --- /dev/null +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProperty.kt @@ -0,0 +1,18 @@ +/* + * 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 org.jetbrains.kotlin.objcexport + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol +import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProperty +import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC + +context(KtAnalysisSession, KtObjCExportSession) +fun KtPropertySymbol.translateToObjCProperty(): ObjCProperty? { + if (!isVisibleInObjC()) return null + // TODO + return null +} \ No newline at end of file diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProtocol.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProtocol.kt index e892c9de485..9718e5a10df 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProtocol.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProtocol.kt @@ -6,25 +6,31 @@ package org.jetbrains.kotlin.objcexport import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.types.KtClassType import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier import org.jetbrains.kotlin.backend.konan.objcexport.ObjCComment -import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportStub import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProtocol import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProtocolImpl +import org.jetbrains.kotlin.backend.konan.objcexport.toNameAttributes +import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC context(KtAnalysisSession, KtObjCExportSession) -fun KtClassOrObjectSymbol.translateToObjCProtocol(): ObjCProtocol { +fun KtClassOrObjectSymbol.translateToObjCProtocol(): ObjCProtocol? { // TODO: check if this symbol shall be exposed in the first place require(classKind == KtClassKind.INTERFACE) + if (isVisibleInObjC()) return null // TODO: Check error type! val name = getObjCClassOrProtocolName() - // TODO: Build members - val members = emptyList() + val members = getMemberScope().getAllSymbols() + .filterIsInstance() + .filter { memberSymbol -> memberSymbol.isVisibleInObjC() } + .mapNotNull { memberSymbol -> memberSymbol.translateToObjCExportStubOrNull() } + .toList() val superProtocols = superTypes .asSequence() @@ -44,7 +50,7 @@ fun KtClassOrObjectSymbol.translateToObjCProtocol(): ObjCProtocol { name = name.objCName, comment = comment, origin = getObjCStubOrigin(), - attributes = emptyList(), + attributes = name.toNameAttributes(), superProtocols = superProtocols, members = members ) diff --git a/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportTranslator.kt b/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportTranslator.kt index 99c73f85dc2..47f76034e87 100644 --- a/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportTranslator.kt +++ b/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportTranslator.kt @@ -628,9 +628,8 @@ class ObjCExportTranslatorImpl( val attributes = mutableListOf() attributes += method.getSwiftPrivateAttribute() ?: swiftNameAttribute(swiftName) - if (baseMethodBridge.returnBridge is MethodBridge.ReturnValue.WithError.ZeroForError - && baseMethodBridge.returnBridge.successMayBeZero - ) { + val returnBridge = baseMethodBridge.returnBridge + if (returnBridge is MethodBridge.ReturnValue.WithError.ZeroForError && returnBridge.successMayBeZero) { // Method may return zero on success, but // standard Objective-C convention doesn't suppose this happening. diff --git a/native/objcexport-header-generator/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportBaseDeclarations.kt b/native/objcexport-header-generator/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportBaseDeclarations.kt index 4d0540a9a2e..309d18842ab 100644 --- a/native/objcexport-header-generator/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportBaseDeclarations.kt +++ b/native/objcexport-header-generator/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportBaseDeclarations.kt @@ -251,11 +251,3 @@ private fun objCProtocol( comment = comment ) - -private fun ObjCExportClassOrProtocolName.toNameAttributes(): List = listOfNotNull( - binaryName.takeIf { it != objCName }?.let { objcRuntimeNameAttribute(it) }, - swiftName.takeIf { it != objCName }?.let { swiftNameAttribute(it) } -) - -private fun swiftNameAttribute(swiftName: String) = "swift_name(\"$swiftName\")" -private fun objcRuntimeNameAttribute(name: String) = "objc_runtime_name(\"$name\")" \ No newline at end of file diff --git a/native/objcexport-header-generator/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportName.kt b/native/objcexport-header-generator/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportName.kt index ef447602ab3..ac690c62760 100644 --- a/native/objcexport-header-generator/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportName.kt +++ b/native/objcexport-header-generator/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportName.kt @@ -44,3 +44,12 @@ private data class ObjCExportPropertyNameImpl( override val swiftName: String, override val objCName: String, ) : ObjCExportPropertyName + + +fun ObjCExportClassOrProtocolName.toNameAttributes(): List = listOfNotNull( + binaryName.takeIf { it != objCName }?.let { objcRuntimeNameAttribute(it) }, + swiftName.takeIf { it != objCName }?.let { swiftNameAttribute(it) } +) + +private fun swiftNameAttribute(swiftName: String) = "swift_name(\"$swiftName\")" +private fun objcRuntimeNameAttribute(name: String) = "objc_runtime_name(\"$name\")" \ No newline at end of file