[KT-63275] Generate wrapper bodies in the SwiftExportExtension
This commit is contained in:
committed by
Space Team
parent
cb19e291a3
commit
591e98a947
+16
@@ -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<String>,
|
||||
)
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
+29
-25
@@ -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<BridgeRequest> {
|
||||
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<BridgeRequest>) {
|
||||
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<BridgeRequest>): BridgeSources {
|
||||
|
||||
val generator = createBridgeGenerator()
|
||||
val kotlinBridgePrinter = createKotlinBridgePrinter()
|
||||
@@ -149,27 +150,30 @@ class SwiftExportExtension(
|
||||
}
|
||||
}
|
||||
|
||||
private object BridgeRequestsBuilder : SirVisitor<Unit, MutableList<BridgeRequest>>() {
|
||||
fun build(from: SirModule): List<BridgeRequest> {
|
||||
val result = mutableListOf<BridgeRequest>()
|
||||
from.accept(this, result)
|
||||
return result
|
||||
private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeRequest>> {
|
||||
override fun run(element: SirElement, data: Nothing?): List<BridgeRequest> {
|
||||
val requests = mutableListOf<BridgeRequest>()
|
||||
element.accept(Visitor(requests))
|
||||
return requests.toList()
|
||||
}
|
||||
|
||||
override fun visitFunction(function: SirFunction, data: MutableList<BridgeRequest>) {
|
||||
val fqName = (function.origin as? SirKotlinOrigin.Function)?.fqName ?: return
|
||||
private class Visitor(val requests: MutableList<BridgeRequest>) : 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<BridgeRequest>) {
|
||||
element.acceptChildren(this, data)
|
||||
requests += bridgeRequest
|
||||
function.body = createFunctionBodyFromRequest(bridgeRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t namespace1_main_foobar();
|
||||
int32_t namespace1_main_foobar(int32_t param);
|
||||
|
||||
int32_t namespace1_foo();
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,4 +13,4 @@ package namespace1.main
|
||||
|
||||
import namespace1
|
||||
import namespace2
|
||||
fun foobar(): Int = foo() + bar()
|
||||
fun foobar(param: Int): Int = foo() + bar() + param
|
||||
|
||||
Reference in New Issue
Block a user