如何将 Kotlin 代码引用从函数更改为 intellij 插件中的字段?

How to change a Kotlin code reference from a function to a field in an intellij plugin?

我正在编写一个 intellij 插件,我正在重构 class,将其 getter(例如 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 中的错误:

Expression 'name' of type String cannot be invoked as a function. The function 'invoke()' is not found

在编辑器中手动重写 name 强制 intellij 刷新引用,错误消失。

我应该怎么做才能防止这种情况发生?

您收到该错误消息是因为您没有修改对旧方法的引用。 Intellij 仍然认为您的调用 myObj.name 正在尝试访问一些不再存在的名为 name() 的方法。

此外,搜索结果将指向 AST that uses your method. In this case name() has a parent PSI object 中的叶节点,该节点包含对 name() 的引用。这就是为什么调用 element.nextSibling 会为您提供 (),然后您可以在其上调用 delete()。但这不会改变 parent 的引用。

我不确定什么是做你想做的最好的方法,但你可以尝试直接替换 parent 的引用。尝试:

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