From 4d21309f845b90efcef24996045bce97ac2a9148 Mon Sep 17 00:00:00 2001 From: Atul Gupta Date: Sat, 27 May 2023 21:07:32 +0530 Subject: [PATCH] UnusedPrivateProperty: Fix false postive by ignoring data classes (#6151) --- .../rules/style/UnusedPrivateProperty.kt | 9 +++++- .../rules/style/UnusedPrivatePropertySpec.kt | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateProperty.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateProperty.kt index 53a5ccdd2ec..61c322f64ca 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateProperty.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateProperty.kt @@ -14,6 +14,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.rules.isActual import io.gitlab.arturbosch.detekt.rules.isExpect import org.jetbrains.kotlin.com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtImportDirective import org.jetbrains.kotlin.psi.KtNamedDeclaration @@ -108,11 +109,17 @@ private class UnusedPrivatePropertyVisitor(private val allowedNames: Regex) : De constructor.valueParameters .filter { (it.isPrivate() || (!it.hasValOrVar() && !constructor.isActual())) && - it.containingClassOrObject?.isExpect() == false + it.containingClassOrObject?.isExpect() == false && + isConstructorForDataOrValueClass(constructor).not() } .forEach { maybeAddUnusedProperty(it) } } + private fun isConstructorForDataOrValueClass(constructor: PsiElement): Boolean { + val parent = constructor.parent as? KtClass ?: return false + return parent.isData() || parent.isValue() || parent.isInline() + } + override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor) { super.visitSecondaryConstructor(constructor) constructor.valueParameters.forEach { maybeAddUnusedProperty(it) } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivatePropertySpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivatePropertySpec.kt index 534b15e8c41..53a6810088c 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivatePropertySpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivatePropertySpec.kt @@ -747,6 +747,37 @@ class UnusedPrivatePropertySpec(val env: KotlinCoreEnvironment) { """.trimIndent() assertThat(subject.lint(code)).isEmpty() } + + @Test + fun `does not report unused private property in data class - #6142`() { + val code = """ + data class Foo( + private val foo: Int, + private val bar: String, + ) + """.trimIndent() + assertThat(subject.lint(code)).isEmpty() + } + + @Test + fun `does not report unused private property in data class with named constructor`() { + val code = """ + data class Foo constructor( + private val foo: Int, + private val bar: String, + ) + """.trimIndent() + assertThat(subject.lint(code)).isEmpty() + } + + @Test + fun `does not report unused private property in value or inline class`() { + val code = """ + @JvmInline value class Foo(private val value: String) + inline class Bar(private val value: String) + """.trimIndent() + assertThat(subject.lint(code)).isEmpty() + } } @Nested