Как изменить ссылку на код Котлина с функции на поле в плагине intellij? - PullRequest
0 голосов
/ 08 июня 2018

Я пишу плагин intellij, в котором я делаю рефакторинг класса, меняя его получатели (например, fun name(): String) на поля (например, val name: String).

Однако я незнать, как лучше обновить соответствующие PsiReference экземпляры.Абонент Kotlin должен изменить значение с myObj.name() на myObj.name без скобок.

В настоящее время я делаю следующее:

ReferencesSearch.search(function).findAll().forEach {
    val nextSibling = it.element.nextSibling
    if ((nextSibling as? KtValueArgumentList)?.arguments?.isEmpty() == true) {
        nextSibling.delete()
    }
}

Вышеприведенное несколько работает.То есть конвертация происходит правильно.Однако IDE все еще думает, что вызывает функцию.Это подчеркивает ошибку в преобразованном myObj.name со следующим сообщением:

Выражение «имя» типа String не может быть вызвано как функция.Функция 'invoke ()' не найдена

Переписывание вручную name в редакторе заставляет intellij обновлять ссылку, и ошибка исчезает.

Что вместо этого следует сделать, чтобы предотвратитьэто случилось?

1 Ответ

0 голосов
/ 14 июня 2018

Вы получаете это сообщение об ошибке, потому что вы не изменяете ссылку на старый метод.Intellij по-прежнему считает, что ваш вызов myObj.name пытается получить доступ к какому-либо методу name(), который больше не существует.

Кроме того, результат поиска будет указывать на конечный узел в AST, который использует ваш метод.В этом случае name() имеет родительский объект PSI , который содержит ссылку на name и ().Вот почему при звонке на номер element.nextSibling вы получаете (), который вы затем можете набрать delete().Но это не меняет ссылку на родителя.

Я не уверен, как лучше всего делать то, что вы хотите, но вы можете попытаться заменить ссылку родителя напрямую.Попробуйте:

element.parent.replace(<reference to your the data class field>)
...