Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new experimental rule function-spacing #1362

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
}
}