From e220a20eed9e5b7ededf471f8ff191b66ab35262 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 23 Jan 2017 21:08:42 +0300 Subject: [PATCH] KT-15796 Import of class referenced only in KDoc not preserved after copy-paste #KT-15796 fixed --- .../org/jetbrains/kotlin/kdoc/psi/api/KDoc.kt | 2 +- .../kotlin/kdoc/psi/impl/KDocElementImpl.java | 3 ++- .../KotlinCopyPasteReferenceProcessor.kt | 26 +++++++++++++------ .../imports/OnlyKDocReferenced.expected.kt | 9 +++++++ .../imports/OnlyKDocReferenced.expected.names | 1 + .../copyPaste/imports/OnlyKDocReferenced.kt | 12 +++++++++ .../imports/OnlyKDocReferenced.to.kt | 4 +++ .../InsertImportOnPasteTestGenerated.java | 12 +++++++++ 8 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 idea/testData/copyPaste/imports/OnlyKDocReferenced.expected.kt create mode 100644 idea/testData/copyPaste/imports/OnlyKDocReferenced.expected.names create mode 100644 idea/testData/copyPaste/imports/OnlyKDocReferenced.kt create mode 100644 idea/testData/copyPaste/imports/OnlyKDocReferenced.to.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/api/KDoc.kt b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/api/KDoc.kt index 9bb1aaf1360..18e12875d1e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/api/KDoc.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/api/KDoc.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag // Don't implement JetElement (or it will be treated as statement) -interface KDoc : PsiComment { +interface KDoc : PsiComment, KDocElement { fun getOwner(): KtDeclaration? fun getDefaultSection(): KDocSection fun findSectionByName(name: String): KDocSection? diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocElementImpl.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocElementImpl.java index dc4cfd328a2..1e017938d21 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocElementImpl.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocElementImpl.java @@ -21,8 +21,9 @@ import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.KotlinLanguage; +import org.jetbrains.kotlin.kdoc.psi.api.KDocElement; -public abstract class KDocElementImpl extends ASTWrapperPsiElement { +public abstract class KDocElementImpl extends ASTWrapperPsiElement implements KDocElement { @NotNull @Override public Language getLanguage() { diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt index 839163666fa..b171681455b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt @@ -40,11 +40,13 @@ import org.jetbrains.kotlin.idea.conversion.copy.end import org.jetbrains.kotlin.idea.conversion.copy.range import org.jetbrains.kotlin.idea.conversion.copy.start import org.jetbrains.kotlin.idea.imports.importableFqName +import org.jetbrains.kotlin.idea.kdoc.KDocReference 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.kdoc.psi.api.KDocElement import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType @@ -124,7 +126,9 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor { val ranges = toTextRanges(startOffsets, endOffsets) - val elementsByRange = ranges.associateBy({ it }, { file.elementsInRange(it).filterIsInstance() }) + val elementsByRange = ranges.associateBy({ it }, { + file.elementsInRange(it).filter { it is KtElement || it is KDocElement } + }) val allElementsToResolve = elementsByRange.values.flatMap { it }.flatMap { it.collectDescendantsOfType() } val bindingContext = file.getResolutionFacade().analyze(allElementsToResolve, BodyResolveMode.PARTIAL) @@ -139,7 +143,7 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor.addReferenceDataInsideElement( - element: KtElement, + element: PsiElement, file: KtFile, startOffset: Int, startOffsets: IntArray, @@ -300,21 +304,27 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor() - val extensionsToImport = ArrayList() + val descriptorsToImport = ArrayList() + for ((reference, refData) in referencesToRestore) { val fqName = FqName(refData.fqName) - if (!refData.kind.isExtension() && reference is KtSimpleNameReference) { - val pointer = smartPointerManager.createSmartPsiElementPointer(reference.element, file) - bindingRequests.add(BindingRequest(pointer, fqName)) + if (!refData.kind.isExtension()) { + if (reference is KtSimpleNameReference) { + val pointer = smartPointerManager.createSmartPsiElementPointer(reference.element, file) + bindingRequests.add(BindingRequest(pointer, fqName)) + } + else if (reference is KDocReference) { + descriptorsToImport.addAll(findImportableDescriptors(fqName, file)) + } } if (refData.kind.isExtension()) { - extensionsToImport.addIfNotNull(findCallableToImport(fqName, file)) + descriptorsToImport.addIfNotNull(findCallableToImport(fqName, file)) } } - for (descriptor in extensionsToImport) { + for (descriptor in descriptorsToImport) { importHelper.importDescriptor(file, descriptor) } for ((pointer, fqName) in bindingRequests) { diff --git a/idea/testData/copyPaste/imports/OnlyKDocReferenced.expected.kt b/idea/testData/copyPaste/imports/OnlyKDocReferenced.expected.kt new file mode 100644 index 00000000000..9f049205502 --- /dev/null +++ b/idea/testData/copyPaste/imports/OnlyKDocReferenced.expected.kt @@ -0,0 +1,9 @@ +import java.io.File + +/** + * [File] + */ + +fun other() { + +} \ No newline at end of file diff --git a/idea/testData/copyPaste/imports/OnlyKDocReferenced.expected.names b/idea/testData/copyPaste/imports/OnlyKDocReferenced.expected.names new file mode 100644 index 00000000000..54037550dcd --- /dev/null +++ b/idea/testData/copyPaste/imports/OnlyKDocReferenced.expected.names @@ -0,0 +1 @@ +java.io.File \ No newline at end of file diff --git a/idea/testData/copyPaste/imports/OnlyKDocReferenced.kt b/idea/testData/copyPaste/imports/OnlyKDocReferenced.kt new file mode 100644 index 00000000000..5fdc6512be1 --- /dev/null +++ b/idea/testData/copyPaste/imports/OnlyKDocReferenced.kt @@ -0,0 +1,12 @@ +// RUNTIME + +import java.io.File + + +/** + * [File] + */ + +fun some() { + +} \ No newline at end of file diff --git a/idea/testData/copyPaste/imports/OnlyKDocReferenced.to.kt b/idea/testData/copyPaste/imports/OnlyKDocReferenced.to.kt new file mode 100644 index 00000000000..01189ba0993 --- /dev/null +++ b/idea/testData/copyPaste/imports/OnlyKDocReferenced.to.kt @@ -0,0 +1,4 @@ + +fun other() { + +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InsertImportOnPasteTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InsertImportOnPasteTestGenerated.java index 81c3d5f488f..48f2d6283f9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InsertImportOnPasteTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InsertImportOnPasteTestGenerated.java @@ -320,6 +320,12 @@ public class InsertImportOnPasteTestGenerated extends AbstractInsertImportOnPast doTestCopy(fileName); } + @TestMetadata("OnlyKDocReferenced.kt") + public void testOnlyKDocReferenced() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/OnlyKDocReferenced.kt"); + doTestCopy(fileName); + } + @TestMetadata("OverloadedExtensionFunction.kt") public void testOverloadedExtensionFunction() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/OverloadedExtensionFunction.kt"); @@ -683,6 +689,12 @@ public class InsertImportOnPasteTestGenerated extends AbstractInsertImportOnPast doTestCut(fileName); } + @TestMetadata("OnlyKDocReferenced.kt") + public void testOnlyKDocReferenced() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/OnlyKDocReferenced.kt"); + doTestCut(fileName); + } + @TestMetadata("OverloadedExtensionFunction.kt") public void testOverloadedExtensionFunction() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/OverloadedExtensionFunction.kt");