From 3e14471d63fa3d8641c1306690ebe9604f7cdb76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brais=20Gab=C3=ADn?= Date: Tue, 2 Aug 2022 09:07:24 +0200 Subject: [PATCH] Add excludesRawStrings in MaxLineLenght --- .../main/resources/default-detekt-config.yml | 1 + .../detekt/rules/style/MaxLineLength.kt | 26 ++++- .../detekt/rules/style/MaxLineLengthSpec.kt | 95 ++++++++----------- 3 files changed, 63 insertions(+), 59 deletions(-) diff --git a/detekt-core/src/main/resources/default-detekt-config.yml b/detekt-core/src/main/resources/default-detekt-config.yml index 934c351e1ec..7be728a345f 100644 --- a/detekt-core/src/main/resources/default-detekt-config.yml +++ b/detekt-core/src/main/resources/default-detekt-config.yml @@ -597,6 +597,7 @@ style: excludePackageStatements: true excludeImportStatements: true excludeCommentStatements: false + excludeRawStrings: true MayBeConst: active: true ModifierOrder: 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 fcc7ba67c1a..4279641f773 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 @@ -13,6 +13,8 @@ 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 +import org.jetbrains.kotlin.psi.KtStringTemplateExpression +import org.jetbrains.kotlin.psi.psiUtil.getParentOfType /** * This rule reports lines of code which exceed a defined maximum line length. @@ -43,6 +45,9 @@ class MaxLineLength(config: Config = Config.empty) : Rule(config) { @Configuration("if comment statements should be ignored") private val excludeCommentStatements: Boolean by config(false) + @Configuration("if comment statements should be ignored") + private val excludeRawStrings: Boolean by config(true) + fun visit(element: KtFileContent) { var offset = 0 val lines = element.content @@ -50,7 +55,7 @@ class MaxLineLength(config: Config = Config.empty) : Rule(config) { for (line in lines) { offset += line.length - if (!isValidLine(line)) { + if (!isValidLine(file, offset, line)) { val ktElement = findFirstMeaningfulKtElementInParents(file, offset, line) if (ktElement != null) { report(CodeSmell(issue, Entity.from(ktElement), issue.description)) @@ -63,15 +68,22 @@ class MaxLineLength(config: Config = Config.empty) : Rule(config) { } } - private fun isValidLine(line: String): Boolean { + private fun isValidLine(file: KtFile, offset: Int, line: String): Boolean { val isUrl = line.lastArgumentMatchesUrl() - return line.length <= maxLineLength || isIgnoredStatement(line) || isUrl + return line.length <= maxLineLength || isIgnoredStatement(file, offset, line) || isUrl } - private fun isIgnoredStatement(line: String): Boolean { + private fun isIgnoredStatement(file: KtFile, offset: Int, line: String): Boolean { return containsIgnoredPackageStatement(line) || containsIgnoredImportStatement(line) || - containsIgnoredCommentStatement(line) + containsIgnoredCommentStatement(line) || + containsIgnoredRawString(file, offset, line) + } + + private fun containsIgnoredRawString(file: KtFile, offset: Int, line: String): Boolean { + if (!excludeRawStrings) return false + + return findKtElementInParents(file, offset, line).lastOrNull()?.isInsideRawString() == true } private fun containsIgnoredPackageStatement(line: String): Boolean { @@ -104,3 +116,7 @@ class MaxLineLength(config: Config = Config.empty) : Rule(config) { } } } + +private fun PsiElement.isInsideRawString(): Boolean { + return this is KtStringTemplateExpression || getParentOfType(false) != null +} 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 b9a814dca7f..867a42111a0 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 @@ -19,10 +19,9 @@ class MaxLineLengthSpec { @Nested inner class `a kt file with some long lines` { - - val file = compileForTest(Case.MaxLineLength.path()) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + private val file = compileForTest(Case.MaxLineLength.path()) + private val lines = file.text.splitToSequence("\n") + private val fileContent = KtFileContent(file, lines) @Test fun `should report no errors when maxLineLength is set to 200`() { @@ -36,6 +35,14 @@ class MaxLineLengthSpec { fun `should report all errors with default maxLineLength`() { val rule = MaxLineLength() + rule.visit(fileContent) + assertThat(rule.findings).hasSize(3) + } + + @Test + fun `should report all errors with default maxLineLength including raw strings`() { + val rule = MaxLineLength(TestConfig("excludeRawStrings" to false)) + rule.visit(fileContent) assertThat(rule.findings).hasSize(7) } @@ -52,10 +59,9 @@ class MaxLineLengthSpec { @Nested inner class `a kt file with long but suppressed lines` { - - val file = compileForTest(Case.MaxLineLengthSuppressed.path()) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + private val file = compileForTest(Case.MaxLineLengthSuppressed.path()) + private val lines = file.text.splitToSequence("\n") + private val fileContent = KtFileContent(file, lines) @Test fun `should not report as lines are suppressed`() { @@ -77,9 +83,9 @@ class MaxLineLengthSpec { } """ - val file = compileContentForTest(code) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + private val file = compileContentForTest(code) + private val lines = file.text.splitToSequence("\n") + private val fileContent = KtFileContent(file, lines) @Test fun `should not report the package statement and import statements by default`() { @@ -115,11 +121,9 @@ class MaxLineLengthSpec { fun `should not report anything if both package and import statements are disabled`() { val rule = MaxLineLength( TestConfig( - mapOf( - MAX_LINE_LENGTH to "60", - EXCLUDE_PACKAGE_STATEMENTS to "true", - EXCLUDE_IMPORT_STATEMENTS to "true" - ) + MAX_LINE_LENGTH to "60", + EXCLUDE_PACKAGE_STATEMENTS to "true", + EXCLUDE_IMPORT_STATEMENTS to "true", ) ) @@ -130,19 +134,14 @@ class MaxLineLengthSpec { @Nested inner class `a kt file with a long package name, long import statements, a long line and long comments` { - - val file = compileForTest(Case.MaxLineLengthWithLongComments.path()) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + private val file = compileForTest(Case.MaxLineLengthWithLongComments.path()) + private val lines = file.text.splitToSequence("\n") + private val fileContent = KtFileContent(file, lines) @Test fun `should report the package statement, import statements, line and comments by default`() { val rule = MaxLineLength( - TestConfig( - mapOf( - MAX_LINE_LENGTH to "60" - ) - ) + TestConfig(MAX_LINE_LENGTH to "60") ) rule.visit(fileContent) @@ -153,12 +152,10 @@ class MaxLineLengthSpec { fun `should report the package statement, import statements, line and comments if they're enabled`() { val rule = MaxLineLength( TestConfig( - mapOf( - MAX_LINE_LENGTH to "60", - EXCLUDE_PACKAGE_STATEMENTS to "false", - EXCLUDE_IMPORT_STATEMENTS to "false", - EXCLUDE_COMMENT_STATEMENTS to "false" - ) + MAX_LINE_LENGTH to "60", + EXCLUDE_PACKAGE_STATEMENTS to "false", + EXCLUDE_IMPORT_STATEMENTS to "false", + EXCLUDE_COMMENT_STATEMENTS to "false", ) ) @@ -194,18 +191,14 @@ class MaxLineLengthSpec { } """.trimIndent() - val file = compileContentForTest(code) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + private val file = compileContentForTest(code) + private val lines = file.text.splitToSequence("\n") + private val fileContent = KtFileContent(file, lines) @Test fun `should only the function line by default`() { val rule = MaxLineLength( - TestConfig( - mapOf( - MAX_LINE_LENGTH to "60" - ) - ) + TestConfig(MAX_LINE_LENGTH to "60") ) rule.visit(fileContent) @@ -216,11 +209,9 @@ class MaxLineLengthSpec { fun `should report the package statement, import statements and line if they're not excluded`() { val rule = MaxLineLength( TestConfig( - mapOf( - MAX_LINE_LENGTH to "60", - EXCLUDE_PACKAGE_STATEMENTS to "false", - EXCLUDE_IMPORT_STATEMENTS to "false" - ) + MAX_LINE_LENGTH to "60", + EXCLUDE_PACKAGE_STATEMENTS to "false", + EXCLUDE_IMPORT_STATEMENTS to "false", ) ) @@ -232,11 +223,9 @@ class MaxLineLengthSpec { fun `should report only method if both package and import statements are disabled`() { val rule = MaxLineLength( TestConfig( - mapOf( - MAX_LINE_LENGTH to "60", - EXCLUDE_PACKAGE_STATEMENTS to "true", - EXCLUDE_IMPORT_STATEMENTS to "true" - ) + MAX_LINE_LENGTH to "60", + EXCLUDE_PACKAGE_STATEMENTS to "true", + EXCLUDE_IMPORT_STATEMENTS to "true", ) ) @@ -248,11 +237,9 @@ class MaxLineLengthSpec { fun `should report correct line and column for function with excessive length`() { val rule = MaxLineLength( TestConfig( - mapOf( - MAX_LINE_LENGTH to "60", - EXCLUDE_PACKAGE_STATEMENTS to "true", - EXCLUDE_IMPORT_STATEMENTS to "true" - ) + MAX_LINE_LENGTH to "60", + EXCLUDE_PACKAGE_STATEMENTS to "true", + EXCLUDE_IMPORT_STATEMENTS to "true", ) )