diff --git a/ChangeLog.md b/ChangeLog.md index 5f7beae93ee..fd932532f4b 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -123,6 +123,7 @@ These artifacts include extensions for the types available in the latter JDKs, s - [`KT-13216`](https://youtrack.jetbrains.com/issue/KT-13216) Move: Forbid moving of enum entries - [`KT-13553`](https://youtrack.jetbrains.com/issue/KT-13553) Move: Do not show directory selection dialog if target directory is already specified by drag-and-drop - [`KT-8867`](https://youtrack.jetbrains.com/issue/KT-8867) Rename: Rename all overridden members if user chooses to refactor base declaration(s) +- Pull Up: Drop 'override' modifier if moved member doesn't override anything ##### New features diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt index 4a31c485a9c..34d26fcfe70 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet import org.jetbrains.kotlin.idea.core.dropDefaultValue import org.jetbrains.kotlin.idea.intentions.setType import org.jetbrains.kotlin.idea.refactoring.createJavaField +import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary import org.jetbrains.kotlin.idea.refactoring.safeDelete.removeOverrideModifier import org.jetbrains.kotlin.idea.util.anonymousObjectSuperTypeOrNull import org.jetbrains.kotlin.idea.util.psi.patternMatching.KotlinPsiUnifier @@ -497,7 +498,8 @@ class KotlinPullUpHelper( } override fun postProcessMember(member: PsiMember) { - + val declaration = member.unwrapped as? KtNamedDeclaration ?: return + dropOverrideKeywordIfNecessary(declaration) } override fun moveFieldInitializations(movedFields: LinkedHashSet) { diff --git a/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverride.kt b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverride.kt new file mode 100644 index 00000000000..816689403e3 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverride.kt @@ -0,0 +1,13 @@ +open class A { +} + +interface I { + fun foo() +} + +class B : A(), I { + // INFO: {"checked": "true", "toAbstract": "false"} + override fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverride.kt.after b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverride.kt.after new file mode 100644 index 00000000000..64995acd219 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverride.kt.after @@ -0,0 +1,13 @@ +open class A { + // INFO: {"checked": "true", "toAbstract": "false"} + fun foo() { + + } +} + +interface I { + fun foo() +} + +class B : A(), I { +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithAbstract.kt b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithAbstract.kt new file mode 100644 index 00000000000..d59de98287c --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithAbstract.kt @@ -0,0 +1,13 @@ +open class A { +} + +interface I { + fun foo() +} + +class B : A(), I { + // INFO: {"checked": "true", "toAbstract": "true"} + override fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithAbstract.kt.after b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithAbstract.kt.after new file mode 100644 index 00000000000..dc0804f241c --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithAbstract.kt.after @@ -0,0 +1,15 @@ +abstract class A { + // INFO: {"checked": "true", "toAbstract": "true"} + abstract fun foo() +} + +interface I { + fun foo() +} + +class B : A(), I { + // INFO: {"checked": "true", "toAbstract": "true"} + override fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntry.kt b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntry.kt new file mode 100644 index 00000000000..f4314312aff --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntry.kt @@ -0,0 +1,14 @@ +open class A { +} + +// INFO: {"checked": "true"} +interface I { + fun foo() +} + +class B : A(), I { + // INFO: {"checked": "true", "toAbstract": "false"} + override fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntry.kt.after b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntry.kt.after new file mode 100644 index 00000000000..a301dadf37e --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntry.kt.after @@ -0,0 +1,14 @@ +open class A : I { + // INFO: {"checked": "true", "toAbstract": "false"} + override fun foo() { + + } +} + +// INFO: {"checked": "true"} +interface I { + fun foo() +} + +class B : A() { +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract.kt b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract.kt new file mode 100644 index 00000000000..ce7b76a3e99 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract.kt @@ -0,0 +1,14 @@ +open class A { +} + +// INFO: {"checked": "true"} +interface I { + fun foo() +} + +class B : A(), I { + // INFO: {"checked": "true", "toAbstract": "true"} + override fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract.kt.after b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract.kt.after new file mode 100644 index 00000000000..11d0d8ef26b --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract.kt.after @@ -0,0 +1,16 @@ +abstract class A : I { + // INFO: {"checked": "true", "toAbstract": "true"} + abstract override fun foo() +} + +// INFO: {"checked": "true"} +interface I { + fun foo() +} + +class B : A() { + // INFO: {"checked": "true", "toAbstract": "true"} + override fun foo() { + + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/pullUp/PullUpTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/pullUp/PullUpTestGenerated.java index 7242089d48f..732ce171b65 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/pullUp/PullUpTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/pullUp/PullUpTestGenerated.java @@ -55,6 +55,30 @@ public class PullUpTestGenerated extends AbstractPullUpTest { doKotlinTest(fileName); } + @TestMetadata("dropModifierWhenMovingSideOverride.kt") + public void testDropModifierWhenMovingSideOverride() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverride.kt"); + doKotlinTest(fileName); + } + + @TestMetadata("dropModifierWhenMovingSideOverrideWithAbstract.kt") + public void testDropModifierWhenMovingSideOverrideWithAbstract() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithAbstract.kt"); + doKotlinTest(fileName); + } + + @TestMetadata("dropModifierWhenMovingSideOverrideWithSuperEntry.kt") + public void testDropModifierWhenMovingSideOverrideWithSuperEntry() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntry.kt"); + doKotlinTest(fileName); + } + + @TestMetadata("dropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract.kt") + public void testDropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/dropModifierWhenMovingSideOverrideWithSuperEntryAndAbstract.kt"); + doKotlinTest(fileName); + } + @TestMetadata("fromClassToClass.kt") public void testFromClassToClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/fromClassToClass.kt");