Skip to content

Commit

Permalink
Enhance generated primary constructor signature for html format (#2313)
Browse files Browse the repository at this point in the history
Fixes #1880
  • Loading branch information
IgnatBeresnev committed Jan 27, 2022
1 parent 066c551 commit 69638c2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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(")")
}
Expand All @@ -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(
Expand Down
Expand Up @@ -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
) {
Expand All @@ -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" } }
}
}
+")"
Expand Down
26 changes: 26 additions & 0 deletions plugins/base/src/test/kotlin/signatures/SignatureTest.kt
Expand Up @@ -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<T>(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 `<T>` expression, an empty `<span class="token keyword"></span>` 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 = \"\"")
Expand Down

0 comments on commit 69638c2

Please sign in to comment.