Как переместить функцию из одного класса Kotlin в другой с помощью IntelliJ?

#intellij-idea #kotlin #refactoring

#intellij-идея #kotlin #рефакторинг

Вопрос:

Я использую IntelliJ IDEA для рефакторинга некоторого кода Kotlin. У меня есть два класса в одном файле, и я хочу переместить функцию из одного класса в другой с помощью Refactor -> Move (F6), но это не работает, и я получаю всплывающее сообщение, в котором говорится: «Невозможно выполнить рефакторинг. Объявление перемещения поддерживается только для объявлений верхнего уровня и вложенных классов «. Я делаю что-то не так? Или этот рефакторинг просто не поддерживается?

[edit1] Я попытался выполнить ту же операцию с классами Java, и все работает отлично; так почему это не разрешено для Kotlin?

[edit2] Я думал, что проблема возникает только тогда, когда два класса находятся в одном файле, но оказывается, что невозможно переместить функцию между классами в отдельных файлах!

Комментарии:

1. Смотрите запрос, за который вы можете проголосовать: youtrack.jetbrains.com/issue/KT-23708

2. Я думаю, что довольно неловко, что, поскольку Kotlin — язык, создаваемый и активно продвигаемый JetBrains, они не смогли сделать такого рода базовые функции (рефакторинг необходим для любого программного проекта) совместимыми с языком, который они создали:(

Ответ №1:

Это хорошо известная проблема только для Kotlin.

  • в IDEA (как бесплатной, так и платной версиях);
  • в Android Studio.

Официальный билет

Комментарии:

1. По-видимому, начиная с версии 1.4, эта проблема все еще существует :/

Ответ №2:

Есть простой, но немного неуклюжий способ обхода.

Вам просто нужно обернуть функцию, которую вы хотите переместить, в класс:

 class TopLevelClass {
    fun functionToMove() {
        //...
    }
}
  

оберните ее в новый класс

 class TopLevelClass {
    class TemporaryMoveClass{ /** you can now move this entire new class */
        fun functionToMove() {
            //...
        }
    }
}
  

и после того, как вы выполните рефакторинг, удалите созданный вами временный класс-оболочку.

Сложная часть заключается в том, что вам нужно заменить все экземпляры functionToMove() на NewTopLevelClass.functionToMove() себя.

Одно из основных преимуществ выполнения этого способа, а не просто вырезать и вставить его самостоятельно, заключается в том, что, как только вы обернете его в TemporaryMoveClass , он сообщит вам, какие параметры вам нужно ввести (Рефакторинг> Извлечение> Параметр). И затем вы можете сделать это внутри оригинала TopLevelClass перед его перемещением. (это сохраняет типы любых TopLevelClass свойств, которые вы использовали, и автоматически вводит новые параметры в существующие вызовы функций)