Products: SonarQube 10.2 and SonarLint (IntelliJ) 9.0.0.75308
Language: Kotlin
Hi everyone,
I believe I’ve come across a false positive related to the rule kotlin:S6514 (Delegator pattern should use “by” clause). Here is a code example to demonstrate the issue:
fun interface Policy { fun doSomething() }
class FirstPolicy : Policy {
override fun doSomething() { println("first") }
}
class SecondPolicy : Policy {
override fun doSomething() { println("second") }
}
class DynamicPolicy: Policy {
private var policy: Policy = FirstPolicy()
fun useSecondPolicy() {
policy = SecondPolicy()
}
override fun doSomething() {
policy.doSomething()
}
}
fun main() {
val dynamicPolicy = DynamicPolicy()
dynamicPolicy.doSomething()
dynamicPolicy.useSecondPolicy()
dynamicPolicy.doSomething()
}
This code triggers the issue “Replace with interface delegation using ‘by’ in the class header.” at line 20.
The “fix” for this issue, as suggested in the rule description, is to use interface delegation:
class DynamicPolicy(private var policy: Policy = FirstPolicy()): Policy by policy {
fun useSecondPolicy() {
policy = SecondPolicy()
}
}
However, despite the code compiling without errors, it doesn’t function correctly due to the way the Kotlin compiler handles interface delegation. This can be verified by running the main
method with both the old and new classes.
IntelliJ IDEA’s Kotlin analyzer issues a warning for the new class: “Delegating to ‘var’ property does not take its changes into account”.
It appears that SonarKotlin shouldn’t raise this issue for “var” properties.