[Swift Export] KT-63516
Add a sir-compiler-bridge module that adds Kotlin and C bridges for SIR. As SIR is still WIP, the module accepts `BridgeRequest` instances instead of SIR elements.
This commit is contained in:
committed by
Space Team
parent
7c15e3f229
commit
fe9ab0a1fc
@@ -10,6 +10,7 @@ sourceSets {
|
||||
|
||||
dependencies {
|
||||
testApi(projectTests(":native:swift:sir-analysis-api"))
|
||||
testApi(projectTests(":native:swift:sir-compiler-bridge"))
|
||||
testImplementation(projectTests(":generators:test-generator"))
|
||||
|
||||
testRuntimeOnly(projectTests(":analysis:analysis-test-framework"))
|
||||
|
||||
+11
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.generators.tests.native.swift.sir.analysis.api
|
||||
|
||||
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
||||
import org.jetbrains.kotlin.sir.analysisapi.AbstractKotlinSirContextTest
|
||||
import org.jetbrains.kotlin.sir.bridge.AbstractKotlinSirBridgeTest
|
||||
|
||||
|
||||
fun main() {
|
||||
@@ -22,5 +23,15 @@ fun main() {
|
||||
model("", pattern = "^([^_](.+)).kt$", recursive = false)
|
||||
}
|
||||
}
|
||||
testGroup(
|
||||
"native/swift/sir-compiler-bridge/tests-gen/",
|
||||
"native/swift/sir-compiler-bridge/testData"
|
||||
) {
|
||||
testClass<AbstractKotlinSirBridgeTest>(
|
||||
suiteTestClassName = "SirCompilerBridgeTestGenerated"
|
||||
) {
|
||||
model("", extension = null, recursive = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Swift IR to Kotlin compiler bridges
|
||||
|
||||
This module is responsible for the generation of "glue" code between Swift Export and Kotlin compiler.
|
||||
|
||||
Swift does not "know" how to call Kotlin directly. But it has a C/C++/Objective-C interop, and we can leverage it for Swift Export.
|
||||
|
||||
We do the following:
|
||||
1. Generate a Kotlin wrapper around the original Kotlin function with a primitive C-like ABI.
|
||||
2. Generate a C header with C declarations of these wrappers.
|
||||
3. Call these C functions from Swift functions.
|
||||
|
||||
That's it! This approach also has the following advantages:
|
||||
1. All nuances of Kotlin compiler and Kotlin/Native runtime are hidden behind wrappers with a simple ABI.
|
||||
So Swift Export (mostly) does not need to care about how Kotlin/Native works under the hood.
|
||||
2. The contract between Swift Export and Kotlin compiler is well-defined in the form of a set of compiler intrinsics.
|
||||
|
||||
For the sake of simplicity, Kotlin wrappers are generated as Kotlin sources,
|
||||
but later we can switch to direct generation of Kotlin Backend IR.
|
||||
@@ -0,0 +1,31 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
description = "SIR to Kotlin bindings generator"
|
||||
|
||||
dependencies {
|
||||
compileOnly(kotlinStdlib())
|
||||
|
||||
testApi(platform(libs.junit.bom))
|
||||
testRuntimeOnly(libs.junit.jupiter.engine)
|
||||
testImplementation(libs.junit.jupiter.api)
|
||||
|
||||
testImplementation(projectTests(":compiler:tests-common"))
|
||||
testImplementation(projectTests(":compiler:tests-common-new"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {
|
||||
projectDefault()
|
||||
generatedTestDir()
|
||||
}
|
||||
}
|
||||
|
||||
projectTest(jUnitMode = JUnitMode.JUnit5) {
|
||||
workingDir = rootDir
|
||||
useJUnitPlatform { }
|
||||
}
|
||||
|
||||
testsJar()
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.sir.bridge
|
||||
|
||||
import org.jetbrains.kotlin.sir.bridge.impl.BridgeGeneratorImpl
|
||||
import org.jetbrains.kotlin.sir.bridge.impl.CBridgePrinter
|
||||
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 bridgeName C name of the bridge
|
||||
*/
|
||||
class BridgeRequest(
|
||||
val fqName: List<String>,
|
||||
val bridgeName: String,
|
||||
val parameters: List<Parameter>,
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A C-like wrapper around some Kotlin function.
|
||||
* Abstracts away all nuances of Kotlin compiler ABI, making it possible
|
||||
* to call Kotlin code from other environments.
|
||||
*/
|
||||
class FunctionBridge(
|
||||
val kotlinFunctionBridge: KotlinFunctionBridge,
|
||||
val cDeclarationBridge: CFunctionBridge,
|
||||
)
|
||||
|
||||
/**
|
||||
* C part of [FunctionBridgeImpl].
|
||||
*
|
||||
* @param lines with function declaration.
|
||||
* @param headerDependencies required headers.
|
||||
*/
|
||||
class CFunctionBridge(
|
||||
val lines: List<String>,
|
||||
val headerDependencies: List<String>,
|
||||
)
|
||||
|
||||
/**
|
||||
* Kotlin part of [FunctionBridgeImpl].
|
||||
*
|
||||
* @param lines definition of Kotlin bridge.
|
||||
* @param packageDependencies required packages to make sources compile.
|
||||
*/
|
||||
class KotlinFunctionBridge(
|
||||
val lines: List<String>,
|
||||
val packageDependencies: List<String>,
|
||||
)
|
||||
|
||||
/**
|
||||
* Generates [FunctionBridge] that binds SIR function to its Kotlin origin.
|
||||
*/
|
||||
interface BridgeGenerator {
|
||||
fun generate(request: BridgeRequest): FunctionBridge
|
||||
}
|
||||
|
||||
/**
|
||||
* A common interface for classes that serialize [FunctionBridge] in some form.
|
||||
*/
|
||||
interface BridgePrinter {
|
||||
/**
|
||||
* Populate printer with an additional [bridge].
|
||||
*/
|
||||
fun add(bridge: FunctionBridge)
|
||||
|
||||
/**
|
||||
* Outputs the aggregated result.
|
||||
*/
|
||||
fun print(): Sequence<String>
|
||||
}
|
||||
|
||||
fun createBridgeGenerator(): BridgeGenerator =
|
||||
BridgeGeneratorImpl()
|
||||
|
||||
fun createCBridgePrinter(): BridgePrinter =
|
||||
CBridgePrinter()
|
||||
|
||||
fun createKotlinBridgePrinter(): BridgePrinter =
|
||||
KotlinBridgePrinter()
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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.sir.bridge.impl
|
||||
|
||||
import org.jetbrains.kotlin.sir.bridge.*
|
||||
|
||||
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 cDeclaration = createCDeclaration(request.bridgeName, cReturnType, parameterBridges.map { it.c })
|
||||
val kotlinBridge = createKotlinBridge(request.bridgeName, request.fqName, kotlinReturnType, parameterBridges.map { it.kotlin })
|
||||
return FunctionBridge(
|
||||
KotlinFunctionBridge(kotlinBridge, listOf(exportAnnotationFqName)),
|
||||
CFunctionBridge(cDeclaration, listOf(stdintHeader))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createKotlinBridge(
|
||||
bridgeName: String,
|
||||
functionFqName: List<String>,
|
||||
returnType: KotlinType,
|
||||
parameterBridges: List<KotlinBridgeParameter>
|
||||
): List<String> {
|
||||
val declaration = createKotlinDeclarationSignature(bridgeName, returnType, parameterBridges)
|
||||
val annotation = "@${exportAnnotationFqName.substringAfterLast('.')}(\"${bridgeName}\")"
|
||||
val resultName = "result"
|
||||
val callSite = createCallSite(functionFqName, parameterBridges.map { it.name }, resultName)
|
||||
return """
|
||||
$annotation
|
||||
$declaration {
|
||||
$callSite
|
||||
return $resultName
|
||||
}
|
||||
""".trimIndent().lines()
|
||||
}
|
||||
|
||||
private fun createCallSite(functionFqName: List<String>, parameterNames: List<String>, resultName: String): String {
|
||||
val functionCall = "${functionFqName.joinToString(separator = ".")}(${parameterNames.joinToString(", ")})"
|
||||
return "val $resultName = $functionCall"
|
||||
}
|
||||
|
||||
private fun createKotlinDeclarationSignature(bridgeName: String, returnType: KotlinType, parameters: List<KotlinBridgeParameter>): String {
|
||||
return "public fun $bridgeName(${
|
||||
parameters.joinToString(
|
||||
separator = ", ",
|
||||
transform = { "${it.name}: ${it.type.repr}" }
|
||||
)
|
||||
}): ${returnType.repr}"
|
||||
}
|
||||
|
||||
private fun createCDeclaration(bridgeName: String, returnType: CType, parameters: List<CBridgeParameter>): List<String> {
|
||||
val cParameters = parameters.joinToString(separator = ", ", transform = { "${it.type.repr} ${it.name}" })
|
||||
val declaration = "${returnType.repr} $bridgeName($cParameters);"
|
||||
return listOf(declaration)
|
||||
}
|
||||
|
||||
|
||||
private fun bridgeType(type: BridgeRequest.Type): Pair<KotlinType, CType> {
|
||||
return when (type) {
|
||||
BridgeRequest.Type.Boolean -> (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)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bridgeParameter(request: BridgeRequest.Parameter): BridgeParameter {
|
||||
val bridgeParameterName = createBridgeParameterName(request.name)
|
||||
val (kotlinType, cType) = bridgeType(request.type)
|
||||
return BridgeParameter(
|
||||
KotlinBridgeParameter(bridgeParameterName, kotlinType),
|
||||
CBridgeParameter(bridgeParameterName, cType)
|
||||
)
|
||||
}
|
||||
|
||||
fun createBridgeParameterName(kotlinName: String): String {
|
||||
// TODO: Post-process because C has stricter naming conventions.
|
||||
return kotlinName
|
||||
}
|
||||
|
||||
internal data class BridgeParameter(
|
||||
val kotlin: KotlinBridgeParameter,
|
||||
val c: CBridgeParameter,
|
||||
)
|
||||
|
||||
internal data class CBridgeParameter(
|
||||
val name: String,
|
||||
val type: CType,
|
||||
)
|
||||
|
||||
enum class CType(val repr: String) {
|
||||
Bool("_Bool"),
|
||||
|
||||
Int8("int8_t"),
|
||||
Int16("int16_t"),
|
||||
Int32("int32_t"),
|
||||
Int64("int64_t"),
|
||||
|
||||
UInt8("uint8_t"),
|
||||
UInt16("uint16_t"),
|
||||
UInt32("uint32_t"),
|
||||
UInt64("uint64_t"),
|
||||
}
|
||||
|
||||
internal data class KotlinBridgeParameter(
|
||||
val name: String,
|
||||
val type: KotlinType,
|
||||
)
|
||||
|
||||
internal enum class KotlinType(val repr: String) {
|
||||
Boolean("Boolean"),
|
||||
|
||||
Byte("Byte"),
|
||||
Short("Short"),
|
||||
Int("Int"),
|
||||
Long("Long"),
|
||||
|
||||
UByte("UByte"),
|
||||
UShort("UShort"),
|
||||
UInt("UInt"),
|
||||
ULong("ULong"),
|
||||
}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.sir.bridge.impl
|
||||
|
||||
import org.jetbrains.kotlin.sir.bridge.BridgePrinter
|
||||
import org.jetbrains.kotlin.sir.bridge.FunctionBridge
|
||||
|
||||
internal class CBridgePrinter : BridgePrinter {
|
||||
|
||||
private val includes = mutableSetOf<String>()
|
||||
|
||||
private val functions = mutableListOf<List<String>>()
|
||||
|
||||
override fun add(bridge: FunctionBridge) {
|
||||
functions += bridge.cDeclarationBridge.lines
|
||||
includes += bridge.cDeclarationBridge.headerDependencies
|
||||
}
|
||||
|
||||
override fun print(): Sequence<String> = sequence {
|
||||
if (includes.isNotEmpty()) {
|
||||
includes.forEach {
|
||||
yield("#include <$it>")
|
||||
}
|
||||
yield("")
|
||||
}
|
||||
functions.forEach { functionLines ->
|
||||
yieldAll(functionLines)
|
||||
yield("")
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.sir.bridge.impl
|
||||
|
||||
import org.jetbrains.kotlin.sir.bridge.BridgePrinter
|
||||
import org.jetbrains.kotlin.sir.bridge.FunctionBridge
|
||||
|
||||
internal class KotlinBridgePrinter : BridgePrinter {
|
||||
|
||||
private val imports = mutableSetOf<String>()
|
||||
private val functions = mutableListOf<List<String>>()
|
||||
|
||||
override fun add(bridge: FunctionBridge) {
|
||||
functions += bridge.kotlinFunctionBridge.lines
|
||||
imports += bridge.kotlinFunctionBridge.packageDependencies
|
||||
}
|
||||
|
||||
override fun print(): Sequence<String> = sequence {
|
||||
if (imports.isNotEmpty()) {
|
||||
imports.forEach {
|
||||
yield("import $it")
|
||||
}
|
||||
yield("")
|
||||
}
|
||||
functions.forEach { functionLines ->
|
||||
yieldAll(functionLines)
|
||||
yield("")
|
||||
}
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.sir.bridge
|
||||
|
||||
import com.intellij.testFramework.TestDataFile
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
abstract class AbstractKotlinSirBridgeTest {
|
||||
protected fun runTest(@TestDataFile testPath: String) {
|
||||
val testPathFull = File(KtTestUtil.getHomeDirectory()).resolve(testPath)
|
||||
val expectedKotlinSrc = testPathFull.resolve("expected.kt")
|
||||
val expectedCHeader = testPathFull.resolve("expected.h")
|
||||
|
||||
val requests = parseRequestsFromTestDir(testPathFull)
|
||||
|
||||
val generator = createBridgeGenerator()
|
||||
val kotlinBridgePrinter = createKotlinBridgePrinter()
|
||||
val cBridgePrinter = createCBridgePrinter()
|
||||
|
||||
requests.forEach { request ->
|
||||
val bridge = generator.generate(request)
|
||||
kotlinBridgePrinter.add(bridge)
|
||||
cBridgePrinter.add(bridge)
|
||||
}
|
||||
|
||||
val actualKotlinSrc = kotlinBridgePrinter.print().joinToString(separator = lineSeparator)
|
||||
val actualHeader = cBridgePrinter.print().joinToString(separator = lineSeparator)
|
||||
|
||||
JUnit5Assertions.assertEqualsToFile(expectedCHeader, actualHeader)
|
||||
JUnit5Assertions.assertEqualsToFile(expectedKotlinSrc, actualKotlinSrc)
|
||||
}
|
||||
}
|
||||
|
||||
private val lineSeparator: String = System.getProperty("line.separator")
|
||||
|
||||
private fun parseRequestsFromTestDir(testDir: File): List<BridgeRequest> =
|
||||
testDir.listFiles()
|
||||
?.filter { it.extension == "properties" && it.name.startsWith("request") }
|
||||
?.map { readRequestFromFile(it) }
|
||||
?.sortedBy { it.bridgeName }
|
||||
?: emptyList()
|
||||
|
||||
private fun parseType(typeName: String): BridgeRequest.Type {
|
||||
return when (typeName.lowercase()) {
|
||||
"boolean" -> BridgeRequest.Type.Boolean
|
||||
|
||||
"byte" -> BridgeRequest.Type.Byte
|
||||
"short" -> BridgeRequest.Type.Short
|
||||
"int" -> BridgeRequest.Type.Int
|
||||
"long" -> BridgeRequest.Type.Long
|
||||
|
||||
"ubyte" -> BridgeRequest.Type.UByte
|
||||
"ushort" -> BridgeRequest.Type.UShort
|
||||
"uint" -> BridgeRequest.Type.UInt
|
||||
"ulong" -> BridgeRequest.Type.ULong
|
||||
|
||||
else -> error("Unknown type: $typeName")
|
||||
}
|
||||
}
|
||||
|
||||
private fun readRequestFromFile(file: File): BridgeRequest {
|
||||
val properties = Properties()
|
||||
file.bufferedReader().use(properties::load)
|
||||
val fqName = properties.getProperty("fqName").split('.')
|
||||
val bridgeName = properties.getProperty("bridgeName")
|
||||
val returnType = parseType(properties.getProperty("returnType"))
|
||||
val parameters = properties.getProperty("parameters").let { parametersString ->
|
||||
when {
|
||||
parametersString.isNullOrEmpty() -> emptyList()
|
||||
else -> parametersString.split(Regex("\\s+"))
|
||||
}.map {
|
||||
BridgeRequest.Parameter(
|
||||
name = it.substringBefore(':'),
|
||||
type = parseType(it.substringAfter(':'))
|
||||
)
|
||||
}
|
||||
}
|
||||
return BridgeRequest(fqName, bridgeName, parameters, returnType)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t a_b_bar_bridge(int32_t param1, int64_t param2);
|
||||
|
||||
_Bool a_b_foo_bridge(int32_t param1, int64_t param2);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import kotlin.native.internal.ExportForCppRuntime
|
||||
|
||||
@ExportForCppRuntime("a_b_bar_bridge")
|
||||
public fun a_b_bar_bridge(param1: Int, param2: Long): Int {
|
||||
val result = a.b.bar(param1, param2)
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("a_b_foo_bridge")
|
||||
public fun a_b_foo_bridge(param1: Int, param2: Long): Boolean {
|
||||
val result = a.b.foo(param1, param2)
|
||||
return result
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fqName=a.b.foo
|
||||
bridgeName=a_b_foo_bridge
|
||||
parameters=param1:int param2:long
|
||||
returnType=boolean
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fqName=a.b.bar
|
||||
bridgeName=a_b_bar_bridge
|
||||
parameters=param1:int param2:long
|
||||
returnType=int
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t a(int8_t p0, int16_t p1, int32_t p2, int64_t p3);
|
||||
|
||||
uint32_t b(uint8_t p0, uint16_t p1, uint32_t p2, uint64_t p3);
|
||||
|
||||
_Bool c(_Bool p0);
|
||||
@@ -0,0 +1,20 @@
|
||||
import kotlin.native.internal.ExportForCppRuntime
|
||||
|
||||
@ExportForCppRuntime("a")
|
||||
public fun a(p0: Byte, p1: Short, p2: Int, p3: Long): Int {
|
||||
val result = pkg.a(p0, p1, p2, p3)
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("b")
|
||||
public fun b(p0: UByte, p1: UShort, p2: UInt, p3: ULong): UInt {
|
||||
val result = pkg.b(p0, p1, p2, p3)
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("c")
|
||||
public fun c(p0: Boolean): Boolean {
|
||||
val result = pkg.c(p0)
|
||||
return result
|
||||
}
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fqName=pkg.a
|
||||
bridgeName=a
|
||||
returnType=int
|
||||
parameters=p0:byte p1:short p2:int p3:long
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fqName=pkg.b
|
||||
bridgeName=b
|
||||
returnType=uint
|
||||
parameters=p0:ubyte p1:ushort p2:uint p3:ulong
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fqName=pkg.c
|
||||
bridgeName=c
|
||||
returnType=boolean
|
||||
parameters=p0:boolean
|
||||
@@ -0,0 +1,11 @@
|
||||
#include <stdint.h>
|
||||
|
||||
_Bool a_bridge();
|
||||
|
||||
int16_t b_bridge();
|
||||
|
||||
int32_t c_bridge();
|
||||
|
||||
int64_t d_bridge();
|
||||
|
||||
int8_t e_bridge();
|
||||
@@ -0,0 +1,31 @@
|
||||
import kotlin.native.internal.ExportForCppRuntime
|
||||
|
||||
@ExportForCppRuntime("a_bridge")
|
||||
public fun a_bridge(): Boolean {
|
||||
val result = a()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("b_bridge")
|
||||
public fun b_bridge(): Short {
|
||||
val result = b()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("c_bridge")
|
||||
public fun c_bridge(): Int {
|
||||
val result = c()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("d_bridge")
|
||||
public fun d_bridge(): Long {
|
||||
val result = d()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("e_bridge")
|
||||
public fun e_bridge(): Byte {
|
||||
val result = e()
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fqName=a
|
||||
bridgeName=a_bridge
|
||||
returnType=boolean
|
||||
@@ -0,0 +1,3 @@
|
||||
fqName=b
|
||||
bridgeName=b_bridge
|
||||
returnType=short
|
||||
@@ -0,0 +1,3 @@
|
||||
fqName=c
|
||||
bridgeName=c_bridge
|
||||
returnType=int
|
||||
@@ -0,0 +1,3 @@
|
||||
fqName=d
|
||||
bridgeName=d_bridge
|
||||
returnType=long
|
||||
@@ -0,0 +1,3 @@
|
||||
fqName=e
|
||||
bridgeName=e_bridge
|
||||
returnType=byte
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t a_b_foo_bridge(int32_t param1, int64_t param2);
|
||||
@@ -0,0 +1,7 @@
|
||||
import kotlin.native.internal.ExportForCppRuntime
|
||||
|
||||
@ExportForCppRuntime("a_b_foo_bridge")
|
||||
public fun a_b_foo_bridge(param1: Int, param2: Long): Int {
|
||||
val result = a.b.foo(param1, param2)
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fqName=a.b.foo
|
||||
bridgeName=a_b_foo_bridge
|
||||
parameters=param1:int param2:long
|
||||
returnType=int
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <stdint.h>
|
||||
|
||||
uint16_t b_bridge();
|
||||
|
||||
uint32_t c_bridge();
|
||||
|
||||
uint64_t d_bridge();
|
||||
|
||||
uint8_t e_bridge();
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import kotlin.native.internal.ExportForCppRuntime
|
||||
|
||||
@ExportForCppRuntime("b_bridge")
|
||||
public fun b_bridge(): UShort {
|
||||
val result = b()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("c_bridge")
|
||||
public fun c_bridge(): UInt {
|
||||
val result = c()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("d_bridge")
|
||||
public fun d_bridge(): ULong {
|
||||
val result = d()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportForCppRuntime("e_bridge")
|
||||
public fun e_bridge(): UByte {
|
||||
val result = e()
|
||||
return result
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fqName=b
|
||||
bridgeName=b_bridge
|
||||
returnType=ushort
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fqName=c
|
||||
bridgeName=c_bridge
|
||||
returnType=uint
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fqName=d
|
||||
bridgeName=d_bridge
|
||||
returnType=ulong
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fqName=e
|
||||
bridgeName=e_bridge
|
||||
returnType=ubyte
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.sir.bridge;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.native.swift.sir.analysis.api.GenerateSirAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("native/swift/sir-compiler-bridge/testData")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class SirCompilerBridgeTestGenerated extends AbstractKotlinSirBridgeTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInTestData() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/sir-compiler-bridge/testData"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multiple_requests")
|
||||
public void testMultiple_requests() throws Exception {
|
||||
runTest("native/swift/sir-compiler-bridge/testData/multiple_requests/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smoke0")
|
||||
public void testSmoke0() throws Exception {
|
||||
runTest("native/swift/sir-compiler-bridge/testData/smoke0/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("primitive_types")
|
||||
public void testPrimitive_types() throws Exception {
|
||||
runTest("native/swift/sir-compiler-bridge/testData/primitive_types/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unsigned_primitive_types")
|
||||
public void testUnsigned_primitive_types() throws Exception {
|
||||
runTest("native/swift/sir-compiler-bridge/testData/unsigned_primitive_types/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("primitive_parameters")
|
||||
public void testPrimitive_parameters() throws Exception {
|
||||
runTest("native/swift/sir-compiler-bridge/testData/primitive_parameters/");
|
||||
}
|
||||
}
|
||||
@@ -401,6 +401,7 @@ include ":plugins:compose-compiler-plugin:compiler",
|
||||
include ":native:swift:sir",
|
||||
":native:swift:sir-passes",
|
||||
":native:swift:sir-analysis-api",
|
||||
":native:swift:sir-compiler-bridge",
|
||||
":generators:sir-analysis-api-generator"
|
||||
|
||||
void intellij(String imlPath) {
|
||||
|
||||
Reference in New Issue
Block a user