Optimize Imports shouldn't delete imports with unresolved parts

#KT-10512 Fixed
This commit is contained in:
Dmitry Gridin
2019-04-30 18:21:14 +07:00
parent 87b559562f
commit ff26acacf9
11 changed files with 24 additions and 29 deletions
@@ -20,7 +20,10 @@ package org.jetbrains.kotlin.idea.imports
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName 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.KtReferenceExpression
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.ImportPath 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.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import java.util.*
object ImportPathComparator : Comparator<ImportPath> { object ImportPathComparator : Comparator<ImportPath> {
override fun compare(import1: ImportPath, import2: ImportPath): Int { override fun compare(import1: ImportPath, import2: ImportPath): Int {
@@ -92,3 +94,5 @@ fun KtReferenceExpression.getImportableTargets(bindingContext: BindingContext):
return targets.map { it.getImportableDescriptor() }.toSet() return targets.map { it.getImportableDescriptor() }.toSet()
} }
fun KtImportDirective.canResolve(): Boolean = (importedReference?.getQualifiedElementSelector() as? KtNameReferenceExpression)
?.reference?.resolve() != null ?: false
@@ -87,6 +87,11 @@ class OptimizedImportsBuilder(
private val importRules = HashSet<ImportRule>() private val importRules = HashSet<ImportRule>()
fun buildOptimizedImports(): List<ImportPath>? { fun buildOptimizedImports(): List<ImportPath>? {
file.importDirectives
.filterNot(KtImportDirective::canResolve)
.mapNotNull(KtImportDirective::getImportPath)
.mapTo(importRules) { ImportRule.Add(it) }
while (true) { while (true) {
val importRulesBefore = importRules.size val importRulesBefore = importRules.size
val result = tryBuildOptimizedImports() val result = tryBuildOptimizedImports()
@@ -1,5 +1,5 @@
import Outer.Nested import Outer.Nested
import Outer.ClassObjectNested import Outer.Companion.ClassObjectNested
import Outer.C.Inner import Outer.C.Inner
import Outer.C.Inner2 import Outer.C.Inner2
@@ -4,8 +4,6 @@ import pack1.foo
import pack1.u1 import pack1.u1
import pack1.u2 import pack1.u2
import pack1.u3 import pack1.u3
import pack1.u4
import pack1.u5
import pack2.* import pack2.*
fun f() { fun f() {
+3 -9
View File
@@ -4,21 +4,15 @@ import java.lang.StringBuilder
import java.net.HttpRetryException import java.net.HttpRetryException
import java.util.ArrayList import java.util.ArrayList
import java.util.HashMap import java.util.HashMap
import kotlin.test.asserter
import kotlin.test.Asserter import kotlin.test.Asserter
import kotlin.Charsets import kotlin.text.Charsets
import kotlin.Assertions
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
class Action { class Action {
fun test() { fun test() {
val chs = Charsets.UTF8 val chs = Charsets.UTF8
// val traait : Asserter = asserter
val traait : Asserter? = null val traait : Asserter? = null
val objectImport : Assertions? = null measureTimeMillis({ println(HashMap<String, Int>().size) })
measureTimeMillis({ println(HashMap<String, Int>().size()) })
val test : ArrayList<Int>? = null val test : ArrayList<Int>? = null
} }
} }
// RUNTIME
@@ -1,16 +1,13 @@
import java.util.ArrayList import java.util.ArrayList
import java.util.HashMap import java.util.HashMap
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
import kotlin.test.Asserter
class Action { class Action {
fun test() { fun test() {
val chs = Charsets.UTF8 val chs = Charsets.UTF8
// val traait : Asserter = asserter
val traait : Asserter? = null val traait : Asserter? = null
val objectImport : Assertions? = null measureTimeMillis({ println(HashMap<String, Int>().size) })
measureTimeMillis({ println(HashMap<String, Int>().size()) })
val test : ArrayList<Int>? = null val test : ArrayList<Int>? = null
} }
} }
// RUNTIME
@@ -0,0 +1,2 @@
Additional checking of reference Getter: Charsets
Additional checking of reference KtSimpleNameReference: Charsets
@@ -1,10 +1,9 @@
import com.sun.corba.se.impl.util.JDKBridge 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.lang.StringBuilder
import java.net.HttpRetryException import java.net.HttpRetryException
import java.util.ArrayList import java.util.ArrayList
import java.util.HashMap import java.util.HashMap
import kotlin.test.asserter
import kotlin.test.Asserter import kotlin.test.Asserter
import kotlin.Charsets import kotlin.Charsets
import kotlin.Assertions import kotlin.Assertions
@@ -13,12 +12,9 @@ import kotlin.system.measureTimeMillis
class Action { class Action {
fun test() { fun test() {
val chs = Charsets.UTF8 val chs = Charsets.UTF8
// val traait : Asserter = asserter
val traait : Asserter? = null val traait : Asserter? = null
val objectImport : Assertions? = null val objectImport : Assertions? = null
measureTimeMillis({ println(HashMap<String, Int>().size()) }) measureTimeMillis({ println(HashMap<String, Int>().size) })
val test : ArrayList<Int>? = null val test : ArrayList<Int>? = null
} }
} }
// RUNTIME
@@ -5,12 +5,9 @@ import kotlin.system.measureTimeMillis
class Action { class Action {
fun test() { fun test() {
val chs = Charsets.UTF8 val chs = Charsets.UTF8
// val traait : Asserter = asserter
val traait : Asserter? = null val traait : Asserter? = null
val objectImport : Assertions? = null val objectImport : Assertions? = null
measureTimeMillis({ println(HashMap<String, Int>().size()) }) measureTimeMillis({ println(HashMap<String, Int>().size) })
val test : ArrayList<Int>? = null val test : ArrayList<Int>? = null
} }
} }
// RUNTIME
@@ -1,4 +1,5 @@
// "Optimize imports" "true" // "Optimize imports" "true"
// WITH_RUNTIME
<caret>import kotlin.collections.* <caret>import kotlin.collections.*
@@ -1,3 +1,4 @@
// "Optimize imports" "true" // "Optimize imports" "true"
// WITH_RUNTIME
val (a, b, c) = Triple(1, 2, 3) val (a, b, c) = Triple(1, 2, 3)