From d1effe72f4b47bb87297e874509af648874b9804 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Thu, 21 Jul 2022 01:11:28 +0900 Subject: [PATCH] UnusedUnaryOperator: fix false positive with var assignment and if expression (#5106) --- .../detekt/rules/bugs/UnusedUnaryOperator.kt | 8 ++++++-- .../detekt/rules/bugs/UnusedUnaryOperatorSpec.kt | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt index 04c95bae66e1..da3b6e64487f 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt @@ -17,8 +17,8 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtPrefixExpression -import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentOfType import org.jetbrains.kotlin.psi.psiUtil.leaves +import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall @@ -62,7 +62,7 @@ class UnusedUnaryOperator(config: Config = Config.empty) : Rule(config) { .none { it is PsiWhiteSpace && it.textContains('\n') } ) return - val parentOrSelf = (expression.getTopmostParentOfType() ?: expression) as KtExpression + val parentOrSelf = expression.parentBinaryExpressionOrThis() if (parentOrSelf.isUsedAsExpression(bindingContext)) return val operatorDescriptor = expression.operationReference.getResolvedCall(bindingContext) @@ -72,4 +72,8 @@ class UnusedUnaryOperator(config: Config = Config.empty) : Rule(config) { val message = "This '${parentOrSelf.text}' is not used" report(CodeSmell(issue, Entity.from(expression), message)) } + + private fun KtExpression.parentBinaryExpressionOrThis(): KtExpression { + return parents.takeWhile { it is KtBinaryExpression }.lastOrNull() as? KtBinaryExpression ?: this + } } diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperatorSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperatorSpec.kt index 7683fbe216b2..fe6f4debbe66 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperatorSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperatorSpec.kt @@ -122,4 +122,20 @@ class UnusedUnaryOperatorSpec(private val env: KotlinCoreEnvironment) { val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).isEmpty() } + + @Test + fun `var assignment by if expression`() { + val code = """ + fun test(b: Boolean) { + var x = 0 + x = if (b) { + -1 + } else { + 1 + } + } + """ + val findings = subject.compileAndLintWithContext(env, code) + assertThat(findings).isEmpty() + } }