diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt index f5fd2c385cf..ce40f65d218 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt @@ -198,14 +198,17 @@ fun PsiClass.forEachDeclaredMemberOverride(processor: (superMember: PsiElement, forEachKotlinOverride(ktClass, members, scope, processor) } -fun findDeepestSuperMethodsKotlinAware(method: PsiElement): List { +fun findDeepestSuperMethodsNoWrapping(method: PsiElement): List { val element = method.unwrapped return when (element) { is PsiMethod -> element.findDeepestSuperMethods().toList() is KtCallableDeclaration -> { 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() } -} \ No newline at end of file +} + +fun findDeepestSuperMethodsKotlinAware(method: PsiElement) = + findDeepestSuperMethodsNoWrapping(method).mapNotNull { it.getRepresentativeLightMethod() } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index b2343e05ed1..623f26b25cd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -914,7 +914,7 @@ fun checkSuperMethods( fun checkSuperMethodsWithPopup( declaration: KtNamedDeclaration, - deepestSuperMethods: List, + deepestSuperMethods: List, actionString: String, editor: Editor, action: (List) -> Unit @@ -923,7 +923,12 @@ fun checkSuperMethodsWithPopup( 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) @@ -946,7 +951,7 @@ fun checkSuperMethodsWithPopup( val renameCurrent = actionString + " only current $kind" val title = buildString { 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(" of ") append(SymbolPresentationUtil.getSymbolPresentableText(superClass)) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt index 9462e21ecee..48972627c91 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.idea.refactoring.checkSuperMethodsWithPopup import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary import org.jetbrains.kotlin.idea.references.KtReference 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.util.application.runReadAction import org.jetbrains.kotlin.psi.* @@ -147,18 +148,21 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() { substituteForExpectOrActual(element)?.let { return preprocessAndPass(it) } - val wrappedMethod = wrapPsiMethod(element) ?: return - - val deepestSuperMethods = findDeepestSuperMethodsKotlinAware(wrappedMethod) + val wrappedMethod = wrapPsiMethod(element) + val deepestSuperMethods = if (wrappedMethod != null) { + findDeepestSuperMethodsKotlinAware(wrappedMethod) + } else { + findDeepestSuperMethodsNoWrapping(element) + } when { deepestSuperMethods.isEmpty() -> preprocessAndPass(element) - wrappedMethod.isConstructor || element !is KtNamedFunction -> { + wrappedMethod != null && (wrappedMethod.isConstructor || element !is KtNamedFunction) -> { javaMethodProcessorInstance.substituteElementToRename(wrappedMethod, editor, Pass(::preprocessAndPass)) } else -> { - val declaration = element.unwrapped as? KtNamedDeclaration ?: return + val declaration = element.unwrapped as? KtNamedFunction ?: return 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) } } } diff --git a/idea/testData/refactoring/rename/privateFunInMultifileFacade/after/test.kt b/idea/testData/refactoring/rename/privateFunInMultifileFacade/after/test.kt new file mode 100644 index 00000000000..dfacf5fa7aa --- /dev/null +++ b/idea/testData/refactoring/rename/privateFunInMultifileFacade/after/test.kt @@ -0,0 +1,9 @@ +@file:JvmMultifileClass() +@file:JvmName("Bazz") +package test + +private fun bar() { } + +fun test() { + bar() +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/privateFunInMultifileFacade/before/test.kt b/idea/testData/refactoring/rename/privateFunInMultifileFacade/before/test.kt new file mode 100644 index 00000000000..454ba1025ea --- /dev/null +++ b/idea/testData/refactoring/rename/privateFunInMultifileFacade/before/test.kt @@ -0,0 +1,9 @@ +@file:JvmMultifileClass() +@file:JvmName("Bazz") +package test + +private fun /*rename*/foo() { } + +fun test() { + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/privateFunInMultifileFacade/privateFunInMultifileFacade.test b/idea/testData/refactoring/rename/privateFunInMultifileFacade/privateFunInMultifileFacade.test new file mode 100644 index 00000000000..9e08b548cbd --- /dev/null +++ b/idea/testData/refactoring/rename/privateFunInMultifileFacade/privateFunInMultifileFacade.test @@ -0,0 +1,5 @@ +{ + "type": "MARKED_ELEMENT", + "mainFile": "test.kt", + "newName": "bar" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java index 524b8d4ec23..3e70331d8e6 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java @@ -469,6 +469,12 @@ public class RenameTestGenerated extends AbstractRenameTest { 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") public void testPrivateTopLevelDeclarationsNoConflict_PrivateTopLevelDeclarationsNoConflict() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/privateTopLevelDeclarationsNoConflict/privateTopLevelDeclarationsNoConflict.test");