Skip to content

Commit b9c853b

Browse files
SONARKT-176 Fix unused import FP of imports pertaining named companion objects. (#104)
1 parent b4cceb4 commit b9c853b

File tree

3 files changed

+19
-8
lines changed

3 files changed

+19
-8
lines changed

kotlin-checks-test-sources/src/main/kotlin/checks/UnnecessaryImportsCheckSample.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.google.common.collect.ImmutableSet.of as immutable_set_of
1616
import com.google.common.io.Files // Noncompliant {{Remove unused import.}}
1717
import com.google.common.io.Files.isFile
1818
import imports.ClassWithCompanionObject
19+
import imports.ClassWithNamedCompanionObject
1920
import okhttp3.TlsVersion
2021
import org.apache.commons.lang.StringUtils
2122
import otherpackage.get
@@ -88,8 +89,10 @@ class UnnecessaryImportsCheckSample {
8889
"" someInfixFun ""
8990
val method: Method? = null
9091
val kf = method!!.kotlinFunction
91-
92+
9293
val c = ClassWithCompanionObject.MY_CONSTANT // Compliant
94+
95+
ClassWithNamedCompanionObject.companionObjectFun()
9396
}
9497

9598
/**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package imports
2+
3+
class ClassWithNamedCompanionObject {
4+
companion object Named {
5+
fun companionObjectFun() {}
6+
}
7+
}

sonar-kotlin-plugin/src/main/java/org/sonarsource/kotlin/checks/UnnecessaryImportsCheck.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
package org.sonarsource.kotlin.checks
2121

2222
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
23-
import org.jetbrains.kotlin.name.FqName
2423
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
2524
import org.jetbrains.kotlin.psi.KtElement
2625
import org.jetbrains.kotlin.psi.KtFile
@@ -37,6 +36,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
3736
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
3837
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
3938
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
39+
import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
4040
import org.jetbrains.kotlin.types.expressions.OperatorConventions
4141
import org.sonar.check.Rule
4242
import org.sonarsource.kotlin.api.AbstractCheck
@@ -99,18 +99,19 @@ class UnnecessaryImportsCheck : AbstractCheck() {
9999
): List<KtImportDirective> {
100100
var relevantImports = importsWithSameName
101101
for (ref in relevantReferences) {
102-
val refName = context.bindingContext.get(BindingContext.REFERENCE_TARGET, ref)?.getImportableDescriptor()?.fqNameOrNull()
102+
val refDescriptor = context.bindingContext.get(BindingContext.REFERENCE_TARGET, ref)?.getImportableDescriptor()
103103
?: return emptyList() // Discard all: over-estimate, resulting in less FPs and more FNs without binding ctx
104-
relevantImports = relevantImports.filter { it.importedFqName != refName && !it.isCompanionObjectImport(refName) }
104+
val refName = refDescriptor.fqNameOrNull() ?: return emptyList()
105+
106+
relevantImports = relevantImports.filter {
107+
it.importedFqName != refName && !(refDescriptor.isCompanionObject() && it.importedFqName == refName.parent())
108+
}
109+
105110
if (relevantImports.isEmpty()) break
106111
}
107112
return relevantImports
108113
}
109114

110-
private fun KtImportDirective.isCompanionObjectImport(
111-
refName: FqName,
112-
) = refName.shortName().asString() == "Companion" && importedFqName == refName.parent()
113-
114115
private fun collectReferences(file: KtFile) =
115116
file.children.asSequence().filter {
116117
it !is KtPackageDirective && it !is KtImportList

0 commit comments

Comments
 (0)