Skip to content

Commit

Permalink
Fix test, add type resolution requirement
Browse files Browse the repository at this point in the history
  • Loading branch information
xcq1 committed Jan 19, 2023
1 parent abbbd14 commit 6fb1292
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ dependencies {
```

If you want to configure the rules individually look at the [config.yml](https://github.com/meisterplan/detekt-rules/blob/main/src/main/resources/config/config.yml) and set the same flags in your local detekt config.

For `CopyOnDataClassWithNonPublicConstructor`, it is required to [run detekt with type resolution](https://detekt.dev/docs/gettingstarted/type-resolution#enabling-on-a-jvm-project).
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.api.Severity
import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution
import io.gitlab.arturbosch.detekt.rules.fqNameOrNull
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassMemberScope

@RequiresTypeResolution
class CopyOnDataClassWithNonPublicConstructor(config: Config) : Rule(config) {

override val issue = Issue(
javaClass.simpleName,
Severity.CodeSmell,
Expand All @@ -37,9 +39,14 @@ class CopyOnDataClassWithNonPublicConstructor(config: Config) : Rule(config) {
val typeMemberScope = type?.memberScope
if (typeMemberScope is LazyClassMemberScope
&& typeMemberScope.getPrimaryConstructor()?.visibility != DescriptorVisibilities.PUBLIC
)
report(CodeSmell(issue, Entity.from(expression), "Non-public constructed data class ${calleeExpression.getReceiverExpression()?.text ?: ""}"
+ " of type ${type.fqNameOrNull()} should not bypass constructor by calling copy()."))
) {
report(
CodeSmell(
issue, Entity.from(expression), "Non-public constructed data class ${calleeExpression.getReceiverExpression()?.text ?: ""}"
+ " of type ${type.fqNameOrNull()} should not bypass constructor by calling copy()."
)
)
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ internal class CopyOnDataClassWithNonPublicConstructorTest(private val env: Kotl
fun `reports private data copy`() {
val code = """
@Suppress("DataClassPrivateConstructor")
data class A private constructor(val i: Int)
val x = A(3)
data class A private constructor(val i: Int) {
companion object {
fun create(i: Int) = A(i)
}
}
val x = A.create(3)
val y = x.copy(i = 4)
"""
val findings = CopyOnDataClassWithNonPublicConstructor(Config.empty).compileAndLintWithContext(env, code)
Expand Down

0 comments on commit 6fb1292

Please sign in to comment.