From a6a26142c54d86ff415ebe210d4b2a2e5ca82a6f Mon Sep 17 00:00:00 2001 From: marschwar Date: Sun, 30 Jan 2022 14:36:33 +0100 Subject: [PATCH] [MaxLineLength] Fix signature in for blank characters in the Baseline (#4504) --- .../io/gitlab/arturbosch/detekt/rules/style/Junk.kt | 6 +++--- .../arturbosch/detekt/rules/style/MaxLineLength.kt | 10 +++++++++- .../detekt/rules/style/TrailingWhitespace.kt | 9 ++++++++- .../detekt/rules/style/MaxLineLengthSpec.kt | 11 ++++++++++- .../src/test/resources/MaxLineLength.kt | 12 +++++++++--- 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/Junk.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/Junk.kt index acbb900d8..30530eb4b 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/Junk.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/Junk.kt @@ -8,12 +8,12 @@ import org.jetbrains.kotlin.psi.psiUtil.elementsInRange import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType /** - * Util function to search for the first [KtElement] in the parents of + * Util function to search for the [KtElement]s in the parents of * the given [line] from a given offset in a [KtFile]. */ -internal fun findFirstKtElementInParents(file: KtFile, offset: Int, line: String): PsiElement? { +internal fun findKtElementInParents(file: KtFile, offset: Int, line: String): Sequence { return file.elementsInRange(TextRange.create(offset - line.length, offset)) + .asSequence() .plus(file.findElementAt(offset)) .mapNotNull { it?.getNonStrictParentOfType() } - .firstOrNull() } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLength.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLength.kt index be2e64521..e1c29b653 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLength.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLength.kt @@ -11,6 +11,8 @@ import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.rules.lastArgumentMatchesUrl +import org.jetbrains.kotlin.com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtFile /** * This rule reports lines of code which exceed a defined maximum line length. @@ -49,7 +51,7 @@ class MaxLineLength(config: Config = Config.empty) : Rule(config) { for (line in lines) { offset += line.length if (!isValidLine(line)) { - val ktElement = findFirstKtElementInParents(file, offset, line) + val ktElement = findFirstMeaningfulKtElementInParents(file, offset, line) if (ktElement != null) { report(CodeSmell(issue, Entity.from(ktElement), issue.description)) } else { @@ -94,5 +96,11 @@ class MaxLineLength(config: Config = Config.empty) : Rule(config) { companion object { private const val DEFAULT_IDEA_LINE_LENGTH = 120 + private val BLANK_OR_QUOTES = """[\s\"]*""".toRegex() + + private fun findFirstMeaningfulKtElementInParents(file: KtFile, offset: Int, line: String): PsiElement? { + return findKtElementInParents(file, offset, line) + .firstOrNull { !BLANK_OR_QUOTES.matches(it.text) } + } } } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespace.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespace.kt index 861bd84d6..dc0b93d72 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespace.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespace.kt @@ -8,6 +8,8 @@ import io.gitlab.arturbosch.detekt.api.Issue import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.rules.isPartOfString +import org.jetbrains.kotlin.com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtFile /** * This rule reports lines that end with a whitespace. @@ -28,7 +30,7 @@ class TrailingWhitespace(config: Config = Config.empty) : Rule(config) { val trailingWhitespaces = countTrailingWhitespace(line) if (trailingWhitespaces > 0) { val file = fileContent.file - val ktElement = findFirstKtElementInParents(file, offset, line) + val ktElement = findFirstKtElementInParentsOrNull(file, offset, line) if (ktElement == null || !ktElement.isPartOfString()) { val entity = Entity.from(file, offset - trailingWhitespaces).let { entity -> entity.copy( @@ -49,4 +51,9 @@ class TrailingWhitespace(config: Config = Config.empty) : Rule(config) { } private fun createMessage(line: Int) = "Line ${line + 1} ends with a whitespace." + + private fun findFirstKtElementInParentsOrNull(file: KtFile, offset: Int, line: String): PsiElement? { + return findKtElementInParents(file, offset, line) + .firstOrNull() + } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt index 21a1dafd3..38aaaeaca 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt @@ -8,6 +8,7 @@ import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.assertThat import org.spekframework.spek2.Spek import org.spekframework.spek2.style.specification.describe +import org.assertj.core.api.Assertions.assertThat as doAssert private const val MAX_LINE_LENGTH = "maxLineLength" private const val EXCLUDE_PACKAGE_STATEMENTS = "excludePackageStatements" @@ -35,7 +36,15 @@ class MaxLineLengthSpec : Spek({ val rule = MaxLineLength() rule.visit(fileContent) - assertThat(rule.findings).hasSize(6) + assertThat(rule.findings).hasSize(7) + } + + it("should report meaningful signature for all violations") { + val rule = MaxLineLength() + + rule.visit(fileContent) + val locations = rule.findings.map { it.signature.substringAfterLast('$') } + doAssert(locations).allSatisfy { doAssert(it).isNotBlank() } } } diff --git a/detekt-rules-style/src/test/resources/MaxLineLength.kt b/detekt-rules-style/src/test/resources/MaxLineLength.kt index eddcbd39b..567a10073 100644 --- a/detekt-rules-style/src/test/resources/MaxLineLength.kt +++ b/detekt-rules-style/src/test/resources/MaxLineLength.kt @@ -6,24 +6,30 @@ class MaxLineLength { val LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." val A_VERY_LONG_MULTI_LINE = """ - This is anotehr very very very very very very very very, very long multiline String that will break the MaxLineLength" + This is another very very very very very very very very, very long multiline String that will break the MaxLineLength" """.trimIndent() } val loremIpsumField = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." val longMultiLineField = """ - This is anotehr very very very very very very very very + This is another very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long multiline String that will break the MaxLineLength """.trimIndent() val longMultiLineFieldWithLineBreaks = """ - This is anotehr very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very + This is another very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long multiline String with Line Break that will break the MaxLineLength """.trimIndent() + val longMultiLineFieldWithLeadingQuote = + """ + "This is yet another very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very" + "very long multiline String with Line Break that will break the MaxLineLength" + """.trimIndent() + fun main() { val thisIsAVeryLongValName = "This is a very, very long String that will break the MaxLineLength"