Skip to content

Commit

Permalink
1281 white between annotated declarations (#1291)
Browse files Browse the repository at this point in the history
* Remove unused variables

* Fix false positive in spacing-between-declarations-with-annotations

A block of comments including at least one blank line between two annotated
declarations was not recognized as having the required spacing.

 Closes #1281

* Fix false positive in spacing-between-declarations-with-annotations (update changelog)

Closes #1281

Co-authored-by: Paul Dingemans <pdingemans@bol.com>
  • Loading branch information
paul-dingemans and Paul Dingemans authored Nov 30, 2021
1 parent 561e20f commit 161925b
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 6 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).

### Fixed
- KtLint CLI 0.43 doesn't work with JDK 1.8 ([#1271](https://github.com/pinterest/ktlint/issues/1271))

- Fix false positive in rule spacing-between-declarations-with-annotations ([#1281] (https://github.com/pinterest/ktlint/issues/1281))
-
### Changed
- Update Kotlin version to `1.6.0` release

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST
import com.pinterest.ktlint.core.ast.children
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.PsiComment
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
import org.jetbrains.kotlin.psi.psiUtil.prevLeafs

/**
* @see https://youtrack.jetbrains.com/issue/KT-35106
Expand All @@ -24,20 +28,41 @@ class SpacingBetweenDeclarationsWithAnnotationsRule : Rule("spacing-between-decl
val declaration = node.psi.parent as? KtDeclaration
val prevDeclaration =
declaration?.getPrevSiblingIgnoringWhitespaceAndComments(withItself = false) as? KtDeclaration
val prevWhiteSpace = prevDeclaration?.nextSibling as? PsiWhiteSpace
if (declaration != null && prevDeclaration != null && prevWhiteSpace?.text?.count { it == '\n' } == 1) {
val whiteSpaceAfterPreviousDeclaration = prevDeclaration?.nextSibling as? PsiWhiteSpace
val startOfDeclarationIncludingLeadingComment = node.psi.parent.getPrevLeafIgnoringCommentAndWhitespaceExceptBlankLines()
if (whiteSpaceAfterPreviousDeclaration?.text != null &&
startOfDeclarationIncludingLeadingComment?.text?.count { it == '\n' } == 1
) {
emit(
node.startOffset,
"Declarations and declarations with annotations should have an empty space between.",
true
)
if (autoCorrect) {
val indent = prevWhiteSpace.text.substringAfter('\n')
(prevWhiteSpace.node as LeafPsiElement).rawReplaceWithText("\n\n$indent")
val indent = whiteSpaceAfterPreviousDeclaration.text.substringAfter('\n')
(whiteSpaceAfterPreviousDeclaration.node as LeafPsiElement).rawReplaceWithText("\n\n$indent")
}
}
}
}

/**
* Gets the previous element but ignores white whitespaces (excluding blank lines) and comments. Note the difference
* with method [PsiElement.getPrevSiblingIgnoringWhitespaceAndComments] which excludes blank lines as well.
*/
private fun PsiElement.getPrevLeafIgnoringCommentAndWhitespaceExceptBlankLines(): PsiElement? {
var prevLeaf: PsiElement? = this.prevLeaf()
val iterator = prevLeafs.iterator()
while (iterator.hasNext()) {
val psiElement = iterator.next()
if (psiElement is PsiComment || (psiElement is PsiWhiteSpace && psiElement.text?.count { it == '\n' } == 1)) {
prevLeaf = psiElement
} else {
break
}
}
return prevLeaf
}

private fun ASTNode.hasAnnotationsAsChildren(): Boolean = children().find { it.psi is KtAnnotationEntry } != null
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class SpacingBetweenDeclarationsWithAnnotationsRuleTest {
}

@Test
fun `missing space after comment with previous variable should do nothing`() {
fun `No blank line is required between comment and an annotated declaration`() {
Assertions.assertThat(
SpacingBetweenDeclarationsWithAnnotationsRule().lint(
"""
Expand All @@ -250,4 +250,27 @@ class SpacingBetweenDeclarationsWithAnnotationsRuleTest {
)
).isEmpty()
}

@Test
fun `Issue 1281 - No blank line is required between comment and an annotated declaration when previous declaration end with a comment`() {
Assertions.assertThat(
SpacingBetweenDeclarationsWithAnnotationsRule().lint(
"""
class KotlinPluginTest {
// tag::setUp[]
@BeforeEach
fun setUp() {
}
// end::setUp[]
// tag::testQuery[]
@Test
fun testFindById() {
}
// end::testQuery[]
}
""".trimIndent()
)
).isEmpty()
}
}

0 comments on commit 161925b

Please sign in to comment.