== Why is this an issue? In Kotlin, `if` and `when` statements are expressions that return a value. This allows for a more concise and functional programming style with less cognitive complexity, because it results in fewer return points and fewer variable assignments in a function. If both branches of an `if` statement end with a `return` statement, the `if` statement should be used instead as an expression for a `return` statement. If all branches of an exhaustive `when` statement end with a `return` statement, the `when` statement should be used instead as an expression for a `return` statement. A `when` statement is exhaustive when it covers all elements of an enum or features an `else` clause. === What is the potential impact? ==== Readability and Understanding This change makes it easier to understand a function because it will reduce its complexity. This is because the function now contains fewer return points that the developer needs to keep track of. == How to fix it Use the `if` statement as an expression for a `return` statement. Lift the `return` keyword from the end of the `if` band `else` branch before the `if` keyword. Use the `when` statement as an expression for a `return` statement. Lift the `return` keyword from the end of all its case clauses before the `when` keyword. === Code examples ==== Noncompliant code example [source,kotlin,diff-id=1,diff-type=noncompliant] ---- fun returnIfElse(value: Int): String { // ... if (value >= 0) { // Noncompliant, every branch contains a return statement return "positive" } else { return "negative" } } ---- ==== Compliant solution [source,kotlin,diff-id=1,diff-type=compliant] ---- fun returnIfElse(value: Int): String { // ... return if (value >= 0) { // Compliant "positive" } else { "negative" } } ---- ==== Noncompliant code example [source,kotlin,diff-id=2,diff-type=noncompliant] ---- fun returnWhenElse(a: Float): Int { // ... when { // Noncompliant, every branch of exhaustive `when` contains a return statement a < 0 -> return -1 a > 0 -> return 1 else -> return 0 } } ---- ==== Compliant solution [source,kotlin,diff-id=2,diff-type=compliant] ---- fun returnWhenElse(a: Float): Int { // ... return when { // Compliant a < 0 -> -1 a > 0 -> 1 else -> 0 } } ---- ==== Noncompliant code example [source,kotlin] ---- enum class OneTwoThree { ONE, TWO, THREE } ---- [source,kotlin,diff-id=3,diff-type=noncompliant] ---- fun returnWhenEnum(oneTwoThree: OneTwoThree): String { // ... when(oneTwoThree) { // Noncompliant, every branch of exhaustive `when` contains a return statement OneTwoThree.ONE -> return "one" OneTwoThree.TWO -> return "two" OneTwoThree.THREE -> return "three" } } ---- ==== Compliant solution [source,kotlin,diff-id=3,diff-type=compliant] ---- fun returnWhenEnum(oneTwoThree: OneTwoThree): String { // ... return when(oneTwoThree) { // Compliant OneTwoThree.ONE -> "one" OneTwoThree.TWO -> "two" OneTwoThree.THREE -> "three" } } ---- ==== Noncompliant code example [source,kotlin,diff-id=4,diff-type=noncompliant] ---- fun returnIfElseWithSideEffects(a: Float, b: Float): Int { // ... if (a < 0) { // Noncompliant, every branch contains a return statement foo() return -1 } else if (a > b) { bar() return 1 } else { return 0 } } ---- ==== Compliant solution [source,kotlin,diff-id=4,diff-type=compliant] ---- fun returnIfElseWithSideEffects(a: Float, b: Float): Int { // ... return if (a < 0) { // Compliant foo() -1 } else if (a > b) { bar() 1 } else { 0 } } ---- == Resources === Documentation * https://kotlinlang.org/docs/control-flow.html#if-expression[Kotlin Docs, If expression] * https://kotlinlang.org/docs/control-flow.html#when-expression[Kotlin Docs, When expression] === Articles & blog posts * https://www.baeldung.com/kotlin/if-else-expression[Baeldung, If-Else Expression in Kotlin] * https://www.baeldung.com/kotlin/when[Baeldung, Guide to the “when{}” Block in Kotlin] * https://www.sonarsource.com/resources/cognitive-complexity[G. Ann Campbell, Cognitive Complexity]