Optimize Imports shouldn't delete imports with unresolved parts

#KT-10512 Fixed
This commit is contained in:
Dmitry Gridin
2019-05-14 11:28:02 +07:00
parent 23e51268ad
commit 32298522dd
8 changed files with 40 additions and 4 deletions
@@ -19,10 +19,11 @@
package org.jetbrains.kotlin.idea.imports package org.jetbrains.kotlin.idea.imports
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtImportDirective 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.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector 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
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets 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.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
object ImportPathComparator : Comparator<ImportPath> { object ImportPathComparator : Comparator<ImportPath> {
@@ -94,5 +96,8 @@ 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) fun KtImportDirective.canResolve(facade: ResolutionFacade): Boolean {
?.reference?.resolve() != null ?: false return (importedReference?.getQualifiedElementSelector() as? KtSimpleNameExpression)?.let { nameExpression ->
nameExpression.getImportableTargets(facade.analyze(nameExpression, BodyResolveMode.PARTIAL)).isNotEmpty()
} ?: false
}
@@ -87,8 +87,9 @@ class OptimizedImportsBuilder(
private val importRules = HashSet<ImportRule>() private val importRules = HashSet<ImportRule>()
fun buildOptimizedImports(): List<ImportPath>? { fun buildOptimizedImports(): List<ImportPath>? {
val facade = file.getResolutionFacade()
file.importDirectives file.importDirectives
.filterNot(KtImportDirective::canResolve) .filterNot { it.canResolve(facade) }
.mapNotNull(KtImportDirective::getImportPath) .mapNotNull(KtImportDirective::getImportPath)
.mapTo(importRules) { ImportRule.Add(it) } .mapTo(importRules) { ImportRule.Add(it) }
@@ -0,0 +1,3 @@
package pack1
class Example
@@ -0,0 +1,8 @@
import pack1.Class4
import pack1.Example
import pack2.*
import pack3.Ggd
fun method(a: Class4) {
Example()
}
@@ -0,0 +1,8 @@
import pack1.Class4
import pack1.Example
import pack2.*
import pack3.Ggd
fun method(a: Class4) {
Example()
}
@@ -1,6 +1,7 @@
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() {
@@ -174,6 +174,11 @@ public class JsOptimizeImportsTestGenerated extends AbstractJsOptimizeImportsTes
runTest("idea/testData/editor/optimizeImports/common/TwoConstructors.kt"); runTest("idea/testData/editor/optimizeImports/common/TwoConstructors.kt");
} }
@TestMetadata("UnresolvedImport.kt")
public void testUnresolvedImport() throws Exception {
runTest("idea/testData/editor/optimizeImports/common/UnresolvedImport.kt");
}
@TestMetadata("idea/testData/editor/optimizeImports/common/kt21515") @TestMetadata("idea/testData/editor/optimizeImports/common/kt21515")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -367,6 +367,11 @@ public class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimizeImportsT
runTest("idea/testData/editor/optimizeImports/common/TwoConstructors.kt"); runTest("idea/testData/editor/optimizeImports/common/TwoConstructors.kt");
} }
@TestMetadata("UnresolvedImport.kt")
public void testUnresolvedImport() throws Exception {
runTest("idea/testData/editor/optimizeImports/common/UnresolvedImport.kt");
}
@TestMetadata("idea/testData/editor/optimizeImports/common/kt21515") @TestMetadata("idea/testData/editor/optimizeImports/common/kt21515")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)