From e95d1c1224ee5072f62a633befbeef749a47e349 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 17 Mar 2020 19:16:16 +0200 Subject: [PATCH] Do not suggest to update usages on renaming duplicated method or property --- ...linSuggestedRefactoringStateChanges.kt.201 | 41 ++++++++++++++-- ...uggestedRefactoringAvailabilityTest.kt.201 | 48 +++++++++++++++++++ 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringStateChanges.kt.201 b/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringStateChanges.kt.201 index f68d8a8427a..f9191729dc3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringStateChanges.kt.201 +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringStateChanges.kt.201 @@ -9,10 +9,7 @@ import com.intellij.refactoring.suggested.SuggestedRefactoringSupport.Parameter import com.intellij.refactoring.suggested.SuggestedRefactoringSupport.Signature import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.KtCallableDeclaration -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtFunction -import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.children class KotlinSuggestedRefactoringStateChanges(refactoringSupport: SuggestedRefactoringSupport) : @@ -22,7 +19,41 @@ class KotlinSuggestedRefactoringStateChanges(refactoringSupport: SuggestedRefact declaration as KtDeclaration if (declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return null // currently not supported if (declaration.hasModifier(KtTokens.ACTUAL_KEYWORD)) return null // currently not supported - return super.createInitialState(declaration) + val state = super.createInitialState(declaration) ?: return null + if (isDuplicate(declaration, state.oldSignature)) return null + return state + } + + private fun isDuplicate(declaration: KtDeclaration, signature: Signature): Boolean { + val container = declaration.parent as? KtDeclarationContainer ?: return false + if (container !is KtFile && container !is KtClassBody) return false + val name = declaration.name ?: return false + return when (declaration) { + is KtFunction -> { + container.declarations + .filter { it != declaration && it.name == name } + .any { + val otherSignature = signature(it, null) ?: return@any false + areDuplicateSignatures(otherSignature, signature) + } + } + + is KtProperty -> { + container.declarations.any { it != declaration && it is KtProperty && it.name == name } + } + + else -> false + } + } + + // we can't compare signatures by equals here because it takes into account parameter id's and they will be different in our case + private fun areDuplicateSignatures(signature1: Signature, signature2: Signature): Boolean { + if (signature1.name != signature2.name) return false + if (signature1.type != signature2.type) return false + if (signature1.parameters.size != signature2.parameters.size) return false + return signature1.parameters.zip(signature2.parameters).all { (p1, p2) -> + p1.type == p2.type && p1.name == p2.name + } } override fun signature(declaration: PsiElement, prevState: SuggestedRefactoringState?): Signature? { diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailabilityTest.kt.201 b/idea/tests/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailabilityTest.kt.201 index 2ee42f89742..216073f3a95 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailabilityTest.kt.201 +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailabilityTest.kt.201 @@ -1,5 +1,6 @@ package org.jetbrains.kotlin.idea.refactoring.suggested +import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.fileTypes.LanguageFileType import com.intellij.refactoring.suggested.BaseSuggestedRefactoringAvailabilityTest import org.jetbrains.kotlin.idea.KotlinFileType @@ -361,6 +362,53 @@ class KotlinSuggestedRefactoringAvailabilityTest : BaseSuggestedRefactoringAvail ) } + fun testDuplicateProperty() { + doTest( + """ + const val CONST1 = 1 + """.trimIndent(), + { + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_DUPLICATE) + }, + { + replaceTextAtCaret("CONST1", "CONST2") + }, + expectedAvailability = Availability.NotAvailable + ) + } + + fun testDuplicateMethod() { + doTest( + """ + class Test { + fun foo(p: Int) {} + } + """.trimIndent(), + { + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_DUPLICATE) + }, + { + replaceTextAtCaret("foo", "bar") + }, + expectedAvailability = Availability.NotAvailable + ) + } + + fun testNotDuplicateMethod() { + doTest( + """ + class Test { + fun foo(p: Int) {} + fun foo(p: String) {} + } + """.trimIndent(), + { + replaceTextAtCaret("foo", "bar") + }, + expectedAvailability = Availability.Available(renameAvailableTooltip("foo", "bar")) + ) + } + private fun addImport(fqName: String) { (file as KtFile).importList!!.add(KtPsiFactory(project).createImportDirective(ImportPath.fromString(fqName))) }