Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MaxLineLength] Fix signature in for blank characters in the Baseline #4504

Merged
merged 1 commit into from Jan 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -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<PsiElement> {
return file.elementsInRange(TextRange.create(offset - line.length, offset))
.asSequence()
.plus(file.findElementAt(offset))
.mapNotNull { it?.getNonStrictParentOfType() }
.firstOrNull()
}
Expand Up @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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) }
}
}
}
Expand Up @@ -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.
Expand All @@ -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(
Expand All @@ -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()
}
}
Expand Up @@ -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
marschwar marked this conversation as resolved.
Show resolved Hide resolved

private const val MAX_LINE_LENGTH = "maxLineLength"
private const val EXCLUDE_PACKAGE_STATEMENTS = "excludePackageStatements"
Expand Down Expand Up @@ -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() }
}
}

Expand Down
12 changes: 9 additions & 3 deletions detekt-rules-style/src/test/resources/MaxLineLength.kt
Expand Up @@ -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"

Expand Down