Skip to content

Commit

Permalink
Allow string template to exceed max line length when it is the only e…
Browse files Browse the repository at this point in the history
…lement on a line (#2480)

Closes #2453
  • Loading branch information
paul-dingemans committed Jan 23, 2024
1 parent 30e8b1d commit 5d9c5bb
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 8 deletions.
8 changes: 5 additions & 3 deletions documentation/snapshot/docs/rules/standard.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`() {
}
Expand All @@ -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"
```


Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)"),
)
}

Expand Down Expand Up @@ -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 =
Expand Down

0 comments on commit 5d9c5bb

Please sign in to comment.