[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:
Gleb Lukianets
2024-02-05 16:29:37 +00:00
committed by Space Team
parent ad5ee28d58
commit f262247b2b
49 changed files with 1172 additions and 72 deletions
@@ -6,13 +6,17 @@
package org.jetbrains.kotlin.sir.analysisapi package org.jetbrains.kotlin.sir.analysisapi
import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
import org.jetbrains.kotlin.psi.psiUtil.isPublic import org.jetbrains.kotlin.psi.psiUtil.isPublic
import org.jetbrains.kotlin.sir.SirDeclaration import org.jetbrains.kotlin.sir.SirDeclaration
import org.jetbrains.kotlin.sir.SirForeignFunction import org.jetbrains.kotlin.sir.SirForeignFunction
import org.jetbrains.kotlin.sir.analysisapi.transformers.toForeignFunction import org.jetbrains.kotlin.sir.analysisapi.transformers.toForeignFunction
import org.jetbrains.kotlin.sir.analysisapi.transformers.toForeignVariable
/** /**
* A root interface for classes that produce Swift IR elements. * A root interface for classes that produce Swift IR elements.
@@ -23,17 +27,25 @@ public interface SirFactory {
public class SirGenerator : SirFactory { public class SirGenerator : SirFactory {
override fun build(fromFile: KtFile): List<SirDeclaration> = analyze(fromFile) { override fun build(fromFile: KtFile): List<SirDeclaration> = analyze(fromFile) {
val res = mutableListOf<SirForeignFunction>() val res = mutableListOf<SirDeclaration>()
fromFile.accept(Visitor(res)) fromFile.accept(Visitor(res))
return res.toList() return res.toList()
} }
private class Visitor(val res: MutableList<SirForeignFunction>) : KtTreeVisitorVoid() { private class Visitor(val res: MutableList<SirDeclaration>) : KtTreeVisitorVoid() {
override fun visitNamedFunction(function: KtNamedFunction) { override fun visitNamedFunction(function: KtNamedFunction) {
super.visitNamedFunction(function) super.visitNamedFunction(function)
function function.process(KtNamedFunction::toForeignFunction)
.takeIf { function.isPublic } }
?.toForeignFunction()
override fun visitProperty(property: KtProperty) {
super.visitProperty(property)
property.process(KtProperty::toForeignVariable)
}
private inline fun <T : KtDeclaration> T.process(converter: T.() -> SirDeclaration) {
this.takeIf { it.isPublic }
?.let(converter)
?.let { res.add(it) } ?.let { res.add(it) }
} }
} }
@@ -44,14 +44,6 @@ private class AAFunction(
get() = originalFunction.docComment?.let { AADocumentation(it) } get() = originalFunction.docComment?.let { AADocumentation(it) }
} }
private data class AAParameter(
override val name: String,
override val type: SirKotlinOrigin.Type
) : SirKotlinOrigin.Parameter
private data class AAKotlinType(
override val name: String
) : SirKotlinOrigin.Type
private data class AADocumentation( private data class AADocumentation(
private val kdoc: KDoc private val kdoc: KDoc
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2024 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.analysisapi.transformers
import org.jetbrains.kotlin.sir.SirKotlinOrigin
internal data class AAParameter(
override val name: String,
override val type: SirKotlinOrigin.Type
) : SirKotlinOrigin.Parameter
internal data class AAKotlinType(
override val name: String
) : SirKotlinOrigin.Type
@@ -0,0 +1,31 @@
/*
* 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.analysisapi.transformers
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildForeignVariable
internal fun KtVariableDeclaration.toForeignVariable(): SirForeignVariable = buildForeignVariable {
origin = AAVariable(this@toForeignVariable)
}
private class AAVariable(
private val original: KtVariableDeclaration
) : SirKotlinOrigin.Property {
override val fqName: FqName
get() = original.fqName ?: FqName.fromSegments(emptyList())
override val type: SirKotlinOrigin.Type
get() = analyze(original) {
AAKotlinType(name = original.getReturnKtType().toString())
}
override val isWriteable: Boolean
get() = original.isVar
}
@@ -5,20 +5,25 @@
package org.jetbrains.kotlin.sir.bridge 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.SirFunctionBody
import org.jetbrains.kotlin.sir.SirNativeCallable
import org.jetbrains.kotlin.sir.bridge.impl.BridgeGeneratorImpl import org.jetbrains.kotlin.sir.bridge.impl.BridgeGeneratorImpl
import org.jetbrains.kotlin.sir.bridge.impl.CBridgePrinter import org.jetbrains.kotlin.sir.bridge.impl.CBridgePrinter
import org.jetbrains.kotlin.sir.bridge.impl.KotlinBridgePrinter 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. * 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 * @param bridgeName C name of the bridge
*/ */
public class BridgeRequest( public class BridgeRequest(
public val function: SirFunction, public val callable: SirNativeCallable,
public val bridgeName: String, public val bridgeName: String,
public val fqName: List<String>, public val fqName: List<String>,
) )
@@ -31,10 +36,11 @@ public class BridgeRequest(
*/ */
public fun createFunctionBodyFromRequest(request: BridgeRequest): SirFunctionBody { public fun createFunctionBodyFromRequest(request: BridgeRequest): SirFunctionBody {
val callee = request.bridgeName 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 callSite = "$callee(${calleeArguments.joinToString(separator = ", ")})"
val callStatement = if (request.callable.returnType.isVoid) callSite else "return $callSite"
return SirFunctionBody( return SirFunctionBody(
listOf("return $callSite") listOf(callStatement)
) )
} }
@@ -9,15 +9,15 @@ import org.jetbrains.kotlin.sir.SirNominalType
import org.jetbrains.kotlin.sir.SirParameter import org.jetbrains.kotlin.sir.SirParameter
import org.jetbrains.kotlin.sir.SirType import org.jetbrains.kotlin.sir.SirType
import org.jetbrains.kotlin.sir.bridge.* 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 exportAnnotationFqName = "kotlin.native.internal.ExportedBridge"
private const val stdintHeader = "stdint.h" private const val stdintHeader = "stdint.h"
internal class BridgeGeneratorImpl : BridgeGenerator { internal class BridgeGeneratorImpl : BridgeGenerator {
override fun generate(request: BridgeRequest): FunctionBridge { override fun generate(request: BridgeRequest): FunctionBridge {
val (kotlinReturnType, cReturnType) = bridgeType(request.function.returnType) val (kotlinReturnType, cReturnType) = bridgeType(request.callable.returnType)
val parameterBridges = request.function.parameters.map { bridgeParameter(it) } val parameterBridges = request.callable.allParameters.mapIndexed { index, value -> bridgeParameter(value, index) }
val cDeclaration = createCDeclaration(request.bridgeName, cReturnType, parameterBridges.map { it.c }) val cDeclaration = createCDeclaration(request.bridgeName, cReturnType, parameterBridges.map { it.c })
val kotlinBridge = createKotlinBridge(request.bridgeName, request.fqName, kotlinReturnType, parameterBridges.map { it.kotlin }) 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> { private fun bridgeType(type: SirType): Pair<KotlinType, CType> {
require(type is SirNominalType) require(type is SirNominalType)
return when (type.type) { return when (type.type) {
SirSwiftModule.void -> (KotlinType.Unit to CType.Void)
SirSwiftModule.bool -> (KotlinType.Boolean to CType.Bool) SirSwiftModule.bool -> (KotlinType.Boolean to CType.Bool)
SirSwiftModule.int8 -> (KotlinType.Byte to CType.Int8) 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 { private fun bridgeParameter(parameter: SirParameter, index: Int): BridgeParameter {
val bridgeParameterName = parameter.argumentName?.let(::createBridgeParameterName) ?: "" 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) val (kotlinType, cType) = bridgeType(parameter.type)
return BridgeParameter( return BridgeParameter(
KotlinBridgeParameter(bridgeParameterName, kotlinType), KotlinBridgeParameter(bridgeParameterName, kotlinType),
@@ -112,6 +116,8 @@ internal data class CBridgeParameter(
) )
public enum class CType(public val repr: String) { public enum class CType(public val repr: String) {
Void("void"),
Bool("_Bool"), Bool("_Bool"),
Int8("int8_t"), Int8("int8_t"),
@@ -131,6 +137,8 @@ internal data class KotlinBridgeParameter(
) )
internal enum class KotlinType(val repr: String) { internal enum class KotlinType(val repr: String) {
Unit("Unit"),
Boolean("Boolean"), Boolean("Boolean"),
Byte("Byte"), Byte("Byte"),
@@ -10,6 +10,9 @@ import org.jetbrains.kotlin.sir.SirNominalType
import org.jetbrains.kotlin.sir.SirParameter import org.jetbrains.kotlin.sir.SirParameter
import org.jetbrains.kotlin.sir.SirType import org.jetbrains.kotlin.sir.SirType
import org.jetbrains.kotlin.sir.builder.buildFunction 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.sir.util.SirSwiftModule
import org.jetbrains.kotlin.test.services.JUnit5Assertions import org.jetbrains.kotlin.test.services.JUnit5Assertions
import org.jetbrains.kotlin.test.util.KtTestUtil import org.jetbrains.kotlin.test.util.KtTestUtil
@@ -86,11 +89,48 @@ private fun readRequestFromFile(file: File): BridgeRequest {
) )
} }
} }
val function = buildFunction {
this.name = fqName.last() val kind = BridgeRequestKind.valueOf(properties.getProperty("kind", "FUNCTION"))
this.returnType = returnType
this.parameters += parameters val callable = when (kind) {
this.isStatic = false 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
}
@@ -0,0 +1,4 @@
fqName=variable
kind=PROPERTY_GETTER
bridgeName=getter_bridge
returnType=boolean
@@ -0,0 +1,4 @@
fqName=variable
kind=PROPERTY_SETTER
bridgeName=setter_bridge
returnType=boolean
@@ -42,6 +42,12 @@ public class SirCompilerBridgeTestGenerated extends AbstractKotlinSirBridgeTest
runTest("native/swift/sir-compiler-bridge/testData/primitive_types/"); 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 @Test
@TestMetadata("smoke0") @TestMetadata("smoke0")
public void testSmoke0() throws Exception { public void testSmoke0() throws Exception {
@@ -7,6 +7,9 @@ package org.jetbrains.sir.passes.translation
import org.jetbrains.kotlin.sir.* import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildFunction 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.sir.util.SirSwiftModule
import org.jetbrains.kotlin.sir.constants.* import org.jetbrains.kotlin.sir.constants.*
import org.jetbrains.kotlin.sir.visitors.SirTransformerVoid import org.jetbrains.kotlin.sir.visitors.SirTransformerVoid
@@ -15,13 +18,9 @@ import java.lang.IllegalStateException
/** /**
* Translates `SirForeignFunction` into `SirFunction`. * Translates `SirForeign*` nodes into their regular "native" counterparts.
* Works only with Nominal Types and top-level functions, currently.
* If received `element` of different type than `SirForeignFunction`,
* or `element` does not contain origin of type `SirOrigin.KotlinEntity.Function`,
* returns original element.
*/ */
public class ForeignIntoSwiftFunctionTranslationPass : SirPass<SirElement, Nothing?, SirDeclaration> { public class ForeignTranslationPass : SirPass<SirElement, Nothing?, SirDeclaration> {
private class Transformer : SirTransformerVoid() { private class Transformer : SirTransformerVoid() {
override fun <E : SirElement> transformElement(element: E): E { override fun <E : SirElement> transformElement(element: E): E {
@@ -29,6 +28,12 @@ public class ForeignIntoSwiftFunctionTranslationPass : SirPass<SirElement, Nothi
return element return element
} }
/**
* Works only with Nominal Types and top-level functions, currently.
* If received `element` of different type than `SirForeignFunction`,
* or `element` does not contain origin of type `SirOrigin.KotlinEntity.Function`,
* returns original element.
*/
override fun transformForeignFunction(function: SirForeignFunction): SirDeclaration { override fun transformForeignFunction(function: SirForeignFunction): SirDeclaration {
val kotlinOrigin = function.origin as? SirKotlinOrigin.Function val kotlinOrigin = function.origin as? SirKotlinOrigin.Function
?: return function ?: return function
@@ -47,6 +52,26 @@ public class ForeignIntoSwiftFunctionTranslationPass : SirPass<SirElement, Nothi
parent = function.parent parent = function.parent
} }
} }
override fun transformForeignVariable(variable: SirForeignVariable): SirDeclaration {
val kotlinOrigin = variable.origin as? SirKotlinOrigin.Property
?: return variable
return buildVariable {
origin = variable.origin
visibility = variable.visibility
isStatic = variable.parent is SirDeclaration
name = kotlinOrigin.path.last()
type = kotlinOrigin.type.toSir()
getter = buildGetter {}
setter = if (kotlinOrigin.isWriteable) buildSetter {} else null
}.also {
it.getter.parent = it
it.setter?.parent = it
}
}
} }
override fun run(element: SirElement, data: Nothing?): SirDeclaration = element.transform(Transformer()) override fun run(element: SirElement, data: Nothing?): SirDeclaration = element.transform(Transformer())
@@ -59,6 +84,7 @@ private fun SirKotlinOrigin.Parameter.toSir(): SirParameter = SirParameter(
private fun SirKotlinOrigin.Type.toSir(): SirType = SirNominalType( private fun SirKotlinOrigin.Type.toSir(): SirType = SirNominalType(
type = when (this.name) { type = when (this.name) {
UNIT -> SirSwiftModule.void
BYTE -> SirSwiftModule.int8 BYTE -> SirSwiftModule.int8
SHORT -> SirSwiftModule.int16 SHORT -> SirSwiftModule.int16
INT -> SirSwiftModule.int32 INT -> SirSwiftModule.int32
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.sir.passes.asserts.assertSirFunctionsEquals
import org.jetbrains.kotlin.sir.passes.mocks.MockSirFunction import org.jetbrains.kotlin.sir.passes.mocks.MockSirFunction
import org.jetbrains.kotlin.sir.passes.util.runWithAsserts import org.jetbrains.kotlin.sir.passes.util.runWithAsserts
import org.jetbrains.kotlin.sir.util.SirSwiftModule import org.jetbrains.kotlin.sir.util.SirSwiftModule
import org.jetbrains.sir.passes.translation.ForeignIntoSwiftFunctionTranslationPass import org.jetbrains.sir.passes.translation.ForeignTranslationPass
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertNotNull import kotlin.test.assertNotNull
@@ -36,7 +36,7 @@ class SirPassTests {
visibility = SirVisibility.PUBLIC visibility = SirVisibility.PUBLIC
} }
mySirElement.parent = module mySirElement.parent = module
val myPass = ForeignIntoSwiftFunctionTranslationPass() val myPass = ForeignTranslationPass()
val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction
assertNotNull(result, "SirFunction should be produced") assertNotNull(result, "SirFunction should be produced")
val exp = MockSirFunction( val exp = MockSirFunction(
@@ -67,7 +67,7 @@ class SirPassTests {
visibility = SirVisibility.PUBLIC visibility = SirVisibility.PUBLIC
} }
mySirElement.parent = mySirEnum mySirElement.parent = mySirEnum
val myPass = ForeignIntoSwiftFunctionTranslationPass() val myPass = ForeignTranslationPass()
val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction
assertNotNull(result, "SirFunction should be produced") assertNotNull(result, "SirFunction should be produced")
val exp = MockSirFunction( val exp = MockSirFunction(
@@ -123,7 +123,7 @@ class SirPassTests {
visibility = SirVisibility.PUBLIC visibility = SirVisibility.PUBLIC
} }
mySirElement.parent = module mySirElement.parent = module
val myPass = ForeignIntoSwiftFunctionTranslationPass() val myPass = ForeignTranslationPass()
val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction
assertNotNull(result, "SirFunction should be produced") assertNotNull(result, "SirFunction should be produced")
val exp = MockSirFunction( val exp = MockSirFunction(
@@ -171,7 +171,7 @@ class SirPassTests {
visibility = SirVisibility.PUBLIC visibility = SirVisibility.PUBLIC
} }
mySirElement.parent = module mySirElement.parent = module
val myPass = ForeignIntoSwiftFunctionTranslationPass() val myPass = ForeignTranslationPass()
val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction
assertNotNull(result, "SirFunction should be produced") assertNotNull(result, "SirFunction should be produced")
val exp = MockSirFunction( val exp = MockSirFunction(
@@ -28,11 +28,54 @@ public class SirAsSwiftSourcesPrinter(private val printer: SmartPrinter) : SirVi
} }
} }
override fun visitVariable(variable: SirVariable): Unit = with(printer) {
print(
variable.visibility.takeIf { it != SirVisibility.INTERNAL }?.let { "${it.swift} " } ?: "",
if (variable.isStatic) "static " else "",
"var ",
variable.name.swiftIdentifier,
": ",
variable.type.swift,
)
println(" {")
withIndent {
variable.getter.accept(this@SirAsSwiftSourcesPrinter)
variable.setter?.accept(this@SirAsSwiftSourcesPrinter)
}
println("}")
}
override fun visitSetter(setter: SirSetter): Unit = with(printer) {
print("set")
setter.body?.let { body ->
println(" {")
withIndent {
printFunctionBody(body).forEach { println(it) }
}
println("}")
} ?: println("")
}
override fun visitGetter(getter: SirGetter): Unit = with(printer) {
print("get")
getter.body?.let { body ->
println(" {")
withIndent {
printFunctionBody(body).forEach { println(it) }
}
println("}")
} ?: println("")
}
override fun visitFunction(function: SirFunction): Unit = with(printer) { override fun visitFunction(function: SirFunction): Unit = with(printer) {
function.documentation?.let { println(it) } function.documentation?.let { println(it) }
print( print(
function.visibility.takeIf { it != SirVisibility.INTERNAL }?.let { "${it.swift} " } ?: "", function.visibility.takeIf { it != SirVisibility.INTERNAL }?.let { "${it.swift} " } ?: "",
if (function.isStatic) { "static " } else { "" }, if (function.isStatic) {
"static "
} else {
""
},
"func ", "func ",
function.name.swiftIdentifier, function.name.swiftIdentifier,
"(" "("
@@ -57,7 +100,7 @@ public class SirAsSwiftSourcesPrinter(private val printer: SmartPrinter) : SirVi
) )
println(" {") println(" {")
withIndent { withIndent {
printFunctionBody(function).forEach { printFunctionBody(function.body).forEach {
println(it) println(it)
} }
} }
@@ -72,15 +115,19 @@ public class SirAsSwiftSourcesPrinter(private val printer: SmartPrinter) : SirVi
println("}") println("}")
} }
override fun visitForeignFunction(function: SirForeignFunction) {} // we do not write foreign nodes // we do not write foreign nodes
override fun visitForeignFunction(function: SirForeignFunction) {}
override fun visitForeignVariable(variable: SirForeignVariable) {}
override fun visitElement(element: SirElement): Unit = with(printer) { override fun visitElement(element: SirElement): Unit = with(printer) {
println("/* ERROR: unsupported element type: " + element.javaClass.simpleName + " */") println("/* ERROR: unsupported element type: " + element.javaClass.simpleName + " */")
} }
} }
private fun printFunctionBody(function: SirFunction): List<String> { private fun printFunctionBody(body: SirFunctionBody?): List<String> {
return function.body?.statements ?: listOf("fatalError()") return body?.statements ?: listOf("fatalError()")
} }
private val SirVisibility.swift private val SirVisibility.swift
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.accessor]
*/
sealed class SirAccessor : SirNativeCallable() {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
abstract var body: SirFunctionBody?
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitAccessor(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformAccessor(this, data) as E
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.foreignVariable]
*/
abstract class SirForeignVariable : SirForeignDeclaration() {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitForeignVariable(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformForeignVariable(this, data) as E
}
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.sir.visitors.SirVisitor
/** /**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.function] * Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.function]
*/ */
abstract class SirFunction : SirElementBase(), SirCallable { abstract class SirFunction : SirNativeCallable() {
abstract override val origin: SirOrigin abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent abstract override var parent: SirDeclarationParent
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.getter]
*/
abstract class SirGetter : SirAccessor() {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
abstract override var body: SirFunctionBody?
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitGetter(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformGetter(this, data) as E
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.nativeCallable]
*/
sealed class SirNativeCallable : SirElementBase(), SirCallable {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitNativeCallable(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformNativeCallable(this, data) as E
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.setter]
*/
abstract class SirSetter : SirAccessor() {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
abstract override var body: SirFunctionBody?
abstract val parameterName: String
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitSetter(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformSetter(this, data) as E
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.variable]
*/
abstract class SirVariable : SirDeclarationParent(), SirDeclaration {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
abstract val name: String
abstract val type: SirType
abstract val getter: SirGetter
abstract val setter: SirSetter?
abstract val isStatic: Boolean
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitVariable(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformVariable(this, data) as E
}
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.sir.SirBuilderDsl
import org.jetbrains.kotlin.sir.SirForeignVariable
import org.jetbrains.kotlin.sir.SirOrigin
import org.jetbrains.kotlin.sir.SirVisibility
import org.jetbrains.kotlin.sir.impl.SirForeignVariableImpl
@SirBuilderDsl
class SirForeignVariableBuilder {
var origin: SirOrigin = SirOrigin.Unknown
var visibility: SirVisibility = SirVisibility.PUBLIC
fun build(): SirForeignVariable {
return SirForeignVariableImpl(
origin,
visibility,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildForeignVariable(init: SirForeignVariableBuilder.() -> Unit = {}): SirForeignVariable {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
return SirForeignVariableBuilder().apply(init).build()
}
@OptIn(ExperimentalContracts::class)
inline fun buildForeignVariableCopy(original: SirForeignVariable, init: SirForeignVariableBuilder.() -> Unit = {}): SirForeignVariable {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
val copyBuilder = SirForeignVariableBuilder()
copyBuilder.origin = original.origin
copyBuilder.visibility = original.visibility
return copyBuilder.apply(init).build()
}
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.impl.SirGetterImpl
@SirBuilderDsl
class SirGetterBuilder {
var origin: SirOrigin = SirOrigin.Unknown
var visibility: SirVisibility = SirVisibility.PUBLIC
var body: SirFunctionBody? = null
fun build(): SirGetter {
return SirGetterImpl(
origin,
visibility,
body,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildGetter(init: SirGetterBuilder.() -> Unit = {}): SirGetter {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
return SirGetterBuilder().apply(init).build()
}
@OptIn(ExperimentalContracts::class)
inline fun buildGetterCopy(original: SirGetter, init: SirGetterBuilder.() -> Unit = {}): SirGetter {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
val copyBuilder = SirGetterBuilder()
copyBuilder.origin = original.origin
copyBuilder.visibility = original.visibility
copyBuilder.body = original.body
return copyBuilder.apply(init).build()
}
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.impl.SirSetterImpl
@SirBuilderDsl
class SirSetterBuilder {
var origin: SirOrigin = SirOrigin.Unknown
var visibility: SirVisibility = SirVisibility.PUBLIC
var body: SirFunctionBody? = null
var parameterName: String = "newValue"
fun build(): SirSetter {
return SirSetterImpl(
origin,
visibility,
body,
parameterName,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildSetter(init: SirSetterBuilder.() -> Unit = {}): SirSetter {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
return SirSetterBuilder().apply(init).build()
}
@OptIn(ExperimentalContracts::class)
inline fun buildSetterCopy(original: SirSetter, init: SirSetterBuilder.() -> Unit = {}): SirSetter {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
val copyBuilder = SirSetterBuilder()
copyBuilder.origin = original.origin
copyBuilder.visibility = original.visibility
copyBuilder.body = original.body
copyBuilder.parameterName = original.parameterName
return copyBuilder.apply(init).build()
}
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.impl.SirVariableImpl
@SirBuilderDsl
class SirVariableBuilder {
var origin: SirOrigin = SirOrigin.Unknown
var visibility: SirVisibility = SirVisibility.PUBLIC
lateinit var name: String
lateinit var type: SirType
lateinit var getter: SirGetter
var setter: SirSetter? = null
var isStatic: Boolean by kotlin.properties.Delegates.notNull<Boolean>()
fun build(): SirVariable {
return SirVariableImpl(
origin,
visibility,
name,
type,
getter,
setter,
isStatic,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildVariable(init: SirVariableBuilder.() -> Unit): SirVariable {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
return SirVariableBuilder().apply(init).build()
}
@OptIn(ExperimentalContracts::class)
inline fun buildVariableCopy(original: SirVariable, init: SirVariableBuilder.() -> Unit): SirVariable {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
val copyBuilder = SirVariableBuilder()
copyBuilder.origin = original.origin
copyBuilder.visibility = original.visibility
copyBuilder.name = original.name
copyBuilder.type = original.type
copyBuilder.getter = original.getter
copyBuilder.setter = original.setter
copyBuilder.isStatic = original.isStatic
return copyBuilder.apply(init).build()
}
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.impl
import org.jetbrains.kotlin.sir.SirDeclarationParent
import org.jetbrains.kotlin.sir.SirForeignVariable
import org.jetbrains.kotlin.sir.SirOrigin
import org.jetbrains.kotlin.sir.SirVisibility
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
internal class SirForeignVariableImpl(
override val origin: SirOrigin,
override val visibility: SirVisibility,
) : SirForeignVariable() {
override lateinit var parent: SirDeclarationParent
override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) {
}
override fun <D> transformChildren(transformer: SirTransformer<D>, data: D) {
}
}
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.impl
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
internal class SirGetterImpl(
override val origin: SirOrigin,
override val visibility: SirVisibility,
override var body: SirFunctionBody?,
) : SirGetter() {
override lateinit var parent: SirDeclarationParent
override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) {
}
override fun <D> transformChildren(transformer: SirTransformer<D>, data: D) {
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.impl
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
internal class SirSetterImpl(
override val origin: SirOrigin,
override val visibility: SirVisibility,
override var body: SirFunctionBody?,
override val parameterName: String,
) : SirSetter() {
override lateinit var parent: SirDeclarationParent
override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) {
}
override fun <D> transformChildren(transformer: SirTransformer<D>, data: D) {
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2024 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.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.impl
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
internal class SirVariableImpl(
override val origin: SirOrigin,
override val visibility: SirVisibility,
override val name: String,
override val type: SirType,
override val getter: SirGetter,
override val setter: SirSetter?,
override val isStatic: Boolean,
) : SirVariable() {
override lateinit var parent: SirDeclarationParent
override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) {
getter.accept(visitor, data)
setter?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: SirTransformer<D>, data: D) {
}
}
@@ -87,6 +87,14 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
return transformCallable(callable, data) return transformCallable(callable, data)
} }
open fun transformNativeCallable(nativeCallable: SirNativeCallable, data: D): SirDeclaration {
return transformCallable(nativeCallable, data)
}
final override fun visitNativeCallable(nativeCallable: SirNativeCallable, data: D): SirDeclaration {
return transformNativeCallable(nativeCallable, data)
}
open fun transformFunction(function: SirFunction, data: D): SirDeclaration { open fun transformFunction(function: SirFunction, data: D): SirDeclaration {
return transformCallable(function, data) return transformCallable(function, data)
} }
@@ -102,4 +110,44 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
final override fun visitForeignFunction(function: SirForeignFunction, data: D): SirDeclaration { final override fun visitForeignFunction(function: SirForeignFunction, data: D): SirDeclaration {
return transformForeignFunction(function, data) return transformForeignFunction(function, data)
} }
open fun transformAccessor(accessor: SirAccessor, data: D): SirDeclaration {
return transformCallable(accessor, data)
}
final override fun visitAccessor(accessor: SirAccessor, data: D): SirDeclaration {
return transformAccessor(accessor, data)
}
open fun transformGetter(getter: SirGetter, data: D): SirDeclaration {
return transformAccessor(getter, data)
}
final override fun visitGetter(getter: SirGetter, data: D): SirDeclaration {
return transformGetter(getter, data)
}
open fun transformSetter(setter: SirSetter, data: D): SirDeclaration {
return transformAccessor(setter, data)
}
final override fun visitSetter(setter: SirSetter, data: D): SirDeclaration {
return transformSetter(setter, data)
}
open fun transformVariable(variable: SirVariable, data: D): SirDeclaration {
return transformDeclaration(variable, data)
}
final override fun visitVariable(variable: SirVariable, data: D): SirDeclaration {
return transformVariable(variable, data)
}
open fun transformForeignVariable(foreignVariable: SirForeignVariable, data: D): SirDeclaration {
return transformDeclaration(foreignVariable, data)
}
final override fun visitForeignVariable(variable: SirForeignVariable, data: D): SirDeclaration {
return transformForeignVariable(variable, data)
}
} }
@@ -68,6 +68,12 @@ abstract class SirTransformerVoid : SirTransformer<Nothing?>() {
final override fun transformCallable(callable: SirCallable, data: Nothing?): SirDeclaration = final override fun transformCallable(callable: SirCallable, data: Nothing?): SirDeclaration =
transformCallable(callable) transformCallable(callable)
open fun transformNativeCallable(nativeCallable: SirNativeCallable): SirDeclaration =
transformCallable(nativeCallable)
final override fun transformNativeCallable(nativeCallable: SirNativeCallable, data: Nothing?): SirDeclaration =
transformNativeCallable(nativeCallable)
open fun transformFunction(function: SirFunction): SirDeclaration = open fun transformFunction(function: SirFunction): SirDeclaration =
transformCallable(function) transformCallable(function)
@@ -79,4 +85,34 @@ abstract class SirTransformerVoid : SirTransformer<Nothing?>() {
final override fun transformForeignFunction(function: SirForeignFunction, data: Nothing?): SirDeclaration = final override fun transformForeignFunction(function: SirForeignFunction, data: Nothing?): SirDeclaration =
transformForeignFunction(function) transformForeignFunction(function)
open fun transformAccessor(accessor: SirAccessor): SirDeclaration =
transformCallable(accessor)
final override fun transformAccessor(accessor: SirAccessor, data: Nothing?): SirDeclaration =
transformAccessor(accessor)
open fun transformGetter(getter: SirGetter): SirDeclaration =
transformAccessor(getter)
final override fun transformGetter(getter: SirGetter, data: Nothing?): SirDeclaration =
transformGetter(getter)
open fun transformSetter(setter: SirSetter): SirDeclaration =
transformAccessor(setter)
final override fun transformSetter(setter: SirSetter, data: Nothing?): SirDeclaration =
transformSetter(setter)
open fun transformVariable(variable: SirVariable): SirDeclaration =
transformDeclaration(variable)
final override fun transformVariable(variable: SirVariable, data: Nothing?): SirDeclaration =
transformVariable(variable)
open fun transformForeignVariable(variable: SirForeignVariable): SirDeclaration =
transformDeclaration(variable)
final override fun transformForeignVariable(variable: SirForeignVariable, data: Nothing?): SirDeclaration =
transformForeignVariable(variable)
} }
@@ -41,9 +41,27 @@ abstract class SirVisitor<out R, in D> {
open fun visitCallable(callable: SirCallable, data: D): R = open fun visitCallable(callable: SirCallable, data: D): R =
visitDeclaration(callable, data) visitDeclaration(callable, data)
open fun visitNativeCallable(nativeCallable: SirNativeCallable, data: D): R =
visitCallable(nativeCallable, data)
open fun visitFunction(function: SirFunction, data: D): R = open fun visitFunction(function: SirFunction, data: D): R =
visitCallable(function, data) visitCallable(function, data)
open fun visitForeignFunction(function: SirForeignFunction, data: D): R = open fun visitForeignFunction(function: SirForeignFunction, data: D): R =
visitCallable(function, data) visitCallable(function, data)
open fun visitAccessor(accessor: SirAccessor, data: D): R =
visitCallable(accessor, data)
open fun visitGetter(getter: SirGetter, data: D): R =
visitAccessor(getter, data)
open fun visitSetter(setter: SirSetter, data: D): R =
visitAccessor(setter, data)
open fun visitVariable(variable: SirVariable, data: D): R =
visitDeclaration(variable, data)
open fun visitForeignVariable(variable: SirForeignVariable, data: D): R =
visitDeclaration(variable, data)
} }
@@ -86,6 +86,14 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
visitDeclaration(callable) visitDeclaration(callable)
} }
final override fun visitNativeCallable(nativeCallable: SirNativeCallable, data: Nothing?) {
visitNativeCallable(nativeCallable)
}
open fun visitNativeCallable(nativeCallable: SirNativeCallable) {
visitCallable(nativeCallable)
}
final override fun visitFunction(function: SirFunction, data: Nothing?) { final override fun visitFunction(function: SirFunction, data: Nothing?) {
visitFunction(function) visitFunction(function)
} }
@@ -101,4 +109,44 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
open fun visitForeignFunction(function: SirForeignFunction) { open fun visitForeignFunction(function: SirForeignFunction) {
visitCallable(function) visitCallable(function)
} }
final override fun visitAccessor(accessor: SirAccessor, data: Nothing?) {
visitAccessor(accessor)
}
open fun visitAccessor(accessor: SirAccessor) {
visitCallable(accessor)
}
final override fun visitGetter(getter: SirGetter, data: Nothing?) {
visitGetter(getter)
}
open fun visitGetter(getter: SirGetter) {
visitAccessor(getter)
}
final override fun visitSetter(setter: SirSetter, data: Nothing?) {
visitSetter(setter)
}
open fun visitSetter(setter: SirSetter) {
visitAccessor(setter)
}
final override fun visitVariable(variable: SirVariable, data: Nothing?) {
visitVariable(variable)
}
open fun visitVariable(variable: SirVariable) {
visitDeclaration(variable)
}
final override fun visitForeignVariable(variable: SirForeignVariable, data: Nothing?) {
visitForeignVariable(variable)
}
open fun visitForeignVariable(variable: SirForeignVariable) {
visitDeclaration(variable)
}
} }
@@ -19,6 +19,11 @@ sealed interface SirKotlinOrigin : SirOrigin.Foreign {
val returnType: Type val returnType: Type
} }
interface Property : SirKotlinOrigin {
val type: Type
val isWriteable: Boolean
}
interface Parameter { interface Parameter {
val name: String val name: String
val type: Type val type: Type
@@ -0,0 +1,19 @@
/*
* 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.constants
private const val KOTLIN_PACKAGE = "kotlin"
private const val DELIMITER = "/"
private const val KOTLIN_BUILTIN_TYPE_PREFIX = "${KOTLIN_PACKAGE}${DELIMITER}"
const val UNIT = "${KOTLIN_BUILTIN_TYPE_PREFIX}Unit"
const val BYTE = "${KOTLIN_BUILTIN_TYPE_PREFIX}Byte"
const val SHORT = "${KOTLIN_BUILTIN_TYPE_PREFIX}Short"
const val INT = "${KOTLIN_BUILTIN_TYPE_PREFIX}Int"
const val LONG = "${KOTLIN_BUILTIN_TYPE_PREFIX}Long"
const val BOOLEAN = "${KOTLIN_BUILTIN_TYPE_PREFIX}Boolean"
const val DOUBLE = "${KOTLIN_BUILTIN_TYPE_PREFIX}Double"
const val FLOAT = "${KOTLIN_BUILTIN_TYPE_PREFIX}Float"
@@ -1,18 +0,0 @@
/*
* 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.constants
private const val KOTLIN_PACKAGE = "kotlin"
private const val DELIMITER = "/"
private const val KOTLIN_NUMERIC_TYPE_PREFIX = "${KOTLIN_PACKAGE}${DELIMITER}"
const val BYTE = "${KOTLIN_NUMERIC_TYPE_PREFIX}Byte"
const val SHORT = "${KOTLIN_NUMERIC_TYPE_PREFIX}Short"
const val INT = "${KOTLIN_NUMERIC_TYPE_PREFIX}Int"
const val LONG = "${KOTLIN_NUMERIC_TYPE_PREFIX}Long"
const val BOOLEAN = "${KOTLIN_NUMERIC_TYPE_PREFIX}Boolean"
const val DOUBLE = "${KOTLIN_NUMERIC_TYPE_PREFIX}Double"
const val FLOAT = "${KOTLIN_NUMERIC_TYPE_PREFIX}Float"
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2024 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.util
import org.jetbrains.kotlin.sir.*
val SirNativeCallable.allParameters: List<SirParameter>
get() = when (this) {
is SirFunction -> this.parameters
is SirSetter -> listOf(SirParameter(parameterName = parameterName, type = this.valueType))
is SirGetter -> listOf()
}
val SirNativeCallable.returnType: SirType
get() = when (this) {
is SirFunction -> this.returnType
is SirGetter -> this.valueType
is SirSetter -> SirNominalType(SirSwiftModule.void)
}
val SirAccessor.valueType: SirType
get() = this.parent.let {
when (it) {
is SirVariable -> it.type
else -> error("Invalid accessor parent $parent")
}
}
val SirVariable.accessors: List<SirAccessor>
get() = listOfNotNull(
getter,
setter,
)
val SirParameter.name: String? get() = parameterName ?: argumentName
val SirType.isVoid: Boolean get() = this is SirNominalType && this.type == SirSwiftModule.void
@@ -20,6 +20,8 @@ object SirSwiftModule : SirModule() {
override val name: String get() = "Swift" override val name: String get() = "Swift"
override val declarations: List<SirDeclaration> by lazy { override val declarations: List<SirDeclaration> by lazy {
listOf( listOf(
void,
bool, bool,
int8, int8,
@@ -52,6 +54,12 @@ object SirSwiftModule : SirModule() {
val double = primitive("Double") val double = primitive("Double")
val float = primitive("Float") val float = primitive("Float")
val void = buildStruct {
origin = SirOrigin.ExternallyDefined(name = "Swift.Void")
visibility = SirVisibility.PUBLIC
name = "Void"
}.also { it.parent = SirSwiftModule }
override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) { override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) {
declarations.forEach { it.accept(visitor, data) } declarations.forEach { it.accept(visitor, data) }
} }
@@ -22,5 +22,9 @@ class BuilderConfigurator(elements: List<Element>) : AbstractSwiftIrTreeBuilderC
configureFieldInAllLeafBuilders("visibility") { configureFieldInAllLeafBuilders("visibility") {
default(it, "SirVisibility.PUBLIC") default(it, "SirVisibility.PUBLIC")
} }
builder(setter) {
default("parameterName", "\"newValue\"")
}
} }
} }
@@ -78,9 +78,15 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
parent(declaration) parent(declaration)
} }
// Denotes "actual" callable node. (I.e. SirCallable & !SIRForeignDeclaration)
// TODO: remove along with foreign declaration (KT-65335); replace usages with just SIRCallable
val nativeCallable by sealedElement {
parent(callable)
}
val function by element { val function by element {
customParentInVisitor = callable customParentInVisitor = callable
parent(callable) parent(nativeCallable)
+field("isStatic", boolean) // todo: KT-65046 Method|function distinction in SIR +field("isStatic", boolean) // todo: KT-65046 Method|function distinction in SIR
+field("name", string) +field("name", string)
@@ -98,4 +104,42 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
visitorParameterName = "function" visitorParameterName = "function"
} }
val accessor by sealedElement {
customParentInVisitor = callable
parent(nativeCallable)
+field("body", functionBodyType, nullable = true, mutable = true)
}
val getter by element {
parent(accessor)
}
val setter by element {
parent(accessor)
+field("parameterName", string, initializer = { })
}
val variable by element {
customParentInVisitor = declaration
parent(declaration)
parent(declarationParent)
+field("name", string)
+field("type", typeType)
+field("getter", getter)
+field("setter", setter, nullable = true)
+field("isStatic", boolean) // todo: KT-65046 Method|function distinction in SIR
}
val foreignVariable by element {
customParentInVisitor = declaration
parent(foreignDeclaration)
visitorParameterName = "variable"
}
} }
@@ -5,8 +5,14 @@
package org.jetbrains.kotlin.swiftexport.standalone.builders package org.jetbrains.kotlin.swiftexport.standalone.builders
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.sir.SirElement import org.jetbrains.kotlin.sir.SirElement
import org.jetbrains.kotlin.sir.SirFunction import org.jetbrains.kotlin.sir.SirFunction
import org.jetbrains.kotlin.sir.SirVariable
import org.jetbrains.kotlin.sir.SirAccessor
import org.jetbrains.kotlin.sir.SirSetter
import org.jetbrains.kotlin.sir.SirGetter
import org.jetbrains.kotlin.sir.util.*
import org.jetbrains.kotlin.sir.SirKotlinOrigin import org.jetbrains.kotlin.sir.SirKotlinOrigin
import org.jetbrains.kotlin.sir.SirModule import org.jetbrains.kotlin.sir.SirModule
import org.jetbrains.kotlin.sir.bridge.BridgeRequest import org.jetbrains.kotlin.sir.bridge.BridgeRequest
@@ -35,11 +41,8 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
override fun visitFunction(function: SirFunction) { override fun visitFunction(function: SirFunction) {
val fqName = (function.origin as? SirKotlinOrigin.Function)?.path val fqName = (function.origin as? SirKotlinOrigin.Function)?.path
?: return ?: return
val fqNameForBridge = if (fqName.count() == 1) { val fqNameForBridge = fqName.forBridge
listOf("__root__", fqName.first()) // todo: should be changed with correct mangling KT-64970
} else {
fqName
}
val bridgeRequest = BridgeRequest( val bridgeRequest = BridgeRequest(
function, function,
fqNameForBridge.joinToString("_"), fqNameForBridge.joinToString("_"),
@@ -48,5 +51,33 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
requests += bridgeRequest requests += bridgeRequest
function.body = createFunctionBodyFromRequest(bridgeRequest) function.body = createFunctionBodyFromRequest(bridgeRequest)
} }
override fun visitVariable(variable: SirVariable) {
val fqName = (variable.origin as? SirKotlinOrigin.Property)?.path?.forBridge
?: return
val fqNameForBridge = fqName.forBridge
variable.accessors.forEach {
val suffix = it.bridgeSuffix
val request = BridgeRequest(
it,
fqNameForBridge.joinToString("_") + "_$suffix",
fqName
)
requests += request
it.body = createFunctionBodyFromRequest(request)
}
}
} }
} }
private val SirAccessor.bridgeSuffix: String get() = when(this) {
is SirGetter -> "get"
is SirSetter -> "set"
}
private val List<String>.forBridge: List<String> get() = if (this.count() == 1) {
listOf("__root__", this.first()) // todo: should be changed with correct mangling KT-64970
} else {
this
}
@@ -13,7 +13,7 @@ import org.jetbrains.sir.passes.SirInflatePackagesPass
import org.jetbrains.sir.passes.SirModulePass import org.jetbrains.sir.passes.SirModulePass
import org.jetbrains.sir.passes.SirPass import org.jetbrains.sir.passes.SirPass
import org.jetbrains.sir.passes.run import org.jetbrains.sir.passes.run
import org.jetbrains.sir.passes.translation.ForeignIntoSwiftFunctionTranslationPass import org.jetbrains.sir.passes.translation.ForeignTranslationPass
internal fun SirModule.transformToSwift(): SirModule { internal fun SirModule.transformToSwift(): SirModule {
return SirPassesConfiguration.passes.fold(this) { module, pass -> return SirPassesConfiguration.passes.fold(this) { module, pass ->
@@ -24,7 +24,7 @@ internal fun SirModule.transformToSwift(): SirModule {
private object SirPassesConfiguration { private object SirPassesConfiguration {
val passes: List<SirModulePass> = listOf( val passes: List<SirModulePass> = listOf(
SirInflatePackagesPass(), SirInflatePackagesPass(),
WholeModuleTranslationByElementPass(ForeignIntoSwiftFunctionTranslationPass()), WholeModuleTranslationByElementPass(ForeignTranslationPass()),
) )
class WholeModuleTranslationByElementPass( class WholeModuleTranslationByElementPass(
@@ -0,0 +1,12 @@
#include <stdint.h>
int32_t namespace_main_foo_get();
int32_t namespace_main_bar_get();
void namespace_main_bar_set(int32_t newValue);
int32_t namespace_main_foobar(int32_t param);
int32_t __root___baz();
@@ -0,0 +1,32 @@
import kotlin.native.internal.ExportedBridge
@ExportedBridge("namespace_main_foo_get")
public fun namespace_main_foo_get(): Int {
val result = namespace.main.foo()
return result
}
@ExportedBridge("namespace_main_bar_get")
public fun namespace_main_bar_get(): Int {
val result = namespace.main.bar()
return result
}
@ExportedBridge("namespace_main_bar_set")
public fun namespace_main_bar_set(newValue: Int): Unit {
val result = namespace.main.bar(newValue)
return result
}
@ExportedBridge("namespace_main_foobar")
public fun namespace_main_foobar(param: Int): Int {
val result = namespace.main.foobar(param)
return result
}
@ExportedBridge("__root___baz")
public fun __root___baz(): Int {
val result = baz()
return result
}
@@ -0,0 +1,26 @@
enum namespace {
enum main {
public static var foo: Swift.Int32 {
get {
return namespace_main_foo_get()
}
}
public static var bar: Swift.Int32 {
get {
return namespace_main_bar_get()
}
set {
namespace_main_bar_set(newValue)
}
}
public static func foobar(
param: Swift.Int32
) -> Swift.Int32 {
return namespace_main_foobar(param)
}
}
}
public func baz() -> Swift.Int32 {
return __root___baz()
}
@@ -0,0 +1,9 @@
package namespace.main
import namespace.*
val foo: Int get() = 10
var bar: Int = 20
fun foobar(param: Int): Int = foo + bar + param + baz
@@ -0,0 +1 @@
fun baz: Int = 30
@@ -35,4 +35,10 @@ public class SwiftExportRunnerTest extends AbstractSwiftRunnerTest {
public void testSimple() throws Exception { public void testSimple() throws Exception {
runTest("native/swift/swift-export-standalone/testData/simple/"); runTest("native/swift/swift-export-standalone/testData/simple/");
} }
@Test
@TestMetadata("variables")
public void testVariables() throws Exception {
runTest("native/swift/swift-export-standalone/testData/variables/");
}
} }