diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt index 4cac91362d4..0a76a87c3a4 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt @@ -30,8 +30,11 @@ internal fun PsiElement.searchName(): String { * Example: KtFile with name /full/path/to/Test.kt will have its name formatted to be simply Test.kt */ private fun String.formatElementName(): String = - if (contains(File.separatorChar)) substringAfterLast(File.separatorChar) - else this + if (contains(File.separatorChar)) { + substringAfterLast(File.separatorChar) + } else { + this + } /* * KtCompiler wrongly used Path.filename as the name for a KtFile instead of the whole path. diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt index c0abcf85551..506a5a3d86d 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt @@ -79,7 +79,9 @@ class AnnotationExcluderSpec(private val env: KotlinCoreEnvironment) { @Test fun `should exclude when the annotation was found with SplitPattern`() { val (file, ktAnnotation) = createKtFile("@SinceKotlin") - val excluder = @Suppress("DEPRECATION") AnnotationExcluder(file, SplitPattern("SinceKotlin")) + + @Suppress("DEPRECATION") + val excluder = AnnotationExcluder(file, SplitPattern("SinceKotlin")) assertThat(excluder.shouldExclude(listOf(ktAnnotation))).isTrue() } @@ -87,7 +89,9 @@ class AnnotationExcluderSpec(private val env: KotlinCoreEnvironment) { @Test fun `should exclude when the annotation was found with List of Strings`() { val (file, ktAnnotation) = createKtFile("@SinceKotlin") - val excluder = @Suppress("DEPRECATION") AnnotationExcluder(file, listOf("SinceKo*")) + + @Suppress("DEPRECATION") + val excluder = AnnotationExcluder(file, listOf("SinceKo*")) assertThat(excluder.shouldExclude(listOf(ktAnnotation))).isTrue() } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt index 03dceaa7811..521496b7624 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt @@ -2,8 +2,8 @@ package io.gitlab.arturbosch.detekt.formatting import com.pinterest.ktlint.core.KtLint import com.pinterest.ktlint.core.Rule.VisitorModifier.RunAsLateAsPossible -import com.pinterest.ktlint.core.Rule.VisitorModifier.RunOnRootNodeOnly import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties.codeStyleSetProperty +import com.pinterest.ktlint.core.api.EditorConfigProperties import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import io.github.detekt.psi.fileName import io.github.detekt.psi.toFilePath @@ -21,9 +21,9 @@ import io.gitlab.arturbosch.detekt.api.SourceLocation import io.gitlab.arturbosch.detekt.api.TextLocation import org.ec4j.core.model.Property import org.jetbrains.kotlin.com.intellij.lang.ASTNode -import org.jetbrains.kotlin.com.intellij.lang.FileASTNode +import org.jetbrains.kotlin.com.intellij.psi.impl.source.JavaDummyElement +import org.jetbrains.kotlin.com.intellij.psi.impl.source.JavaDummyHolder import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.psiUtil.endOffset /** * Rule to detect formatting violations. @@ -39,12 +39,35 @@ abstract class FormattingRule(config: Config) : Rule(config) { protected val isAndroid get() = FormattingProvider.android.value(ruleSetConfig) - val runOnRootNodeOnly - get() = RunOnRootNodeOnly in wrapping.visitorModifiers - val runAsLateAsPossible get() = RunAsLateAsPossible in wrapping.visitorModifiers + private val emit = { offset: Int, message: String, _: Boolean -> + val (line, column) = positionByOffset(offset) + val location = Location( + SourceLocation(line, column), + // Use offset + 1 since ktlint always reports a single location. + TextLocation(offset, offset + 1), + root.toFilePath() + ) + + // Nodes reported by 'NoConsecutiveBlankLines' are dangling whitespace nodes which means they have + // no direct parent which we can use to get the containing file needed to baseline or suppress findings. + // For these reasons we do not report a KtElement which may lead to crashes when postprocessing it + // e.g. reports (html), baseline etc. + val packageName = root.packageFqName.asString() + .takeIf { it.isNotEmpty() } + ?.plus(".") + .orEmpty() + val entity = Entity("", "$packageName${root.fileName}:$line", location, root) + + if (canBeCorrectedByKtLint(message)) { + report(CorrectableCodeSmell(issue, entity, message, autoCorrectEnabled = autoCorrect)) + } else { + report(CodeSmell(issue, entity, message)) + } + } + private var positionByOffset: (offset: Int) -> Pair by SingleAssign() private var root: KtFile by SingleAssign() @@ -58,66 +81,63 @@ abstract class FormattingRule(config: Config) : Rule(config) { this.root = root positionByOffset = KtLintLineColCalculator .calculateLineColByOffset(KtLintLineColCalculator.normalizeText(root.text)) + root.node.putUserData(KtLint.FILE_PATH_USER_DATA_KEY, root.name) - val editorConfigProperties = overrideEditorConfigProperties()?.toMutableMap() + wrapping.beforeFirstNode(computeEditorConfigProperties()) + root.node.visitASTNodes() + wrapping.afterLastNode() + } + + open fun overrideEditorConfigProperties(): Map, String>? = null + + private fun computeEditorConfigProperties(): EditorConfigProperties { + val usesEditorConfigProperties = overrideEditorConfigProperties()?.toMutableMap() ?: mutableMapOf() if (isAndroid) { - editorConfigProperties[codeStyleSetProperty] = "android" + usesEditorConfigProperties[codeStyleSetProperty] = "android" } - if (editorConfigProperties.isNotEmpty()) { - val userData = (root.node.getUserData(KtLint.EDITOR_CONFIG_PROPERTIES_USER_DATA_KEY).orEmpty()) - .toMutableMap() - - editorConfigProperties.forEach { (editorConfigProperty, defaultValue) -> - userData[editorConfigProperty.type.name] = Property.builder() - .name(editorConfigProperty.type.name) - .type(editorConfigProperty.type) - .value(defaultValue) - .build() + return buildMap { + usesEditorConfigProperties.forEach { (editorConfigProperty, defaultValue) -> + put( + key = editorConfigProperty.type.name, + value = Property.builder() + .name(editorConfigProperty.type.name) + .type(editorConfigProperty.type) + .value(defaultValue) + .build() + ) } - root.node.putUserData(KtLint.EDITOR_CONFIG_PROPERTIES_USER_DATA_KEY, userData) } - root.node.putUserData(KtLint.FILE_PATH_USER_DATA_KEY, root.name) } - open fun overrideEditorConfigProperties(): Map, String>? = null - - fun apply(node: ASTNode) { - if (ruleShouldOnlyRunOnFileNode(node)) { - return + private fun beforeVisitChildNodes(node: ASTNode) { + wrapping.beforeVisitChildNodes(node, autoCorrect) { offset, errorMessage, canBeAutoCorrected -> + emit.invoke(offset, errorMessage, canBeAutoCorrected) } + } - wrapping.visit(node, autoCorrect) { offset, message, _ -> - val (line, column) = positionByOffset(offset) - val location = Location( - SourceLocation(line, column), - getTextLocationForViolation(node, offset), - root.toFilePath() - ) - - // Nodes reported by 'NoConsecutiveBlankLines' are dangling whitespace nodes which means they have - // no direct parent which we can use to get the containing file needed to baseline or suppress findings. - // For these reasons we do not report a KtElement which may lead to crashes when postprocessing it - // e.g. reports (html), baseline etc. - val packageName = root.packageFqName.asString() - .takeIf { it.isNotEmpty() } - ?.plus(".") - .orEmpty() - val entity = Entity("", "$packageName${root.fileName}:$line", location, root) - - if (canBeCorrectedByKtLint(message)) { - report(CorrectableCodeSmell(issue, entity, message, autoCorrectEnabled = autoCorrect)) - } else { - report(CodeSmell(issue, entity, message)) - } + private fun afterVisitChildNodes(node: ASTNode) { + wrapping.afterVisitChildNodes(node, autoCorrect) { offset, errorMessage, canBeAutoCorrected -> + emit.invoke(offset, errorMessage, canBeAutoCorrected) } } - open fun getTextLocationForViolation(node: ASTNode, offset: Int) = - TextLocation(node.startOffset, node.psi.endOffset) + private fun ASTNode.visitASTNodes() { + if (isNotDummyElement()) { + beforeVisitChildNodes(this) + } + getChildren(null).forEach { + it.visitASTNodes() + } + if (isNotDummyElement()) { + afterVisitChildNodes(this) + } + } - private fun ruleShouldOnlyRunOnFileNode(node: ASTNode) = - runOnRootNodeOnly && node !is FileASTNode + private fun ASTNode.isNotDummyElement(): Boolean { + val parent = this.psi?.parent + return parent !is JavaDummyHolder && parent !is JavaDummyElement + } } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt index b003a594357..40459ae5044 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt @@ -57,14 +57,12 @@ import io.gitlab.arturbosch.detekt.formatting.wrappers.SpacingBetweenDeclaration import io.gitlab.arturbosch.detekt.formatting.wrappers.SpacingBetweenDeclarationsWithComments import io.gitlab.arturbosch.detekt.formatting.wrappers.SpacingBetweenFunctionNameAndOpeningParenthesis import io.gitlab.arturbosch.detekt.formatting.wrappers.StringTemplate -import io.gitlab.arturbosch.detekt.formatting.wrappers.TrailingComma +import io.gitlab.arturbosch.detekt.formatting.wrappers.TrailingCommaOnCallSite +import io.gitlab.arturbosch.detekt.formatting.wrappers.TrailingCommaOnDeclarationSite import io.gitlab.arturbosch.detekt.formatting.wrappers.TypeArgumentListSpacing import io.gitlab.arturbosch.detekt.formatting.wrappers.TypeParameterListSpacing import io.gitlab.arturbosch.detekt.formatting.wrappers.UnnecessaryParenthesesBeforeTrailingLambda import io.gitlab.arturbosch.detekt.formatting.wrappers.Wrapping -import org.jetbrains.kotlin.com.intellij.lang.ASTNode -import org.jetbrains.kotlin.com.intellij.psi.impl.source.JavaDummyElement -import org.jetbrains.kotlin.com.intellij.psi.impl.source.JavaDummyHolder import org.jetbrains.kotlin.psi.KtFile import java.util.LinkedList @@ -119,7 +117,8 @@ class KtLintMultiRule(config: Config = Config.empty) : SpacingBetweenDeclarationsWithAnnotations(config), SpacingBetweenDeclarationsWithComments(config), StringTemplate(config), - TrailingComma(config), // in standard ruleset but not enabled by default + TrailingCommaOnCallSite(config), // in standard ruleset but not enabled by default + TrailingCommaOnDeclarationSite(config), // in standard ruleset but not enabled by default Wrapping(config), // Wrappers for ktlint-ruleset-experimental rules. Disabled by default. @@ -142,43 +141,23 @@ class KtLintMultiRule(config: Config = Config.empty) : ) override fun visit(root: KtFile) { - val sortedRules = getSortedRules() - sortedRules.forEach { it.visit(root) } - root.node.visitTokens { node -> - sortedRules.forEach { it.apply(node) } + getSortedRules().forEach { rule -> + rule.visit(root) } } internal fun getSortedRules(): List { - val runFirstOnRoot = mutableListOf() val other = mutableListOf() - val runLastOnRoot = mutableListOf() val runLast = mutableListOf() for (rule in activeRules.filterIsInstance()) { when { - rule.runOnRootNodeOnly && rule.runAsLateAsPossible -> runLastOnRoot.add(rule) - rule.runOnRootNodeOnly -> runFirstOnRoot.add(rule) rule.runAsLateAsPossible -> runLast.add(rule) else -> other.add(rule) } } return LinkedList().apply { - addAll(runFirstOnRoot) addAll(other) - addAll(runLastOnRoot) addAll(runLast) } } - - private fun ASTNode.visitTokens(currentNode: (ASTNode) -> Unit) { - if (this.isNoFakeElement()) { - currentNode(this) - } - getChildren(null).forEach { it.visitTokens(currentNode) } - } - - private fun ASTNode.isNoFakeElement(): Boolean { - val parent = this.psi?.parent - return parent !is JavaDummyHolder && parent !is JavaDummyElement - } } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt index 09271411230..5d3bec78765 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt @@ -4,13 +4,11 @@ import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.IndentationRule import io.gitlab.arturbosch.detekt.api.Config -import io.gitlab.arturbosch.detekt.api.TextLocation import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule -import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** * See [ktlint docs](https://pinterest.github.io/ktlint/rules/standard/#indentation) for documentation. @@ -36,15 +34,4 @@ class Indentation(config: Config) : FormattingRule(config) { mapOf( DefaultEditorConfigProperties.indentSizeProperty to indentSize.toString(), ) - - /** - * [IndentationRule] has visitor modifier RunOnRootNodeOnly, so [node] is always the root file. - * Override the parent implementation to highlight the entire file. - */ - override fun getTextLocationForViolation(node: ASTNode, offset: Int): TextLocation { - val relativeEnd = node.text - .drop(offset) - .indexOfFirst { !it.isWhitespace() } - return TextLocation(offset, offset + relativeEnd) - } } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingCommaOnCallSite.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingCommaOnCallSite.kt new file mode 100644 index 00000000000..855055f4831 --- /dev/null +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingCommaOnCallSite.kt @@ -0,0 +1,27 @@ +package io.gitlab.arturbosch.detekt.formatting.wrappers + +import com.pinterest.ktlint.core.api.UsesEditorConfigProperties +import com.pinterest.ktlint.ruleset.standard.TrailingCommaOnCallSiteRule +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.config +import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable +import io.gitlab.arturbosch.detekt.api.internal.Configuration +import io.gitlab.arturbosch.detekt.formatting.FormattingRule + +/** + * See [ktlint docs](https://pinterest.github.io/ktlint/rules/standard/) for documentation. + */ +@AutoCorrectable(since = "1.22.0") +class TrailingCommaOnCallSite(config: Config) : FormattingRule(config) { + + override val wrapping = TrailingCommaOnCallSiteRule() + override val issue = issueFor("Rule to mandate/forbid trailing commas at call sites") + + @Configuration("Defines whether a trailing comma (or no trailing comma) should be enforced at call sites") + private val useTrailingCommaOnCallSite by config(false) + + override fun overrideEditorConfigProperties(): Map, String> = + mapOf( + TrailingCommaOnCallSiteRule.allowTrailingCommaOnCallSiteProperty to useTrailingCommaOnCallSite.toString(), + ) +} diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingComma.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingCommaOnDeclarationSite.kt similarity index 51% rename from detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingComma.kt rename to detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingCommaOnDeclarationSite.kt index 98ca6a7e3e1..6c6bdb0c815 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingComma.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingCommaOnDeclarationSite.kt @@ -1,7 +1,7 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers import com.pinterest.ktlint.core.api.UsesEditorConfigProperties -import com.pinterest.ktlint.ruleset.experimental.trailingcomma.TrailingCommaRule +import com.pinterest.ktlint.ruleset.standard.TrailingCommaOnDeclarationSiteRule import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable @@ -11,21 +11,18 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** * See [ktlint docs](https://pinterest.github.io/ktlint/rules/standard/) for documentation. */ -@AutoCorrectable(since = "1.20.0") -class TrailingComma(config: Config) : FormattingRule(config) { +@AutoCorrectable(since = "1.22.0") +class TrailingCommaOnDeclarationSite(config: Config) : FormattingRule(config) { - override val wrapping = TrailingCommaRule() - override val issue = issueFor("Rule to mandate/forbid trailing commas") + override val wrapping = TrailingCommaOnDeclarationSiteRule() + override val issue = issueFor("Rule to mandate/forbid trailing commas at declaration sites") - @Configuration("Defines whether a trailing comma (or no trailing comma) should be enforced on the defining side") - private val allowTrailingComma by config(false) - - @Configuration("Defines whether a trailing comma (or no trailing comma) should be enforced on the calling side") - private val allowTrailingCommaOnCallSite by config(false) + @Configuration("Defines whether a trailing comma (or no trailing comma) should be enforced at declaration sites") + private val useTrailingCommaOnDeclarationSite by config(false) override fun overrideEditorConfigProperties(): Map, String> = mapOf( - TrailingCommaRule.allowTrailingCommaProperty to allowTrailingComma.toString(), - TrailingCommaRule.allowTrailingCommaOnCallSiteProperty to allowTrailingCommaOnCallSite.toString(), + TrailingCommaOnDeclarationSiteRule.allowTrailingCommaProperty to + useTrailingCommaOnDeclarationSite.toString(), ) } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Wrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Wrapping.kt index 82b0283ac02..55e4388f127 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Wrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Wrapping.kt @@ -4,13 +4,11 @@ import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.WrappingRule import io.gitlab.arturbosch.detekt.api.Config -import io.gitlab.arturbosch.detekt.api.TextLocation import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule -import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** * See [ktlint docs](https://pinterest.github.io/ktlint/rules/standard/#wrapping) for documentation. @@ -25,15 +23,6 @@ class Wrapping(config: Config) : FormattingRule(config) { @Configuration("indentation size") private val indentSize by config(4) - /** - * [Wrapping] has visitor modifier RunOnRootNodeOnly, so [node] is always the root file. - * Override the parent implementation to highlight the entire file. - */ - override fun getTextLocationForViolation(node: ASTNode, offset: Int): TextLocation { - // Use offset + 1 since Wrapping always reports the location of missing new line. - return TextLocation(offset, offset + 1) - } - override fun overrideEditorConfigProperties(): Map, String> = mapOf( DefaultEditorConfigProperties.indentSizeProperty to indentSize.toString(), diff --git a/detekt-formatting/src/main/resources/config/config.yml b/detekt-formatting/src/main/resources/config/config.yml index 340a53c90dc..fdc9e9c2800 100644 --- a/detekt-formatting/src/main/resources/config/config.yml +++ b/detekt-formatting/src/main/resources/config/config.yml @@ -179,11 +179,14 @@ formatting: StringTemplate: active: true autoCorrect: true - TrailingComma: + TrailingCommaOnCallSite: active: false autoCorrect: true - allowTrailingComma: false - allowTrailingCommaOnCallSite: false + useTrailingCommaOnCallSite: false + TrailingCommaOnDeclarationSite: + active: false + autoCorrect: true + useTrailingCommaOnDeclarationSite: false TypeArgumentListSpacing: active: false autoCorrect: true diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRuleSpec.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRuleSpec.kt index 9b225f91173..5fd78570a24 100644 --- a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRuleSpec.kt +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRuleSpec.kt @@ -13,14 +13,8 @@ class KtLintMultiRuleSpec { ktlintRule.visitFile(compileContentForTest("")) val sortedRules = ktlintRule.getSortedRules() assertThat(sortedRules).isNotEmpty - assertThat(sortedRules.indexOfFirst { it.runOnRootNodeOnly }) + assertThat(sortedRules.indexOfFirst { !it.runAsLateAsPossible }) .isGreaterThan(-1) - .isLessThan(sortedRules.indexOfFirst { !it.runOnRootNodeOnly }) - assertThat(sortedRules.indexOfFirst { !it.runOnRootNodeOnly }) - .isGreaterThan(-1) - .isLessThan(sortedRules.indexOfFirst { it.runOnRootNodeOnly && it.runAsLateAsPossible }) - assertThat(sortedRules.indexOfFirst { it.runOnRootNodeOnly && it.runAsLateAsPossible }) - .isGreaterThan(-1) - .isLessThan(sortedRules.indexOfFirst { it.runAsLateAsPossible && !it.runOnRootNodeOnly }) + .isLessThan(sortedRules.indexOfFirst { it.runAsLateAsPossible }) } } diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TestFiles.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TestFiles.kt index 636725d4dbc..2989a7a54bc 100644 --- a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TestFiles.kt +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TestFiles.kt @@ -13,7 +13,6 @@ import java.nio.file.Paths fun FormattingRule.lint(@Language("kotlin") content: String, fileName: String = "Test.kt"): List { val root = compileContentForTest(content, fileName) this.visit(root) - root.node.visit { node -> this.apply(node) } return this.findings } diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaSpec.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaOnCallSiteSpec.kt similarity index 60% rename from detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaSpec.kt rename to detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaOnCallSiteSpec.kt index f72703cb707..f49b11d9b56 100644 --- a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaSpec.kt +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaOnCallSiteSpec.kt @@ -1,30 +1,27 @@ package io.gitlab.arturbosch.detekt.formatting -import io.gitlab.arturbosch.detekt.formatting.wrappers.TrailingComma +import io.gitlab.arturbosch.detekt.formatting.wrappers.TrailingCommaOnCallSite import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.assertThat import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test -private const val ALLOW_TRAILING_COMMA = "allowTrailingComma" -private const val ALLOW_TRAILING_COMMA_ON_CALL_SITE = "allowTrailingCommaOnCallSite" - /** * Some test cases were used directly from KtLint to verify the wrapper rule: * - * https://github.com/pinterest/ktlint/blob/master/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/TrailingCommaRuleTest.kt + * https://github.com/pinterest/ktlint/blob/master/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/TrailingCommaOnCallSiteRuleTest.kt */ -class TrailingCommaSpec { +class TrailingCommaOnCallSiteSpec { @Nested - inner class `unnecessary comma` { + inner class Unnecessary { @Test fun `reports unnecessary comma on function call`() { val code = """ val foo1 = listOf("a", "b",) """.trimIndent() - val findings = TrailingComma(TestConfig(mapOf(ALLOW_TRAILING_COMMA to false))).lint(code) + val findings = TrailingCommaOnCallSite(TestConfig(mapOf(USE_TRAILING_COMMA to false))).lint(code) assertThat(findings).hasSize(1) } @@ -33,7 +30,7 @@ class TrailingCommaSpec { val code = """ val foo2 = Pair(1, 2,) """.trimIndent() - val findings = TrailingComma(TestConfig(mapOf(ALLOW_TRAILING_COMMA to false))).lint(code) + val findings = TrailingCommaOnCallSite(TestConfig(mapOf(USE_TRAILING_COMMA to false))).lint(code) assertThat(findings).hasSize(1) } @@ -42,7 +39,7 @@ class TrailingCommaSpec { val code = """ val foo3: List = emptyList() """.trimIndent() - val findings = TrailingComma(TestConfig(mapOf(ALLOW_TRAILING_COMMA to false))).lint(code) + val findings = TrailingCommaOnCallSite(TestConfig(mapOf(USE_TRAILING_COMMA to false))).lint(code) assertThat(findings).hasSize(1) } @@ -52,7 +49,7 @@ class TrailingCommaSpec { val foo4 = Array(2) { 42 } val bar4 = foo4[1,] """.trimIndent() - val findings = TrailingComma(TestConfig(mapOf(ALLOW_TRAILING_COMMA to false))).lint(code) + val findings = TrailingCommaOnCallSite(TestConfig(mapOf(USE_TRAILING_COMMA to false))).lint(code) assertThat(findings).hasSize(1) } @@ -62,25 +59,13 @@ class TrailingCommaSpec { @Foo5([1, 2,]) val foo5: Int = 0 """.trimIndent() - val findings = TrailingComma(TestConfig(mapOf(ALLOW_TRAILING_COMMA to false))).lint(code) + val findings = TrailingCommaOnCallSite(TestConfig(mapOf(USE_TRAILING_COMMA to false))).lint(code) assertThat(findings).hasSize(1) } } @Nested - inner class `missing comma` { - - @Test - fun `reports missing comma on field definition`() { - val code = """ - data class Foo1(val bar: Int) - data class Foo2( - val bar: Int - ) - """.trimIndent() - val findings = TrailingComma(TestConfig(mapOf(ALLOW_TRAILING_COMMA to true))).lint(code) - assertThat(findings).hasSize(1) - } + inner class MissingComma { @Test fun `reports missing comma on function call`() { @@ -91,7 +76,7 @@ class TrailingCommaSpec { "b" ) """.trimIndent() - val findings = TrailingComma(TestConfig(mapOf(ALLOW_TRAILING_COMMA_ON_CALL_SITE to true))).lint(code) + val findings = TrailingCommaOnCallSite(TestConfig(mapOf(USE_TRAILING_COMMA to true))).lint(code) assertThat(findings).hasSize(1) } @@ -104,8 +89,12 @@ class TrailingCommaSpec { 2 ) """.trimIndent() - val findings = TrailingComma(TestConfig(mapOf(ALLOW_TRAILING_COMMA_ON_CALL_SITE to true))).lint(code) + val findings = TrailingCommaOnCallSite(TestConfig(mapOf(USE_TRAILING_COMMA to true))).lint(code) assertThat(findings).hasSize(1) } } + + private companion object { + private const val USE_TRAILING_COMMA = "useTrailingCommaOnCallSite" + } } diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaOnDeclarationSiteSpec.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaOnDeclarationSiteSpec.kt new file mode 100644 index 00000000000..c6cce3f467d --- /dev/null +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TrailingCommaOnDeclarationSiteSpec.kt @@ -0,0 +1,72 @@ +package io.gitlab.arturbosch.detekt.formatting + +import io.gitlab.arturbosch.detekt.formatting.wrappers.TrailingCommaOnDeclarationSite +import io.gitlab.arturbosch.detekt.test.TestConfig +import io.gitlab.arturbosch.detekt.test.assertThat +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +/** + * Some test cases were used directly from KtLint to verify the wrapper rule: + * + * https://github.com/pinterest/ktlint/blob/master/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/TrailingCommaOnDeclarationSiteRuleTest.kt + */ +class TrailingCommaOnDeclarationSiteSpec { + + @Nested + inner class UnnecessaryComma { + + @Test + fun `reports unnecessary comma on generic type definition`() { + val code = """ + class Foo1 {} + """.trimIndent() + val findings = TrailingCommaOnDeclarationSite(TestConfig(mapOf(USE_TRAILING_COMMA to false))).lint(code) + assertThat(findings).hasSize(1) + } + + @Test + fun `reports unnecessary comma on property definition`() { + val code = """ + data class Foo1(val bar: Int,) + data class Foo2( + val bar: Int, + ) + """.trimIndent() + val findings = TrailingCommaOnDeclarationSite(TestConfig(mapOf(USE_TRAILING_COMMA to false))).lint(code) + assertThat(findings).hasSize(2) + } + } + + @Nested + inner class MissingComma { + + @Test + fun `reports missing comma on generic type definition`() { + val code = """ + class Foo1< + A, + B + > {} + """.trimIndent() + val findings = TrailingCommaOnDeclarationSite(TestConfig(mapOf(USE_TRAILING_COMMA to true))).lint(code) + assertThat(findings).hasSize(1) + } + + @Test + fun `reports missing comma on property definition`() { + val code = """ + data class Foo1(val bar: Int) + data class Foo2( + val bar: Int + ) + """.trimIndent() + val findings = TrailingCommaOnDeclarationSite(TestConfig(mapOf(USE_TRAILING_COMMA to true))).lint(code) + assertThat(findings).hasSize(1) + } + } + + private companion object { + private const val USE_TRAILING_COMMA = "useTrailingCommaOnDeclarationSite" + } +} diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektAndroid.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektAndroid.kt index 737e77c3d36..d86a76975ce 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektAndroid.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektAndroid.kt @@ -64,8 +64,11 @@ internal class DetektAndroid(private val project: Project) { } private val BaseVariant.testVariants: List - get() = if (this is TestedVariant) listOfNotNull(testVariant, unitTestVariant) - else emptyList() + get() = if (this is TestedVariant) { + listOfNotNull(testVariant, unitTestVariant) + } else { + emptyList() + } fun registerTasks(extension: DetektExtension) { // There is not a single Android plugin, but each registers an extension based on BaseExtension, diff --git a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethod.kt b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethod.kt index 9c645e3c60b..c24764c7f77 100644 --- a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethod.kt +++ b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethod.kt @@ -52,8 +52,11 @@ class LongMethod(config: Config = Config.empty) : Rule(config) { val functionToLines = HashMap() functionToLinesCache.map { (function, lines) -> val isNested = function.getStrictParentOfType() != null - if (isNested) functionToLines[function] = functionToBodyLinesCache[function] ?: 0 - else functionToLines[function] = lines + if (isNested) { + functionToLines[function] = functionToBodyLinesCache[function] ?: 0 + } else { + functionToLines[function] = lines + } } for ((function, lines) in functionToLines) { if (lines >= threshold) { diff --git a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt index 69251a0c5c4..9b825662f3c 100644 --- a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt +++ b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt @@ -68,7 +68,9 @@ class NamedArguments(config: Config = Config.empty) : Rule(config) { val parameter = resolvedCall.getParameterForArgument(argument) ?: return@mapNotNull null if (ignoreArgumentsMatchingNames && parameter.name.asString() == argument.getArgumentExpression()?.text - ) return@mapNotNull null + ) { + return@mapNotNull null + } argument to parameter } if (unnamedArguments.isEmpty()) return false diff --git a/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/RedundantSuspendModifier.kt b/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/RedundantSuspendModifier.kt index 95ae114332a..7c7c990bcb0 100644 --- a/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/RedundantSuspendModifier.kt +++ b/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/RedundantSuspendModifier.kt @@ -83,8 +83,11 @@ class RedundantSuspendModifier(config: Config) : Rule(config) { is KtOperationReferenceExpression, is KtForExpression, is KtProperty, is KtNameReferenceExpression -> true else -> { val parent = parent - if (parent is KtCallExpression && parent.calleeExpression == this) true - else this is KtCallExpression && this.calleeExpression is KtCallExpression + if (parent is KtCallExpression && parent.calleeExpression == this) { + true + } else { + this is KtCallExpression && this.calleeExpression is KtCallExpression + } } } } @@ -117,8 +120,9 @@ class RedundantSuspendModifier(config: Config) : Rule(config) { } else -> { val resolvedCall = getResolvedCall(bindingContext) - if ((resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.isSuspend == true) true - else { + if ((resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.isSuspend == true) { + true + } else { val propertyDescriptor = resolvedCall?.resultingDescriptor as? PropertyDescriptor val s = propertyDescriptor?.fqNameSafe?.asString() s?.startsWith("kotlin.coroutines.") == true && s.endsWith(".coroutineContext") diff --git a/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/OutdatedDocumentation.kt b/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/OutdatedDocumentation.kt index f6fd27d969e..62e55fdf7ba 100644 --- a/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/OutdatedDocumentation.kt +++ b/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/OutdatedDocumentation.kt @@ -99,14 +99,18 @@ class OutdatedDocumentation(config: Config = Config.empty) : Rule(config) { val constructorDeclarations = if (ctor != null) getPrimaryConstructorDeclarations(ctor) else emptyList() val typeParams = if (matchTypeParameters) { klass.typeParameters.mapNotNull { it.name.toParamOrNull() } - } else emptyList() + } else { + emptyList() + } return typeParams + constructorDeclarations } private fun getFunctionDeclarations(function: KtNamedFunction): List { val typeParams = if (matchTypeParameters) { function.typeParameters.mapNotNull { it.name.toParamOrNull() } - } else emptyList() + } else { + emptyList() + } val valueParams = function.valueParameters.mapNotNull { it.name.toParamOrNull() } return typeParams + valueParams } diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IgnoredReturnValue.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IgnoredReturnValue.kt index 443a57f1385..410d8fa8989 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IgnoredReturnValue.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IgnoredReturnValue.kt @@ -107,7 +107,9 @@ class IgnoredReturnValue(config: Config = Config.empty) : Rule(config) { if (restrictToConfig && resultingDescriptor.returnType !in returnValueTypes && (annotations + resultingDescriptor.containingDeclaration.annotations).none { it in returnValueAnnotations } - ) return + ) { + return + } val messageText = expression.calleeExpression?.text ?: expression.text report( diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt index 402410feb41..6211a948198 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt @@ -58,7 +58,9 @@ class UnusedUnaryOperator(config: Config = Config.empty) : Rule(config) { if (expression.node.leaves(forward = false) .takeWhile { it is PsiWhiteSpace || it is PsiComment } .none { it is PsiWhiteSpace && it.textContains('\n') } - ) return + ) { + return + } val parentOrSelf = expression.parentBinaryExpressionOrThis() if (parentOrSelf.isUsedAsExpression(bindingContext)) return diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt index 0bcb7e29fcf..f5298e4f85c 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt @@ -96,7 +96,11 @@ class UselessPostfixExpression(config: Config = Config.empty) : Rule(config) { private fun KtExpression.asPostFixExpression() = if (this is KtPostfixExpression && (operationToken === PLUSPLUS || operationToken === MINUSMINUS) - ) this else null + ) { + this + } else { + null + } private fun checkPostfixExpression(postfixExpression: KtPostfixExpression, leftIdentifierText: String?) { if (leftIdentifierText == postfixExpression.firstChild?.text) { diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt index 7efb0d212f0..ec33f8d41d7 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt @@ -6,7 +6,9 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test class DuplicateCaseInWhenExpressionSpec { - private val subject = @Suppress("DEPRECATION") DuplicateCaseInWhenExpression(Config.empty) + + @Suppress("DEPRECATION") + private val subject = DuplicateCaseInWhenExpression(Config.empty) @Test fun `reports duplicated label in when`() { diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt index bc6c50fa718..2c47dca8952 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt @@ -14,7 +14,9 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { @Nested inner class `MissingWhenCase rule` { - private val subject = @Suppress("DEPRECATION") MissingWhenCase() + + @Suppress("DEPRECATION") + private val subject = MissingWhenCase() @Nested inner class `enum` { @@ -309,7 +311,9 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { @Nested inner class `MissingWhenCase rule when else expression is not considered` { - private val subject = @Suppress("DEPRECATION") MissingWhenCase( + + @Suppress("DEPRECATION") + private val subject = MissingWhenCase( TestConfig(mapOf("allowElseExpression" to false)) ) diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt index 7d5c9e28e6e..689d9c3231a 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt @@ -10,7 +10,9 @@ import org.junit.jupiter.api.Test @KotlinCoreEnvironmentTest class RedundantElseInWhenSpec(private val env: KotlinCoreEnvironment) { - private val subject = @Suppress("DEPRECATION") RedundantElseInWhen() + + @Suppress("DEPRECATION") + private val subject = RedundantElseInWhen() @Nested inner class `enum` { diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethod.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethod.kt index ba7d03b4f5e..6cdd10e10c9 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethod.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethod.kt @@ -58,9 +58,11 @@ class ExplicitCollectionElementAccessMethod(config: Config = Config.empty) : Rul } private fun isIndexGetterRecommended(expression: KtCallExpression): Boolean { - val getter = - if (expression.calleeExpression?.text == "get") expression.getFunctionDescriptor() - else null + val getter = if (expression.calleeExpression?.text == "get") { + expression.getFunctionDescriptor() + } else { + null + } if (getter == null) return false return canReplace(getter) && shouldReplace(getter) @@ -70,8 +72,11 @@ class ExplicitCollectionElementAccessMethod(config: Config = Config.empty) : Rul when (expression.calleeExpression?.text) { "set" -> { val setter = expression.getFunctionDescriptor() - if (setter == null) false - else canReplace(setter) && shouldReplace(setter) + if (setter == null) { + false + } else { + canReplace(setter) && shouldReplace(setter) + } } // `put` isn't an operator function, but can be replaced with indexer when the caller is Map. "put" -> isCallerMap(expression) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NullableBooleanCheck.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NullableBooleanCheck.kt index c70b7971250..af8be212bcd 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NullableBooleanCheck.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NullableBooleanCheck.kt @@ -47,8 +47,11 @@ class NullableBooleanCheck(config: Config = Config.empty) : Rule(config) { expression.left?.getType(bindingContext)?.isBooleanOrNullableBoolean() == true ) { val messageSuffix = - if (expression.right?.text == "true") "`!= false` rather than `?: true`" - else "`== true` rather than `?: false`" + if (expression.right?.text == "true") { + "`!= false` rather than `?: true`" + } else { + "`== true` rather than `?: false`" + } report( CodeSmell( issue = issue, diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt index ee5effeed4f..81642b88994 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt @@ -131,7 +131,9 @@ private class UnusedFunctionVisitor( listOf(KtTokens.IN_KEYWORD, KtTokens.NOT_IN).flatMap { functionReferences[it.value].orEmpty() } - } else emptyList() + } else { + emptyList() + } directReferences + assignmentReferences + containingReferences } else { emptyList() diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseOrEmpty.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseOrEmpty.kt index c0e43203263..9e770cefb26 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseOrEmpty.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseOrEmpty.kt @@ -69,7 +69,9 @@ class UseOrEmpty(config: Config = Config.empty) : Rule(config) { if (functionDescriptor != null && functionDescriptor.isOperator && functionDescriptor.typeParameters.isNotEmpty() - ) return + ) { + return + } } val rightType = right.getType(bindingContext) ?: return diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt index 7659bec664d..92825461e51 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt @@ -29,8 +29,11 @@ open class TestConfig( } override fun valueOrNull(key: String): T? = - if (key == Config.ACTIVE_KEY) (values[Config.ACTIVE_KEY] ?: true) as T? - else values[key] as? T + if (key == Config.ACTIVE_KEY) { + (values[Config.ACTIVE_KEY] ?: true) as T? + } else { + values[key] as? T + } private fun tryParseBasedOnDefaultRespectingCollections(result: String, defaultResult: Any): Any = when (defaultResult) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 98c71bbd804..4637a959400 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ dokka = "1.7.10" jacoco = "0.8.8" kotlin = "1.7.20" -ktlint = "0.46.1" +ktlint = "0.47.1" junit = "5.9.1" contester = "0.2.0"