From 5eeb82bb6f0e6ef9b719dd62ef5376182b275fb9 Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Fri, 24 Nov 2023 14:16:11 +0100 Subject: [PATCH] [Swift Export] Update sir-compiler-bridge to use SIR Now that SIR has finally landed in the repository, we can remove unnecessary entities from the bridge generator. --- .../sir-compiler-bridge/build.gradle.kts | 2 + .../kotlin/sir/bridge/BridgeGenerator.kt | 31 +++----------- .../sir/bridge/impl/BridgeGeneratorImpl.kt | 42 +++++++++++-------- .../sir/bridge/AbstractKotlinSirBridgeTest.kt | 38 ++++++++++------- .../kotlin/sir/util/SirSwiftModule.kt | 14 +++++++ 5 files changed, 69 insertions(+), 58 deletions(-) diff --git a/native/swift/sir-compiler-bridge/build.gradle.kts b/native/swift/sir-compiler-bridge/build.gradle.kts index 8fa412bbf2d..4134367c806 100644 --- a/native/swift/sir-compiler-bridge/build.gradle.kts +++ b/native/swift/sir-compiler-bridge/build.gradle.kts @@ -7,6 +7,8 @@ description = "SIR to Kotlin bindings generator" dependencies { compileOnly(kotlinStdlib()) + api(project(":native:swift:sir")) + testApi(platform(libs.junit.bom)) testRuntimeOnly(libs.junit.jupiter.engine) testImplementation(libs.junit.jupiter.api) diff --git a/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/BridgeGenerator.kt b/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/BridgeGenerator.kt index f0ac062cb85..d0e6e89e608 100644 --- a/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/BridgeGenerator.kt +++ b/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/BridgeGenerator.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.sir.bridge +import org.jetbrains.kotlin.sir.SirFunction import org.jetbrains.kotlin.sir.bridge.impl.BridgeGeneratorImpl import org.jetbrains.kotlin.sir.bridge.impl.CBridgePrinter import org.jetbrains.kotlin.sir.bridge.impl.KotlinBridgePrinter @@ -12,36 +13,14 @@ import org.jetbrains.kotlin.sir.bridge.impl.KotlinBridgePrinter /** * Description of a Kotlin function for which we are creating the bridge. * - * TODO: Replace with SIR once KT-63266 is merged. - * - * @param fqName Fully qualified name of the function we are bridging. + * @param function SIR function we are generating bridge for * @param bridgeName C name of the bridge */ class BridgeRequest( - val fqName: List, + val function: SirFunction, val bridgeName: String, - val parameters: List, - val returnType: Type, -) { - class Parameter( - val name: String, - val type: Type, - ) - - sealed interface Type { - data object Boolean : Type - - data object Byte : Type - data object Short : Type - data object Int : Type - data object Long : Type - - data object UByte : Type - data object UShort : Type - data object UInt : Type - data object ULong : Type - } -} + val fqName: List, +) /** * A C-like wrapper around some Kotlin function. diff --git a/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/impl/BridgeGeneratorImpl.kt b/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/impl/BridgeGeneratorImpl.kt index 05bd2cfa740..26cd6d6009c 100644 --- a/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/impl/BridgeGeneratorImpl.kt +++ b/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/impl/BridgeGeneratorImpl.kt @@ -5,16 +5,19 @@ package org.jetbrains.kotlin.sir.bridge.impl +import org.jetbrains.kotlin.sir.SirNominalType +import org.jetbrains.kotlin.sir.SirParameter +import org.jetbrains.kotlin.sir.SirType import org.jetbrains.kotlin.sir.bridge.* +import org.jetbrains.kotlin.sir.util.SirSwiftModule private const val exportAnnotationFqName = "kotlin.native.internal.ExportForCppRuntime" private const val stdintHeader = "stdint.h" internal class BridgeGeneratorImpl : BridgeGenerator { override fun generate(request: BridgeRequest): FunctionBridge { - - val (kotlinReturnType, cReturnType) = bridgeType(request.returnType) - val parameterBridges = request.parameters.map { bridgeParameter(it) } + val (kotlinReturnType, cReturnType) = bridgeType(request.function.returnType) + val parameterBridges = request.function.parameters.map { bridgeParameter(it) } val cDeclaration = createCDeclaration(request.bridgeName, cReturnType, parameterBridges.map { it.c }) val kotlinBridge = createKotlinBridge(request.bridgeName, request.fqName, kotlinReturnType, parameterBridges.map { it.kotlin }) @@ -29,7 +32,7 @@ private fun createKotlinBridge( bridgeName: String, functionFqName: List, returnType: KotlinType, - parameterBridges: List + parameterBridges: List, ): List { val declaration = createKotlinDeclarationSignature(bridgeName, returnType, parameterBridges) val annotation = "@${exportAnnotationFqName.substringAfterLast('.')}(\"${bridgeName}\")" @@ -65,25 +68,28 @@ private fun createCDeclaration(bridgeName: String, returnType: CType, parameters } -private fun bridgeType(type: BridgeRequest.Type): Pair { - return when (type) { - BridgeRequest.Type.Boolean -> (KotlinType.Boolean to CType.Bool) +private fun bridgeType(type: SirType): Pair { + require(type is SirNominalType) + return when (type.type) { + SirSwiftModule.bool -> (KotlinType.Boolean to CType.Bool) - BridgeRequest.Type.Byte -> (KotlinType.Byte to CType.Int8) - BridgeRequest.Type.Int -> (KotlinType.Int to CType.Int32) - BridgeRequest.Type.Long -> (KotlinType.Long to CType.Int64) - BridgeRequest.Type.Short -> (KotlinType.Short to CType.Int16) + SirSwiftModule.int8 -> (KotlinType.Byte to CType.Int8) + SirSwiftModule.int32 -> (KotlinType.Int to CType.Int32) + SirSwiftModule.int64 -> (KotlinType.Long to CType.Int64) + SirSwiftModule.int16 -> (KotlinType.Short to CType.Int16) - BridgeRequest.Type.UByte -> (KotlinType.UByte to CType.UInt8) - BridgeRequest.Type.UInt -> (KotlinType.UInt to CType.UInt32) - BridgeRequest.Type.ULong -> (KotlinType.ULong to CType.UInt64) - BridgeRequest.Type.UShort -> (KotlinType.UShort to CType.UInt16) + SirSwiftModule.uint8 -> (KotlinType.UByte to CType.UInt8) + SirSwiftModule.uint32 -> (KotlinType.UInt to CType.UInt32) + SirSwiftModule.uint64 -> (KotlinType.ULong to CType.UInt64) + SirSwiftModule.uint16 -> (KotlinType.UShort to CType.UInt16) + + else -> error("Unsupported type: ${type.type}") } } -private fun bridgeParameter(request: BridgeRequest.Parameter): BridgeParameter { - val bridgeParameterName = createBridgeParameterName(request.name) - val (kotlinType, cType) = bridgeType(request.type) +private fun bridgeParameter(parameter: SirParameter): BridgeParameter { + val bridgeParameterName = parameter.argumentName?.let(::createBridgeParameterName) ?: "" + val (kotlinType, cType) = bridgeType(parameter.type) return BridgeParameter( KotlinBridgeParameter(bridgeParameterName, kotlinType), CBridgeParameter(bridgeParameterName, cType) diff --git a/native/swift/sir-compiler-bridge/test/org/jetbrains/kotlin/sir/bridge/AbstractKotlinSirBridgeTest.kt b/native/swift/sir-compiler-bridge/test/org/jetbrains/kotlin/sir/bridge/AbstractKotlinSirBridgeTest.kt index fa1265763fa..8b97df9b8f1 100644 --- a/native/swift/sir-compiler-bridge/test/org/jetbrains/kotlin/sir/bridge/AbstractKotlinSirBridgeTest.kt +++ b/native/swift/sir-compiler-bridge/test/org/jetbrains/kotlin/sir/bridge/AbstractKotlinSirBridgeTest.kt @@ -6,6 +6,11 @@ package org.jetbrains.kotlin.sir.bridge import com.intellij.testFramework.TestDataFile +import org.jetbrains.kotlin.sir.SirNominalType +import org.jetbrains.kotlin.sir.SirParameter +import org.jetbrains.kotlin.sir.SirType +import org.jetbrains.kotlin.sir.builder.buildFunction +import org.jetbrains.kotlin.sir.util.SirSwiftModule import org.jetbrains.kotlin.test.services.JUnit5Assertions import org.jetbrains.kotlin.test.util.KtTestUtil import java.io.File @@ -46,22 +51,22 @@ private fun parseRequestsFromTestDir(testDir: File): List = ?.sortedBy { it.bridgeName } ?: emptyList() -private fun parseType(typeName: String): BridgeRequest.Type { +private fun parseType(typeName: String): SirType { return when (typeName.lowercase()) { - "boolean" -> BridgeRequest.Type.Boolean + "boolean" -> SirSwiftModule.bool - "byte" -> BridgeRequest.Type.Byte - "short" -> BridgeRequest.Type.Short - "int" -> BridgeRequest.Type.Int - "long" -> BridgeRequest.Type.Long + "byte" -> SirSwiftModule.int8 + "short" -> SirSwiftModule.int16 + "int" -> SirSwiftModule.int32 + "long" -> SirSwiftModule.int64 - "ubyte" -> BridgeRequest.Type.UByte - "ushort" -> BridgeRequest.Type.UShort - "uint" -> BridgeRequest.Type.UInt - "ulong" -> BridgeRequest.Type.ULong + "ubyte" -> SirSwiftModule.uint8 + "ushort" -> SirSwiftModule.uint16 + "uint" -> SirSwiftModule.uint32 + "ulong" -> SirSwiftModule.uint64 else -> error("Unknown type: $typeName") - } + }.let { SirNominalType(it) } } private fun readRequestFromFile(file: File): BridgeRequest { @@ -75,11 +80,16 @@ private fun readRequestFromFile(file: File): BridgeRequest { parametersString.isNullOrEmpty() -> emptyList() else -> parametersString.split(Regex("\\s+")) }.map { - BridgeRequest.Parameter( - name = it.substringBefore(':'), + SirParameter( + argumentName = it.substringBefore(':'), type = parseType(it.substringAfter(':')) ) } } - return BridgeRequest(fqName, bridgeName, parameters, returnType) + val function = buildFunction { + this.name = fqName.last() + this.returnType = returnType + this.parameters += parameters + } + return BridgeRequest(function, bridgeName, fqName) } \ No newline at end of file diff --git a/native/swift/sir/src/org/jetbrains/kotlin/sir/util/SirSwiftModule.kt b/native/swift/sir/src/org/jetbrains/kotlin/sir/util/SirSwiftModule.kt index a971d1ff0d5..a7839f53a05 100644 --- a/native/swift/sir/src/org/jetbrains/kotlin/sir/util/SirSwiftModule.kt +++ b/native/swift/sir/src/org/jetbrains/kotlin/sir/util/SirSwiftModule.kt @@ -21,20 +21,34 @@ object SirSwiftModule : SirModule() { override val declarations: List by lazy { listOf( bool, + int8, int16, int32, int64, + + uint8, + uint16, + uint32, + uint64, + double, float, ) } val bool = primitive("Bool") + val int8 = primitive("Int8") val int16 = primitive("Int16") val int32 = primitive("Int32") val int64 = primitive("Int64") + + val uint8 = primitive("UInt8") + val uint16 = primitive("UInt16") + val uint32 = primitive("UInt32") + val uint64 = primitive("UInt64") + val double = primitive("Double") val float = primitive("Float")