KotlinPoet:向现有类添加功能

时间:2018-12-16 20:21:11

标签: kotlin code-generation kotlinpoet

我想构建一个注释处理器,以生成私有“可变类”字段的公共“非可变类” getter函数(例如,返回LiveData字段的MutableLiveData版本)。

我要写的东西:

class MyClass {  
    @WithGetNonMutable  
    private val popup: MutableLiveData<PopupTO?> = MutableLiveData()  
}

我想产生什么

class MyClass {  
    private val popup: MutableLiveData<PopupTO?> = MutableLiveData()  
    fun getPopup(): LiveData<PopupTO?> = popup  
}

使用正确的返回类型生成函数没问题:

val liveDataType = ClassName("android.arch.lifecycle", "LiveData")
val returnType = liveDataType.parameterizedBy(genericDataType)

val function = FunSpec.builder("get${element.simpleName}")
                .addModifiers(KModifier.PUBLIC)
                .addStatement("return ${element.simpleName}")
                .returns(returnType)
                .build()

问题在于变量(popup)是私有的-因此要访问它,我生成的函数还必须是该类的一部分(它不能是新文件中的简单扩展函数)。 KotlinPoet示例全部写入新文件-但是无法访问私有字段(或存在),因此我需要在实际的类文件中写入函数吗?我该如何实现?

1 个答案:

答案 0 :(得分:1)

注释处理器不能修改现有代码,只能生成新代码。


也就是说,您可以修改方法并生成扩展函数而不是成员函数。

  1. 保留您的MyClass(将private修改器更改为internal):
class MyClass {  
    @WithGetNonMutable  
    internal val popup: MutableLiveData<PopupTO?> = MutableLiveData()  
}
  1. 生成具有以下内容的新文件(在同一软件包中):
fun MyClass.getPopup(): LiveData<PopupTO?> = this.popup  

如果您完全无法修改MyClass(不能将private更改为internal),则可以(虽然不那么优雅,但是可以做到):

在生成的扩展函数中,使用Reflection访问私有字段。