diff --git a/documentation/snapshot/docs/rules/standard.md b/documentation/snapshot/docs/rules/standard.md index dff1aa6858..1fb8eca029 100644 --- a/documentation/snapshot/docs/rules/standard.md +++ b/documentation/snapshot/docs/rules/standard.md @@ -4454,6 +4454,8 @@ Suppress or disable rule (1) Multiline expression on the right hand side of an expression are forced to start on a separate line. Expressions in return statement are excluded as that would result in a compilation error. +Setting `ktlint_function_signature_body_expression_wrapping` of the `function-signature` rule takes precedence when set to `default`. This setting keeps the first line of a multiline expression body on the same line as the end of function signature as long as the max line length is not exceeded. In that case, this rule does not wrap the multiline expression. + === "[:material-heart:](#) Ktlint" ```kotlin diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MultilineExpressionWrappingRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MultilineExpressionWrappingRule.kt index 79756519e6..e7a72931cd 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MultilineExpressionWrappingRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MultilineExpressionWrappingRule.kt @@ -50,6 +50,8 @@ 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.upsertWhitespaceBeforeMe import com.pinterest.ktlint.ruleset.standard.StandardRule +import com.pinterest.ktlint.ruleset.standard.rules.FunctionSignatureRule.Companion.FUNCTION_BODY_EXPRESSION_WRAPPING_PROPERTY +import com.pinterest.ktlint.ruleset.standard.rules.FunctionSignatureRule.FunctionBodyExpressionWrapping.default import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** @@ -64,10 +66,12 @@ public class MultilineExpressionWrappingRule : setOf( INDENT_SIZE_PROPERTY, INDENT_STYLE_PROPERTY, + FUNCTION_BODY_EXPRESSION_WRAPPING_PROPERTY, ), ), Rule.OfficialCodeStyle { private var indentConfig = DEFAULT_INDENT_CONFIG + private lateinit var functionBodyExpressionWrapping: FunctionSignatureRule.FunctionBodyExpressionWrapping override fun beforeFirstNode(editorConfig: EditorConfig) { indentConfig = @@ -75,6 +79,7 @@ public class MultilineExpressionWrappingRule : indentStyle = editorConfig[INDENT_STYLE_PROPERTY], tabWidth = editorConfig[INDENT_SIZE_PROPERTY], ) + functionBodyExpressionWrapping = editorConfig[FUNCTION_BODY_EXPRESSION_WRAPPING_PROPERTY] } override fun beforeVisitChildNodes( @@ -172,6 +177,7 @@ public class MultilineExpressionWrappingRule : null != prevCodeSibling() ?.takeIf { it.elementType == EQ || it.elementType == OPERATION_REFERENCE } + ?.takeUnless { functionBodyExpressionWrapping == default && it.treeParent.elementType == FUN } ?.takeUnless { it.isElvisOperator() } ?.takeUnless { it diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MultilineExpressionWrappingRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MultilineExpressionWrappingRuleTest.kt index 1f163b0fe0..f56195acf1 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MultilineExpressionWrappingRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/MultilineExpressionWrappingRuleTest.kt @@ -2,6 +2,8 @@ package com.pinterest.ktlint.ruleset.standard.rules import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CODE_STYLE_PROPERTY import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CodeStyleValue +import com.pinterest.ktlint.ruleset.standard.rules.FunctionSignatureRule.Companion.FUNCTION_BODY_EXPRESSION_WRAPPING_PROPERTY +import com.pinterest.ktlint.ruleset.standard.rules.FunctionSignatureRule.FunctionBodyExpressionWrapping.default import com.pinterest.ktlint.test.KtLintAssertThat import com.pinterest.ktlint.test.LintViolation import com.pinterest.ktlint.test.MULTILINE_STRING_QUOTE @@ -360,6 +362,22 @@ class MultilineExpressionWrappingRuleTest { .isFormattedAs(formattedCode) } + @Test + fun `Given a function with a multiline body expression, and the function signature body expression wrapping is set to 'default' (eg keep first line of expression on same line)`() { + val code = + """ + fun foo() = bar( + "bar" + ) + """.trimIndent() + multilineExpressionWrappingRuleAssertThat(code) + .addAdditionalRuleProvider { IndentationRule() } + .addAdditionalRuleProvider { FunctionSignatureRule() } + .withEditorConfigOverride(CODE_STYLE_PROPERTY to CodeStyleValue.ktlint_official) + .withEditorConfigOverride(FUNCTION_BODY_EXPRESSION_WRAPPING_PROPERTY to default) + .hasNoLintViolations() + } + @Test fun `Given a function with a multiline signature without a return type but with a multiline expression body starting on same line as closing parenthesis of function`() { val code =