0

我想构建一个注释处理器,它生成一个私有“可变类”字段的公共“非可变类”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 示例都写入新文件 - 但无法访问私有字段(或者是否存在?)所以我需要在实际的类文件中编写函数?我怎样才能做到这一点?

4

1 回答 1

1

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


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

  1. 保留您的MyClassprivate修饰符更改为internal):
class MyClass {  
    @WithGetNonMutable  
    internal val popup: MutableLiveData<PopupTO?> = MutableLiveData()  
}
  1. 生成一个新文件(在同一个包中),内容如下:
fun MyClass.getPopup(): LiveData<PopupTO?> = this.popup  

如果你完全不能修改MyClass(你不能改成privateinternal,你可以(它不是那么优雅,但你可以做到):

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

于 2019-01-11T16:31:20.740 回答