KT-15796 Import of class referenced only in KDoc not preserved after copy-paste

#KT-15796 fixed
This commit is contained in:
Simon Ogorodnik
2017-01-23 21:08:42 +03:00
parent 4ca10c61fd
commit e220a20eed
8 changed files with 59 additions and 10 deletions
@@ -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?
@@ -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() {
@@ -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<KotlinReference
endOffsets: IntArray
): List<KotlinReferenceData> {
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 bindingContext = file.getResolutionFacade().analyze(allElementsToResolve, BodyResolveMode.PARTIAL)
@@ -139,7 +143,7 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor<KotlinReference
}
private fun MutableCollection<KotlinReferenceData>.addReferenceDataInsideElement(
element: KtElement,
element: PsiElement,
file: KtFile,
startOffset: Int,
startOffsets: IntArray,
@@ -300,21 +304,27 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor<KotlinReference
)
val bindingRequests = ArrayList<BindingRequest>()
val extensionsToImport = ArrayList<CallableDescriptor>()
val descriptorsToImport = ArrayList<DeclarationDescriptor>()
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) {
@@ -0,0 +1,9 @@
import java.io.File
/**
* [File]
*/
fun other() {
}
@@ -0,0 +1 @@
java.io.File
+12
View File
@@ -0,0 +1,12 @@
// RUNTIME
import java.io.File
<selection>
/**
* [File]
*/
</selection>
fun some() {
}
@@ -0,0 +1,4 @@
<caret>
fun other() {
}
@@ -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");