From ff26acacf950eaa583a469fcc9f3503c88e7e595 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Tue, 30 Apr 2019 18:21:14 +0700 Subject: [PATCH] Optimize Imports shouldn't delete imports with unresolved parts #KT-10512 Fixed --- .../org/jetbrains/kotlin/idea/util/ImportsUtils.kt | 6 +++++- .../kotlin/idea/util/OptimizedImportsBuilder.kt | 5 +++++ .../editor/optimizeImports/common/MembersInScope.kt | 2 +- .../editor/optimizeImports/common/Overloads.kt | 2 -- .../editor/optimizeImports/jvm/UnusedImports.kt | 12 +++--------- .../optimizeImports/jvm/UnusedImports.kt.after | 9 +++------ .../editor/optimizeImports/jvm/UnusedImports.kt.log | 2 ++ .../optimizeImports/jvm/UnusedImportsInScript.kts | 8 ++------ .../jvm/UnusedImportsInScript.kts.after | 5 +---- .../quickfix/optimizeImports/destructuringAtTop.kt | 1 + .../optimizeImports/destructuringAtTop.kt.after | 1 + 11 files changed, 24 insertions(+), 29 deletions(-) create mode 100644 idea/testData/editor/optimizeImports/jvm/UnusedImports.kt.log diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ImportsUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ImportsUtils.kt index 3a7b4a4ccc2..746185eeaf3 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ImportsUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ImportsUtils.kt @@ -20,7 +20,10 @@ package org.jetbrains.kotlin.idea.imports import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtImportDirective +import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.kotlin.psi.KtReferenceExpression +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.ImportPath @@ -28,7 +31,6 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.types.KotlinType -import java.util.* object ImportPathComparator : Comparator { override fun compare(import1: ImportPath, import2: ImportPath): Int { @@ -92,3 +94,5 @@ fun KtReferenceExpression.getImportableTargets(bindingContext: BindingContext): return targets.map { it.getImportableDescriptor() }.toSet() } +fun KtImportDirective.canResolve(): Boolean = (importedReference?.getQualifiedElementSelector() as? KtNameReferenceExpression) + ?.reference?.resolve() != null ?: false \ No newline at end of file diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/OptimizedImportsBuilder.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/OptimizedImportsBuilder.kt index 9ab68dddddf..5000448673a 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/OptimizedImportsBuilder.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/OptimizedImportsBuilder.kt @@ -87,6 +87,11 @@ class OptimizedImportsBuilder( private val importRules = HashSet() fun buildOptimizedImports(): List? { + file.importDirectives + .filterNot(KtImportDirective::canResolve) + .mapNotNull(KtImportDirective::getImportPath) + .mapTo(importRules) { ImportRule.Add(it) } + while (true) { val importRulesBefore = importRules.size val result = tryBuildOptimizedImports() diff --git a/idea/testData/editor/optimizeImports/common/MembersInScope.kt b/idea/testData/editor/optimizeImports/common/MembersInScope.kt index fe3531ff18a..c0292552dc2 100644 --- a/idea/testData/editor/optimizeImports/common/MembersInScope.kt +++ b/idea/testData/editor/optimizeImports/common/MembersInScope.kt @@ -1,5 +1,5 @@ import Outer.Nested -import Outer.ClassObjectNested +import Outer.Companion.ClassObjectNested import Outer.C.Inner import Outer.C.Inner2 diff --git a/idea/testData/editor/optimizeImports/common/Overloads.kt b/idea/testData/editor/optimizeImports/common/Overloads.kt index a2c89777638..94797cdac38 100644 --- a/idea/testData/editor/optimizeImports/common/Overloads.kt +++ b/idea/testData/editor/optimizeImports/common/Overloads.kt @@ -4,8 +4,6 @@ import pack1.foo import pack1.u1 import pack1.u2 import pack1.u3 -import pack1.u4 -import pack1.u5 import pack2.* fun f() { diff --git a/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt b/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt index 10858936de2..5f0994874e4 100644 --- a/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt +++ b/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt @@ -4,21 +4,15 @@ import java.lang.StringBuilder import java.net.HttpRetryException import java.util.ArrayList import java.util.HashMap -import kotlin.test.asserter import kotlin.test.Asserter -import kotlin.Charsets -import kotlin.Assertions +import kotlin.text.Charsets import kotlin.system.measureTimeMillis class Action { fun test() { val chs = Charsets.UTF8 - // val traait : Asserter = asserter val traait : Asserter? = null - val objectImport : Assertions? = null - measureTimeMillis({ println(HashMap().size()) }) + measureTimeMillis({ println(HashMap().size) }) val test : ArrayList? = null } -} - -// RUNTIME \ No newline at end of file +} \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt.after b/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt.after index de9e03043f6..c7d967b7a13 100644 --- a/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt.after +++ b/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt.after @@ -1,16 +1,13 @@ import java.util.ArrayList import java.util.HashMap import kotlin.system.measureTimeMillis +import kotlin.test.Asserter class Action { fun test() { val chs = Charsets.UTF8 - // val traait : Asserter = asserter val traait : Asserter? = null - val objectImport : Assertions? = null - measureTimeMillis({ println(HashMap().size()) }) + measureTimeMillis({ println(HashMap().size) }) val test : ArrayList? = null } -} - -// RUNTIME \ No newline at end of file +} \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt.log b/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt.log new file mode 100644 index 00000000000..38cc289e418 --- /dev/null +++ b/idea/testData/editor/optimizeImports/jvm/UnusedImports.kt.log @@ -0,0 +1,2 @@ +Additional checking of reference Getter: Charsets +Additional checking of reference KtSimpleNameReference: Charsets diff --git a/idea/testData/editor/optimizeImports/jvm/UnusedImportsInScript.kts b/idea/testData/editor/optimizeImports/jvm/UnusedImportsInScript.kts index 10858936de2..0b58a114845 100644 --- a/idea/testData/editor/optimizeImports/jvm/UnusedImportsInScript.kts +++ b/idea/testData/editor/optimizeImports/jvm/UnusedImportsInScript.kts @@ -1,10 +1,9 @@ import com.sun.corba.se.impl.util.JDKBridge -import com.sun.org.apache.xpath.internal.operations.And +import kotlin.collections.filter import java.lang.StringBuilder import java.net.HttpRetryException import java.util.ArrayList import java.util.HashMap -import kotlin.test.asserter import kotlin.test.Asserter import kotlin.Charsets import kotlin.Assertions @@ -13,12 +12,9 @@ import kotlin.system.measureTimeMillis class Action { fun test() { val chs = Charsets.UTF8 - // val traait : Asserter = asserter val traait : Asserter? = null val objectImport : Assertions? = null - measureTimeMillis({ println(HashMap().size()) }) + measureTimeMillis({ println(HashMap().size) }) val test : ArrayList? = null } } - -// RUNTIME \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/jvm/UnusedImportsInScript.kts.after b/idea/testData/editor/optimizeImports/jvm/UnusedImportsInScript.kts.after index de9e03043f6..2c86d7f4e12 100644 --- a/idea/testData/editor/optimizeImports/jvm/UnusedImportsInScript.kts.after +++ b/idea/testData/editor/optimizeImports/jvm/UnusedImportsInScript.kts.after @@ -5,12 +5,9 @@ import kotlin.system.measureTimeMillis class Action { fun test() { val chs = Charsets.UTF8 - // val traait : Asserter = asserter val traait : Asserter? = null val objectImport : Assertions? = null - measureTimeMillis({ println(HashMap().size()) }) + measureTimeMillis({ println(HashMap().size) }) val test : ArrayList? = null } } - -// RUNTIME \ No newline at end of file diff --git a/idea/testData/quickfix/optimizeImports/destructuringAtTop.kt b/idea/testData/quickfix/optimizeImports/destructuringAtTop.kt index b252c09ea99..71034b4db9b 100644 --- a/idea/testData/quickfix/optimizeImports/destructuringAtTop.kt +++ b/idea/testData/quickfix/optimizeImports/destructuringAtTop.kt @@ -1,4 +1,5 @@ // "Optimize imports" "true" +// WITH_RUNTIME import kotlin.collections.* diff --git a/idea/testData/quickfix/optimizeImports/destructuringAtTop.kt.after b/idea/testData/quickfix/optimizeImports/destructuringAtTop.kt.after index f66adf256f2..47d8f1033eb 100644 --- a/idea/testData/quickfix/optimizeImports/destructuringAtTop.kt.after +++ b/idea/testData/quickfix/optimizeImports/destructuringAtTop.kt.after @@ -1,3 +1,4 @@ // "Optimize imports" "true" +// WITH_RUNTIME val (a, b, c) = Triple(1, 2, 3) \ No newline at end of file