Skip to content
New issue

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

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

Already on GitHub? # to your account

Fix indentation of super type list of class in case it is preceded by a comment #2228

Merged
merged 1 commit into from
Sep 4, 2023
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 @@ -103,6 +103,7 @@ If an `EditorConfigProperty` is defined in a `Rule` that is only provided via a
* Remove registration of class "org.jetbrains.kotlin.com.intellij.treeCopyHandler" as extension point for the compiler as this is not supported in the embedded Kotlin compiler version 1.9. Also remove Ktlint CLI command line flag `disable-kotlin-extension-point`, and parameter `enableKotlinCompilerExtensionPoint` from `KtLintRuleEngine` to disable the kotlin extension point [#2061](https://github.com/pinterest/ktlint/issues/2061)
* Do not wrap expression after a spread operator `multiline-expression-wrapping` [#2188](https://github.com/pinterest/ktlint/issues/2188)
* 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))

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.pinterest.ktlint.rule.engine.core.api.ElementType.CLASS_BODY
import com.pinterest.ktlint.rule.engine.core.api.ElementType.COLON
import com.pinterest.ktlint.rule.engine.core.api.ElementType.COMMA
import com.pinterest.ktlint.rule.engine.core.api.ElementType.CONSTRUCTOR_KEYWORD
import com.pinterest.ktlint.rule.engine.core.api.ElementType.EOL_COMMENT
import com.pinterest.ktlint.rule.engine.core.api.ElementType.MODIFIER_LIST
import com.pinterest.ktlint.rule.engine.core.api.ElementType.PRIMARY_CONSTRUCTOR
import com.pinterest.ktlint.rule.engine.core.api.ElementType.RPAR
Expand Down Expand Up @@ -492,6 +493,7 @@ public class ClassSignatureRule :
firstSuperType
.prevLeaf()
.takeIf { it.isWhiteSpaceWithNewline() }
?.takeUnless { it.prevSibling()?.elementType == EOL_COMMENT }
?.let { whiteSpaceBeforeSuperType ->
val expectedWhitespace = " "
if (whiteSpaceBeforeSuperType.text != expectedWhitespace) {
Expand Down Expand Up @@ -547,8 +549,8 @@ public class ClassSignatureRule :
.let { whiteSpaceBeforeIdentifier ->
if (index == 0 && node.hasMultilinePrimaryConstructor()) {
val expectedWhitespace = " "
if (whiteSpaceBeforeIdentifier == null ||
whiteSpaceBeforeIdentifier.text != expectedWhitespace
if (whiteSpaceBeforeIdentifier?.prevLeaf()?.elementType != EOL_COMMENT &&
(whiteSpaceBeforeIdentifier == null || whiteSpaceBeforeIdentifier.text != expectedWhitespace)
) {
emit(firstChildNodeInSuperType.startOffset, "Expected single space before the first super type", true)
if (autoCorrect) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,22 +220,31 @@ public class IndentationRule :
lastChildIndent = "",
)

node.elementType == SUPER_TYPE_LIST -> {
if (codeStyle == ktlint_official && node.isPartOfClassWithAMultilinePrimaryConstructor()) {
// Contrary to the default IntelliJ IDEA formatter, indent the super type call entry so that it looks better in case it
// is followed by another super type:
// class Foo(
// val bar1: Bar,
// val bar2: Bar,
// ) : FooBar(
// bar1,
// bar2
// ),
// BarFoo,
startIndentContext(
fromAstNode = node,
activated = true,
)
(node.elementType == SUPER_TYPE_LIST && !node.isPrecededByComment()) ||
(node.isPartOfComment() && node.nextCodeSibling()?.elementType == SUPER_TYPE_LIST) -> {
if (codeStyle == ktlint_official) {
val superTypeList =
if (node.isPartOfComment()) {
node.nextCodeLeaf()!!
} else {
node
}
if (superTypeList.isPartOfClassWithAMultilinePrimaryConstructor()) {
// Contrary to the default IntelliJ IDEA formatter, indent the super type call entry so that it looks better in case it
// is followed by another super type:
// class Foo(
// val bar1: Bar,
// val bar2: Bar,
// ) : FooBar(
// bar1,
// bar2
// ),
// BarFoo,
startIndentContext(
fromAstNode = node,
activated = true,
)
}
}
}

Expand Down Expand Up @@ -1222,6 +1231,8 @@ public class IndentationRule :
activated = true,
)

private fun ASTNode.isPrecededByComment() = prevSibling { !it.isWhiteSpace() }?.isPartOfComment() == true

private companion object {
const val KDOC_CONTINUATION_INDENT = " "
const val TYPE_CONSTRAINT_CONTINUATION_INDENT = " " // Length of keyword "where" plus separating space
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,34 @@ class ClassSignatureRuleTest {
classSignatureWrappingRuleAssertThat(code).hasNoLintViolations()
}

@Test
fun `Given a class with an annotated super type call entry`() {
val code =
"""
class Foo(
bar: Bar,
) : // Some comment
@Unused
FooBar()
""".trimIndent()
classSignatureWrappingRuleAssertThat(code).hasNoLintViolations()
}

@Test
fun `Given a class with an annotated super type entry`() {
val code =
"""
class Foo(
bar: Bar,
) : // Some comment
@Unused
FooBar(),
FooBar2
""".trimIndent()
classSignatureWrappingRuleAssertThat(code)
.hasNoLintViolations()
}

private companion object {
const val UNEXPECTED_SPACES = " "
const val NO_SPACE = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5548,6 +5548,19 @@ internal class IndentationRuleTest {
).isFormattedAs(formattedCode)
}

@Test
fun `Given a class with a comment before the super type list`() {
val code =
"""
class Foo(
bar: Bar,
) : // Some comment
@Unused
FooBar()
""".trimIndent()
indentationRuleAssertThat(code).hasNoLintViolations()
}

private companion object {
val INDENT_STYLE_TAB =
INDENT_STYLE_PROPERTY to PropertyType.IndentStyleValue.tab
Expand Down