Rename: Fix processing of functions without light methods
#KT-22461 Fixed
This commit is contained in:
+5
-2
@@ -198,14 +198,17 @@ fun PsiClass.forEachDeclaredMemberOverride(processor: (superMember: PsiElement,
|
|||||||
forEachKotlinOverride(ktClass, members, scope, processor)
|
forEachKotlinOverride(ktClass, members, scope, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findDeepestSuperMethodsKotlinAware(method: PsiElement): List<PsiMethod> {
|
fun findDeepestSuperMethodsNoWrapping(method: PsiElement): List<PsiElement> {
|
||||||
val element = method.unwrapped
|
val element = method.unwrapped
|
||||||
return when (element) {
|
return when (element) {
|
||||||
is PsiMethod -> element.findDeepestSuperMethods().toList()
|
is PsiMethod -> element.findDeepestSuperMethods().toList()
|
||||||
is KtCallableDeclaration -> {
|
is KtCallableDeclaration -> {
|
||||||
val descriptor = element.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return emptyList()
|
val descriptor = element.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return emptyList()
|
||||||
descriptor.getDeepestSuperDeclarations(false).mapNotNull { it.source.getPsi()?.getRepresentativeLightMethod() }
|
descriptor.getDeepestSuperDeclarations(false).mapNotNull { it.source.getPsi() }
|
||||||
}
|
}
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun findDeepestSuperMethodsKotlinAware(method: PsiElement) =
|
||||||
|
findDeepestSuperMethodsNoWrapping(method).mapNotNull { it.getRepresentativeLightMethod() }
|
||||||
@@ -914,7 +914,7 @@ fun checkSuperMethods(
|
|||||||
|
|
||||||
fun checkSuperMethodsWithPopup(
|
fun checkSuperMethodsWithPopup(
|
||||||
declaration: KtNamedDeclaration,
|
declaration: KtNamedDeclaration,
|
||||||
deepestSuperMethods: List<PsiMethod>,
|
deepestSuperMethods: List<PsiElement>,
|
||||||
actionString: String,
|
actionString: String,
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
action: (List<PsiElement>) -> Unit
|
action: (List<PsiElement>) -> Unit
|
||||||
@@ -923,7 +923,12 @@ fun checkSuperMethodsWithPopup(
|
|||||||
|
|
||||||
val superMethod = deepestSuperMethods.first()
|
val superMethod = deepestSuperMethods.first()
|
||||||
|
|
||||||
val superClass = superMethod.containingClass ?: return action(listOf(declaration))
|
val (superClass, isAbstract) = when (superMethod) {
|
||||||
|
is PsiMember -> superMethod.containingClass to superMethod.hasModifierProperty(PsiModifier.ABSTRACT)
|
||||||
|
is KtNamedDeclaration -> superMethod.containingClassOrObject to superMethod.isAbstract()
|
||||||
|
else -> null
|
||||||
|
} ?: return action(listOf(declaration))
|
||||||
|
if (superClass == null) return action(listOf(declaration))
|
||||||
|
|
||||||
if (ApplicationManager.getApplication().isUnitTestMode) return action(deepestSuperMethods)
|
if (ApplicationManager.getApplication().isUnitTestMode) return action(deepestSuperMethods)
|
||||||
|
|
||||||
@@ -946,7 +951,7 @@ fun checkSuperMethodsWithPopup(
|
|||||||
val renameCurrent = actionString + " only current $kind"
|
val renameCurrent = actionString + " only current $kind"
|
||||||
val title = buildString {
|
val title = buildString {
|
||||||
append(declaration.name)
|
append(declaration.name)
|
||||||
append(if (superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) " implements " else " overrides ")
|
append(if (isAbstract) " implements " else " overrides ")
|
||||||
append(ElementDescriptionUtil.getElementDescription(superMethod, UsageViewTypeLocation.INSTANCE))
|
append(ElementDescriptionUtil.getElementDescription(superMethod, UsageViewTypeLocation.INSTANCE))
|
||||||
append(" of ")
|
append(" of ")
|
||||||
append(SymbolPresentationUtil.getSymbolPresentableText(superClass))
|
append(SymbolPresentationUtil.getSymbolPresentableText(superClass))
|
||||||
|
|||||||
+10
-6
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.idea.refactoring.checkSuperMethodsWithPopup
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary
|
import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsKotlinAware
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsKotlinAware
|
||||||
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsNoWrapping
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -147,18 +148,21 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
|
|||||||
|
|
||||||
substituteForExpectOrActual(element)?.let { return preprocessAndPass(it) }
|
substituteForExpectOrActual(element)?.let { return preprocessAndPass(it) }
|
||||||
|
|
||||||
val wrappedMethod = wrapPsiMethod(element) ?: return
|
val wrappedMethod = wrapPsiMethod(element)
|
||||||
|
val deepestSuperMethods = if (wrappedMethod != null) {
|
||||||
val deepestSuperMethods = findDeepestSuperMethodsKotlinAware(wrappedMethod)
|
findDeepestSuperMethodsKotlinAware(wrappedMethod)
|
||||||
|
} else {
|
||||||
|
findDeepestSuperMethodsNoWrapping(element)
|
||||||
|
}
|
||||||
when {
|
when {
|
||||||
deepestSuperMethods.isEmpty() -> preprocessAndPass(element)
|
deepestSuperMethods.isEmpty() -> preprocessAndPass(element)
|
||||||
wrappedMethod.isConstructor || element !is KtNamedFunction -> {
|
wrappedMethod != null && (wrappedMethod.isConstructor || element !is KtNamedFunction) -> {
|
||||||
javaMethodProcessorInstance.substituteElementToRename(wrappedMethod, editor, Pass(::preprocessAndPass))
|
javaMethodProcessorInstance.substituteElementToRename(wrappedMethod, editor, Pass(::preprocessAndPass))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val declaration = element.unwrapped as? KtNamedDeclaration ?: return
|
val declaration = element.unwrapped as? KtNamedFunction ?: return
|
||||||
checkSuperMethodsWithPopup(declaration, deepestSuperMethods.toList(), "Rename", editor) {
|
checkSuperMethodsWithPopup(declaration, deepestSuperMethods.toList(), "Rename", editor) {
|
||||||
preprocessAndPass(if (it.size > 1) FunctionWithSupersWrapper(element, it) else wrappedMethod)
|
preprocessAndPass(if (it.size > 1) FunctionWithSupersWrapper(declaration, it) else wrappedMethod ?: element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
@file:JvmMultifileClass()
|
||||||
|
@file:JvmName("Bazz")
|
||||||
|
package test
|
||||||
|
|
||||||
|
private fun bar() { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
bar()
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
@file:JvmMultifileClass()
|
||||||
|
@file:JvmName("Bazz")
|
||||||
|
package test
|
||||||
|
|
||||||
|
private fun /*rename*/foo() { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"type": "MARKED_ELEMENT",
|
||||||
|
"mainFile": "test.kt",
|
||||||
|
"newName": "bar"
|
||||||
|
}
|
||||||
+6
@@ -469,6 +469,12 @@ public class RenameTestGenerated extends AbstractRenameTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateFunInMultifileFacade/privateFunInMultifileFacade.test")
|
||||||
|
public void testPrivateFunInMultifileFacade_privateFunInMultifileFacade() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/privateFunInMultifileFacade/privateFunInMultifileFacade.test");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateTopLevelDeclarationsNoConflict/privateTopLevelDeclarationsNoConflict.test")
|
@TestMetadata("privateTopLevelDeclarationsNoConflict/privateTopLevelDeclarationsNoConflict.test")
|
||||||
public void testPrivateTopLevelDeclarationsNoConflict_PrivateTopLevelDeclarationsNoConflict() throws Exception {
|
public void testPrivateTopLevelDeclarationsNoConflict_PrivateTopLevelDeclarationsNoConflict() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/privateTopLevelDeclarationsNoConflict/privateTopLevelDeclarationsNoConflict.test");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/privateTopLevelDeclarationsNoConflict/privateTopLevelDeclarationsNoConflict.test");
|
||||||
|
|||||||
Reference in New Issue
Block a user