From a89c78d15c77dccfc0dc333a51c1a4d1cc6c6197 Mon Sep 17 00:00:00 2001
From: paul-dingemans <paul-dingemans@users.noreply.github.com>
Date: Sat, 23 Sep 2023 14:00:17 +0200
Subject: [PATCH 1/2] Do not replace function body having a return statement
 only in case the return statement contains an intermediate exit point

Closes #2269
---
 CHANGELOG.md                                      |  1 +
 .../standard/rules/FunctionExpressionBodyRule.kt  |  7 +++++++
 .../rules/FunctionExpressionBodyRuleTest.kt       | 15 +++++++++++++++
 3 files changed, 23 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 23fd898cf5..f50741a9db 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
 * Fix indent of multiline object declaration inside class `indent` [#2257](https://github.com/pinterest/ktlint/issue/2257)
 * Ignore anonymous function in rule `function-naming` [#2260](https://github.com/pinterest/ktlint/issue/2260)
 * Do not force blank line before function in right hand side of assignment `blank-line-before-declaration` [#2260](https://github.com/pinterest/ktlint/issue/2260)
+* Do not replace function body having a return statement only in case the return statement contains an intermediate exit point 'function-expression-body' [#2269](https://github.com/pinterest/ktlint/issue/2269)
 
 ### Changed
 
diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt
index d9a7ef01b9..0e3b84cd8f 100644
--- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt
+++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt
@@ -21,7 +21,9 @@ import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfig
 import com.pinterest.ktlint.rule.engine.core.api.editorconfig.INDENT_SIZE_PROPERTY
 import com.pinterest.ktlint.rule.engine.core.api.editorconfig.INDENT_STYLE_PROPERTY
 import com.pinterest.ktlint.rule.engine.core.api.editorconfig.MAX_LINE_LENGTH_PROPERTY
+import com.pinterest.ktlint.rule.engine.core.api.firstChildLeafOrSelf
 import com.pinterest.ktlint.rule.engine.core.api.isWhiteSpace
+import com.pinterest.ktlint.rule.engine.core.api.leavesIncludingSelf
 import com.pinterest.ktlint.rule.engine.core.api.nextSibling
 import com.pinterest.ktlint.rule.engine.core.api.prevSibling
 import com.pinterest.ktlint.ruleset.standard.StandardRule
@@ -36,6 +38,7 @@ import org.jetbrains.kotlin.psi.KtFunction
 import org.jetbrains.kotlin.psi.KtScript
 import org.jetbrains.kotlin.psi.KtTypeReference
 import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
+import org.jetbrains.kotlin.psi.psiUtil.leaves
 
 /**
  * [Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html#functions):
@@ -109,6 +112,7 @@ public class FunctionExpressionBodyRule :
         require(block.elementType == BLOCK)
         block
             .takeIf { it.containingOnly(RETURN) }
+            ?.takeUnless { it.containsMultipleReturns() }
             ?.findChildByType(RETURN)
             ?.findChildByType(RETURN_KEYWORD)
             ?.nextSibling { !it.isWhiteSpace() }
@@ -161,6 +165,9 @@ public class FunctionExpressionBodyRule :
                 .singleOrNull()
                 ?.elementType
 
+    private fun ASTNode.containsMultipleReturns() =
+        firstChildLeafOrSelf().leavesIncludingSelf().count { it.elementType == RETURN_KEYWORD } > 1
+
     private fun ASTNode.createUnitTypeReference() =
         PsiFileFactory
             .getInstance(psi.project)
diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRuleTest.kt
index 7c2fa3b07e..10bc76f00f 100644
--- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRuleTest.kt
+++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRuleTest.kt
@@ -153,4 +153,19 @@ class FunctionExpressionBodyRuleTest {
             .isFormattedAs(formattedCode)
             .hasLintViolation(1, 16, "Function body should be replaced with body expression")
     }
+
+    @Test
+    fun `Given a function with a single expression but having multiple return expression inside then do not covert as it results in a compilation error`() {
+        val code =
+            """
+            fun foo(): Any {
+                return if (true) {
+                    Foo()
+                } else {
+                    return Bar()
+                }
+            }
+            """.trimIndent()
+        functionExpressionBodyRule(code).hasNoLintViolations()
+    }
 }

From bb72b54990f88a9b8ced427365a50f77c21c5515 Mon Sep 17 00:00:00 2001
From: paul-dingemans <paul-dingemans@users.noreply.github.com>
Date: Sat, 23 Sep 2023 14:29:24 +0200
Subject: [PATCH 2/2] Fix lint violation

---
 .../ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt  | 1 -
 1 file changed, 1 deletion(-)

diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt
index 0e3b84cd8f..8514b8a2e1 100644
--- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt
+++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionExpressionBodyRule.kt
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.psi.KtFunction
 import org.jetbrains.kotlin.psi.KtScript
 import org.jetbrains.kotlin.psi.KtTypeReference
 import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
-import org.jetbrains.kotlin.psi.psiUtil.leaves
 
 /**
  * [Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html#functions):