diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt index a81af8036ae..d58f51fd40c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt @@ -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(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 { + 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, file: KtFile) { val importHelper = ImportInsertHelper.getInstance(file.project) val smartPointerManager = SmartPointerManager.getInstance(file.project) diff --git a/idea/testData/copyPaste/imports/ClassObject.expected.names b/idea/testData/copyPaste/imports/ClassObject.expected.names index c16c0990c16..2afc705bcb1 100644 --- a/idea/testData/copyPaste/imports/ClassObject.expected.names +++ b/idea/testData/copyPaste/imports/ClassObject.expected.names @@ -1,5 +1,3 @@ a.A -a.A.Companion a.B -a.B.Companion -a.T +a.T \ No newline at end of file diff --git a/idea/testData/copyPaste/imports/ClassResolvedToPackage.expected.names b/idea/testData/copyPaste/imports/ClassResolvedToPackage.expected.names index d6d5ebaaf76..6c762b0f038 100644 --- a/idea/testData/copyPaste/imports/ClassResolvedToPackage.expected.names +++ b/idea/testData/copyPaste/imports/ClassResolvedToPackage.expected.names @@ -1,2 +1 @@ -a.a -a.a.Companion +a.a \ No newline at end of file diff --git a/idea/testData/copyPaste/imports/DependencyOnKotlinLibrary.expected.names b/idea/testData/copyPaste/imports/DependencyOnKotlinLibrary.expected.names index e6157dde936..8e958503a94 100644 --- a/idea/testData/copyPaste/imports/DependencyOnKotlinLibrary.expected.names +++ b/idea/testData/copyPaste/imports/DependencyOnKotlinLibrary.expected.names @@ -1,5 +1,5 @@ d.A -d.ClassObject.Companion +d.ClassObject d.E.ENTRY d.O1 d.O2 diff --git a/idea/testData/copyPaste/imports/ImportDependency.expected.names b/idea/testData/copyPaste/imports/ImportDependency.expected.names index e6157dde936..8e958503a94 100644 --- a/idea/testData/copyPaste/imports/ImportDependency.expected.names +++ b/idea/testData/copyPaste/imports/ImportDependency.expected.names @@ -1,5 +1,5 @@ d.A -d.ClassObject.Companion +d.ClassObject d.E.ENTRY d.O1 d.O2 diff --git a/idea/testData/copyPaste/imports/KT10433.expected.kt b/idea/testData/copyPaste/imports/KT10433.expected.kt new file mode 100644 index 00000000000..b5eb1df2af6 --- /dev/null +++ b/idea/testData/copyPaste/imports/KT10433.expected.kt @@ -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) +} diff --git a/idea/testData/copyPaste/imports/KT10433.expected.names b/idea/testData/copyPaste/imports/KT10433.expected.names new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/copyPaste/imports/KT10433.kt b/idea/testData/copyPaste/imports/KT10433.kt new file mode 100644 index 00000000000..72c85514f9d --- /dev/null +++ b/idea/testData/copyPaste/imports/KT10433.kt @@ -0,0 +1,12 @@ +package p + +class X { + companion object { val v = 1 } +} + +fun c(value:Int, text:String) {} + +fun f() { + c(X.v, "") +} + diff --git a/idea/testData/copyPaste/imports/KT10433.to.kt b/idea/testData/copyPaste/imports/KT10433.to.kt new file mode 100644 index 00000000000..73505d347e4 --- /dev/null +++ b/idea/testData/copyPaste/imports/KT10433.to.kt @@ -0,0 +1,7 @@ +package p + +fun g() { + val fff = "0" + c(fff) +} + diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InsertImportOnPasteTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InsertImportOnPasteTestGenerated.java index 9095149c809..b872ed4462d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InsertImportOnPasteTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InsertImportOnPasteTestGenerated.java @@ -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");