ImportOptimizer: add cases for unresolved references

Part of #KT-31331
This commit is contained in:
Dmitry Gridin
2020-06-17 21:13:25 +07:00
parent 4de582564c
commit 10c62b8d77
8 changed files with 58 additions and 12 deletions
@@ -28,10 +28,12 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.*
import org.jetbrains.kotlin.types.error.ErrorSimpleFunctionDescriptorImpl
class KotlinImportOptimizer : ImportOptimizer {
override fun supports(file: PsiFile) = file is KtFile
@@ -145,17 +147,27 @@ class KotlinImportOptimizer : ImportOptimizer {
}
override fun visitKtElement(element: KtElement) {
for (reference in element.references) {
super.visitKtElement(element)
val references = element.references.ifEmpty { return }
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
val isResolved = if (element is KtCallElement)
element.getResolvedCall(bindingContext) != null
else
element.mainReference?.resolveToDescriptors(bindingContext)?.let { descriptors ->
descriptors.isNotEmpty() && descriptors.none { it is ErrorSimpleFunctionDescriptorImpl }
} == true
for (reference in references) {
if (reference !is KtReference) continue
abstractRefs.add(AbstractReferenceImpl(reference))
val names = reference.resolvesByNames
var isResolved = false
if (!isResolved) {
unresolvedNames += names
}
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
for (target in reference.targets(bindingContext)) {
isResolved = true
val importableDescriptor = target.getImportableDescriptor()
val importableFqName = target.importableFqName ?: continue
val parentFqName = importableFqName.parent()
@@ -171,11 +183,7 @@ class KotlinImportOptimizer : ImportOptimizer {
namesToImport.getOrPut(importableFqName) { hashSetOf() } += descriptorNames
descriptorsToImport += importableDescriptor
}
if (!isResolved && reference is KtSimpleNameReference) unresolvedNames += names
}
super.visitKtElement(element)
}
private fun isAccessibleAsMember(target: DeclarationDescriptor, place: KtElement, bindingContext: BindingContext): Boolean {
@@ -1,5 +1,6 @@
import test1.MyClass
import test1.iterator
import test2.iterator
fun foo() {
val s = MyClass()
@@ -0,0 +1,11 @@
import test1.MyClass
import test1.iterator
import test2.iterator
import test3.notIterator
import test1.invoke
import test4.*
fun foo() {
val s = MyClass()
for (i in s) {}
}
@@ -0,0 +1,10 @@
import test1.MyClass
import test1.invoke
import test1.iterator
import test2.iterator
import test4.*
fun foo() {
val s = MyClass()
for (i in s) {}
}
@@ -133,6 +133,11 @@ public class JsOptimizeImportsTestGenerated extends AbstractJsOptimizeImportsTes
runTest("idea/testData/editor/optimizeImports/common/IteratorFunction.kt");
}
@TestMetadata("IteratorFunction2.kt")
public void testIteratorFunction2() throws Exception {
runTest("idea/testData/editor/optimizeImports/common/IteratorFunction2.kt");
}
@TestMetadata("KT11640.kt")
public void testKT11640() throws Exception {
runTest("idea/testData/editor/optimizeImports/common/KT11640.kt");
@@ -331,6 +331,11 @@ public class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimizeImportsT
runTest("idea/testData/editor/optimizeImports/common/IteratorFunction.kt");
}
@TestMetadata("IteratorFunction2.kt")
public void testIteratorFunction2() throws Exception {
runTest("idea/testData/editor/optimizeImports/common/IteratorFunction2.kt");
}
@TestMetadata("KT11640.kt")
public void testKT11640() throws Exception {
runTest("idea/testData/editor/optimizeImports/common/KT11640.kt");
@@ -2,5 +2,8 @@
package test;
import as.type.val.var.fun.is.in.object.when.typeof;
import as.type.val.var.fun.is.in.object.when.typeof.as;
class Test {}
class Test {
public void foo(as a) { }
}
+5 -2
View File
@@ -1,6 +1,9 @@
// ERROR: Unresolved reference: `as`
// ERROR: Unresolved reference: `as`
package test
import `as`.type.`val`.`var`.`fun`.`is`.`in`.`object`.`when`.`typeof`
import `as`.type.`val`.`var`.`fun`.`is`.`in`.`object`.`when`.`typeof`.`as`
internal class Test
internal class Test {
fun foo(a: `as`?) {}
}