diff --git a/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/impl/BridgeGeneratorImpl.kt b/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/impl/BridgeGeneratorImpl.kt index 1464312385c..4706d481ff2 100644 --- a/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/impl/BridgeGeneratorImpl.kt +++ b/native/swift/sir-compiler-bridge/src/org/jetbrains/kotlin/sir/bridge/impl/BridgeGeneratorImpl.kt @@ -5,9 +5,7 @@ package org.jetbrains.kotlin.sir.bridge.impl -import org.jetbrains.kotlin.sir.SirNominalType -import org.jetbrains.kotlin.sir.SirParameter -import org.jetbrains.kotlin.sir.SirType +import org.jetbrains.kotlin.sir.* import org.jetbrains.kotlin.sir.bridge.* import org.jetbrains.kotlin.sir.util.* @@ -181,4 +179,3 @@ internal enum class KotlinType(val repr: String) { Float("Float"), Double("Double"), } - diff --git a/native/swift/sir-compiler-bridge/test/org/jetbrains/kotlin/sir/bridge/AbstractKotlinSirBridgeTest.kt b/native/swift/sir-compiler-bridge/test/org/jetbrains/kotlin/sir/bridge/AbstractKotlinSirBridgeTest.kt index e6316e8d97b..fd98b7e993c 100644 --- a/native/swift/sir-compiler-bridge/test/org/jetbrains/kotlin/sir/bridge/AbstractKotlinSirBridgeTest.kt +++ b/native/swift/sir-compiler-bridge/test/org/jetbrains/kotlin/sir/bridge/AbstractKotlinSirBridgeTest.kt @@ -33,9 +33,10 @@ abstract class AbstractKotlinSirBridgeTest { val cBridgePrinter = createCBridgePrinter() requests.forEach { request -> - val bridge = generator.generate(request) - kotlinBridgePrinter.add(bridge) - cBridgePrinter.add(bridge) + generator.generate(request)?.let { + kotlinBridgePrinter.add(it) + cBridgePrinter.add(it) + } } val actualKotlinSrc = kotlinBridgePrinter.print().joinToString(separator = lineSeparator) diff --git a/native/swift/sir-passes/src/org/jetbrains/sir/passes/builder/SirFromPsiBuilder.kt b/native/swift/sir-passes/src/org/jetbrains/sir/passes/builder/SirFromPsiBuilder.kt index de4f8780cd1..7f298cbef41 100644 --- a/native/swift/sir-passes/src/org/jetbrains/sir/passes/builder/SirFromPsiBuilder.kt +++ b/native/swift/sir-passes/src/org/jetbrains/sir/passes/builder/SirFromPsiBuilder.kt @@ -25,7 +25,7 @@ public fun KtAnalysisSession.buildSirDeclarationList(from: KtElement): List, private val checker: PsiToSirTranslation, private val translator: PsiToSirTranslation, + private val isFirstLevel: Boolean = true, ) : KtTreeVisitorVoid() { override fun visitClassOrObject(classOrObject: KtClassOrObject) { - classOrObject.checkAndTranslate(null) + if (isFirstLevel) { + classOrObject.checkAndTranslate(null) + } } override fun visitNamedFunction(function: KtNamedFunction) { @@ -72,7 +75,6 @@ private class PsiToSirTranslatableChecker( override fun visitNamedFunction(function: KtNamedFunction, data: Unit?): Boolean = with(analysisSession) { val functionIsPublicAndTopLevel = function.isPublic - && function.isTopLevel && !function.isAnonymous val functionSymbolIsTranslatable = (function.getFunctionLikeSymbol() as? KtFunctionSymbol) ?.let { symbol -> @@ -87,7 +89,6 @@ private class PsiToSirTranslatableChecker( override fun visitProperty(property: KtProperty, data: Unit?): Boolean { return property.isPublic - && property.isTopLevel } } @@ -110,11 +111,21 @@ private class PsiToSirElementTranslation( context(KtAnalysisSession) internal fun buildSirClassFromPsi(classOrObject: KtClassOrObject): SirNamedDeclaration { - // if there is no symbol - it will be handled by `PsiToSirTranslatableChecker` val symbol = classOrObject.getNamedClassOrObjectSymbol()!! return buildClass { name = classOrObject.name ?: "UNKNOWN_CLASS" // todo: error handling strategy: KT-65980 origin = KotlinSource(symbol) + + classOrObject.acceptChildren( + PsiToSirTranslationCollector( + declarations, + PsiToSirTranslatableChecker(analysisSession), + PsiToSirElementTranslation(analysisSession), + false + ) + ) + }.also { resultedClass -> + resultedClass.declarations.forEach { decl -> decl.parent = resultedClass } } } diff --git a/native/swift/sir-printer/testData/class_with_function.golden.swift b/native/swift/sir-printer/testData/class_with_function.golden.swift new file mode 100644 index 00000000000..fceaccea14a --- /dev/null +++ b/native/swift/sir-printer/testData/class_with_function.golden.swift @@ -0,0 +1,21 @@ +public class Foo { + public func foo( + arg1: Swift.Bool, + arg2: Swift.Int8, + arg3: Swift.Int16, + arg4: Swift.Int32, + arg5: Swift.Int64, + arg6: Swift.Double, + arg7: Swift.Float + ) -> Swift.Bool { + fatalError() + } + public func bar( + arg1: Swift.UInt8, + arg2: Swift.UInt16, + arg3: Swift.UInt32, + arg4: Swift.UInt64 + ) -> Swift.Bool { + fatalError() + } +} \ No newline at end of file diff --git a/native/swift/sir-printer/testData/class_with_variable.golden.swift b/native/swift/sir-printer/testData/class_with_variable.golden.swift new file mode 100644 index 00000000000..46c74dcfa2f --- /dev/null +++ b/native/swift/sir-printer/testData/class_with_variable.golden.swift @@ -0,0 +1,8 @@ +public class Foo { + public var my_variable1: Swift.Bool { + get + } + public var my_variable2: Swift.Int8 { + get + } +} \ No newline at end of file diff --git a/native/swift/sir-printer/tests/org/jetbrains/kotlin/sir/printer/SirAsSwiftSourcesPrinterTests.kt b/native/swift/sir-printer/tests/org/jetbrains/kotlin/sir/printer/SirAsSwiftSourcesPrinterTests.kt index 743fb64a54d..17f1aef6be7 100644 --- a/native/swift/sir-printer/tests/org/jetbrains/kotlin/sir/printer/SirAsSwiftSourcesPrinterTests.kt +++ b/native/swift/sir-printer/tests/org/jetbrains/kotlin/sir/printer/SirAsSwiftSourcesPrinterTests.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.sir.printer import org.jetbrains.kotlin.sir.* -import org.jetbrains.kotlin.sir.builder.buildClass -import org.jetbrains.kotlin.sir.builder.buildEnum -import org.jetbrains.kotlin.sir.builder.buildFunction -import org.jetbrains.kotlin.sir.builder.buildModule +import org.jetbrains.kotlin.sir.builder.* import org.jetbrains.kotlin.sir.util.SirSwiftModule import org.jetbrains.kotlin.test.services.JUnit5Assertions import org.jetbrains.kotlin.test.util.KtTestUtil @@ -372,6 +369,136 @@ class SirAsSwiftSourcesPrinterTests { ) } + @Test + fun `should print class with function`() { + + val module = buildModule { + name = "Test" + declarations.add( + buildClass { + origin = SirOrigin.Unknown + name = "Foo" + + declarations.add( + buildFunction { + origin = SirOrigin.Unknown + kind = SirCallableKind.INSTANCE_METHOD + visibility = SirVisibility.PUBLIC + name = "foo" + parameters.addAll( + listOf( + SirParameter( + argumentName = "arg1", + type = SirNominalType(SirSwiftModule.bool) + ), + SirParameter( + argumentName = "arg2", + type = SirNominalType(SirSwiftModule.int8) + ), + SirParameter( + argumentName = "arg3", + type = SirNominalType(SirSwiftModule.int16) + ), + SirParameter( + argumentName = "arg4", + type = SirNominalType(SirSwiftModule.int32) + ), + SirParameter( + argumentName = "arg5", + type = SirNominalType(SirSwiftModule.int64) + ), + SirParameter( + argumentName = "arg6", + type = SirNominalType(SirSwiftModule.double) + ), + SirParameter( + argumentName = "arg7", + type = SirNominalType(SirSwiftModule.float) + ), + ) + ) + returnType = SirNominalType(SirSwiftModule.bool) + } + ) + + declarations.add( + buildFunction { + origin = SirOrigin.Unknown + kind = SirCallableKind.INSTANCE_METHOD + visibility = SirVisibility.PUBLIC + name = "bar" + parameters.addAll( + listOf( + SirParameter( + argumentName = "arg1", + type = SirNominalType(SirSwiftModule.uint8) + ), + SirParameter( + argumentName = "arg2", + type = SirNominalType(SirSwiftModule.uint16) + ), + SirParameter( + argumentName = "arg3", + type = SirNominalType(SirSwiftModule.uint32) + ), + SirParameter( + argumentName = "arg4", + type = SirNominalType(SirSwiftModule.uint64) + ), + ) + ) + returnType = SirNominalType(SirSwiftModule.bool) + } + ) + } + ) + } + + runTest( + module, + "testData/class_with_function" + ) + } + + @Test + fun `should print class with variable`() { + + val module = buildModule { + name = "Test" + declarations.add( + buildClass { + origin = SirOrigin.Unknown + name = "Foo" + + declarations.add( + buildVariable { + name = "my_variable1" + type = SirNominalType(SirSwiftModule.bool) + getter = buildGetter { + kind = SirCallableKind.INSTANCE_METHOD + } + } + ) + + declarations.add( + buildVariable { + name = "my_variable2" + type = SirNominalType(SirSwiftModule.int8) + getter = buildGetter { + kind = SirCallableKind.INSTANCE_METHOD + } + } + ) + } + ) + } + + runTest( + module, + "testData/class_with_variable" + ) + } + private fun runTest(module: SirModule, goldenDataFile: String) { val expectedSwiftSrc = File(KtTestUtil.getHomeDirectory()).resolve("$goldenDataFile.golden.swift") diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirAccessor.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirAccessor.kt index 93ed99e45cb..fa5f5a815e4 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirAccessor.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirAccessor.kt @@ -19,7 +19,7 @@ sealed class SirAccessor : SirCallable() { abstract override val visibility: SirVisibility abstract override var parent: SirDeclarationParent abstract override val kind: SirCallableKind - abstract var body: SirFunctionBody? + abstract override var body: SirFunctionBody? override fun accept(visitor: SirVisitor, data: D): R = visitor.visitAccessor(this, data) diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirCallable.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirCallable.kt index 2727c978327..650596acb14 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirCallable.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirCallable.kt @@ -19,6 +19,7 @@ sealed class SirCallable : SirElementBase(), SirDeclaration { abstract override val visibility: SirVisibility abstract override var parent: SirDeclarationParent abstract val kind: SirCallableKind + abstract var body: SirFunctionBody? override fun accept(visitor: SirVisitor, data: D): R = visitor.visitCallable(this, data) diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirFunction.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirFunction.kt index 79145037834..f05865d2e34 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirFunction.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirFunction.kt @@ -19,10 +19,10 @@ abstract class SirFunction : SirCallable() { abstract override val visibility: SirVisibility abstract override var parent: SirDeclarationParent abstract override val kind: SirCallableKind + abstract override var body: SirFunctionBody? abstract val name: String abstract val parameters: List abstract val returnType: SirType - abstract var body: SirFunctionBody? abstract var documentation: String? override fun accept(visitor: SirVisitor, data: D): R = diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirFunctionBuilder.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirFunctionBuilder.kt index bccbfbe9b65..3ed038f62b4 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirFunctionBuilder.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirFunctionBuilder.kt @@ -19,10 +19,10 @@ class SirFunctionBuilder { var origin: SirOrigin = SirOrigin.Unknown var visibility: SirVisibility = SirVisibility.PUBLIC lateinit var kind: SirCallableKind + var body: SirFunctionBody? = null lateinit var name: String val parameters: MutableList = mutableListOf() lateinit var returnType: SirType - var body: SirFunctionBody? = null var documentation: String? = null fun build(): SirFunction { @@ -30,10 +30,10 @@ class SirFunctionBuilder { origin, visibility, kind, + body, name, parameters, returnType, - body, documentation, ) } @@ -57,10 +57,10 @@ inline fun buildFunctionCopy(original: SirFunction, init: SirFunctionBuilder.() copyBuilder.origin = original.origin copyBuilder.visibility = original.visibility copyBuilder.kind = original.kind + copyBuilder.body = original.body copyBuilder.name = original.name copyBuilder.parameters.addAll(original.parameters) copyBuilder.returnType = original.returnType - copyBuilder.body = original.body copyBuilder.documentation = original.documentation return copyBuilder.apply(init).build() } diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt index 7f720738b97..5abef96ffe7 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt @@ -18,10 +18,10 @@ internal class SirFunctionImpl( override val origin: SirOrigin, override val visibility: SirVisibility, override val kind: SirCallableKind, + override var body: SirFunctionBody?, override val name: String, override val parameters: MutableList, override val returnType: SirType, - override var body: SirFunctionBody?, override var documentation: String?, ) : SirFunction() { override lateinit var parent: SirDeclarationParent diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt index 55ea1c80282..480f182a600 100644 --- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt @@ -78,6 +78,7 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() { parent(declaration) +field("kind", callableKind) + +field("body", functionBodyType, nullable = true, mutable = true) } val function by element { @@ -87,7 +88,6 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() { +field("name", string) +listField("parameters", parameterType) +field("returnType", typeType) - +field("body", functionBodyType, nullable = true, mutable = true) +field(name = "documentation", string, nullable = true, mutable = true) } @@ -95,8 +95,6 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() { val accessor by sealedElement { customParentInVisitor = callable parent(callable) - - +field("body", functionBodyType, nullable = true, mutable = true) } val getter by element { diff --git a/native/swift/swift-export-standalone/src/org/jetbrains/kotlin/swiftexport/standalone/builders/buildFunctionBridges.kt b/native/swift/swift-export-standalone/src/org/jetbrains/kotlin/swiftexport/standalone/builders/buildFunctionBridges.kt index 6ae603d8ae9..68f7369bd35 100644 --- a/native/swift/swift-export-standalone/src/org/jetbrains/kotlin/swiftexport/standalone/builders/buildFunctionBridges.kt +++ b/native/swift/swift-export-standalone/src/org/jetbrains/kotlin/swiftexport/standalone/builders/buildFunctionBridges.kt @@ -7,19 +7,12 @@ package org.jetbrains.kotlin.swiftexport.standalone.builders import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol -import org.jetbrains.kotlin.analysis.api.symbols.psiSafe -import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.sir.SirElement -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.* import org.jetbrains.kotlin.sir.util.* -import org.jetbrains.kotlin.sir.SirModule import org.jetbrains.kotlin.sir.bridge.BridgeRequest import org.jetbrains.kotlin.sir.bridge.createFunctionBodyFromRequest import org.jetbrains.kotlin.sir.visitors.SirVisitorVoid +import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.sir.passes.SirPass import org.jetbrains.sir.passes.builder.KotlinSource import org.jetbrains.sir.passes.run @@ -46,15 +39,10 @@ private object BridgeGenerationPass : SirPass, +): BridgeRequest? = when (kind) { + SirCallableKind.FUNCTION, + SirCallableKind.STATIC_METHOD, + -> { + val suffix = bridgeSuffix + val request = BridgeRequest( + this, + fqName.forBridge.joinToString("_") + suffix, + fqName + ) + body = createFunctionBodyFromRequest(request) + request + } + SirCallableKind.INSTANCE_METHOD, + SirCallableKind.CLASS_METHOD, + -> { + body = SirFunctionBody(listOf("fatalError()")) + null + } +} + +private val SirCallable.bridgeSuffix: String + get() = when (this) { + is SirAccessor -> "_$bridgeSuffix" + else -> "" + } + private val SirAccessor.bridgeSuffix: String get() = when (this) { is SirGetter -> "get" diff --git a/native/swift/swift-export-standalone/src/org/jetbrains/kotlin/swiftexport/standalone/writer/dumpResultToFiles.kt b/native/swift/swift-export-standalone/src/org/jetbrains/kotlin/swiftexport/standalone/writer/dumpResultToFiles.kt index f0c86065e3c..3830e2a8256 100644 --- a/native/swift/swift-export-standalone/src/org/jetbrains/kotlin/swiftexport/standalone/writer/dumpResultToFiles.kt +++ b/native/swift/swift-export-standalone/src/org/jetbrains/kotlin/swiftexport/standalone/writer/dumpResultToFiles.kt @@ -38,11 +38,12 @@ private fun generateBridgeSources(requests: List): BridgeSources val kotlinBridgePrinter = createKotlinBridgePrinter() val cBridgePrinter = createCBridgePrinter() - requests.forEach { request -> - val bridge = generator.generate(request) - kotlinBridgePrinter.add(bridge) - cBridgePrinter.add(bridge) - } + requests + .map(generator::generate) + .forEach { + kotlinBridgePrinter.add(it) + cBridgePrinter.add(it) + } val actualKotlinSrc = kotlinBridgePrinter.print() val actualCHeader = cBridgePrinter.print() diff --git a/native/swift/swift-export-standalone/testData/classes/golden_result/result.swift b/native/swift/swift-export-standalone/testData/classes/golden_result/result.swift index 76bfad78ec8..a33eade1c0b 100644 --- a/native/swift/swift-export-standalone/testData/classes/golden_result/result.swift +++ b/native/swift/swift-export-standalone/testData/classes/golden_result/result.swift @@ -6,13 +6,61 @@ public enum namespace { public class NAMESPACED_CLASS { } public class Foo { + public func foo() -> Swift.Bool { + fatalError() + } + public var my_value: Swift.UInt32 { + get { + fatalError() + } + } + public var my_variable: Swift.Int64 { + get { + fatalError() + } + set { + fatalError() + } + } } } public class NAMESPACED_CLASS { } public class Foo { + public func foo() -> Swift.Bool { + fatalError() + } + public var my_value: Swift.UInt32 { + get { + fatalError() + } + } + public var my_variable: Swift.Int64 { + get { + fatalError() + } + set { + fatalError() + } + } } } public class Foo { + public func foo() -> Swift.Bool { + fatalError() + } + public var my_value: Swift.UInt32 { + get { + fatalError() + } + } + public var my_variable: Swift.Int64 { + get { + fatalError() + } + set { + fatalError() + } + } } diff --git a/native/swift/swift-export-standalone/testData/classes/input_root/class_with_deeper_package.kt b/native/swift/swift-export-standalone/testData/classes/input_root/class_with_deeper_package.kt index 364e71ff508..e30521a8f66 100644 --- a/native/swift/swift-export-standalone/testData/classes/input_root/class_with_deeper_package.kt +++ b/native/swift/swift-export-standalone/testData/classes/input_root/class_with_deeper_package.kt @@ -4,4 +4,11 @@ class NAMESPACED_CLASS class Foo { class INSIDE_CLASS // this should be ignored currently + + fun foo(): Boolean = TODO() + + val my_value: UInt = 5u + + var my_variable: Long = 5 + } diff --git a/native/swift/swift-export-standalone/testData/classes/input_root/class_with_package.kt b/native/swift/swift-export-standalone/testData/classes/input_root/class_with_package.kt index c771d463cce..2b786c504ef 100644 --- a/native/swift/swift-export-standalone/testData/classes/input_root/class_with_package.kt +++ b/native/swift/swift-export-standalone/testData/classes/input_root/class_with_package.kt @@ -4,4 +4,11 @@ class NAMESPACED_CLASS class Foo { class INSIDE_CLASS // this should be ignored currently + + fun foo(): Boolean = TODO() + + val my_value: UInt = 5u + + var my_variable: Long = 5 + } diff --git a/native/swift/swift-export-standalone/testData/classes/input_root/classes.kt b/native/swift/swift-export-standalone/testData/classes/input_root/classes.kt index 5af7d1aae51..5b2b123b5bb 100644 --- a/native/swift/swift-export-standalone/testData/classes/input_root/classes.kt +++ b/native/swift/swift-export-standalone/testData/classes/input_root/classes.kt @@ -1,4 +1,11 @@ class Foo { class INSIDE_CLASS // this should be ignored currently + + fun foo(): Boolean = TODO() + + val my_value: UInt = 5u + + var my_variable: Long = 5 + }