From 16b5adcc4dd4e1fcb88e79c7415bf04eeb16c158 Mon Sep 17 00:00:00 2001 From: Svyatoslav Chatchenko Date: Wed, 20 Jun 2018 15:01:38 +0200 Subject: [PATCH] Rule: NoSpaceBetweenParentheses New rule forbids redundant spaces between parentheses. Fixes #223 --- .../standard/NoSpaceBetweenParentheses.kt | 36 +++++++++++++++++ .../standard/StandardRuleSetProvider.kt | 1 + .../standard/NoSpaceBetweenParenthesesTest.kt | 40 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 ktlint-ruleset-standard/src/main/kotlin/com/github/shyiko/ktlint/ruleset/standard/NoSpaceBetweenParentheses.kt create mode 100644 ktlint-ruleset-standard/src/test/kotlin/com/github/shyiko/ktlint/ruleset/standard/NoSpaceBetweenParenthesesTest.kt diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/github/shyiko/ktlint/ruleset/standard/NoSpaceBetweenParentheses.kt b/ktlint-ruleset-standard/src/main/kotlin/com/github/shyiko/ktlint/ruleset/standard/NoSpaceBetweenParentheses.kt new file mode 100644 index 0000000000..951c2d61a7 --- /dev/null +++ b/ktlint-ruleset-standard/src/main/kotlin/com/github/shyiko/ktlint/ruleset/standard/NoSpaceBetweenParentheses.kt @@ -0,0 +1,36 @@ +package com.github.shyiko.ktlint.ruleset.standard + +import com.github.shyiko.ktlint.core.Rule +import org.jetbrains.kotlin.com.intellij.lang.ASTNode +import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.psiUtil.siblings + +class NoSpaceBetweenParentheses : Rule("no-space-between-parentheses") { + + override fun visit(node: ASTNode, autoCorrect: Boolean, emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit) { + if (node.elementType == KtTokens.LPAR) { + val iterator = node.siblings().iterator() + var foundEnclosingPar = false + var hasSpaces = false + while (iterator.hasNext() && !foundEnclosingPar) { + val nextNode = iterator.next() + if (!hasSpaces && nextNode is PsiWhiteSpace) { + hasSpaces = true + } else if (nextNode.elementType == KtTokens.RPAR) { + foundEnclosingPar = true + } else { + // the case when there are parameters or multiline declaration + break + } + } + if (hasSpaces && foundEnclosingPar) { + emit(node.startOffset + 1, "Unexpected space between parentheses", true) + if (autoCorrect) { + val enclosingPar = node.siblings().first { it.elementType == KtTokens.RPAR } + node.treeParent.removeRange(node.siblings().first(), enclosingPar) + } + } + } + } +} diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/github/shyiko/ktlint/ruleset/standard/StandardRuleSetProvider.kt b/ktlint-ruleset-standard/src/main/kotlin/com/github/shyiko/ktlint/ruleset/standard/StandardRuleSetProvider.kt index 87f06b4254..26c58539ce 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/github/shyiko/ktlint/ruleset/standard/StandardRuleSetProvider.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/github/shyiko/ktlint/ruleset/standard/StandardRuleSetProvider.kt @@ -24,6 +24,7 @@ class StandardRuleSetProvider : RuleSetProvider { NoLineBreakBeforeAssignmentRule(), NoMultipleSpacesRule(), NoSemicolonsRule(), + NoSpaceBetweenParentheses(), NoTrailingSpacesRule(), NoUnitReturnRule(), NoUnusedImportsRule(), diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/github/shyiko/ktlint/ruleset/standard/NoSpaceBetweenParenthesesTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/github/shyiko/ktlint/ruleset/standard/NoSpaceBetweenParenthesesTest.kt new file mode 100644 index 0000000000..0f7ab5a185 --- /dev/null +++ b/ktlint-ruleset-standard/src/test/kotlin/com/github/shyiko/ktlint/ruleset/standard/NoSpaceBetweenParenthesesTest.kt @@ -0,0 +1,40 @@ +package com.github.shyiko.ktlint.ruleset.standard + +import com.github.shyiko.ktlint.core.LintError +import com.github.shyiko.ktlint.test.format +import com.github.shyiko.ktlint.test.lint +import org.assertj.core.api.Assertions.assertThat +import org.testng.annotations.Test + +class NoSpaceBetweenParenthesesTest { + @Test + fun testFailWhenEncounterSpace() { + assertThat(NoSpaceBetweenParentheses().lint("fun main( ) {}")) + .isEqualTo(listOf( + LintError(1, 10, "no-space-between-parentheses", "Unexpected space between parentheses") + )) + } + + @Test + fun testNoFailureWhenOnlyParentheses() { + assertThat(NoSpaceBetweenParentheses().lint("fun main() {}")) + .isEmpty() + } + + @Test + fun testNoFailureWhenMultilineDeclaration() { + assertThat(NoSpaceBetweenParentheses().lint( + """ + fun main( + val a: String + ) {} + """ + )).isEmpty() + } + + @Test + fun testAutoFormat() { + assertThat(NoSpaceBetweenParentheses().format("fun main( ) {}")) + .isEqualTo("fun main() {}") + } +}