Skip to content

Commit

Permalink
Change lint message
Browse files Browse the repository at this point in the history
Change message from "Unnecessary space(s)" to "Unnecessary long whitespace". The length of
the whitespace element is considered while it is not checked whether the whitespace
actually contains spaces only. However, it still make sense to replace a non-indent
whitespace which is too long, by a single space.
  • Loading branch information
paul-dingemans committed Mar 5, 2022
1 parent 07e452c commit 9b54139
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,30 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement

class NoMultipleSpacesRule : Rule("no-multi-spaces") {

public class NoMultipleSpacesRule : Rule("no-multi-spaces") {
override fun visit(
node: ASTNode,
autoCorrect: Boolean,
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit
) {
if (node is PsiWhiteSpace && !node.textContains('\n') && node.getTextLength() > 1 &&
// allow multiple spaces in KDoc in case of KDOC_TAG for alignment, e.g.
// @param foo stuff
// @param foobar stuff2
!(node.treePrev?.elementType == KDOC_MARKDOWN_LINK && node.treeParent?.elementType == KDOC_TAG)
) {
emit(node.startOffset + 1, "Unnecessary space(s)", true)
if (autoCorrect) {
(node as LeafPsiElement).rawReplaceWithText(" ")
node
.takeIf { node is PsiWhiteSpace }
.takeUnless { node.isIndentation() }
.takeIf { node.textLength > 1 }
.takeUnless { node.isPossibleAlignmentOfKdocTag() }
?.let {
emit(node.startOffset + 1, "Unnecessary long whitespace", true)
if (autoCorrect) {
(node as LeafPsiElement).rawReplaceWithText(" ")
}
}
}
}

private fun ASTNode.isIndentation() = this.text.startsWith("\n")

// allow multiple spaces in KDoc in case of KDOC_TAG for alignment, e.g.
// @param foo stuff
// @param foobar stuff2
private fun ASTNode.isPossibleAlignmentOfKdocTag() =
treePrev?.elementType == KDOC_MARKDOWN_LINK && treeParent?.elementType == KDOC_TAG
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,70 +7,84 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

class NoMultipleSpacesRuleTest {

@Test
fun testLint() {
assertThat(NoMultipleSpacesRule().lint("fun main() { x(1,3); x(1, 3)\n \n }"))
fun `Given a whitespace element not being an indent containing multiple spaces then replace it with a single space`() {
val code =
"""
fun main() {
x(1,${SPACE}${SPACE}3)
}
""".trimIndent()
val formattedCode =
"""
fun main() {
x(1,${SPACE}3)
}
""".trimIndent()
assertThat(NoMultipleSpacesRule().lint(code))
.isEqualTo(
listOf(
LintError(1, 22, "no-multi-spaces", "Unnecessary space(s)")
LintError(2, 10, "no-multi-spaces", "Unnecessary long whitespace")
)
)
assertThat(NoMultipleSpacesRule().format(code)).isEqualTo(formattedCode)
}

@Test
fun testFormat() {
assertThat(NoMultipleSpacesRule().format("fun main() { x(1,3); x(1, 3)\n \n }"))
.isEqualTo("fun main() { x(1,3); x(1, 3)\n \n }")
}

@Test
fun `lint multiple spaces in kdoc allowed`() {
assertThat(
NoMultipleSpacesRule().lint(
"""
/**
* Gets Blabla from user.
*
* @param blabls12 1234
* @param blabla123 6789
* @param blabla 5678
* @param longparam345 4567890
* @param userId 567890
* @return the user profile
*
*/
""".trimIndent()
fun `Given a whitespace element containing multiple tabs then replace it with a single space`() {
val code =
"""
fun main() {
x(1,${TAB}${TAB}3)
val fooBar = "Foo${TAB}${TAB}Bar"
}
""".trimIndent()
val formattedCode =
"""
fun main() {
x(1,${SPACE}3)
val fooBar = "Foo${TAB}${TAB}Bar"
}
""".trimIndent()
assertThat(NoMultipleSpacesRule().lint(code))
.isEqualTo(
listOf(
LintError(2, 10, "no-multi-spaces", "Unnecessary long whitespace")
)
)
).isEmpty()
assertThat(NoMultipleSpacesRule().format(code)).isEqualTo(formattedCode)
}

@Test
fun `format multiple spaces in kdoc allowed`() {
fun `lint multiple spaces in kdoc allowed`() {
val code =
"""
/**
* Gets Blabla from user.
*
* @param blabls12 1234
* @param blabla123 6789
* @param blabla 5678
* @param longparam345 4567890
* @param userId 567890
* @return the user profile
*
*/
* Gets Blabla from user.
*
* @param blabls12 1234
* @param blabla123 6789
* @param blabla 5678
* @param longparam345 4567890
* @param userId 567890
* @return the user profile
*
*/
""".trimIndent()
assertThat(NoMultipleSpacesRule().lint(code)).isEmpty()
assertThat(NoMultipleSpacesRule().format(code)).isEqualTo(code)
}

@Test
fun `test multiple spaces in the beginning of the file`() {
assertThat(NoMultipleSpacesRule().lint(" package my.company.android"))
.isEqualTo(
listOf(
LintError(1, 2, "no-multi-spaces", "Unnecessary space(s)")
)
)
val code = " package my.company.android"
assertThat(NoMultipleSpacesRule().lint(code)).containsExactly(
LintError(1, 2, "no-multi-spaces", "Unnecessary long whitespace")
)
}

private companion object {
const val SPACE = " "
const val TAB = "\t"
}
}

0 comments on commit 9b54139

Please sign in to comment.