#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
свойств, которые вы использовали, и автоматически вводит новые параметры в существующие вызовы функций)