Repository: detekt/detekt (kotlin)

Issue:
`UnusedImports` false negative with two imports of the same name from different packages
<!-- The bug you're experiencing might have already be reported! -->
<!-- Please search in the [issues](https://github.com/detekt/detekt/issues) before creating one. -->

## Expected Behavior
<!-- Tell us what should happen -->
`UnusedImports` error on `import kotlin.io.path.Path`. intellij's unused import inspection is able to detect it:

![Image](https://github.com/user-attachments/assets/9e39e596-944f-4d75-b98b-7717bb5a7bd1)

## Observed Behavior
no error

## Steps to Reproduce
<!-- Provide a link to a live example, or an unambiguous set of steps to -->
<!-- reproduce this bug. Include code to reproduce, if relevant -->
```kt
import java.nio.file.Path // this import is used
import kotlin.io.path.Path // this one is not

typealias Foo = Path
```
## Context
<!-- How has this issue affected you? What are you trying to accomplish? -->
<!-- Providing context helps us come up with a solution that is most useful in the real world -->

## Your Environment
<!-- Include as many relevant details about the environment you experienced the bug in -->
* Version of detekt used: 1.23.8
* Operating System and version: windows 10

Pull request:
Fixes https://github.com/detekt/detekt/issues/8120

Patch:
diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImport.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImport.kt
index 380040d7731f..ea9d6cee0fa7 100644
--- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImport.kt
+++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImport.kt
@@ -11,9 +11,12 @@ import dev.detekt.api.config
 import dev.detekt.psi.isPartOf
 import org.jetbrains.kotlin.analysis.api.analyze
 import org.jetbrains.kotlin.analysis.api.symbols.KaCallableSymbol
+import org.jetbrains.kotlin.analysis.api.symbols.KaClassLikeSymbol
+import org.jetbrains.kotlin.analysis.api.symbols.KaSymbol
 import org.jetbrains.kotlin.idea.references.mainReference
 import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
 import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.SpecialNames
 import org.jetbrains.kotlin.psi.KtDeclaration
 import org.jetbrains.kotlin.psi.KtFile
 import org.jetbrains.kotlin.psi.KtImportDirective
@@ -155,8 +158,25 @@ class UnusedImport(config: Config) :
             }
         }
 
+        @Suppress("ClassOrdering")
+        private val KaSymbol.fqNameForImport: FqName?
+            get() = when (this) {
+                is KaClassLikeSymbol -> {
+                    val classIdRemovingCompanion =
+                        if (classId?.shortClassName == SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) {
+                            classId?.outerClassId
+                        } else {
+                            classId
+                        }
+                    classIdRemovingCompanion?.asSingleFqName()
+                }
+
+                is KaCallableSymbol -> callableId?.asSingleFqName()
+                else -> null
+            }
+
         private fun KtReferenceExpression.fqNameOrNull(): FqName? = analyze(this) {
-            (mainReference.resolveToSymbol() as? KaCallableSymbol)?.callableId?.asSingleFqName()
+            mainReference.resolveToSymbol()?.fqNameForImport
         }
     }
 


Test patch:
diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportSpec.kt
index 5f786c5e1ea3..62f04b65644e 100644
--- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportSpec.kt
+++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportSpec.kt
@@ -917,4 +917,18 @@ class UnusedImportSpec(
 
         assertThat(subject.lintWithContext(env, mainFile, additionalFile)).isEmpty()
     }
+
+    @Test
+    fun `does report only for function when import is used based on type - #8120`() {
+        val mainFile =
+            """
+            import java.nio.file.Path // this import is used
+            import kotlin.io.path.Path // this one is not
+
+            typealias Foo = Path
+            """.trimIndent()
+        assertThat(subject.lintWithContext(env, mainFile))
+            .singleElement()
+            .hasMessage("The import 'kotlin.io.path.Path' is unused.")
+    }
 }