From 591e98a9472222a0a2b03bd04152d878475b90c8 Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Fri, 12 Jan 2024 13:42:55 +0200 Subject: [PATCH] [KT-63275] Generate wrapper bodies in the SwiftExportExtension --- .../kotlin/sir/bridge/BridgeGenerator.kt | 16 ++++++ .../swiftexport/SwiftExportExtension.kt | 54 ++++++++++--------- plugins/swift-export/testData/simple.golden.h | 2 +- .../swift-export/testData/simple.golden.kt | 4 +- .../swift-export/testData/simple.golden.swift | 10 ++-- plugins/swift-export/testData/simple.kt | 2 +- 6 files changed, 55 insertions(+), 33 deletions(-) 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 c2a19d218d0..ebe374f7189 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 @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.sir.bridge import org.jetbrains.kotlin.sir.SirFunction +import org.jetbrains.kotlin.sir.SirFunctionBody import org.jetbrains.kotlin.sir.bridge.impl.BridgeGeneratorImpl import org.jetbrains.kotlin.sir.bridge.impl.CBridgePrinter import org.jetbrains.kotlin.sir.bridge.impl.KotlinBridgePrinter @@ -22,6 +23,21 @@ public class BridgeRequest( public val fqName: List, ) +/** + * Generates the body of a function from a given request. + * + * @param request the BridgeRequest object that contains information about the function and the bridge + * @return the generated SirFunctionBody object representing the body of the function + */ +public fun createFunctionBodyFromRequest(request: BridgeRequest): SirFunctionBody { + val callee = request.bridgeName + val calleeArguments = request.function.parameters.map { it.argumentName } + val callSite = "$callee(${calleeArguments.joinToString(separator = ", ")})" + return SirFunctionBody( + listOf("return $callSite") + ) +} + /** * A C-like wrapper around some Kotlin function. * Abstracts away all nuances of Kotlin compiler ABI, making it possible diff --git a/plugins/swift-export/swift-export.backend/src/org/jetbrains/kotlin/swiftexport/SwiftExportExtension.kt b/plugins/swift-export/swift-export.backend/src/org/jetbrains/kotlin/swiftexport/SwiftExportExtension.kt index 859de4c5581..453e180410e 100644 --- a/plugins/swift-export/swift-export.backend/src/org/jetbrains/kotlin/swiftexport/SwiftExportExtension.kt +++ b/plugins/swift-export/swift-export.backend/src/org/jetbrains/kotlin/swiftexport/SwiftExportExtension.kt @@ -14,12 +14,9 @@ import org.jetbrains.kotlin.fir.extensions.FirAnalysisHandlerExtension import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.sir.* import org.jetbrains.kotlin.sir.analysisapi.SirGenerator -import org.jetbrains.kotlin.sir.bridge.BridgeRequest -import org.jetbrains.kotlin.sir.bridge.createBridgeGenerator -import org.jetbrains.kotlin.sir.bridge.createCBridgePrinter -import org.jetbrains.kotlin.sir.bridge.createKotlinBridgePrinter +import org.jetbrains.kotlin.sir.bridge.* import org.jetbrains.kotlin.sir.builder.buildModule -import org.jetbrains.kotlin.sir.visitors.SirVisitor +import org.jetbrains.kotlin.sir.visitors.SirVisitorVoid import org.jetbrains.sir.passes.SirInflatePackagesPass import org.jetbrains.sir.passes.SirModulePass import org.jetbrains.sir.passes.SirPass @@ -37,12 +34,17 @@ class SwiftExportExtension( } override fun doAnalysis(configuration: CompilerConfiguration): Boolean { - buildSwiftModule(configuration) + val module = buildSwiftModule(configuration) .transformToSwift() - .dumpResultToFiles() + val bridgeRequests = module.createFunctionBridges() + module.dumpResultToFiles(bridgeRequests) return true } + private fun SirModule.createFunctionBridges(): List { + return BridgeGenerationPass.run(this) + } + @OptIn(KtAnalysisApiInternals::class) private fun buildSwiftModule(configuration: CompilerConfiguration): SirModule { val standaloneAnalysisAPISession = @@ -74,14 +76,14 @@ class SwiftExportExtension( } } - private fun SirModule.dumpResultToFiles() { + private fun SirModule.dumpResultToFiles(requests: List) { val destinationPath = destination.absolutePath val cHeaderFile = File("${destinationPath}/${outputFileName}.h") val ktBridgeFile = File("${destinationPath}/${outputFileName}.kt") val swiftFile = File("${destinationPath}/${outputFileName}.swift") - val bridges = generateBridgeSources() + val bridges = generateBridgeSources(requests) val swiftSrc = generateSwiftSrc() dumpTextAtFile(bridges.ktSrc, ktBridgeFile) @@ -93,8 +95,7 @@ class SwiftExportExtension( return SirAsSwiftSourcesPrinter().print(this) } - private fun SirModule.generateBridgeSources(): BridgeSources { - val requests = BridgeRequestsBuilder.build(this) + private fun generateBridgeSources(requests: List): BridgeSources { val generator = createBridgeGenerator() val kotlinBridgePrinter = createKotlinBridgePrinter() @@ -149,27 +150,30 @@ class SwiftExportExtension( } } - private object BridgeRequestsBuilder : SirVisitor>() { - fun build(from: SirModule): List { - val result = mutableListOf() - from.accept(this, result) - return result + private object BridgeGenerationPass : SirPass> { + override fun run(element: SirElement, data: Nothing?): List { + val requests = mutableListOf() + element.accept(Visitor(requests)) + return requests.toList() } - override fun visitFunction(function: SirFunction, data: MutableList) { - val fqName = (function.origin as? SirKotlinOrigin.Function)?.fqName ?: return + private class Visitor(val requests: MutableList) : SirVisitorVoid() { - data.add( - BridgeRequest( + override fun visitElement(element: SirElement) { + element.acceptChildren(this) + } + + override fun visitFunction(function: SirFunction) { + val fqName = (function.origin as? SirKotlinOrigin.Function)?.fqName + ?: return + val bridgeRequest = BridgeRequest( function, fqName.joinToString("_"), fqName ) - ) - } - - override fun visitElement(element: SirElement, data: MutableList) { - element.acceptChildren(this, data) + requests += bridgeRequest + function.body = createFunctionBodyFromRequest(bridgeRequest) + } } } } diff --git a/plugins/swift-export/testData/simple.golden.h b/plugins/swift-export/testData/simple.golden.h index bdc83244c70..78b6c22b4f4 100644 --- a/plugins/swift-export/testData/simple.golden.h +++ b/plugins/swift-export/testData/simple.golden.h @@ -1,6 +1,6 @@ #include -int32_t namespace1_main_foobar(); +int32_t namespace1_main_foobar(int32_t param); int32_t namespace1_foo(); diff --git a/plugins/swift-export/testData/simple.golden.kt b/plugins/swift-export/testData/simple.golden.kt index 4d0cf133c1f..ed6403176d1 100644 --- a/plugins/swift-export/testData/simple.golden.kt +++ b/plugins/swift-export/testData/simple.golden.kt @@ -1,8 +1,8 @@ import kotlin.native.internal.ExportedBridge @ExportedBridge("namespace1_main_foobar") -public fun namespace1_main_foobar(): Int { - val result = namespace1.main.foobar() +public fun namespace1_main_foobar(param: Int): Int { + val result = namespace1.main.foobar(param) return result } diff --git a/plugins/swift-export/testData/simple.golden.swift b/plugins/swift-export/testData/simple.golden.swift index 4f9a4209871..dba9120f6eb 100644 --- a/plugins/swift-export/testData/simple.golden.swift +++ b/plugins/swift-export/testData/simple.golden.swift @@ -1,16 +1,18 @@ enum namespace1 { enum main { - public func foobar() -> Swift.Int32 { - fatalError() + public func foobar( + param: Swift.Int32 + ) -> Swift.Int32 { + return namespace1_main_foobar(param) } } public func foo() -> Swift.Int32 { - fatalError() + return namespace1_foo() } } enum namespace2 { public func bar() -> Swift.Int32 { - fatalError() + return namespace2_bar() } } diff --git a/plugins/swift-export/testData/simple.kt b/plugins/swift-export/testData/simple.kt index d5762729882..e8896b112b6 100644 --- a/plugins/swift-export/testData/simple.kt +++ b/plugins/swift-export/testData/simple.kt @@ -13,4 +13,4 @@ package namespace1.main import namespace1 import namespace2 -fun foobar(): Int = foo() + bar() +fun foobar(param: Int): Int = foo() + bar() + param