Skip to content

Commit

Permalink
Add new experimental rule fun-keyword-spacing (#1362)
Browse files Browse the repository at this point in the history
Lints and formats the spacing after the fun keyword.

This rule is required to create a rule which can rewrite the function signature automatically as is described in #1341
  • Loading branch information
paul-dingemans committed Mar 9, 2022
1 parent f7f7900 commit 14c0adf
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Please welcome [paul-dingemans](https://github.com/paul-dingemans) as an officia
- Basic tests for CLI ([#540](https://github.com/pinterest/ktlint/issues/540))
- Add experimental rule for unexpected spaces in a type reference before a function identifier (`function-type-reference-spacing`) ([#1341](https://github.com/pinterest/ktlint/issues/1341))
- Add experimental rule for unnecessary parentheses in function call followed by lambda ([#1068](https://github.com/pinterest/ktlint/issues/1068))
- Add rule to check spacing after fun keyword (`fun-keyword-spacing`) ([#1362](https://github.com/pinterest/ktlint/pull/1362))
- Add experimental rules for unnecessary spacing between modifiers in and after the last modifier in a modifier list ([#1361](https://github.com/pinterest/ktlint/pull/1361))

### Fixed
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ by passing the `--experimental` flag to `ktlint`.
### Spacing
- `experimental:annotation-spacing`: Annotations should be separated by the annotated declaration by a single line break
- `experimental:double-colon-spacing`: No spaces around `::`
- `experimental:fun-keyword-spacing`: Consistent spacing after the fun keyword
- `experimental:function-type-reference-spacing`: Consistent spacing in the type reference before a function
- `experimental:modifier-list-spacing`: Consistent spacing between modifiers in and after the last modifier in a modifier list
- `experimental:spacing-around-angle-brackets`: No spaces around angle brackets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class ExperimentalRuleSetProvider : RuleSetProvider {
SpacingAroundUnaryOperatorRule(),
AnnotationSpacingRule(),
UnnecessaryParenthesesBeforeTrailingLambdaRule(),
FunKeywordSpacingRule(),
FunctionTypeReferenceSpacingRule(),
ModifierListSpacingRule()
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.pinterest.ktlint.ruleset.experimental

import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.ast.ElementType
import com.pinterest.ktlint.core.ast.ElementType.FUN_KEYWORD
import com.pinterest.ktlint.core.ast.nextLeaf
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement

/**
* Lints and formats the spacing after the fun keyword
*/
public class FunKeywordSpacingRule : Rule("fun-keyword-spacing") {
override fun visit(
node: ASTNode,
autoCorrect: Boolean,
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit
) {
node
.takeIf { it.elementType == FUN_KEYWORD }
?.nextLeaf(includeEmpty = true)
?.takeIf { it.elementType == ElementType.WHITE_SPACE && it.text != " " }
?.let { whiteSpaceAfterFunKeyword ->
emit(
whiteSpaceAfterFunKeyword.startOffset,
"Single space expected after the fun keyword",
true
)
if (autoCorrect) {
(whiteSpaceAfterFunKeyword as LeafPsiElement).rawReplaceWithText(" ")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.pinterest.ktlint.ruleset.experimental

import com.pinterest.ktlint.core.LintError
import com.pinterest.ktlint.test.format
import com.pinterest.ktlint.test.lint
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

class FunKeywordSpacingRuleTest {
@Test
fun `Given a function signature with multiple spaces between the fun keyword and the function name then remove the redundant spaces`() {
val code =
"""
fun foo() = "some-result"
""".trimIndent()
val formattedCode =
"""
fun foo() = "some-result"
""".trimIndent()
assertThat(FunKeywordSpacingRule().lint(code)).containsExactly(
LintError(1, 4, "fun-keyword-spacing", "Single space expected after the fun keyword")
)
assertThat(FunKeywordSpacingRule().format(code)).isEqualTo(formattedCode)
}

@Test
fun `Given a function signature with a newline between the fun keyword and the function name then remove the redundant newline`() {
val code =
"""
fun
foo() = "some-result"
""".trimIndent()
val formattedCode =
"""
fun foo() = "some-result"
""".trimIndent()
assertThat(FunKeywordSpacingRule().lint(code)).containsExactly(
LintError(1, 4, "fun-keyword-spacing", "Single space expected after the fun keyword")
)
assertThat(FunKeywordSpacingRule().format(code)).isEqualTo(formattedCode)
}
}

0 comments on commit 14c0adf

Please sign in to comment.