[Swift Export] KT-65008: support simple top-level properties
Merge-request: KT-MR-14131 Merged-by: Gleb Lukianets <Gleb.Lukianets@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
ad5ee28d58
commit
f262247b2b
+11
-5
@@ -5,20 +5,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.sir.bridge
|
||||
|
||||
import org.jetbrains.kotlin.sir.SirFunction
|
||||
import org.jetbrains.kotlin.sir.SirCallable
|
||||
import org.jetbrains.kotlin.sir.SirFunctionBody
|
||||
import org.jetbrains.kotlin.sir.SirNativeCallable
|
||||
import org.jetbrains.kotlin.sir.bridge.impl.BridgeGeneratorImpl
|
||||
import org.jetbrains.kotlin.sir.bridge.impl.CBridgePrinter
|
||||
import org.jetbrains.kotlin.sir.bridge.impl.KotlinBridgePrinter
|
||||
import org.jetbrains.kotlin.sir.util.allParameters
|
||||
import org.jetbrains.kotlin.sir.util.isVoid
|
||||
import org.jetbrains.kotlin.sir.util.name
|
||||
import org.jetbrains.kotlin.sir.util.returnType
|
||||
|
||||
/**
|
||||
* Description of a Kotlin function for which we are creating the bridge.
|
||||
*
|
||||
* @param function SIR function we are generating bridge for
|
||||
* @param callable SIR function we are generating bridge for
|
||||
* @param bridgeName C name of the bridge
|
||||
*/
|
||||
public class BridgeRequest(
|
||||
public val function: SirFunction,
|
||||
public val callable: SirNativeCallable,
|
||||
public val bridgeName: String,
|
||||
public val fqName: List<String>,
|
||||
)
|
||||
@@ -31,10 +36,11 @@ public class BridgeRequest(
|
||||
*/
|
||||
public fun createFunctionBodyFromRequest(request: BridgeRequest): SirFunctionBody {
|
||||
val callee = request.bridgeName
|
||||
val calleeArguments = request.function.parameters.map { it.argumentName }
|
||||
val calleeArguments = request.callable.allParameters.map { it.name }
|
||||
val callSite = "$callee(${calleeArguments.joinToString(separator = ", ")})"
|
||||
val callStatement = if (request.callable.returnType.isVoid) callSite else "return $callSite"
|
||||
return SirFunctionBody(
|
||||
listOf("return $callSite")
|
||||
listOf(callStatement)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+13
-5
@@ -9,15 +9,15 @@ 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
|
||||
import org.jetbrains.kotlin.sir.util.*
|
||||
|
||||
private const val exportAnnotationFqName = "kotlin.native.internal.ExportedBridge"
|
||||
private const val stdintHeader = "stdint.h"
|
||||
|
||||
internal class BridgeGeneratorImpl : BridgeGenerator {
|
||||
override fun generate(request: BridgeRequest): FunctionBridge {
|
||||
val (kotlinReturnType, cReturnType) = bridgeType(request.function.returnType)
|
||||
val parameterBridges = request.function.parameters.map { bridgeParameter(it) }
|
||||
val (kotlinReturnType, cReturnType) = bridgeType(request.callable.returnType)
|
||||
val parameterBridges = request.callable.allParameters.mapIndexed { index, value -> bridgeParameter(value, index) }
|
||||
|
||||
val cDeclaration = createCDeclaration(request.bridgeName, cReturnType, parameterBridges.map { it.c })
|
||||
val kotlinBridge = createKotlinBridge(request.bridgeName, request.fqName, kotlinReturnType, parameterBridges.map { it.kotlin })
|
||||
@@ -71,6 +71,8 @@ private fun createCDeclaration(bridgeName: String, returnType: CType, parameters
|
||||
private fun bridgeType(type: SirType): Pair<KotlinType, CType> {
|
||||
require(type is SirNominalType)
|
||||
return when (type.type) {
|
||||
SirSwiftModule.void -> (KotlinType.Unit to CType.Void)
|
||||
|
||||
SirSwiftModule.bool -> (KotlinType.Boolean to CType.Bool)
|
||||
|
||||
SirSwiftModule.int8 -> (KotlinType.Byte to CType.Int8)
|
||||
@@ -87,8 +89,10 @@ private fun bridgeType(type: SirType): Pair<KotlinType, CType> {
|
||||
}
|
||||
}
|
||||
|
||||
private fun bridgeParameter(parameter: SirParameter): BridgeParameter {
|
||||
val bridgeParameterName = parameter.argumentName?.let(::createBridgeParameterName) ?: ""
|
||||
private fun bridgeParameter(parameter: SirParameter, index: Int): BridgeParameter {
|
||||
val bridgeParameterName = parameter.name?.let(::createBridgeParameterName) ?: "_$index"
|
||||
// TODO: Remove this check when non-trivial type bridges are supported
|
||||
check(!parameter.type.isVoid) { "The parameter $bridgeParameterName can not have Void type" }
|
||||
val (kotlinType, cType) = bridgeType(parameter.type)
|
||||
return BridgeParameter(
|
||||
KotlinBridgeParameter(bridgeParameterName, kotlinType),
|
||||
@@ -112,6 +116,8 @@ internal data class CBridgeParameter(
|
||||
)
|
||||
|
||||
public enum class CType(public val repr: String) {
|
||||
Void("void"),
|
||||
|
||||
Bool("_Bool"),
|
||||
|
||||
Int8("int8_t"),
|
||||
@@ -131,6 +137,8 @@ internal data class KotlinBridgeParameter(
|
||||
)
|
||||
|
||||
internal enum class KotlinType(val repr: String) {
|
||||
Unit("Unit"),
|
||||
|
||||
Boolean("Boolean"),
|
||||
|
||||
Byte("Byte"),
|
||||
|
||||
+46
-6
@@ -10,6 +10,9 @@ 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.builder.buildGetter
|
||||
import org.jetbrains.kotlin.sir.builder.buildSetter
|
||||
import org.jetbrains.kotlin.sir.builder.buildVariable
|
||||
import org.jetbrains.kotlin.sir.util.SirSwiftModule
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
@@ -86,11 +89,48 @@ private fun readRequestFromFile(file: File): BridgeRequest {
|
||||
)
|
||||
}
|
||||
}
|
||||
val function = buildFunction {
|
||||
this.name = fqName.last()
|
||||
this.returnType = returnType
|
||||
this.parameters += parameters
|
||||
this.isStatic = false
|
||||
|
||||
val kind = BridgeRequestKind.valueOf(properties.getProperty("kind", "FUNCTION"))
|
||||
|
||||
val callable = when (kind) {
|
||||
BridgeRequestKind.FUNCTION -> buildFunction {
|
||||
this.name = fqName.last()
|
||||
this.returnType = returnType
|
||||
this.parameters += parameters
|
||||
this.isStatic = false
|
||||
}
|
||||
BridgeRequestKind.PROPERTY_GETTER -> {
|
||||
val getter = buildGetter()
|
||||
|
||||
getter.parent = buildVariable {
|
||||
this.name = fqName.last()
|
||||
this.type = returnType
|
||||
check(parameters.isEmpty())
|
||||
this.isStatic = false
|
||||
this.getter = getter
|
||||
}
|
||||
|
||||
getter
|
||||
}
|
||||
BridgeRequestKind.PROPERTY_SETTER -> {
|
||||
val setter = buildSetter()
|
||||
|
||||
setter.parent = buildVariable {
|
||||
this.name = fqName.last()
|
||||
this.type = returnType
|
||||
check(parameters.isEmpty())
|
||||
this.isStatic = false
|
||||
this.getter = buildGetter()
|
||||
this.setter = setter
|
||||
}
|
||||
|
||||
setter
|
||||
}
|
||||
}
|
||||
return BridgeRequest(function, bridgeName, fqName)
|
||||
|
||||
return BridgeRequest(callable, bridgeName, fqName)
|
||||
}
|
||||
|
||||
private enum class BridgeRequestKind {
|
||||
FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
_Bool getter_bridge();
|
||||
|
||||
void setter_bridge(_Bool newValue);
|
||||
@@ -0,0 +1,13 @@
|
||||
import kotlin.native.internal.ExportedBridge
|
||||
|
||||
@ExportedBridge("getter_bridge")
|
||||
public fun getter_bridge(): Boolean {
|
||||
val result = variable()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportedBridge("setter_bridge")
|
||||
public fun setter_bridge(newValue: Boolean): Unit {
|
||||
val result = variable(newValue)
|
||||
return result
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fqName=variable
|
||||
kind=PROPERTY_GETTER
|
||||
bridgeName=getter_bridge
|
||||
returnType=boolean
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fqName=variable
|
||||
kind=PROPERTY_SETTER
|
||||
bridgeName=setter_bridge
|
||||
returnType=boolean
|
||||
+6
@@ -42,6 +42,12 @@ public class SirCompilerBridgeTestGenerated extends AbstractKotlinSirBridgeTest
|
||||
runTest("native/swift/sir-compiler-bridge/testData/primitive_types/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("property_accessors")
|
||||
public void testProperty_accessors() throws Exception {
|
||||
runTest("native/swift/sir-compiler-bridge/testData/property_accessors/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smoke0")
|
||||
public void testSmoke0() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user