From f18b40e45d9ac948b43215318641bad41a7f7ffa Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Mon, 28 Sep 2020 09:01:25 +0900 Subject: [PATCH 1/2] ArgumentListWrappingRule: don't report it when line breaks is inside a lambda --- .../experimental/ArgumentListWrappingRule.kt | 11 +--- .../ArgumentListWrappingRuleTest.kt | 57 +++++++++++-------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt index f52b98b199..d3aa6738bf 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt @@ -52,14 +52,14 @@ class ArgumentListWrappingRule : Rule("argument-list-wrapping") { // skip lambda arguments node.treeParent?.elementType != ElementType.FUNCTION_LITERAL && // skip if number of arguments is big (we assume it with a magic number of 8) - node.children().filter { it.elementType == ElementType.VALUE_ARGUMENT }.toList().size <= 8 + node.children().count { it.elementType == ElementType.VALUE_ARGUMENT } <= 8 ) { // each argument should be on a separate line if // - at least one of the arguments is // - maxLineLength exceeded (and separating arguments with \n would actually help) // in addition, "(" and ")" must be on separates line if any of the arguments are (otherwise on the same) val putArgumentsOnSeparateLines = - node.textContainsIgnoringLambda('\n') || + node.children().any { it.isWhiteSpaceWithNewline() } || // max_line_length exceeded maxLineLength > -1 && (node.column - 1 + node.textLength) > maxLineLength if (putArgumentsOnSeparateLines) { @@ -181,13 +181,6 @@ class ArgumentListWrappingRule : Rule("argument-list-wrapping") { else -> throw UnsupportedOperationException() } - private fun ASTNode.textContainsIgnoringLambda(char: Char): Boolean { - return children() - .flatMap { if (it.elementType == ElementType.VALUE_ARGUMENT) it.children() else sequenceOf(it) } - .filter { it.elementType != ElementType.LAMBDA_EXPRESSION } - .any { it.textContains(char) } - } - private fun ASTNode.hasTypeParameterListInFront(): Boolean = treeParent.children() .firstOrNull { it.elementType == ElementType.TYPE_PARAMETER_LIST } diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt index d54c87887a..f4511474b4 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt @@ -135,6 +135,37 @@ class ArgumentListWrappingRuleTest { ).isEmpty() } + @Test + fun testLambdaArgumentsAreIgnored2() { + assertThat( + ArgumentListWrappingRule().lint( + """ + fun main() { + foo(bar.apply { + // stuff + }) + } + """.trimIndent() + ) + ).isEmpty() + } + + @Test + fun testLambdaArgumentsAreIgnored3() { + assertThat( + ArgumentListWrappingRule().lint( + """ + fun main() { + println(Runnable { + println("hello") + println("world") + }) + } + """.trimIndent() + ) + ).isEmpty() + } + @Test fun testFormatWithLambdaArguments() { assertThat( @@ -254,9 +285,9 @@ class ArgumentListWrappingRuleTest { } @Test - fun testFormatPreservesIndentWithAnnotationsOnMultiLine() { + fun testLintPreservesIndentWithAnnotationsOnMultiLine() { assertThat( - ArgumentListWrappingRule().format( + ArgumentListWrappingRule().lint( """ class A { fun f(@Annotation @@ -275,26 +306,6 @@ class ArgumentListWrappingRuleTest { } """.trimIndent() ) - ).isEqualTo( - """ - class A { - fun f(@Annotation - a: Any, - @Annotation( - [ - "v1", - "v2" - ] - ) - b: Any, - c: Any = - false, - @Annotation d: Any, - @SingleLineAnnotation([1, 2]) - e: Any) { - } - } - """.trimIndent() - ) + ).isEmpty() } } From 9337be3f77b51722e30c99a019736f146d20fea9 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Mon, 28 Sep 2020 18:49:33 +0900 Subject: [PATCH 2/2] Undo `testFormatPreservesIndentWithAnnotationsOnMultiLine` --- .../experimental/ArgumentListWrappingRule.kt | 11 +++++++- .../ArgumentListWrappingRuleTest.kt | 26 ++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt index d3aa6738bf..4cfdd7d751 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt @@ -59,7 +59,7 @@ class ArgumentListWrappingRule : Rule("argument-list-wrapping") { // - maxLineLength exceeded (and separating arguments with \n would actually help) // in addition, "(" and ")" must be on separates line if any of the arguments are (otherwise on the same) val putArgumentsOnSeparateLines = - node.children().any { it.isWhiteSpaceWithNewline() } || + node.textContainsIgnoringLambda('\n') || // max_line_length exceeded maxLineLength > -1 && (node.column - 1 + node.textLength) > maxLineLength if (putArgumentsOnSeparateLines) { @@ -181,6 +181,15 @@ class ArgumentListWrappingRule : Rule("argument-list-wrapping") { else -> throw UnsupportedOperationException() } + private fun ASTNode.textContainsIgnoringLambda(char: Char): Boolean { + return children().any { child -> + val elementType = child.elementType + elementType == ElementType.WHITE_SPACE && child.textContains(char) || + elementType == ElementType.COLLECTION_LITERAL_EXPRESSION && child.textContains(char) || + elementType == ElementType.VALUE_ARGUMENT && child.children().any { it.textContainsIgnoringLambda(char) } + } + } + private fun ASTNode.hasTypeParameterListInFront(): Boolean = treeParent.children() .firstOrNull { it.elementType == ElementType.TYPE_PARAMETER_LIST } diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt index f4511474b4..07f6675401 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt @@ -285,9 +285,9 @@ class ArgumentListWrappingRuleTest { } @Test - fun testLintPreservesIndentWithAnnotationsOnMultiLine() { + fun testFormatPreservesIndentWithAnnotationsOnMultiLine() { assertThat( - ArgumentListWrappingRule().lint( + ArgumentListWrappingRule().format( """ class A { fun f(@Annotation @@ -306,6 +306,26 @@ class ArgumentListWrappingRuleTest { } """.trimIndent() ) - ).isEmpty() + ).isEqualTo( + """ + class A { + fun f(@Annotation + a: Any, + @Annotation( + [ + "v1", + "v2" + ] + ) + b: Any, + c: Any = + false, + @Annotation d: Any, + @SingleLineAnnotation([1, 2]) + e: Any) { + } + } + """.trimIndent() + ) } }