Skip to content

Commit

Permalink
Allow a super type list starting with an annotation having a paramete…
Browse files Browse the repository at this point in the history
…r to be on the same line as the closing parenthesis of the enclosing class (#2230)
  • Loading branch information
paul-dingemans authored Sep 4, 2023
1 parent d84c4a0 commit 698d976
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ If an `EditorConfigProperty` is defined in a `Rule` that is only provided via a
* Prevent cyclic dependency between `modifier-list-spacing` rule and `indent` rule when the super type call entry is annotated ([#2227](https://github.com/pinterest/ktlint/pull/2227))
* Do not remove parenthesis after explicit constructor keyword when it has no parameters ([#2226](https://github.com/pinterest/ktlint/pull/2226))
* Fix indentation of super type list of class in case it is preceded by a comment ([#2228](https://github.com/pinterest/ktlint/pull/2228))
* Allow a super type list starting with an annotation having a parameter to be on the same line as the closing parenthesis of the enclosing class ([#2230](https://github.com/pinterest/ktlint/pull/2230))

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package com.pinterest.ktlint.ruleset.standard.rules
import com.pinterest.ktlint.rule.engine.core.api.ElementType.ANNOTATED_EXPRESSION
import com.pinterest.ktlint.rule.engine.core.api.ElementType.ANNOTATION
import com.pinterest.ktlint.rule.engine.core.api.ElementType.ANNOTATION_ENTRY
import com.pinterest.ktlint.rule.engine.core.api.ElementType.CLASS
import com.pinterest.ktlint.rule.engine.core.api.ElementType.COLON
import com.pinterest.ktlint.rule.engine.core.api.ElementType.CONSTRUCTOR_KEYWORD
import com.pinterest.ktlint.rule.engine.core.api.ElementType.FILE_ANNOTATION_LIST
import com.pinterest.ktlint.rule.engine.core.api.ElementType.GT
import com.pinterest.ktlint.rule.engine.core.api.ElementType.MODIFIER_LIST
import com.pinterest.ktlint.rule.engine.core.api.ElementType.RPAR
import com.pinterest.ktlint.rule.engine.core.api.ElementType.TYPE_ARGUMENT_LIST
import com.pinterest.ktlint.rule.engine.core.api.ElementType.TYPE_PROJECTION
import com.pinterest.ktlint.rule.engine.core.api.ElementType.TYPE_REFERENCE
Expand All @@ -32,6 +35,8 @@ import com.pinterest.ktlint.rule.engine.core.api.isWhiteSpaceWithNewline
import com.pinterest.ktlint.rule.engine.core.api.lastChildLeafOrSelf
import com.pinterest.ktlint.rule.engine.core.api.nextCodeLeaf
import com.pinterest.ktlint.rule.engine.core.api.nextCodeSibling
import com.pinterest.ktlint.rule.engine.core.api.prevCodeLeaf
import com.pinterest.ktlint.rule.engine.core.api.prevCodeSibling
import com.pinterest.ktlint.rule.engine.core.api.prevLeaf
import com.pinterest.ktlint.rule.engine.core.api.upsertWhitespaceAfterMe
import com.pinterest.ktlint.rule.engine.core.api.upsertWhitespaceBeforeMe
Expand Down Expand Up @@ -153,10 +158,19 @@ public class AnnotationRule :
.filter {
it.isAnnotationEntryWithValueArgumentList() ||
!it.isPrecededByOtherAnnotationEntryWithoutParametersOnTheSameLine()
}.forEach { annotationEntry ->
}.forEachIndexed { index, annotationEntry ->
annotationEntry
.prevLeaf()
?.let { prevLeaf ->
.takeUnless {
// Allow in ktlint_official code style:
// class Foo(
// bar: Bar,
// ) : @Suppress("DEPRECATION")
// FooBar()
index == 0 &&
codeStyle == CodeStyleValue.ktlint_official &&
it.annotationOnSameLineAsClosingParenthesisOfClassParameterList()
}?.let { prevLeaf ->
// Let the indentation rule determine the exact indentation and only report and fix when the line needs to be
// wrapped
if (!prevLeaf.textContains('\n')) {
Expand Down Expand Up @@ -369,6 +383,22 @@ public class AnnotationRule :

private fun ASTNode.isFollowedByOtherAnnotationEntry() = siblings(forward = true).any { it.elementType == ANNOTATION_ENTRY }

private fun ASTNode?.annotationOnSameLineAsClosingParenthesisOfClassParameterList() =
// Allow:
// class Foo(
// bar: Bar,
// ) : @Suppress("DEPRECATION")
// FooBar()
this
?.takeIf { it.treeParent?.elementType == CLASS }
?.prevCodeSibling()
?.takeIf { it.elementType == COLON }
?.prevCodeLeaf()
?.takeIf { it.elementType == RPAR }
?.prevLeaf()
?.isWhiteSpaceWithNewline()
?: false

private fun ASTNode.isOnSameLineAsNextAnnotationEntry() =
siblings(forward = true)
.takeWhile { it.elementType != ANNOTATION_ENTRY }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -974,4 +974,16 @@ class AnnotationRuleTest {
""".trimIndent()
annotationRuleAssertThat(code).hasNoLintViolations()
}

@Test
fun `Given a class with a super type list starting with an annotation having parameter`() {
val code =
"""
class Foo(
bar: Bar,
) : @Suppress("DEPRECATION")
FooBar()
""".trimIndent()
annotationRuleAssertThat(code).hasNoLintViolations()
}
}

0 comments on commit 698d976

Please sign in to comment.