diff --git a/detekt-psi-utils/api/detekt-psi-utils.api b/detekt-psi-utils/api/detekt-psi-utils.api index b1e2a840ba1..d2aac2a350d 100644 --- a/detekt-psi-utils/api/detekt-psi-utils.api +++ b/detekt-psi-utils/api/detekt-psi-utils.api @@ -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 } diff --git a/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/GuardClauses.kt b/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/GuardClauses.kt index d1a6d3dda9d..1274c10c85b 100644 --- a/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/GuardClauses.kt +++ b/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/GuardClauses.kt @@ -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 @@ -23,7 +24,7 @@ inline fun KtNamedFunction.yieldStatementsSkippingGua inline fun KtExpression.isGuardClause(): Boolean { val descendantExpr = this.findDescendantOfType() ?: return false - return this.isIfConditionGuardClause(descendantExpr) || this.isElvisOperatorGuardClause() + return this.isIfConditionGuardClause(descendantExpr) || this.isElvisOperatorGuardClause(descendantExpr) } fun KtExpression.isIfConditionGuardClause(descendantExpr: T): Boolean { @@ -32,7 +33,5 @@ fun KtExpression.isIfConditionGuardClause(descendantExpr: T): descendantExpr === ifExpr.then?.lastBlockStatementOrThis() } -fun KtExpression.isElvisOperatorGuardClause(): Boolean { - val elvisExpr = this.findDescendantOfType() ?: return false - return elvisExpr.operationToken == KtTokens.ELVIS -} +fun KtExpression.isElvisOperatorGuardClause(descendantExpr: T): Boolean = + this.anyDescendantOfType { it.operationToken == KtTokens.ELVIS && it.right == descendantExpr } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCountSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCountSpec.kt index b9e43bd7dc8..978e931c629 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCountSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCountSpec.kt @@ -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