#KT-25674: Fix unexpected reference renames in literals when moving referenced files.
This commit is contained in:
+17
-1
@@ -64,7 +64,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import java.lang.AssertionError
|
||||
import java.util.*
|
||||
|
||||
interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration {
|
||||
@@ -205,6 +204,10 @@ class MoveKotlinDeclarationsProcessor(
|
||||
val searchScope = getSearchScope(lightElement) ?: return@flatMapTo emptyList()
|
||||
|
||||
val newFqName = StringUtil.getQualifiedName(newContainerName, lightElement.name)
|
||||
val newFqNameForKt = StringUtil.getQualifiedName(
|
||||
newContainerName,
|
||||
lightElement.namedUnwrappedElement?.name?: lightElement.name
|
||||
)
|
||||
|
||||
val foundReferences = HashSet<PsiReference>()
|
||||
val results = ReferencesSearch
|
||||
@@ -232,6 +235,19 @@ class MoveKotlinDeclarationsProcessor(
|
||||
if (handler !is MoveKotlinClassHandler) handler.preprocessUsages(results)
|
||||
}
|
||||
|
||||
results
|
||||
.filter { it is NonCodeUsageInfo && it.file is KtFile }
|
||||
.forEach {
|
||||
val newText = NonCodeUsageInfo::class.java.getField("newText")
|
||||
// A 'newText' is marked as final initially, but here we need to change it to prevent
|
||||
// light-class names in kotlin files.
|
||||
val oldAccessibility = newText.isAccessible
|
||||
newText.isAccessible = true
|
||||
newText.set(it, newFqNameForKt)
|
||||
// Restore initial accessibility of 'newText' field.
|
||||
newText.isAccessible = oldAccessibility
|
||||
}
|
||||
|
||||
results
|
||||
}
|
||||
}
|
||||
|
||||
+32
-19
@@ -24,42 +24,55 @@ import com.intellij.psi.PsiReferenceRegistrar
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FilePathReferenceProvider
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference
|
||||
import com.intellij.util.ProcessingContext
|
||||
import org.jetbrains.kotlin.idea.completion.KotlinCompletionCharFilter
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getContentRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isPlain
|
||||
import org.jetbrains.kotlin.psi.psiUtil.plainContent
|
||||
import org.jetbrains.kotlin.idea.completion.KotlinCompletionCharFilter
|
||||
|
||||
class KotlinFilePathReferenceContributor : AbstractKotlinReferenceContributor() {
|
||||
object KotlinFilePathReferenceProvider : FilePathReferenceProvider() {
|
||||
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<out PsiReference> {
|
||||
if (element !is KtStringTemplateExpression) return PsiReference.EMPTY_ARRAY
|
||||
if (!element.isPlain()) return PsiReference.EMPTY_ARRAY
|
||||
return getReferencesByElement(element, element.plainContent, element.getContentRange().startOffset, true)
|
||||
.map {
|
||||
if (it is FileReference) {
|
||||
object: FileReference(it.fileReferenceSet, it.rangeInElement, it.index, it.text) {
|
||||
override fun getVariants(): Array<out Any> {
|
||||
return super.getVariants()
|
||||
.map {
|
||||
(it as? LookupElement)?.apply {
|
||||
putUserData(KotlinCompletionCharFilter.SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING, Unit)
|
||||
} ?: it
|
||||
}
|
||||
.toTypedArray()
|
||||
}
|
||||
val refByElem = getReferencesByElement(element, element.plainContent, element.getContentRange().startOffset, true)
|
||||
val res = refByElem
|
||||
.map {
|
||||
if (it is FileReference) {
|
||||
object : FileReference(it.fileReferenceSet, it.rangeInElement, it.index, it.text) {
|
||||
override fun getVariants(): Array<out Any> {
|
||||
return super.getVariants()
|
||||
.map {
|
||||
(it as? LookupElement)?.apply {
|
||||
putUserData(KotlinCompletionCharFilter.SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING, Unit)
|
||||
} ?: it
|
||||
}
|
||||
.toTypedArray()
|
||||
}
|
||||
|
||||
// Note: this is a hack that prevents IDE from renaming paths in string literals when doing move.
|
||||
// TODO: find another way of doing this (that may need re-implementing move files refactoring using .java move)
|
||||
override fun getLastFileReference() = null
|
||||
|
||||
override fun bindToElement(element: PsiElement): PsiElement {
|
||||
return rename(element.text)
|
||||
}
|
||||
|
||||
override fun bindToElement(element: PsiElement, absolute: Boolean): PsiElement {
|
||||
return rename(element.text)
|
||||
}
|
||||
}
|
||||
else it
|
||||
}
|
||||
.toTypedArray()
|
||||
} else it
|
||||
}
|
||||
.toTypedArray()
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
|
||||
registrar.registerReferenceProvider(
|
||||
PlatformPatterns.psiElement(KtStringTemplateExpression::class.java),
|
||||
KotlinFilePathReferenceProvider
|
||||
PlatformPatterns.psiElement(KtStringTemplateExpression::class.java),
|
||||
KotlinFilePathReferenceProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user