diff --git a/documentation/snapshot/docs/rules/standard.md b/documentation/snapshot/docs/rules/standard.md index 375b5c35d3..0ca3e05656 100644 --- a/documentation/snapshot/docs/rules/standard.md +++ b/documentation/snapshot/docs/rules/standard.md @@ -918,11 +918,14 @@ Ensures that lines do not exceed the maximum length of a line. This rule does no package com.toooooooooooooooooooooooooooo.long import com.tooooooooooooooooooooooooooooo.long - val foo = + val foo1 = """ fooooooooooooooooooooooooooooooooooooooooo """ + val foo2 = + "fooooooooooooooooooooooooooooooooooooooo" + @Test fun `Test description which is toooooooooooo long`() { } @@ -933,9 +936,8 @@ Ensures that lines do not exceed the maximum length of a line. This rule does no // Assume that the last allowed character is // at the X character on the right X val fooooooooooooooo = "fooooooooooooooooooooo" + val foo = "foo" + "ooooooooooooooooooooooooooo" val foooooooooooooo = "foooooooooooooooooooo" // some comment - val fooooooooooooo = - "foooooooooooooooooooooooooooooooooooooooo" ``` diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MaxLineLengthRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MaxLineLengthRule.kt index e52df82544..7b393cac2d 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MaxLineLengthRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MaxLineLengthRule.kt @@ -1,7 +1,7 @@ package com.pinterest.ktlint.ruleset.standard.rules -import com.pinterest.ktlint.rule.engine.core.api.ElementType import com.pinterest.ktlint.rule.engine.core.api.ElementType.IDENTIFIER +import com.pinterest.ktlint.rule.engine.core.api.ElementType.STRING_TEMPLATE import com.pinterest.ktlint.rule.engine.core.api.Rule.VisitorModifier.RunAfterRule.Mode.REGARDLESS_WHETHER_RUN_AFTER_RULE_IS_LOADED_OR_DISABLED import com.pinterest.ktlint.rule.engine.core.api.RuleId import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint @@ -81,6 +81,7 @@ public class MaxLineLengthRule : ?.takeUnless { it.isPartOf(KtImportDirective::class) } ?.takeUnless { it.isPartOf(KDoc::class) } ?.takeUnless { it.isPartOfRawMultiLineString() } + ?.takeUnless { it.isLineOnlyContainingSingleTemplateString() } ?.takeUnless { it.isLineOnlyContainingComment() } ?.let { lastNodeOnLine -> // Calculate the offset at the last possible position at which the newline should be inserted on the line @@ -115,9 +116,21 @@ public class MaxLineLengthRule : } private fun ASTNode.isPartOfRawMultiLineString() = - parent(ElementType.STRING_TEMPLATE, strict = false) + parent(STRING_TEMPLATE, strict = false) ?.let { it.firstChildNode.text == "\"\"\"" && it.textContains('\n') } == true + private fun ASTNode.isLineOnlyContainingSingleTemplateString() = + treeParent + ?.takeIf { it.elementType == STRING_TEMPLATE } + ?.let { stringTemplate -> + stringTemplate + .prevLeaf() + .let { leafBeforeStringTemplate -> + leafBeforeStringTemplate == null || leafBeforeStringTemplate.isWhiteSpaceWithNewline() + } + } + ?: false + private fun ASTNode.isLineOnlyContainingComment() = isPartOf(PsiComment::class) && (prevLeaf() == null || prevLeaf().isWhiteSpaceWithNewline()) diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MaxLineLengthRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MaxLineLengthRuleTest.kt index f27808e15e..6de8d216e0 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MaxLineLengthRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MaxLineLengthRuleTest.kt @@ -20,15 +20,12 @@ class MaxLineLengthRuleTest { // $MAX_LINE_LENGTH_MARKER $EOL_CHAR val fooooooooooooooo = "fooooooooooooooooooooo" val foooooooooooooo = "foooooooooooooooooooo" // some comment - val fooooooooooooo = - "foooooooooooooooooooooooooooooooooooooooo" """.trimIndent() maxLineLengthRuleAssertThat(code) .setMaxLineLength() .hasLintViolationsWithoutAutoCorrect( LintViolation(2, 47, "Exceeded max line length (46)"), LintViolation(3, 47, "Exceeded max line length (46)"), - LintViolation(5, 47, "Exceeded max line length (46)"), ) } @@ -73,6 +70,25 @@ class MaxLineLengthRuleTest { .hasNoLintViolations() } + @Test + fun `Given a single line string which exceeds the max line length, and which has no other non-whitespace elements on the same line then do not return a lint error`() { + val code = + """ + // $MAX_LINE_LENGTH_MARKER $EOL_CHAR + fun foo() { + logger.info { + "fooooooooooooooooooooooooooo" + } + logger.info { + "foo" + "oooooooooooooooooooo" + } + } + """.trimIndent() + maxLineLengthRuleAssertThat(code) + .setMaxLineLength() + .hasLintViolationWithoutAutoCorrect(7, 38, "Exceeded max line length (37)") + } + @Test fun `Given a block comment which exceeds the max line length then do not return a lint error`() { val code =