diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index 3f8c1703a8..8d97701d6f 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -2,12 +2,12 @@ package org.jetbrains.dokka.base.signatures import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.analysis.DescriptorDocumentableSource import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.dri import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.driOrNull import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder -import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder.DocumentableContentBuilder import org.jetbrains.dokka.links.* import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.Nullable @@ -18,6 +18,8 @@ import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.utilities.DokkaLogger +import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi +import org.jetbrains.kotlin.psi.KtParameter import kotlin.text.Typography.nbsp class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogger) @@ -182,12 +184,23 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog // should be present only if it has parameters. If there are // no parameters, it should result in `class Example` if (pConstructor.parameters.isNotEmpty()) { + val parameterPropertiesByName = c.properties + .filter { it.isAlsoParameter(sourceSet) } + .associateBy { it.name } + punctuation("(") parametersBlock(pConstructor) { param -> annotationsInline(param) + parameterPropertiesByName[param.name]?.let { property -> + property.setter?.let { keyword("var ") } ?: keyword("val ") + } text(param.name.orEmpty()) operator(": ") signatureForProjection(param.type) + param.extra[DefaultValue]?.let { + operator(" = ") + highlightValue(it.value) + } } punctuation(")") } @@ -207,6 +220,13 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog } } + /** + * An example would be a primary constructor `class A(val s: String)`, + * where `s` is both a function parameter and a property + */ + private fun DProperty.isAlsoParameter(sourceSet: DokkaSourceSet) = + (this.sources[sourceSet] as? DescriptorDocumentableSource)?.descriptor?.findPsi() is KtParameter + private fun propertySignature(p: DProperty) = p.sourceSets.map { contentBuilder.contentFor( diff --git a/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt b/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt index 508a0a3693..b6fc4e6ba1 100644 --- a/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt +++ b/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt @@ -122,7 +122,7 @@ class ConstructorsSignaturesTest : BaseAbstractTest() { |/src/main/kotlin/test/source.kt |package test | - |class SomeClass(val a: String) + |class SomeClass(val a: String, var i: Int) | """.trimIndent(), testConfiguration ) { @@ -139,8 +139,13 @@ class ConstructorsSignaturesTest : BaseAbstractTest() { +"(" group { group { - +"a: " // TODO: Make sure if we still do not want to have "val" here + +"val a: " group { link { +"String" } } + +", " + } + group { + +"var i: " + group { link { +"Int" } } } } +")" diff --git a/plugins/base/src/test/kotlin/signatures/SignatureTest.kt b/plugins/base/src/test/kotlin/signatures/SignatureTest.kt index 7ab0f66315..ddf1c89294 100644 --- a/plugins/base/src/test/kotlin/signatures/SignatureTest.kt +++ b/plugins/base/src/test/kotlin/signatures/SignatureTest.kt @@ -744,6 +744,32 @@ class SignatureTest : BaseAbstractTest() { } } + @Test + fun `primary constructor with properties check for all tokens`() { + val writerPlugin = TestOutputWriterPlugin() + + testInline( + """ + |/src/main/kotlin/common/Test.kt + |package example + | + |class PrimaryConstructorClass(val x: Int, var s: String) { } + """.trimMargin(), + configuration, + pluginOverrides = listOf(writerPlugin) + ) { + renderingStage = { _, _ -> + writerPlugin.writer.renderedContent("root/example/-primary-constructor-class/index.html").firstSignature().match( + // In `` expression, an empty `` is present for some reason + Span("class "), A("PrimaryConstructorClass"), Span("<"), Span(), A("T"), Span(">"), Span("("), Parameters( + Parameter(Span("val "), "x", Span(": "), A("Int"), Span(",")), + Parameter(Span("var "), "s", Span(": "), A("String")) + ), Span(")"), Span(), + ) + } + } + } + @Test fun `fun with default values`() { val source = source("fun simpleFun(int: Int = 1, string: String = \"string\"): String = \"\"")