From b68bed53e21cf207e160e423dcdc324c769189a2 Mon Sep 17 00:00:00 2001 From: paul-dingemans Date: Sat, 15 Jul 2023 18:36:28 +0200 Subject: [PATCH 1/2] Display log message `Format was not able to resolve all violations which (theoretically) can be autocorrected in file ... in 3 consecutive runs of format` only when after the third consecutive run still a violation exists that can be autocorrected. Closes #2129 --- CHANGELOG.md | 1 + .../rule/engine/core/api/ASTNodeExtension.kt | 38 ++++- .../engine/core/api/ASTNodeExtensionTest.kt | 137 ++++++++++++++---- .../rule/engine/api/KtLintRuleEngine.kt | 27 +++- 4 files changed, 166 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c49dcbfb5..db3c6c0767 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). * Allow to disable ktlint in `.editorconfig` for a glob ([#2100](https://github.com/pinterest/ktlint/issues/2100)) * Fix wrapping of nested function literals `wrapping` ([#2106](https://github.com/pinterest/ktlint/issues/2106)) * Do not indent class body for classes having a long super type list in code style `ktlint_official` as it is inconsistent compared to other class bodies `indent` [#2115](https://github.com/pinterest/ktlint/issues/2115) +* Log message `Format was not able to resolve all violations which (theoretically) can be autocorrected in file ... in 3 consecutive runs of format` is now only displayed in case a new ktlint rule is actually needed. [#2129](https://github.com/pinterest/ktlint/issues/2129) ### Changed diff --git a/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtension.kt b/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtension.kt index 201e7dac43..054d306400 100644 --- a/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtension.kt +++ b/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtension.kt @@ -245,11 +245,23 @@ public fun ASTNode.upsertWhitespaceBeforeMe(text: String) { } } } else { - val prevLeaf = - requireNotNull(prevLeaf()) { - "Can not upsert a whitespace if the first node is a non-leaf node" + when (val prevSibling = prevSibling()) { + null -> { + // Never insert a whitespace element as first child node in a composite node. Instead, upsert just before the composite node + treeParent.upsertWhitespaceBeforeMe(text) } - prevLeaf.upsertWhitespaceAfterMe(text) + + is LeafElement -> { + prevSibling.upsertWhitespaceAfterMe(text) + } + + else -> { + // Insert in between two composite nodes + PsiWhiteSpaceImpl(text).also { psiWhiteSpace -> + treeParent.addChild(psiWhiteSpace.node, this) + } + } + } } } @@ -279,7 +291,23 @@ public fun ASTNode.upsertWhitespaceAfterMe(text: String) { } } } else { - lastChildLeafOrSelf().upsertWhitespaceAfterMe(text) + when (val nextSibling = nextSibling()) { + null -> { + // Never insert a whitespace element as last child node in a composite node. Instead, upsert just after the composite node + treeParent.upsertWhitespaceAfterMe(text) + } + + is LeafElement -> { + nextSibling.upsertWhitespaceBeforeMe(text) + } + + else -> { + // Insert in between two composite nodes + PsiWhiteSpaceImpl(text).also { psiWhiteSpace -> + treeParent.addChild(psiWhiteSpace.node, nextSibling) + } + } + } } } diff --git a/ktlint-rule-engine-core/src/test/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtensionTest.kt b/ktlint-rule-engine-core/src/test/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtensionTest.kt index 314059d452..d08d098c71 100644 --- a/ktlint-rule-engine-core/src/test/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtensionTest.kt +++ b/ktlint-rule-engine-core/src/test/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtensionTest.kt @@ -2,13 +2,16 @@ package com.pinterest.ktlint.rule.engine.core.api import com.pinterest.ktlint.rule.engine.api.Code import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine +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.CLASS_BODY import com.pinterest.ktlint.rule.engine.core.api.ElementType.ENUM_ENTRY import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUN import com.pinterest.ktlint.rule.engine.core.api.ElementType.IDENTIFIER import com.pinterest.ktlint.rule.engine.core.api.ElementType.LPAR +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_REFERENCE import com.pinterest.ktlint.rule.engine.core.api.ElementType.VALUE_PARAMETER import com.pinterest.ktlint.rule.engine.core.api.ElementType.VALUE_PARAMETER_LIST import com.pinterest.ktlint.rule.engine.core.api.ElementType.WHITE_SPACE @@ -303,7 +306,7 @@ class ASTNodeExtensionTest { @Nested inner class UpsertWhitespaceBeforeMe { @Test - fun `Given a whitespace node and upsert a whitespace before the node (RPAR) then replace the current whitespace element`() { + fun `Given an upsert of a whitespace based before another whitespace node then replace the existing whitespace element`() { val code = """ fun foo( ) = 42 @@ -327,10 +330,10 @@ class ASTNodeExtensionTest { } @Test - fun `Given a node (RPAR) which is preceded by a non-whitespace leaf element (LPAR) and upsert a whitespace before the node (RPAR) then create a new whitespace element before the node (RPAR)`() { + fun `Given an upsert of a whitespace before a non-whitespace node (RPAR) which is preceded by a whitespace leaf element (LPAR) then then replace the whitespace element`() { val code = """ - fun foo() = 42 + fun foo( ) = 42 """.trimIndent() val formattedCode = """ @@ -350,10 +353,10 @@ class ASTNodeExtensionTest { } @Test - fun `Given a node (RPAR) which is preceded by a whitespace leaf element and upsert a whitespace before the node (RPAR) then replace the whitespace element before the node (RPAR)`() { + fun `Given an upsert of a whitespace before a non-whitespace node (RPAR) which is preceded by another non-whitespace leaf element (LPAR) then create a new whitespace element`() { val code = """ - fun foo( ) = 42 + fun foo() = 42 """.trimIndent() val formattedCode = """ @@ -373,7 +376,33 @@ class ASTNodeExtensionTest { } @Test - fun `Given a node (VALUE_PARAMETER) which is preceded by a non-whitespace leaf element (LPAR) and upsert a whitespace before the node (VALUE_PARAMETER) then create a new whitespace element before the node (VALUE_PARAMETER)`() { + fun `Given an upsert of a whitespace before a composite node (ANNOTATION_ENTRY) which is the first child of another composite element then create a new whitespace before (VALUE_PARAMETER)`() { + val code = + """ + fun foo(@Bar string: String) = 42 + """.trimIndent() + val formattedCode = + """ + fun foo( + @Bar string: String) = 42 + """.trimIndent() + + val actual = + code + .transformAst { + findChildByType(FUN) + ?.findChildByType(VALUE_PARAMETER_LIST) + ?.findChildByType(VALUE_PARAMETER) + ?.findChildByType(MODIFIER_LIST) + ?.findChildByType(ANNOTATION_ENTRY) + ?.upsertWhitespaceBeforeMe("\n ") + }.text + + assertThat(actual).isEqualTo(formattedCode) + } + + @Test + fun `Given an upsert of a whitespace before a composite node (VALUE_PARAMETER) which is preceded by a non-whitespace leaf element (LPAR) then create a new whitespace element before the node (VALUE_PARAMETER)`() { val code = """ fun foo(string: String) = 42 @@ -397,25 +426,26 @@ class ASTNodeExtensionTest { } @Test - fun `Given a node (FUN bar) which is preceded by a composite element (FUN foo) and upsert a whitespace before the node (FUN bar) then create a new whitespace element before the node (FUN bar)`() { + fun `Given an upsert of a whitespace before a composite node (ANNOTATION_ENTRY) which is preceded by another composite node (ANNOTATION_ENTRY) then create a new whitespace between the ANNOTATION_ENTRIES`() { val code = """ - fun foo() = "foo" - fun bar() = "bar" + fun foo(@Bar@Foo string: String) = 42 """.trimIndent() val formattedCode = """ - fun foo() = "foo" - - fun bar() = "bar" + fun foo(@Bar @Foo string: String) = 42 """.trimIndent() val actual = code .transformAst { - children() - .last { it.elementType == FUN } - .upsertWhitespaceBeforeMe("\n\n") + findChildByType(FUN) + ?.findChildByType(VALUE_PARAMETER_LIST) + ?.findChildByType(VALUE_PARAMETER) + ?.findChildByType(MODIFIER_LIST) + ?.findChildByType(ANNOTATION_ENTRY) + ?.nextSibling() + ?.upsertWhitespaceBeforeMe(" ") }.text assertThat(actual).isEqualTo(formattedCode) @@ -425,10 +455,34 @@ class ASTNodeExtensionTest { @Nested inner class UpsertWhitespaceAfterMe { @Test - fun `Given a node (LPAR) which is followed by a non-whitespace leaf element (RPAR) and upsert a whitespace after the node (LPAR) then create a new whitespace element after the node (LPAR)`() { + fun `Given an upsert of a whitespace based after another whitespace node then replace the existing whitespace element`() { val code = """ - fun foo() = 42 + fun foo( ) = 42 + """.trimIndent() + val formattedCode = + """ + fun foo( + ) = 42 + """.trimIndent() + + val actual = + code + .transformAst { + findChildByType(FUN) + ?.findChildByType(VALUE_PARAMETER_LIST) + ?.findChildByType(WHITE_SPACE) + ?.upsertWhitespaceAfterMe("\n") + }.text + + assertThat(actual).isEqualTo(formattedCode) + } + + @Test + fun `Given an upsert of a whitespace after a non-whitespace node (LPAR) which is followed by a whitespace leaf element (RPAR) then then replace the whitespace element`() { + val code = + """ + fun foo( ) = 42 """.trimIndent() val formattedCode = """ @@ -448,10 +502,10 @@ class ASTNodeExtensionTest { } @Test - fun `Given a node (LPAR) which is followed by a whitespace leaf element and upsert a whitespace after the node (LPAR) then replace the whitespace element after the node (LPAR)`() { + fun `Given an upsert of a whitespace after a non-whitespace node (LPAR) which is followed by another non-whitespace leaf element (RPAR) then create a new whitespace element`() { val code = """ - fun foo( ) = 42 + fun foo() = 42 """.trimIndent() val formattedCode = """ @@ -471,7 +525,32 @@ class ASTNodeExtensionTest { } @Test - fun `Given a node (VALUE_PARAMETER) which is followed by a non-whitespace leaf element (RPAR) and upsert a whitespace after the node (VALUE_PARAMETER) then create a new whitespace element after the node (VALUE_PARAMETER)`() { + fun `Given an upsert of a whitespace after a composite node (ANNOTATION_ENTRY) which is the last child of another composite element then create a new whitespace after (VALUE_PARAMETER)`() { + val code = + """ + fun foo(@Bar string: String) = 42 + """.trimIndent() + val formattedCode = + """ + fun foo(@Bar string: String + ) = 42 + """.trimIndent() + + val actual = + code + .transformAst { + findChildByType(FUN) + ?.findChildByType(VALUE_PARAMETER_LIST) + ?.findChildByType(VALUE_PARAMETER) + ?.findChildByType(TYPE_REFERENCE) + ?.upsertWhitespaceAfterMe("\n") + }.text + + assertThat(actual).isEqualTo(formattedCode) + } + + @Test + fun `Given an upsert of a whitespace after a composite node (VALUE_PARAMETER) which is followed by a non-whitespace leaf element (RPAR) then create a new whitespace element after the node (VALUE_PARAMETER)`() { val code = """ fun foo(string: String) = 42 @@ -495,25 +574,25 @@ class ASTNodeExtensionTest { } @Test - fun `Given a node (FUN foo) which is followed by a composite element (FUN bar) and upsert a whitespace after the node (FUN foo) then create a new whitespace element after the node (FUN foo)`() { + fun `Given an upsert of a whitespace after a composite node (ANNOTATION_ENTRY) which is followed by another composite node (ANNOTATION_ENTRY) then create a new whitespace between the ANNOTATION_ENTRIES`() { val code = """ - fun foo() = "foo" - fun bar() = "bar" + fun foo(@Bar@Foo string: String) = 42 """.trimIndent() val formattedCode = """ - fun foo() = "foo" - - fun bar() = "bar" + fun foo(@Bar @Foo string: String) = 42 """.trimIndent() val actual = code .transformAst { - children() - .first { it.elementType == FUN } - .upsertWhitespaceAfterMe("\n\n") + findChildByType(FUN) + ?.findChildByType(VALUE_PARAMETER_LIST) + ?.findChildByType(VALUE_PARAMETER) + ?.findChildByType(MODIFIER_LIST) + ?.findChildByType(ANNOTATION_ENTRY) + ?.upsertWhitespaceAfterMe(" ") }.text assertThat(actual).isEqualTo(formattedCode) diff --git a/ktlint-rule-engine/src/main/kotlin/com/pinterest/ktlint/rule/engine/api/KtLintRuleEngine.kt b/ktlint-rule-engine/src/main/kotlin/com/pinterest/ktlint/rule/engine/api/KtLintRuleEngine.kt index 3fdbdc1129..1c5ba36c7e 100644 --- a/ktlint-rule-engine/src/main/kotlin/com/pinterest/ktlint/rule/engine/api/KtLintRuleEngine.kt +++ b/ktlint-rule-engine/src/main/kotlin/com/pinterest/ktlint/rule/engine/api/KtLintRuleEngine.kt @@ -179,9 +179,30 @@ public class KtLintRuleEngine( } } while (mutated && formatRunCount < MAX_FORMAT_RUNS_PER_FILE) if (formatRunCount == MAX_FORMAT_RUNS_PER_FILE && mutated) { - LOGGER.warn { - "Format was not able to resolve all violations which (theoretically) can be autocorrected in file " + - "${code.filePathOrStdin()} in $MAX_FORMAT_RUNS_PER_FILE consecutive runs of format." + // It is unknown if the last format run introduces new lint violations which can be autocorrected. So run lint once more so that + // the user can be informed about this correctly. + var hasErrorsWhichCanBeAutocorrected = false + visitorProvider + .visitor() + .invoke { rule -> + ruleExecutionContext.executeRule(rule, false) { offset, message, canBeAutoCorrected -> + if (canBeAutoCorrected) { + ruleExecutionContext.rebuildSuppressionLocator() + val formattedCode = + ruleExecutionContext + .rootNode + .text + .replace("\n", ruleExecutionContext.determineLineSeparator(code.content)) + val (line, col) = ruleExecutionContext.positionInTextLocator(offset) + hasErrorsWhichCanBeAutocorrected = true + } + } + } + if (hasErrorsWhichCanBeAutocorrected) { + LOGGER.warn { + "Format was not able to resolve all violations which (theoretically) can be autocorrected in file " + + "${code.filePathOrStdin()} in $MAX_FORMAT_RUNS_PER_FILE consecutive runs of format." + } } } From 49eb918a827f711056016997019d2d0bc37f5194 Mon Sep 17 00:00:00 2001 From: paul-dingemans Date: Sat, 15 Jul 2023 18:57:33 +0200 Subject: [PATCH 2/2] Fix wrapping of function signature in case the opening brace of the function body block exceeds the maximum line length. Fix upsert of whitespace into composite nodes. Closes #2130 --- CHANGELOG.md | 1 + .../standard/rules/FunctionSignatureRule.kt | 89 ++++++++++--------- .../rules/FunctionSignatureRuleTest.kt | 9 +- 3 files changed, 53 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db3c6c0767..dd08d5f709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). * Fix wrapping of nested function literals `wrapping` ([#2106](https://github.com/pinterest/ktlint/issues/2106)) * Do not indent class body for classes having a long super type list in code style `ktlint_official` as it is inconsistent compared to other class bodies `indent` [#2115](https://github.com/pinterest/ktlint/issues/2115) * Log message `Format was not able to resolve all violations which (theoretically) can be autocorrected in file ... in 3 consecutive runs of format` is now only displayed in case a new ktlint rule is actually needed. [#2129](https://github.com/pinterest/ktlint/issues/2129) +* Fix wrapping of function signature in case the opening brace of the function body block exceeds the maximum line length. Fix upsert of whitespace into composite nodes. `function-signature` [#2130](https://github.com/pinterest/ktlint/issues/2130) ### Changed diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionSignatureRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionSignatureRule.kt index 596533b3eb..3625054e2a 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionSignatureRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionSignatureRule.kt @@ -9,6 +9,7 @@ import com.pinterest.ktlint.rule.engine.core.api.ElementType.EOL_COMMENT import com.pinterest.ktlint.rule.engine.core.api.ElementType.EQ import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUN import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUN_KEYWORD +import com.pinterest.ktlint.rule.engine.core.api.ElementType.LBRACE import com.pinterest.ktlint.rule.engine.core.api.ElementType.LPAR import com.pinterest.ktlint.rule.engine.core.api.ElementType.MODIFIER_LIST import com.pinterest.ktlint.rule.engine.core.api.ElementType.RPAR @@ -178,13 +179,21 @@ public class FunctionSignatureRule : val rewriteFunctionSignatureWithParameters = node.countParameters() > 0 && singleLineFunctionSignatureLength > maxLineLength if (forceMultilineSignature || rewriteFunctionSignatureWithParameters) { fixWhiteSpacesInValueParameterList(node, emit, autoCorrect, multiline = true, dryRun = false) - // Due to rewriting the function signature, the remaining length on the last line of the multiline - // signature needs to be recalculated - val lengthOfLastLine = recalculateRemainLengthForFirstLineOfBodyExpression(node) - fixFunctionBody(node, emit, autoCorrect, maxLineLength - lengthOfLastLine) + if (node.findChildByType(EQ) == null) { + fixWhitespaceBeforeFunctionBodyBlock(node, emit, autoCorrect, dryRun = false) + } else { + // Due to rewriting the function signature, the remaining length on the last line of the multiline signature needs to be + // recalculated + val lengthOfLastLine = recalculateRemainingLengthForFirstLineOfBodyExpression(node) + fixFunctionBodyExpression(node, emit, autoCorrect, maxLineLength - lengthOfLastLine) + } } else { fixWhiteSpacesInValueParameterList(node, emit, autoCorrect, multiline = false, dryRun = false) - fixFunctionBody(node, emit, autoCorrect, maxLineLength - singleLineFunctionSignatureLength) + if (node.findChildByType(EQ) == null) { + fixWhitespaceBeforeFunctionBodyBlock(node, emit, autoCorrect, dryRun = false) + } else { + fixFunctionBodyExpression(node, emit, autoCorrect, maxLineLength - singleLineFunctionSignatureLength) + } } } else { // When max line length is not set then keep it as single line function signature only when the original @@ -202,7 +211,7 @@ public class FunctionSignatureRule : } } - private fun recalculateRemainLengthForFirstLineOfBodyExpression(node: ASTNode): Int { + private fun recalculateRemainingLengthForFirstLineOfBodyExpression(node: ASTNode): Int { val closingParenthesis = node .findChildByType(VALUE_PARAMETER_LIST) @@ -250,7 +259,12 @@ public class FunctionSignatureRule : // maximum line length). The white space correction will be calculated via a dry run of the actual fix. return actualFunctionSignatureLength + // Calculate the white space correction in case the signature would be rewritten to a single line - fixWhiteSpacesInValueParameterList(node, emit, autoCorrect, multiline = false, dryRun = true) + fixWhiteSpacesInValueParameterList(node, emit, autoCorrect, multiline = false, dryRun = true) + + if (node.findChildByType(EQ) == null) { + fixWhitespaceBeforeFunctionBodyBlock(node, emit, autoCorrect, dryRun = true) + } else { + 0 + } } private fun ASTNode.getFunctionSignatureLength() = indent(false).length + getFunctionSignatureNodesLength() @@ -505,19 +519,6 @@ public class FunctionSignatureRule : return whiteSpaceCorrection } - private fun fixFunctionBody( - node: ASTNode, - emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit, - autoCorrect: Boolean, - maxLengthRemainingForFirstLineOfBodyExpression: Int, - ) { - if (node.findChildByType(EQ) == null) { - fixFunctionBodyBlock(node, emit, autoCorrect) - } else { - fixFunctionBodyExpression(node, emit, autoCorrect, maxLengthRemainingForFirstLineOfBodyExpression) - } - } - private fun fixFunctionBodyExpression( node: ASTNode, emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit, @@ -618,36 +619,36 @@ public class FunctionSignatureRule : ?.matches(INDENT_WITH_CLOSING_PARENTHESIS) ?: false - private fun fixFunctionBodyBlock( + private fun fixWhitespaceBeforeFunctionBodyBlock( node: ASTNode, emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit, autoCorrect: Boolean, - ) { - val lastNodeOfFunctionSignatureWithBlockBody = - node - .getLastNodeOfFunctionSignatureWithBlockBody() - ?.nextLeaf(includeEmpty = true) - ?: return - - val bodyNodes = node.getFunctionBody(lastNodeOfFunctionSignatureWithBlockBody) - val whiteSpaceBeforeFunctionBodyExpression = bodyNodes.getStartingWhitespaceOrNull() - val functionBodyBlock = bodyNodes.dropWhile { it.isWhiteSpace() } + dryRun: Boolean, + ): Int { + var whiteSpaceCorrection = 0 - functionBodyBlock - .joinTextToString() - .split("\n") - .firstOrNull() - ?.also { - if (whiteSpaceBeforeFunctionBodyExpression?.text != " ") { - emit(functionBodyBlock.first().startOffset, "Expected a single space before body block", true) - if (autoCorrect) { - functionBodyBlock - .first() - .prevLeaf(true) - ?.upsertWhitespaceAfterMe(" ") + node + .findChildByType(BLOCK) + ?.takeIf { it.findChildByType(LBRACE) != null } + ?.let { block -> + block + .prevLeaf() + .takeIf { it.isWhiteSpace() } + .let { whiteSpaceBeforeBlock -> + if (whiteSpaceBeforeBlock == null || whiteSpaceBeforeBlock.text != " ") { + if (!dryRun) { + emit(block.startOffset, "Expected a single space before body block", true) + } + if (autoCorrect && !dryRun) { + block.upsertWhitespaceBeforeMe(" ") + } else { + whiteSpaceCorrection += 1 - (whiteSpaceBeforeBlock?.textLength ?: 0) + } + } } - } } + + return whiteSpaceCorrection } private fun ASTNode.getFunctionBody(splitNode: ASTNode?): List = diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionSignatureRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionSignatureRuleTest.kt index 138b8cd989..b965d01431 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionSignatureRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionSignatureRuleTest.kt @@ -63,8 +63,13 @@ class FunctionSignatureRuleTest { functionSignatureWrappingRuleAssertThat(code) .setMaxLineLength() .addAdditionalRuleProvider { FunctionStartOfBodySpacingRule() } - .hasLintViolation(2, 38, "Expected a single space before body block") - .isFormattedAs(formattedCode) + .hasLintViolations( + LintViolation(2, 7, "Newline expected after opening parenthesis"), + LintViolation(2, 15, "Parameter should start on a newline"), + LintViolation(2, 23, "Parameter should start on a newline"), + LintViolation(2, 29, "Newline expected before closing parenthesis"), + LintViolation(2, 38, "Expected a single space before body block"), + ).isFormattedAs(formattedCode) } @Test