From 9062a2fe725879340b63d237f6c3ea118024c696 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Thu, 25 Apr 2019 18:01:29 +0700 Subject: [PATCH] Fix false positive "Unused import directive" for imports under several alias #KT-30949 Fixed --- compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt | 2 +- .../kotlin/idea/imports/KotlinImportOptimizer.kt | 9 +++++++-- .../common/ConflictWithAlias.dependency.kt | 1 + .../optimizeImports/common/ConflictWithAlias.kt | 4 ++++ .../common/ConflictWithAlias.kt.after | 4 ++++ .../common/ConflictWithAlias2.dependency.kt | 5 +++++ .../optimizeImports/common/ConflictWithAlias2.kt | 11 +++++++++++ .../common/ConflictWithAlias2.kt.after | 8 ++++++++ .../common/ConflictWithAlias2.kt.log | 13 +++++++++++++ ...UnusedImportForImportsWithSameName.Dependency.kt | 1 + .../noUnusedImportForImportsWithSameName.kt | 4 ++++ .../imports/JsOptimizeImportsTestGenerated.java | 10 ++++++++++ .../imports/JvmOptimizeImportsTestGenerated.java | 10 ++++++++++ 13 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 idea/testData/editor/optimizeImports/common/ConflictWithAlias.dependency.kt create mode 100644 idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt create mode 100644 idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt.after create mode 100644 idea/testData/editor/optimizeImports/common/ConflictWithAlias2.dependency.kt create mode 100644 idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt create mode 100644 idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt.after create mode 100644 idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt.log create mode 100644 idea/testData/inspections/unusedImport/noUnusedImportForImportsWithSameName.Dependency.kt create mode 100644 idea/testData/inspections/unusedImport/noUnusedImportForImportsWithSameName.kt diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt index 9c1d758715a..9ecb453f1e8 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt @@ -175,7 +175,7 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) : importDirectives.firstOrNull { name == it.aliasName } fun findAliasByFqName(fqName: FqName): KtImportAlias? = importDirectives.firstOrNull { - fqName == it.importedFqName + it.alias != null && fqName == it.importedFqName }?.alias @Deprecated("") // getPackageFqName should be used instead diff --git a/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt b/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt index af5055a4196..66ec3c3f4bd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt @@ -42,7 +42,6 @@ import org.jetbrains.kotlin.resolve.ImportPath import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope import org.jetbrains.kotlin.resolve.scopes.utils.* -import java.util.* class KotlinImportOptimizer : ImportOptimizer { override fun supports(file: PsiFile?) = file is KtFile @@ -74,6 +73,12 @@ class KotlinImportOptimizer : ImportOptimizer { private class CollectUsedDescriptorsVisitor(file: KtFile) : KtVisitorVoid() { private val currentPackageName = file.packageFqName + private val withAlias: Set = file.importDirectives + .asSequence() + .filter { it.alias != null && it.aliasName != it.importPath?.fqName?.shortName()?.asString() } + .mapNotNull(KtImportDirective::importedFqName) + .toSet() + private val descriptorsToImport = HashSet() private val abstractRefs = ArrayList() @@ -107,7 +112,7 @@ class KotlinImportOptimizer : ImportOptimizer { val importableFqName = target.importableFqName ?: continue val parentFqName = importableFqName.parent() if (target is PackageViewDescriptor && parentFqName == FqName.ROOT) continue // no need to import top-level packages - if (target !is PackageViewDescriptor && parentFqName == currentPackageName) continue + if (target !is PackageViewDescriptor && parentFqName == currentPackageName && importableFqName !in withAlias) continue if (!reference.canBeResolvedViaImport(target, bindingContext)) continue diff --git a/idea/testData/editor/optimizeImports/common/ConflictWithAlias.dependency.kt b/idea/testData/editor/optimizeImports/common/ConflictWithAlias.dependency.kt new file mode 100644 index 00000000000..f75980cce48 --- /dev/null +++ b/idea/testData/editor/optimizeImports/common/ConflictWithAlias.dependency.kt @@ -0,0 +1 @@ +const val name = 42 \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt b/idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt new file mode 100644 index 00000000000..d1ab5684ebe --- /dev/null +++ b/idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt @@ -0,0 +1,4 @@ +import name +import name as names + +val a = name \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt.after b/idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt.after new file mode 100644 index 00000000000..60f552c81c3 --- /dev/null +++ b/idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt.after @@ -0,0 +1,4 @@ +import name +import name as names + +val a = name diff --git a/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.dependency.kt b/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.dependency.kt new file mode 100644 index 00000000000..e88db9cadb5 --- /dev/null +++ b/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.dependency.kt @@ -0,0 +1,5 @@ +package duration + +val Int.hours: Int get() = TODO() +val Int.minutes: Int get() = TODO() +val Int.seconds: Int get() = TODO() \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt b/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt new file mode 100644 index 00000000000..c0203313241 --- /dev/null +++ b/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt @@ -0,0 +1,11 @@ +import duration.* +import duration.hours as hour +import duration.minutes as minute +import duration.minutes as minutes +import duration.seconds as second +import duration.seconds as seconds + +fun main() { + val totalDuration = 1.hour - 30.minutes + 1.second + println(totalDuration) +} \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt.after b/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt.after new file mode 100644 index 00000000000..874e6806e6d --- /dev/null +++ b/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt.after @@ -0,0 +1,8 @@ +import duration.minutes +import duration.hours as hour +import duration.seconds as second + +fun main() { + val totalDuration = 1.hour - 30.minutes + 1.second + println(totalDuration) +} \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt.log b/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt.log new file mode 100644 index 00000000000..96bae4e5245 --- /dev/null +++ b/idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt.log @@ -0,0 +1,13 @@ +Additional checking of reference Getter: hour +Additional checking of reference KtSimpleNameReference: hour +Changed resolve of KtSimpleNameReference: hour +Additional checking of reference Getter: second +Additional checking of reference KtSimpleNameReference: second +Changed resolve of KtSimpleNameReference: second +Trying to build import list again with import rules: +duration.hours as hour, +duration.seconds as second +Additional checking of reference Getter: hour +Additional checking of reference KtSimpleNameReference: hour +Changed resolve of KtSimpleNameReference: hour +Additional checking of reference Getter: second +Additional checking of reference KtSimpleNameReference: second +Changed resolve of KtSimpleNameReference: second diff --git a/idea/testData/inspections/unusedImport/noUnusedImportForImportsWithSameName.Dependency.kt b/idea/testData/inspections/unusedImport/noUnusedImportForImportsWithSameName.Dependency.kt new file mode 100644 index 00000000000..f75980cce48 --- /dev/null +++ b/idea/testData/inspections/unusedImport/noUnusedImportForImportsWithSameName.Dependency.kt @@ -0,0 +1 @@ +const val name = 42 \ No newline at end of file diff --git a/idea/testData/inspections/unusedImport/noUnusedImportForImportsWithSameName.kt b/idea/testData/inspections/unusedImport/noUnusedImportForImportsWithSameName.kt new file mode 100644 index 00000000000..d1ab5684ebe --- /dev/null +++ b/idea/testData/inspections/unusedImport/noUnusedImportForImportsWithSameName.kt @@ -0,0 +1,4 @@ +import name +import name as names + +val a = name \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/imports/JsOptimizeImportsTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/imports/JsOptimizeImportsTestGenerated.java index 945f264d7fa..dd7bebe02a2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/imports/JsOptimizeImportsTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/imports/JsOptimizeImportsTestGenerated.java @@ -64,6 +64,16 @@ public class JsOptimizeImportsTestGenerated extends AbstractJsOptimizeImportsTes runTest("idea/testData/editor/optimizeImports/common/ComponentFunction.kt"); } + @TestMetadata("ConflictWithAlias.kt") + public void testConflictWithAlias() throws Exception { + runTest("idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt"); + } + + @TestMetadata("ConflictWithAlias2.kt") + public void testConflictWithAlias2() throws Exception { + runTest("idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt"); + } + @TestMetadata("CurrentPackage.kt") public void testCurrentPackage() throws Exception { runTest("idea/testData/editor/optimizeImports/common/CurrentPackage.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/imports/JvmOptimizeImportsTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/imports/JvmOptimizeImportsTestGenerated.java index d811a161ae0..013bfc6ad5a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/imports/JvmOptimizeImportsTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/imports/JvmOptimizeImportsTestGenerated.java @@ -257,6 +257,16 @@ public class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimizeImportsT runTest("idea/testData/editor/optimizeImports/common/ComponentFunction.kt"); } + @TestMetadata("ConflictWithAlias.kt") + public void testConflictWithAlias() throws Exception { + runTest("idea/testData/editor/optimizeImports/common/ConflictWithAlias.kt"); + } + + @TestMetadata("ConflictWithAlias2.kt") + public void testConflictWithAlias2() throws Exception { + runTest("idea/testData/editor/optimizeImports/common/ConflictWithAlias2.kt"); + } + @TestMetadata("CurrentPackage.kt") public void testCurrentPackage() throws Exception { runTest("idea/testData/editor/optimizeImports/common/CurrentPackage.kt");