KT-10433 Copy-pasting reference to companion object member causes import dialog in specific case
#KT-10433 Fixed
This commit is contained in:
+17
-4
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.util.getFileResolutionScope
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening
|
||||
@@ -45,12 +44,14 @@ import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||
import org.jetbrains.kotlin.idea.references.*
|
||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.util.getFileResolutionScope
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
|
||||
@@ -142,12 +143,12 @@ class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<KotlinReferen
|
||||
element.forEachDescendantOfType<KtElement>(canGoInside = { it.javaClass as Class<*> !in IGNORE_REFERENCES_INSIDE }) { element ->
|
||||
val reference = element.mainReference ?: return@forEachDescendantOfType
|
||||
|
||||
val descriptors = reference.resolveToDescriptors(element.analyze()) //TODO: we could use partial body resolve for all references together
|
||||
val descriptors = resolveReference(reference)
|
||||
//check whether this reference is unambiguous
|
||||
if (reference !is KtMultiReference<*> && descriptors.size > 1) return@forEachDescendantOfType
|
||||
|
||||
for (descriptor in descriptors) {
|
||||
val declarations = DescriptorToSourceUtilsIde.getAllDeclarations(file.getProject(), descriptor)
|
||||
val declarations = DescriptorToSourceUtilsIde.getAllDeclarations(file.project, descriptor)
|
||||
val declaration = declarations.singleOrNull()
|
||||
if (declaration != null && declaration.isInCopiedArea(file, startOffsets, endOffsets)) continue
|
||||
|
||||
@@ -242,7 +243,7 @@ class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<KotlinReferen
|
||||
}
|
||||
|
||||
val referencedDescriptors = try {
|
||||
reference.resolveToDescriptors(reference.getElement().analyze()) //TODO: we could use partial body resolve for all references together
|
||||
resolveReference(reference)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error("Failed to analyze reference ($reference) after copy paste", e)
|
||||
@@ -262,6 +263,18 @@ class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<KotlinReferen
|
||||
return ReferenceToRestoreData(reference, refData)
|
||||
}
|
||||
|
||||
private fun resolveReference(reference: KtReference): Collection<DeclarationDescriptor> {
|
||||
val element = reference.element
|
||||
val bindingContext = element.analyze() //TODO: we could use partial body resolve for all references together
|
||||
|
||||
if (element is KtNameReferenceExpression && reference is KtSimpleNameReference) {
|
||||
bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, element]
|
||||
?.let { return listOf(it) }
|
||||
}
|
||||
|
||||
return reference.resolveToDescriptors(bindingContext)
|
||||
}
|
||||
|
||||
private fun restoreReferences(referencesToRestore: Collection<ReferenceToRestoreData>, file: KtFile) {
|
||||
val importHelper = ImportInsertHelper.getInstance(file.project)
|
||||
val smartPointerManager = SmartPointerManager.getInstance(file.project)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
a.A
|
||||
a.A.Companion
|
||||
a.B
|
||||
a.B.Companion
|
||||
a.T
|
||||
a.T
|
||||
@@ -1,2 +1 @@
|
||||
a.a
|
||||
a.a.Companion
|
||||
a.a
|
||||
@@ -1,5 +1,5 @@
|
||||
d.A
|
||||
d.ClassObject.Companion
|
||||
d.ClassObject
|
||||
d.E.ENTRY
|
||||
d.O1
|
||||
d.O2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
d.A
|
||||
d.ClassObject.Companion
|
||||
d.ClassObject
|
||||
d.E.ENTRY
|
||||
d.O1
|
||||
d.O2
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// ERROR: Unresolved reference: vfff
|
||||
// ERROR: No value passed for parameter text
|
||||
package p
|
||||
|
||||
fun g() {
|
||||
val fff = "0"
|
||||
c(X.vfff)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package p
|
||||
|
||||
class X {
|
||||
companion object { val v = 1 }
|
||||
}
|
||||
|
||||
fun c(value:Int, text:String) {}
|
||||
|
||||
fun f() {
|
||||
c(<selection>X.v</selection>, "")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package p
|
||||
|
||||
fun g() {
|
||||
val fff = "0"
|
||||
c(<caret>fff)
|
||||
}
|
||||
|
||||
+12
@@ -259,6 +259,12 @@ public class InsertImportOnPasteTestGenerated extends AbstractInsertImportOnPast
|
||||
doTestCopy(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("KT10433.kt")
|
||||
public void testKT10433() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/KT10433.kt");
|
||||
doTestCopy(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("KeywordClassName.kt")
|
||||
public void testKeywordClassName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/KeywordClassName.kt");
|
||||
@@ -616,6 +622,12 @@ public class InsertImportOnPasteTestGenerated extends AbstractInsertImportOnPast
|
||||
doTestCut(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("KT10433.kt")
|
||||
public void testKT10433() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/KT10433.kt");
|
||||
doTestCut(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("KeywordClassName.kt")
|
||||
public void testKeywordClassName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/KeywordClassName.kt");
|
||||
|
||||
Reference in New Issue
Block a user