From e0a10c24ea7e623137f2ab21522ed0f84bf59814 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Thu, 27 Jan 2022 12:56:27 +0300 Subject: 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 --- .../SkippingParenthesisForConstructorsTest.kt | 45 +++++-- .../src/test/kotlin/signatures/SignatureTest.kt | 136 +++++++++++++++++---- plugins/base/src/test/kotlin/utils/contentUtils.kt | 54 ++++---- 3 files changed, 177 insertions(+), 58 deletions(-) (limited to 'plugins/base/src/test') diff --git a/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt b/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt index 12160db8..508a0a36 100644 --- a/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt +++ b/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt @@ -98,8 +98,13 @@ class ConstructorsSignaturesTest : BaseAbstractTest() { group { +"class " link { +"SomeClass" } - +"(a: " - group { link { +"String" } } + +"(" + group { + group { + +"a: " + group { link { +"String" } } + } + } +")" } } @@ -131,8 +136,13 @@ class ConstructorsSignaturesTest : BaseAbstractTest() { group { +"class " link { +"SomeClass" } - +"(a: " // TODO: Make sure if we still do not want to have "val" here - group { link { +"String" } } + +"(" + group { + group { + +"a: " // TODO: Make sure if we still do not want to have "val" here + group { link { +"String" } } + } + } +")" } } @@ -165,8 +175,13 @@ class ConstructorsSignaturesTest : BaseAbstractTest() { group { +"class " link { +"SomeClass" } - +"(a: " - group { link { +"String" } } + +"(" + group { + group { + +"a: " + group { link { +"String" } } + } + } +")" } } @@ -227,8 +242,13 @@ class ConstructorsSignaturesTest : BaseAbstractTest() { group { +"class " link { +"SomeClass" } - +"(a: " - group { link { +"String" } } + +"(" + group { + group { + +"a: " + group { link { +"String" } } + } + } +")" } skipAllNotMatching() @@ -243,9 +263,14 @@ class ConstructorsSignaturesTest : BaseAbstractTest() { group { +"fun " link { +"SomeClass" } - +"(a: " + +"(" group { - link { +"String" } + group { + +"a: " + group { + link { +"String" } + } + } } +")" } diff --git a/plugins/base/src/test/kotlin/signatures/SignatureTest.kt b/plugins/base/src/test/kotlin/signatures/SignatureTest.kt index 9ca6a5db..7ab0f663 100644 --- a/plugins/base/src/test/kotlin/signatures/SignatureTest.kt +++ b/plugins/base/src/test/kotlin/signatures/SignatureTest.kt @@ -4,6 +4,7 @@ import org.jetbrains.dokka.DokkaSourceSetID import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest import org.junit.jupiter.api.Test import utils.* +import kotlin.test.assertFalse class SignatureTest : BaseAbstractTest() { private val configuration = dokkaConfiguration { @@ -93,10 +94,12 @@ class SignatureTest : BaseAbstractTest() { ) { renderingStage = { _, _ -> writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match( - "fun ", A("simpleFun"), "(a: ", A("Int"), - ", b: ", A("Boolean"), ", c: ", A("Any"), - "): ", A("String"), Span(), - ignoreSpanWithTokenStyle = true + "fun ", A("simpleFun"), "(", Parameters( + Parameter("a: ", A("Int"), ","), + Parameter("b: ", A("Boolean"), ","), + Parameter("c: ", A("Any")), + ), "): ", A("String"), Span(), + ignoreSpanWithTokenStyle = true ) } } @@ -114,9 +117,10 @@ class SignatureTest : BaseAbstractTest() { ) { renderingStage = { _, _ -> writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match( - "fun ", A("simpleFun"), "(a: (", A("Int"), - ") -> ", A("String"), "): ", A("String"), Span(), - ignoreSpanWithTokenStyle = true + "fun ", A("simpleFun"), "(", Parameters( + Parameter("a: (", A("Int"), ") -> ", A("String")), + ),"): ", A("String"), Span(), + ignoreSpanWithTokenStyle = true ) } } @@ -174,9 +178,11 @@ class SignatureTest : BaseAbstractTest() { ) { renderingStage = { _, _ -> writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match( - "inline suspend fun <", A("T"), " : ", A("String"), "> ", A("simpleFun"), - "(a: ", A("Int"), ", b: ", A("String"), "): ", A("T"), Span(), - ignoreSpanWithTokenStyle = true + "inline suspend fun <", A("T"), " : ", A("String"), "> ", A("simpleFun"), "(", Parameters( + Parameter("a: ", A("Int"), ","), + Parameter("b: ", A("String")), + ), "): ", A("T"), Span(), + ignoreSpanWithTokenStyle = true ) } } @@ -194,8 +200,10 @@ class SignatureTest : BaseAbstractTest() { ) { renderingStage = { _, _ -> writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match( - "fun ", A("simpleFun"), "(vararg params: ", A("Int"), ")", Span(), - ignoreSpanWithTokenStyle = true + "fun ", A("simpleFun"), "(", Parameters( + Parameter("vararg params: ", A("Int")), + ), ")", Span(), + ignoreSpanWithTokenStyle = true ) } } @@ -655,9 +663,11 @@ class SignatureTest : BaseAbstractTest() { pluginOverrides = listOf(writerPlugin) ) { renderingStage = { _, _ -> - writerPlugin.writer.renderedContent("root/kotlinAsJavaPlugin/-a-b-c/some-fun.html").signature().first().match( - "fun ", A("someFun"), "(xd: ", A("XD"), "<", A("Int"), - ", ", A("String"), ">):", A("Int"), Span(), + writerPlugin.writer.renderedContent("root/kotlinAsJavaPlugin/-a-b-c/some-fun.html").signature().first() + .match( + "fun ", A("someFun"), "(", Parameters( + Parameter("xd: ", A("XD"), "<", A("Int"), ", ", A("String"), ">"), + ), "):", A("Int"), Span(), ignoreSpanWithTokenStyle = true ) } @@ -666,8 +676,6 @@ class SignatureTest : BaseAbstractTest() { @Test fun `generic constructor params`() { - - val writerPlugin = TestOutputWriterPlugin() testInline( @@ -694,13 +702,40 @@ class SignatureTest : BaseAbstractTest() { renderingStage = { _, _ -> writerPlugin.writer.renderedContent("root/example/-generic-class/-generic-class.html").signature().zip( listOf( - arrayOf("fun <", A("T"), "> ", A("GenericClass"), "(x: ", A("T"), ")", Span()), - arrayOf("fun ", A("GenericClass"), "(x: ", A("Int"), ", y: ", A("String"), ")", Span()), - arrayOf("fun <", A("T"), "> ", A("GenericClass"), "(x: ", A("Int"), ", y: ", A("List"), "<", A("T"), ">)", Span()), - arrayOf("fun ", A("GenericClass"), "(x: ", A("Boolean"), ", y: ", A("Int"), ", z:", A("String"), ")", Span()), - arrayOf("fun <", A("T"), "> ", A("GenericClass"), "(x: ", A("List"), "<", A("Comparable"), - "<", A("Lazy"), "<", A("T"), ">>>?)", Span()), - arrayOf("fun ", A("GenericClass"), "(x: ", A("Int"), ")", Span()), + arrayOf( + "fun <", A("T"), "> ", A("GenericClass"), "(", Parameters( + Parameter("x: ", A("T")) + ), ")", Span() + ), + arrayOf( + "fun ", A("GenericClass"), "(", Parameters( + Parameter("x: ", A("Int"), ", "), + Parameter("y: ", A("String")) + ), ")", Span() + ), + arrayOf( + "fun <", A("T"), "> ", A("GenericClass"), "(", Parameters( + Parameter("x: ", A("Int"), ", "), + Parameter("y: ", A("List"), "<", A("T"), ">") + ), ")", Span() + ), + arrayOf( + "fun ", A("GenericClass"), "(", Parameters( + Parameter("x: ", A("Boolean"), ", "), + Parameter("y: ", A("Int"), ", "), + Parameter("z:", A("String")) + ), ")", Span() + ), + arrayOf( + "fun <", A("T"), "> ", A("GenericClass"), "(", Parameters( + Parameter("x: ", A("List"), "<", A("Comparable"), "<", A("Lazy"), "<", A("T"), ">>>?") + ), ")", Span() + ), + arrayOf( + "fun ", A("GenericClass"), "(", Parameters( + Parameter("x: ", A("Int")) + ), ")", Span() + ), ) ).forEach { it.first.match(*it.second, ignoreSpanWithTokenStyle = true) @@ -721,14 +756,63 @@ class SignatureTest : BaseAbstractTest() { ) { renderingStage = { _, _ -> writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match( - "fun", A("simpleFun"), "(int: ", A("Int"), " = 1, string: ", A("String"), - " = \"string\"): ", A("String"), Span(), + "fun", A("simpleFun"), "(", Parameters( + Parameter("int: ", A("Int"), " = 1,"), + Parameter("string: ", A("String"), " = \"string\"") + ), "): ", A("String"), Span(), ignoreSpanWithTokenStyle = true ) } } } + @Test + fun `fun with single param should NOT have any wrapped or indented parameters`() { + val source = source("fun assertNoIndent(int: Int): String = \"\"") + val writerPlugin = TestOutputWriterPlugin() + + testInline( + source, + configuration, + pluginOverrides = listOf(writerPlugin) + ) { + renderingStage = { _, _ -> + val signature = writerPlugin.writer.renderedContent("root/example/assert-no-indent.html").firstSignature() + signature.match( + "fun", A("assertNoIndent"), "(", Parameters( + Parameter("int: ", A("Int")), + ), "): ", A("String"), Span(), + ignoreSpanWithTokenStyle = true + ) + assertFalse { signature.select("span.parameters").single().hasClass("wrapped") } + assertFalse { signature.select("span.parameters > span.parameter").single().hasClass("indented") } + } + } + } + + @Test + fun `fun with many params should have wrapped and indented parameters`() { + val source = source("fun assertParamsIndent(int: Int, string: String, long: Long): String = \"\"") + val writerPlugin = TestOutputWriterPlugin() + + testInline( + source, + configuration, + pluginOverrides = listOf(writerPlugin) + ) { + renderingStage = { _, _ -> + writerPlugin.writer.renderedContent("root/example/assert-params-indent.html").firstSignature().match( + "fun", A("assertParamsIndent"), "(", Parameters( + Parameter("int: ", A("Int"), ",").withClasses("indented"), + Parameter("string: ", A("String"), ",").withClasses("indented"), + Parameter("long: ", A("Long")).withClasses("indented") + ).withClasses("wrapped"), "): ", A("String"), Span(), + ignoreSpanWithTokenStyle = true + ) + } + } + } + @Test fun `const val with default values`() { val source = source("const val simpleVal = 1") diff --git a/plugins/base/src/test/kotlin/utils/contentUtils.kt b/plugins/base/src/test/kotlin/utils/contentUtils.kt index be796c89..66e5ef53 100644 --- a/plugins/base/src/test/kotlin/utils/contentUtils.kt +++ b/plugins/base/src/test/kotlin/utils/contentUtils.kt @@ -38,19 +38,24 @@ fun ContentMatcherBuilder<*>.bareSignature( +("${keywords.joinToString("") { "$it " }}fun ") link { +name } +"(" - params.forEachIndexed { id, (n, t) -> + if (params.isNotEmpty()) { + group { + params.forEachIndexed { id, (n, t) -> + group { + t.annotations.forEach { + unwrapAnnotation(it) + } + t.keywords.forEach { + +it + } - t.annotations.forEach { - unwrapAnnotation(it) - } - t.keywords.forEach { - +it + +"$n: " + group { link { +(t.type) } } + if (id != params.lastIndex) + +", " + } + } } - - +"$n: " - group { link { +(t.type) } } - if (id != params.lastIndex) - +", " } +")" if (returnType != null) { @@ -101,19 +106,24 @@ fun ContentMatcherBuilder<*>.bareSignatureWithReceiver( +"." link { +name } +"(" - params.forEachIndexed { id, (n, t) -> + if (params.isNotEmpty()) { + group { + params.forEachIndexed { id, (n, t) -> + group { + t.annotations.forEach { + unwrapAnnotation(it) + } + t.keywords.forEach { + +it + } - t.annotations.forEach { - unwrapAnnotation(it) - } - t.keywords.forEach { - +it + +"$n: " + group { link { +(t.type) } } + if (id != params.lastIndex) + +", " + } + } } - - +"$n: " - group { link { +(t.type) } } - if (id != params.lastIndex) - +", " } +")" if (returnType != null) { -- cgit