From 8c4fdd1edd3cdcfc47c549611f113246fbc7ab7f Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Tue, 8 Oct 2019 23:43:53 +0900 Subject: [PATCH] Unused import: do not report for 'invoke' function import that is used from same file #KT-24281 Fixed --- .../KotlinUnusedImportInspection.kt | 13 ++++++++++--- .../quickfix/optimizeImports/invoke.kt | 18 ++++++++++++++++++ .../quickfix/optimizeImports/invoke2.kt | 17 +++++++++++++++++ .../quickfix/optimizeImports/invoke2.kt.after | 15 +++++++++++++++ .../idea/quickfix/QuickFixTestGenerated.java | 10 ++++++++++ 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 idea/testData/quickfix/optimizeImports/invoke.kt create mode 100644 idea/testData/quickfix/optimizeImports/invoke2.kt create mode 100644 idea/testData/quickfix/optimizeImports/invoke2.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinUnusedImportInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinUnusedImportInspection.kt index 68619699b79..c96e2b76b45 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinUnusedImportInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinUnusedImportInspection.kt @@ -47,11 +47,12 @@ import org.jetbrains.kotlin.idea.core.targetDescriptors import org.jetbrains.kotlin.idea.imports.KotlinImportOptimizer import org.jetbrains.kotlin.idea.imports.OptimizedImportsBuilder import org.jetbrains.kotlin.idea.imports.importableFqName +import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference +import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtCodeFragment -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtImportDirective +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.siblings import org.jetbrains.kotlin.resolve.ImportPath @@ -86,6 +87,11 @@ class KotlinUnusedImportInspection : AbstractKotlinInspection() { } } + val invokeFunctionCallFqNames = optimizerData.references.mapNotNull { + val reference = (it.element as? KtCallExpression)?.mainReference as? KtInvokeFunctionReference ?: return@mapNotNull null + (reference.resolve() as? KtNamedFunction)?.descriptor?.importableFqName + } + val importPaths = HashSet(directives.size) val unusedImports = ArrayList() @@ -97,6 +103,7 @@ class KotlinUnusedImportInspection : AbstractKotlinInspection() { !importPaths.add(importPath) -> false importPath.isAllUnder -> importPath.fqName in parentFqNames importPath.fqName in fqNames -> importPath.importedName?.let { it in fqNames.getValue(importPath.fqName) } ?: false + importPath.fqName in invokeFunctionCallFqNames -> true // case for type alias else -> directive.targetDescriptors(resolutionFacade).firstOrNull()?.let { it.importableFqName in fqNames } ?: false } diff --git a/idea/testData/quickfix/optimizeImports/invoke.kt b/idea/testData/quickfix/optimizeImports/invoke.kt new file mode 100644 index 00000000000..786590f5c81 --- /dev/null +++ b/idea/testData/quickfix/optimizeImports/invoke.kt @@ -0,0 +1,18 @@ +// "Optimize imports" "false" +// WITH_RUNTIME +// ACTION: Introduce import alias +package ppp + +import ppp.invoke + +object Bar +object Foo { + val bar = Bar +} + +fun Foo.bar() = 1 +operator fun Bar.invoke() = 2 + +fun main() { + println(Foo.bar()) +} \ No newline at end of file diff --git a/idea/testData/quickfix/optimizeImports/invoke2.kt b/idea/testData/quickfix/optimizeImports/invoke2.kt new file mode 100644 index 00000000000..de4537dc859 --- /dev/null +++ b/idea/testData/quickfix/optimizeImports/invoke2.kt @@ -0,0 +1,17 @@ +// "Optimize imports" "true" +// WITH_RUNTIME +package ppp + +import ppp.invoke + +object Bar +object Foo { + // val bar = Bar +} + +fun Foo.bar() = 1 +operator fun Bar.invoke() = 2 + +fun main() { + println(Foo.bar()) +} \ No newline at end of file diff --git a/idea/testData/quickfix/optimizeImports/invoke2.kt.after b/idea/testData/quickfix/optimizeImports/invoke2.kt.after new file mode 100644 index 00000000000..7f83ce424ad --- /dev/null +++ b/idea/testData/quickfix/optimizeImports/invoke2.kt.after @@ -0,0 +1,15 @@ +// "Optimize imports" "true" +// WITH_RUNTIME +package ppp + +object Bar +object Foo { + // val bar = Bar +} + +fun Foo.bar() = 1 +operator fun Bar.invoke() = 2 + +fun main() { + println(Foo.bar()) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 675afddc91f..c89dcc9f2f5 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -9726,6 +9726,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { public void testImportAlias() throws Exception { runTest("idea/testData/quickfix/optimizeImports/importAlias.kt"); } + + @TestMetadata("invoke.kt") + public void testInvoke() throws Exception { + runTest("idea/testData/quickfix/optimizeImports/invoke.kt"); + } + + @TestMetadata("invoke2.kt") + public void testInvoke2() throws Exception { + runTest("idea/testData/quickfix/optimizeImports/invoke2.kt"); + } } @TestMetadata("idea/testData/quickfix/override")