KT-15796 Import of class referenced only in KDoc not preserved after copy-paste
#KT-15796 fixed
This commit is contained in:
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
|||||||
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
||||||
|
|
||||||
// Don't implement JetElement (or it will be treated as statement)
|
// Don't implement JetElement (or it will be treated as statement)
|
||||||
interface KDoc : PsiComment {
|
interface KDoc : PsiComment, KDocElement {
|
||||||
fun getOwner(): KtDeclaration?
|
fun getOwner(): KtDeclaration?
|
||||||
fun getDefaultSection(): KDocSection
|
fun getDefaultSection(): KDocSection
|
||||||
fun findSectionByName(name: String): KDocSection?
|
fun findSectionByName(name: String): KDocSection?
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ import com.intellij.lang.ASTNode;
|
|||||||
import com.intellij.lang.Language;
|
import com.intellij.lang.Language;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Language getLanguage() {
|
public Language getLanguage() {
|
||||||
|
|||||||
+18
-8
@@ -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.range
|
||||||
import org.jetbrains.kotlin.idea.conversion.copy.start
|
import org.jetbrains.kotlin.idea.conversion.copy.start
|
||||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
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.references.*
|
||||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.idea.util.getFileResolutionScope
|
import org.jetbrains.kotlin.idea.util.getFileResolutionScope
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
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.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||||
@@ -124,7 +126,9 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor<KotlinReference
|
|||||||
endOffsets: IntArray
|
endOffsets: IntArray
|
||||||
): List<KotlinReferenceData> {
|
): List<KotlinReferenceData> {
|
||||||
val ranges = toTextRanges(startOffsets, endOffsets)
|
val ranges = toTextRanges(startOffsets, endOffsets)
|
||||||
val elementsByRange = ranges.associateBy({ it }, { file.elementsInRange(it).filterIsInstance<KtElement>() })
|
val elementsByRange = ranges.associateBy({ it }, {
|
||||||
|
file.elementsInRange(it).filter { it is KtElement || it is KDocElement }
|
||||||
|
})
|
||||||
|
|
||||||
val allElementsToResolve = elementsByRange.values.flatMap { it }.flatMap { it.collectDescendantsOfType<KtElement>() }
|
val allElementsToResolve = elementsByRange.values.flatMap { it }.flatMap { it.collectDescendantsOfType<KtElement>() }
|
||||||
val bindingContext = file.getResolutionFacade().analyze(allElementsToResolve, BodyResolveMode.PARTIAL)
|
val bindingContext = file.getResolutionFacade().analyze(allElementsToResolve, BodyResolveMode.PARTIAL)
|
||||||
@@ -139,7 +143,7 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor<KotlinReference
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableCollection<KotlinReferenceData>.addReferenceDataInsideElement(
|
private fun MutableCollection<KotlinReferenceData>.addReferenceDataInsideElement(
|
||||||
element: KtElement,
|
element: PsiElement,
|
||||||
file: KtFile,
|
file: KtFile,
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
startOffsets: IntArray,
|
startOffsets: IntArray,
|
||||||
@@ -300,21 +304,27 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor<KotlinReference
|
|||||||
)
|
)
|
||||||
|
|
||||||
val bindingRequests = ArrayList<BindingRequest>()
|
val bindingRequests = ArrayList<BindingRequest>()
|
||||||
val extensionsToImport = ArrayList<CallableDescriptor>()
|
val descriptorsToImport = ArrayList<DeclarationDescriptor>()
|
||||||
|
|
||||||
for ((reference, refData) in referencesToRestore) {
|
for ((reference, refData) in referencesToRestore) {
|
||||||
val fqName = FqName(refData.fqName)
|
val fqName = FqName(refData.fqName)
|
||||||
|
|
||||||
if (!refData.kind.isExtension() && reference is KtSimpleNameReference) {
|
if (!refData.kind.isExtension()) {
|
||||||
val pointer = smartPointerManager.createSmartPsiElementPointer(reference.element, file)
|
if (reference is KtSimpleNameReference) {
|
||||||
bindingRequests.add(BindingRequest(pointer, fqName))
|
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()) {
|
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)
|
importHelper.importDescriptor(file, descriptor)
|
||||||
}
|
}
|
||||||
for ((pointer, fqName) in bindingRequests) {
|
for ((pointer, fqName) in bindingRequests) {
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [File]
|
||||||
|
*/
|
||||||
|
|
||||||
|
fun other() {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
java.io.File
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// RUNTIME
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
<selection>
|
||||||
|
/**
|
||||||
|
* [File]
|
||||||
|
*/
|
||||||
|
</selection>
|
||||||
|
fun some() {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<caret>
|
||||||
|
fun other() {
|
||||||
|
|
||||||
|
}
|
||||||
+12
@@ -320,6 +320,12 @@ public class InsertImportOnPasteTestGenerated extends AbstractInsertImportOnPast
|
|||||||
doTestCopy(fileName);
|
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")
|
@TestMetadata("OverloadedExtensionFunction.kt")
|
||||||
public void testOverloadedExtensionFunction() throws Exception {
|
public void testOverloadedExtensionFunction() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/OverloadedExtensionFunction.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/OverloadedExtensionFunction.kt");
|
||||||
@@ -683,6 +689,12 @@ public class InsertImportOnPasteTestGenerated extends AbstractInsertImportOnPast
|
|||||||
doTestCut(fileName);
|
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")
|
@TestMetadata("OverloadedExtensionFunction.kt")
|
||||||
public void testOverloadedExtensionFunction() throws Exception {
|
public void testOverloadedExtensionFunction() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/OverloadedExtensionFunction.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/imports/OverloadedExtensionFunction.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user