diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeVal.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeVal.kt index 6a98d79a3..8bc2fc7c2 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeVal.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeVal.kt @@ -105,7 +105,10 @@ class VarCouldBeVal(config: Config = Config.empty) : Rule(config) { if (assignments.isNullOrEmpty()) return false val declarationDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, this] return assignments.any { - it.getResolvedCall(bindingContext)?.resultingDescriptor?.original == declarationDescriptor + it.getResolvedCall(bindingContext)?.resultingDescriptor?.original == declarationDescriptor || + // inside an unknown types context? (example: with-statement with unknown type) + // (i.e, it can't be resolved if the assignment is from the context or from an outer variable) + it.getResolvedCall(bindingContext) == null } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeValSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeValSpec.kt index 17e89eb46..e20de06b2 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeValSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeValSpec.kt @@ -4,6 +4,7 @@ import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.compileAndLint import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext +import io.gitlab.arturbosch.detekt.test.lintWithContext import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.junit.jupiter.api.Nested @@ -50,6 +51,39 @@ class VarCouldBeValSpec(val env: KotlinCoreEnvironment) { assertThat(subject.compileAndLintWithContext(env, code)).isEmpty() } + + @Test + fun `does not report private variables that are re-assigned inside an unknown type`() { + val code = """ + private var a = 1 + + fun foo() { + with(UnknownReference) { + a = 2 + } + } + """ + + assertThat(subject.lintWithContext(env, code)).isEmpty() + } + + @Test + fun `reports private variables that have the same name as those re-assigned within a known type`() { + val code = """ + class MyClass(var a: Int) + + private var a = 1 + private val myObj = MyClass(1) + + fun foo() { + with(myObj) { + a = 2 + } + } + """ + + assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1) + } } @Nested