diff --git a/native/swift/sir-analysis-api/src/org/jetbrains/kotlin/sir/analysisapi/transformers/NamedFunction.kt b/native/swift/sir-analysis-api/src/org/jetbrains/kotlin/sir/analysisapi/transformers/NamedFunction.kt index e5fab381af7..0b9b71030a2 100644 --- a/native/swift/sir-analysis-api/src/org/jetbrains/kotlin/sir/analysisapi/transformers/NamedFunction.kt +++ b/native/swift/sir-analysis-api/src/org/jetbrains/kotlin/sir/analysisapi/transformers/NamedFunction.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.sir.analysisapi.transformers import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol +import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.sir.* @@ -39,6 +40,9 @@ private class AAFunction( AAKotlinType(name = function.returnType.toString()) } + override val documentation: SirKotlinOrigin.Documentation? + get() = originalFunction.docComment?.let { AADocumentation(it) } + } private data class AAParameter( override val name: String, @@ -48,3 +52,10 @@ private data class AAParameter( private data class AAKotlinType( override val name: String ) : SirKotlinOrigin.Type + +private data class AADocumentation( + private val kdoc: KDoc +) : SirKotlinOrigin.Documentation { + override val content: String + get() = kdoc.text +} diff --git a/native/swift/sir-analysis-api/testData/function_with_comment.kt b/native/swift/sir-analysis-api/testData/function_with_comment.kt new file mode 100644 index 00000000000..ab747a41d40 --- /dev/null +++ b/native/swift/sir-analysis-api/testData/function_with_comment.kt @@ -0,0 +1,8 @@ +/** + * Function foo description + * + * @param p first Integer to consume + * @param p2 second Double to consume + * @return Short, constant 1 + */ +fun foo(p: Int, p2: Double): Short = 1 diff --git a/native/swift/sir-analysis-api/testData/function_with_comment.sir b/native/swift/sir-analysis-api/testData/function_with_comment.sir new file mode 100644 index 00000000000..378e5399490 --- /dev/null +++ b/native/swift/sir-analysis-api/testData/function_with_comment.sir @@ -0,0 +1 @@ +[foo] commented \ No newline at end of file diff --git a/native/swift/sir-analysis-api/tests-gen/org/jetbrains/kotlin/sir/analysisapi/SirAnalysisGeneratedTests.java b/native/swift/sir-analysis-api/tests-gen/org/jetbrains/kotlin/sir/analysisapi/SirAnalysisGeneratedTests.java index 37e21e6acc7..5289903e099 100644 --- a/native/swift/sir-analysis-api/tests-gen/org/jetbrains/kotlin/sir/analysisapi/SirAnalysisGeneratedTests.java +++ b/native/swift/sir-analysis-api/tests-gen/org/jetbrains/kotlin/sir/analysisapi/SirAnalysisGeneratedTests.java @@ -24,6 +24,12 @@ public class SirAnalysisGeneratedTests extends AbstractKotlinSirContextTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/sir-analysis-api/testData"), Pattern.compile("^(.+)\\.kt$"), null, false); } + @Test + @TestMetadata("function_with_comment.kt") + public void testFunction_with_comment() throws Exception { + runTest("native/swift/sir-analysis-api/testData/function_with_comment.kt"); + } + @Test @TestMetadata("functions_overload.kt") public void testFunctions_overload() throws Exception { diff --git a/native/swift/sir-analysis-api/tests/org/jetbrains/kotlin/sir/analysisapi/AbstractKotlinSirContextTest.kt b/native/swift/sir-analysis-api/tests/org/jetbrains/kotlin/sir/analysisapi/AbstractKotlinSirContextTest.kt index 0957e7912aa..0b24fae8bf5 100644 --- a/native/swift/sir-analysis-api/tests/org/jetbrains/kotlin/sir/analysisapi/AbstractKotlinSirContextTest.kt +++ b/native/swift/sir-analysis-api/tests/org/jetbrains/kotlin/sir/analysisapi/AbstractKotlinSirContextTest.kt @@ -43,9 +43,11 @@ abstract class AbstractKotlinSirContextTestBase : AbstractAnalysisApiBasedTest() val actual = buildString { module.declarations .filterIsInstance() - .forEach { - val function = it.origin as SirKotlinOrigin.Function - appendLine("${function.path}") + .forEach { sirForeignFunction -> + val function = sirForeignFunction.origin as SirKotlinOrigin.Function + val functionPath = "${function.path}" + val isCommented = function.documentation?.let { " commented" } ?: "" + appendLine("$functionPath$isCommented") } } diff --git a/native/swift/sir-passes/src/org/jetbrains/sir/passes/translation/ForeignIntoSwiftFunctionTranslationPass.kt b/native/swift/sir-passes/src/org/jetbrains/sir/passes/translation/ForeignIntoSwiftFunctionTranslationPass.kt index d965e95236a..864115ce5a4 100644 --- a/native/swift/sir-passes/src/org/jetbrains/sir/passes/translation/ForeignIntoSwiftFunctionTranslationPass.kt +++ b/native/swift/sir-passes/src/org/jetbrains/sir/passes/translation/ForeignIntoSwiftFunctionTranslationPass.kt @@ -41,6 +41,8 @@ public class ForeignIntoSwiftFunctionTranslationPass : SirPass, override val returnType: SirType, + override var documentation: String? = null, ) : SirFunction() { override fun acceptChildren(visitor: SirVisitor, data: D) = Unit override fun transformChildren(transformer: SirTransformer, data: D) = Unit diff --git a/native/swift/sir-printer/src/org/jetbrains/sir/printer/SirAsSwiftSourcesPrinter.kt b/native/swift/sir-printer/src/org/jetbrains/sir/printer/SirAsSwiftSourcesPrinter.kt index 29c6c55f554..95a68b0cb7e 100644 --- a/native/swift/sir-printer/src/org/jetbrains/sir/printer/SirAsSwiftSourcesPrinter.kt +++ b/native/swift/sir-printer/src/org/jetbrains/sir/printer/SirAsSwiftSourcesPrinter.kt @@ -29,6 +29,7 @@ public class SirAsSwiftSourcesPrinter(private val printer: SmartPrinter) : SirVi } override fun visitFunction(function: SirFunction): Unit = with(printer) { + function.documentation?.let { println(it) } print( function.visibility.takeIf { it != SirVisibility.INTERNAL }?.let { "${it.swift} " } ?: "", if (function.isStatic) { "static " } else { "" }, diff --git a/native/swift/sir-printer/testData/commented_function.golden.swift b/native/swift/sir-printer/testData/commented_function.golden.swift new file mode 100644 index 00000000000..1dbfd82aa69 --- /dev/null +++ b/native/swift/sir-printer/testData/commented_function.golden.swift @@ -0,0 +1,10 @@ + +/// Function foo description. +/// - Parameters: +/// - p: first Integer to consume +/// - Returns: Bool +public func foo( + p: Swift.Int64 +) -> Swift.Bool { + fatalError() +} 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 01e901e5cd1..a3194355583 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 @@ -255,6 +255,40 @@ class SirAsSwiftSourcesPrinterTests { ) } + @Test + fun `should print DocC comment`() { + + val module = buildModule { + name = "Test" + declarations.add( + buildFunction { + origin = SirOrigin.Unknown + isStatic = false + visibility = SirVisibility.PUBLIC + name = "foo" + parameters.add( + SirParameter( + argumentName = "p", + type = SirNominalType(SirSwiftModule.int64) + ) + ) + returnType = SirNominalType(SirSwiftModule.bool) + documentation = """ + /// Function foo description. + /// - Parameters: + /// - p: first Integer to consume + /// - Returns: Bool + """.trimIndent() + } + ) + } + + runTest( + module, + "testData/commented_function" + ) + } + 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/SirFunction.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirFunction.kt index 00bf37ee08a..03a143ed122 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirFunction.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirFunction.kt @@ -23,6 +23,7 @@ abstract class SirFunction : SirElementBase(), SirCallable { abstract val parameters: List abstract val returnType: SirType abstract var body: SirFunctionBody? + abstract var documentation: String? override fun accept(visitor: SirVisitor, data: D): R = visitor.visitFunction(this, data) 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 722e2487337..8852f9ca8f6 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 @@ -23,6 +23,7 @@ class SirFunctionBuilder { val parameters: MutableList = mutableListOf() lateinit var returnType: SirType var body: SirFunctionBody? = null + var documentation: String? = null fun build(): SirFunction { return SirFunctionImpl( @@ -33,6 +34,7 @@ class SirFunctionBuilder { parameters, returnType, body, + documentation, ) } @@ -59,5 +61,6 @@ inline fun buildFunctionCopy(original: SirFunction, init: SirFunctionBuilder.() 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 01564f8ab75..096328ec6e5 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 @@ -22,6 +22,7 @@ internal class SirFunctionImpl( 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/src/org/jetbrains/kotlin/sir/SirKotlinOrigin.kt b/native/swift/sir/src/org/jetbrains/kotlin/sir/SirKotlinOrigin.kt index 062b1cf1066..b24d4666999 100644 --- a/native/swift/sir/src/org/jetbrains/kotlin/sir/SirKotlinOrigin.kt +++ b/native/swift/sir/src/org/jetbrains/kotlin/sir/SirKotlinOrigin.kt @@ -14,6 +14,7 @@ sealed interface SirKotlinOrigin : SirOrigin.Foreign { get() = fqName.pathSegments().map { it.asString() } interface Function : SirKotlinOrigin { + val documentation: Documentation? val parameters: List val returnType: Type } @@ -26,4 +27,8 @@ sealed interface SirKotlinOrigin : SirOrigin.Foreign { interface Type { val name: String } + + interface Documentation { + val content: String + } } diff --git a/native/swift/sir/tests/org/jetbrains/kotlin/sir/mock/KotlinEntity.kt b/native/swift/sir/tests/org/jetbrains/kotlin/sir/mock/KotlinEntity.kt index b36578c2ef4..4d589905c8b 100644 --- a/native/swift/sir/tests/org/jetbrains/kotlin/sir/mock/KotlinEntity.kt +++ b/native/swift/sir/tests/org/jetbrains/kotlin/sir/mock/KotlinEntity.kt @@ -7,11 +7,13 @@ package org.jetbrains.kotlin.sir.mock import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.sir.SirKotlinOrigin +import org.jetbrains.kotlin.sir.SirOrigin data class MockFunction( override val fqName: FqName, override val parameters: List, override val returnType: SirKotlinOrigin.Type, + override val documentation: SirKotlinOrigin.Documentation? = null, ) : SirKotlinOrigin.Function data class MockParameter( @@ -22,3 +24,5 @@ data class MockParameter( data class MockKotlinType( override val name: String ) : SirKotlinOrigin.Type + +data class MockDocumentation(override val content: String) : SirKotlinOrigin.Documentation diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt index bcd531ce486..05ada428eb1 100644 --- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Main.kt @@ -17,7 +17,7 @@ typealias Model = org.jetbrains.kotlin.generators.tree.Model fun main(args: Array) { val generationPath = args.firstOrNull()?.let { File(it) } - ?: File("../../tree/gen").canonicalFile + ?: File("./native/swift/sir/gen/").canonicalFile val model = SwiftIrTree.build() generateTree( generationPath, 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 4d1a3c5db98..43e3da239d9 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 @@ -87,6 +87,8 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() { +listField("parameters", parameterType) +field("returnType", typeType) +field("body", functionBodyType, nullable = true, mutable = true) + + +field(name = "documentation", string, nullable = true, mutable = true) } val foreignFunction by element { @@ -96,4 +98,4 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() { visitorParameterName = "function" } -} \ No newline at end of file +}