Skip to content

Commit

Permalink
ReturnCount: correctly count assignment expressions with elvis return…
Browse files Browse the repository at this point in the history
… as guard clauses (#5539)

Fixes #5536
  • Loading branch information
t-kameyama committed Nov 18, 2022
1 parent 411ef80 commit 7fd9987
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 7 deletions.
2 changes: 1 addition & 1 deletion detekt-psi-utils/api/detekt-psi-utils.api
Expand Up @@ -45,7 +45,7 @@ public final class io/gitlab/arturbosch/detekt/rules/AllowedExceptionNamePattern
}

public final class io/gitlab/arturbosch/detekt/rules/GuardClausesKt {
public static final fun isElvisOperatorGuardClause (Lorg/jetbrains/kotlin/psi/KtExpression;)Z
public static final fun isElvisOperatorGuardClause (Lorg/jetbrains/kotlin/psi/KtExpression;Lorg/jetbrains/kotlin/psi/KtExpression;)Z
public static final fun isIfConditionGuardClause (Lorg/jetbrains/kotlin/psi/KtExpression;Lorg/jetbrains/kotlin/psi/KtExpression;)Z
}

Expand Down
Expand Up @@ -5,6 +5,7 @@ import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis

Expand All @@ -23,7 +24,7 @@ inline fun <reified T : KtExpression> KtNamedFunction.yieldStatementsSkippingGua

inline fun <reified T : KtExpression> KtExpression.isGuardClause(): Boolean {
val descendantExpr = this.findDescendantOfType<T>() ?: return false
return this.isIfConditionGuardClause(descendantExpr) || this.isElvisOperatorGuardClause()
return this.isIfConditionGuardClause(descendantExpr) || this.isElvisOperatorGuardClause(descendantExpr)
}

fun <T : KtExpression> KtExpression.isIfConditionGuardClause(descendantExpr: T): Boolean {
Expand All @@ -32,7 +33,5 @@ fun <T : KtExpression> KtExpression.isIfConditionGuardClause(descendantExpr: T):
descendantExpr === ifExpr.then?.lastBlockStatementOrThis()
}

fun KtExpression.isElvisOperatorGuardClause(): Boolean {
val elvisExpr = this.findDescendantOfType<KtBinaryExpression>() ?: return false
return elvisExpr.operationToken == KtTokens.ELVIS
}
fun <T : KtExpression> KtExpression.isElvisOperatorGuardClause(descendantExpr: T): Boolean =
this.anyDescendantOfType<KtBinaryExpression> { it.operationToken == KtTokens.ELVIS && it.right == descendantExpr }
Expand Up @@ -186,10 +186,12 @@ class ReturnCountSpec {
@Nested
inner class `a file with multiple guard clauses` {
val code = """
fun multipleGuards(a: Int?, b: Any?, c: Int?) {
var x = 1
fun multipleGuards(a: Int?, b: Any?, c: Int?, d: Int?) {
if(a == null) return
val models = b as? Int ?: return
val position = c?.takeIf { it != -1 } ?: return
x = d ?: return
if(b !is String) {
println("b is not a String")
return
Expand Down

0 comments on commit 7fd9987

Please sign in to comment.