Provide an extension point that allows plugins to handle renaming of references in other languages

This commit is contained in:
Vyacheslav Karpukhin
2020-04-29 20:56:46 +02:00
parent df4f1365ec
commit ba993ba0fe
4 changed files with 40 additions and 6 deletions
@@ -73,6 +73,10 @@
<extensionPoint qualifiedName="org.jetbrains.kotlin.experimentalFeature"
interface="org.jetbrains.kotlin.idea.configuration.ExperimentalFeature"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.foreignUsagesRenameProcessor"
interface="org.jetbrains.kotlin.idea.refactoring.rename.ForeignUsagesRenameProcessor" dynamic="true"/>
</extensionPoints>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.lang.Language
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.psi.PsiElement
import com.intellij.usageView.UsageInfo
abstract class ForeignUsagesRenameProcessor {
companion object {
private val EP_NAME = ExtensionPointName<ForeignUsagesRenameProcessor>("org.jetbrains.kotlin.foreignUsagesRenameProcessor")
@JvmStatic
fun processAll(element: PsiElement, newName: String, usages: Array<UsageInfo>, fallbackHandler: (UsageInfo) -> Unit) {
val usagesByLanguage = usages.groupBy { it.element?.language }
for ((language, languageInfos) in usagesByLanguage) {
if (language != null && EP_NAME.extensions.any { it.process(element, newName, language, languageInfos) }) {
continue
}
languageInfos.forEach(fallbackHandler)
}
}
}
abstract fun process(element: PsiElement, newName: String, language: Language, allUsages: Collection<UsageInfo>): Boolean
}
@@ -217,10 +217,10 @@ abstract class RenameKotlinFunctionProcessorCompat : RenameKotlinPsiProcessor()
override fun renameElement(element: PsiElement, newName: String, usages: Array<UsageInfo>, listener: RefactoringElementListener?) {
val simpleUsages = ArrayList<UsageInfo>(usages.size)
val ambiguousImportUsages = SmartList<UsageInfo>()
for (usage in usages) {
ForeignUsagesRenameProcessor.processAll(element, newName, usages, fallbackHandler = { usage ->
if (usage is LostDefaultValuesInOverridingFunctionUsageInfo) {
usage.apply()
continue
return@processAll
}
if (usage.isAmbiguousImportUsage()) {
@@ -230,7 +230,7 @@ abstract class RenameKotlinFunctionProcessorCompat : RenameKotlinPsiProcessor()
simpleUsages += usage
}
}
}
})
element.ambiguousImportUsages = ambiguousImportUsages
RenameUtil.doRenameGenericNamedElement(element, newName, simpleUsages.toTypedArray(), listener)
@@ -161,10 +161,10 @@ abstract class RenameKotlinPsiProcessorCompat : RenamePsiElementProcessor() {
listener: RefactoringElementListener?
) {
val simpleUsages = ArrayList<UsageInfo>(usages.size)
for (usage in usages) {
if (renameMangledUsageIfPossible(usage, element, newName)) continue
ForeignUsagesRenameProcessor.processAll(element, newName, usages, fallbackHandler = { usage ->
if (renameMangledUsageIfPossible(usage, element, newName)) return@processAll
simpleUsages += usage
}
})
RenameUtil.doRenameGenericNamedElement(element, newName, simpleUsages.toTypedArray(), listener)
}