aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat@beresnev.me>2022-01-27 12:56:27 +0300
committerGitHub <noreply@github.com>2022-01-27 12:56:27 +0300
commite0a10c24ea7e623137f2ab21522ed0f84bf59814 (patch)
treec863973a41efccb4ad34858c88b885e5370b2dbd /plugins/base/src/main
parent7c44db1ef0075e2b80a4723e0747bbf57c32e775 (diff)
downloaddokka-e0a10c24ea7e623137f2ab21522ed0f84bf59814.tar.gz
dokka-e0a10c24ea7e623137f2ab21522ed0f84bf59814.tar.bz2
dokka-e0a10c24ea7e623137f2ab21522ed0f84bf59814.zip
KT-50292 - Implement vertical alignment of parameters (#2309)
* Implement vertical alignment (wrapping) of parameters for kt * Add tests for params wrapping and extend matchers to check for classes * Add distinguishable parameters block to kotlinAsJava, extract common logic * Create a separate Kind for symbol function parameters
Diffstat (limited to 'plugins/base/src/main')
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt15
-rw-r--r--plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt51
-rw-r--r--plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt56
-rw-r--r--plugins/base/src/main/resources/dokka/styles/style.css4
4 files changed, 99 insertions, 27 deletions
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
index 8d258461..2906e8f2 100644
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
@@ -98,6 +98,21 @@ open class HtmlRenderer(
}
node.hasStyle(TextStyle.Span) -> span { childrenCallback() }
node.dci.kind == ContentKind.Symbol -> div("symbol $additionalClasses") { childrenCallback() }
+ node.dci.kind == SymbolContentKind.Parameters -> {
+ span("parameters $additionalClasses") {
+ childrenCallback()
+ }
+ }
+ node.dci.kind == SymbolContentKind.Parameter -> {
+ span("parameter $additionalClasses") {
+ if (node.hasStyle(ContentStyle.Indented)) {
+ // could've been done with CSS (padding-left, ::before, etc), but the indent needs to
+ // consist of physical spaces, otherwise select and copy won't work properly
+ repeat(4) { consumer.onTagContentEntity(Entities.nbsp) }
+ }
+ childrenCallback()
+ }
+ }
node.dci.kind == ContentKind.BriefComment -> div("brief $additionalClasses") { childrenCallback() }
node.dci.kind == ContentKind.Cover -> div("cover $additionalClasses") { //TODO this can be removed
childrenCallback()
diff --git a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt
index 94af96e2..b6841323 100644
--- a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt
+++ b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt
@@ -174,6 +174,57 @@ interface JvmSignatureUtils {
parameters.flatMap { listOf(it.dri) + it.type.drisOfAllNestedBounds })
return t.dri in allDris
}
+
+ /**
+ * Builds a distinguishable [function] parameters block, so that it
+ * can be processed or custom rendered down the road.
+ *
+ * Resulting structure:
+ * ```
+ * SymbolContentKind.Parameters(style = wrapped) {
+ * SymbolContentKind.Parameter(style = indented) { param, }
+ * SymbolContentKind.Parameter(style = indented) { param, }
+ * SymbolContentKind.Parameter(style = indented) { param }
+ * }
+ * ```
+ * Wrapping and indentation of parameters is applied conditionally, see [shouldWrapParams]
+ */
+ fun PageContentBuilder.DocumentableContentBuilder.parametersBlock(
+ function: DFunction, paramBuilder: PageContentBuilder.DocumentableContentBuilder.(DParameter) -> Unit
+ ) {
+ val shouldWrap = function.shouldWrapParams()
+ val parametersStyle = if (shouldWrap) setOf(ContentStyle.Wrapped) else emptySet()
+ val elementStyle = if (shouldWrap) setOf(ContentStyle.Indented) else emptySet()
+ group(kind = SymbolContentKind.Parameters, styles = parametersStyle) {
+ function.parameters.dropLast(1).forEach {
+ group(kind = SymbolContentKind.Parameter, styles = elementStyle) {
+ paramBuilder(it)
+ punctuation(", ")
+ }
+ }
+ group(kind = SymbolContentKind.Parameter, styles = elementStyle) {
+ paramBuilder(function.parameters.last())
+ }
+ }
+ }
+
+ /**
+ * Determines whether parameters in a function (including constructor) should be wrapped
+ *
+ * Without wrapping:
+ * ```
+ * class SimpleClass(foo: String, bar: String) {}
+ * ```
+ * With wrapping:
+ * ```
+ * class SimpleClass(
+ * foo: String,
+ * bar: String,
+ * baz: String
+ * )
+ * ```
+ */
+ private fun DFunction.shouldWrapParams() = this.parameters.size >= 3
}
sealed class AtStrategy
diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
index 47e16e69..3f8c1703 100644
--- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
+++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
@@ -7,15 +7,13 @@ 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
import org.jetbrains.dokka.model.TypeConstructor
import org.jetbrains.dokka.model.properties.WithExtraProperties
-import org.jetbrains.dokka.pages.ContentKind
-import org.jetbrains.dokka.pages.ContentNode
-import org.jetbrains.dokka.pages.TextStyle
-import org.jetbrains.dokka.pages.TokenStyle
+import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
@@ -179,19 +177,19 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
annotationsInline(pConstructor)
keyword("constructor")
}
- list(
- elements = pConstructor.parameters,
- prefix = "(",
- suffix = ")",
- separator = ", ",
- separatorStyles = mainStyles + TokenStyle.Punctuation,
- surroundingCharactersStyle = mainStyles + TokenStyle.Punctuation,
- sourceSets = pConstructor.sourceSets.toSet()
- ) {
- annotationsInline(it)
- text(it.name.orEmpty())
- operator(": ")
- signatureForProjection(it.type)
+
+ // for primary constructor, opening and closing parentheses
+ // should be present only if it has parameters. If there are
+ // no parameters, it should result in `class Example`
+ if (pConstructor.parameters.isNotEmpty()) {
+ punctuation("(")
+ parametersBlock(pConstructor) { param ->
+ annotationsInline(param)
+ text(param.name.orEmpty())
+ operator(": ")
+ signatureForProjection(param.type)
+ }
+ punctuation(")")
}
}
}
@@ -283,17 +281,21 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
punctuation(".")
}
link(f.name, f.dri, styles = mainStyles + TokenStyle.Function)
+
+ // for a function, opening and closing parentheses must be present
+ // anyway, even if it has no parameters, resulting in `fun test(): R`
punctuation("(")
- list(f.parameters,
- separatorStyles = mainStyles + TokenStyle.Punctuation) {
- annotationsInline(it)
- processExtraModifiers(it)
- text(it.name!!)
- operator(": ")
- signatureForProjection(it.type)
- it.extra[DefaultValue]?.run {
- operator(" = ")
- highlightValue(value)
+ if (f.parameters.isNotEmpty()) {
+ parametersBlock(f) { param ->
+ annotationsInline(param)
+ processExtraModifiers(param)
+ text(param.name!!)
+ operator(": ")
+ signatureForProjection(param.type)
+ param.extra[DefaultValue]?.run {
+ operator(" = ")
+ highlightValue(value)
+ }
}
}
punctuation(")")
diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css
index ad28e895..cc8b6823 100644
--- a/plugins/base/src/main/resources/dokka/styles/style.css
+++ b/plugins/base/src/main/resources/dokka/styles/style.css
@@ -886,6 +886,10 @@ td.content {
padding-bottom: 0;
}
+.parameters.wrapped > .parameter {
+ display: block;
+}
+
.table-row .with-platform-tabs .sourceset-depenent-content .brief {
padding: 8px;
}