diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 48b9d81a565..b832b6b043e 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -2781,6 +2781,7 @@ + diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameSyntheticDeclarationByReferenceHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameSyntheticDeclarationByReferenceHandler.kt new file mode 100644 index 00000000000..82bc397664d --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameSyntheticDeclarationByReferenceHandler.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. 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.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.refactoring.rename.RenameHandler +import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall +import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.tower.isSynthesized + +class RenameSyntheticDeclarationByReferenceHandler : RenameHandler { + override fun isAvailableOnDataContext(dataContext: DataContext?): Boolean { + if (dataContext == null) return false + val file = CommonDataKeys.PSI_FILE.getData(dataContext) ?: return false + val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: return false + val refExpression = file.findElementForRename(editor.caretModel.offset) ?: return false + return (refExpression.resolveToCall()?.resultingDescriptor)?.isSynthesized ?: false + } + + override fun isRenaming(dataContext: DataContext?) = isAvailableOnDataContext(dataContext) + + override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) { + CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to synthetic declaration", "Rename", null) + } + + override fun invoke(project: Project, elements: Array, dataContext: DataContext?) { + // Do nothing: this method is not called from editor + } +} diff --git a/idea/testData/refactoring/rename/dataClassComponentN/after/test.kt b/idea/testData/refactoring/rename/dataClassComponentN/after/test.kt new file mode 100644 index 00000000000..ec8d59de831 --- /dev/null +++ b/idea/testData/refactoring/rename/dataClassComponentN/after/test.kt @@ -0,0 +1,5 @@ +data class XYZ(val x: Int, val y: Int, val z: Int) + +fun test() { + val y = XYZ(1, 2, 3)./*rename*/component2() +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/dataClassComponentN/before/test.kt b/idea/testData/refactoring/rename/dataClassComponentN/before/test.kt new file mode 100644 index 00000000000..ec8d59de831 --- /dev/null +++ b/idea/testData/refactoring/rename/dataClassComponentN/before/test.kt @@ -0,0 +1,5 @@ +data class XYZ(val x: Int, val y: Int, val z: Int) + +fun test() { + val y = XYZ(1, 2, 3)./*rename*/component2() +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/dataClassComponentN/dataClassComponentN.test b/idea/testData/refactoring/rename/dataClassComponentN/dataClassComponentN.test new file mode 100644 index 00000000000..136def502e0 --- /dev/null +++ b/idea/testData/refactoring/rename/dataClassComponentN/dataClassComponentN.test @@ -0,0 +1,7 @@ +{ + "type": "AUTO_DETECT", + "mainFile": "test.kt", + "newName": "component123", + "withRuntime": "true", + "hint": "Rename is not applicable to synthetic declaration" +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/dataClassCopy/after/test.kt b/idea/testData/refactoring/rename/dataClassCopy/after/test.kt new file mode 100644 index 00000000000..c79f75b8c74 --- /dev/null +++ b/idea/testData/refactoring/rename/dataClassCopy/after/test.kt @@ -0,0 +1,5 @@ +data class XYZ(val x: Int, val y: Int, val z: Int) + +fun test() { + XYZ(1, 2, 3)./*rename*/copy(x = 10) +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/dataClassCopy/before/test.kt b/idea/testData/refactoring/rename/dataClassCopy/before/test.kt new file mode 100644 index 00000000000..c79f75b8c74 --- /dev/null +++ b/idea/testData/refactoring/rename/dataClassCopy/before/test.kt @@ -0,0 +1,5 @@ +data class XYZ(val x: Int, val y: Int, val z: Int) + +fun test() { + XYZ(1, 2, 3)./*rename*/copy(x = 10) +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/dataClassCopy/dataClassCopy.test b/idea/testData/refactoring/rename/dataClassCopy/dataClassCopy.test new file mode 100644 index 00000000000..0d6c55fab1b --- /dev/null +++ b/idea/testData/refactoring/rename/dataClassCopy/dataClassCopy.test @@ -0,0 +1,7 @@ +{ + "type": "AUTO_DETECT", + "mainFile": "test.kt", + "newName": "copyNew", + "withRuntime": "true", + "hint": "Rename is not applicable to synthetic declaration" +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/enumValueOf/after/test.kt b/idea/testData/refactoring/rename/enumValueOf/after/test.kt new file mode 100644 index 00000000000..e2691609a1f --- /dev/null +++ b/idea/testData/refactoring/rename/enumValueOf/after/test.kt @@ -0,0 +1,2 @@ +enum class Foo{BAR, BAZ} +val bar = Foo./*rename*/valueOf("BAR") \ No newline at end of file diff --git a/idea/testData/refactoring/rename/enumValueOf/before/test.kt b/idea/testData/refactoring/rename/enumValueOf/before/test.kt new file mode 100644 index 00000000000..e2691609a1f --- /dev/null +++ b/idea/testData/refactoring/rename/enumValueOf/before/test.kt @@ -0,0 +1,2 @@ +enum class Foo{BAR, BAZ} +val bar = Foo./*rename*/valueOf("BAR") \ No newline at end of file diff --git a/idea/testData/refactoring/rename/enumValueOf/enumValueOf.test b/idea/testData/refactoring/rename/enumValueOf/enumValueOf.test new file mode 100644 index 00000000000..81a1a57cb22 --- /dev/null +++ b/idea/testData/refactoring/rename/enumValueOf/enumValueOf.test @@ -0,0 +1,7 @@ +{ + "type": "AUTO_DETECT", + "mainFile": "test.kt", + "newName": "valueOfNew", + "withRuntime": "true", + "hint": "Rename is not applicable to synthetic declaration" +} \ 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 fbfc6728054..a5fb64dc674 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java @@ -205,6 +205,24 @@ public class RenameTestGenerated extends AbstractRenameTest { doTest(fileName); } + @TestMetadata("dataClassComponentN/dataClassComponentN.test") + public void testDataClassComponentN_DataClassComponentN() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/dataClassComponentN/dataClassComponentN.test"); + doTest(fileName); + } + + @TestMetadata("dataClassCopy/dataClassCopy.test") + public void testDataClassCopy_DataClassCopy() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/dataClassCopy/dataClassCopy.test"); + doTest(fileName); + } + + @TestMetadata("enumValueOf/enumValueOf.test") + public void testEnumValueOf_EnumValueOf() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/enumValueOf/enumValueOf.test"); + doTest(fileName); + } + @TestMetadata("funTextOccurrences/funTextOccurrences.test") public void testFunTextOccurrences_FunTextOccurrences() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/funTextOccurrences/funTextOccurrences.test");