KotlinPoet:向现有类添加功能 [英] KotlinPoet: Add function to existing class

查看:435
本文介绍了KotlinPoet:向现有类添加功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to build an annotation processor that generates a public "non-mutable class" getter function of a private "mutable class" field (e.g. returning a LiveData version of a MutableLiveData field).

我要写的东西:

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

我想产生什么

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

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

Generating the function with the correct return type is no problem:

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示例全部写入新文件-但无法访问私有字段(或存在),因此我需要在实际的类文件中写入函数吗?我该如何实现?

The problem is that the variable (popup) is private - so to access it my generated function also needs to be part of that class (it can't be a simple extension function in a new file). The KotlinPoet example all write to new files - but there's no way to access the private field (or is there?) so I'd need to write the function in the actual class file? How can I achieve this?

推荐答案

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

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

That said, you could maybe modify your approach and generate an extension function instead of a member function.

  1. 保留您的MyClass(将private修改器更改为internal):
  1. Keep your MyClass (with private modifier changed to internal):

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

  1. 生成具有以下内容的新文件(在同一个程序包中):

fun MyClass.getPopup(): LiveData<PopupTO?> = this.popup  


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


If you completely can't modify the MyClass (you can't change private to internal), you can (it's not that elegant, but you can do it):

在生成的扩展功能中,使用Reflection访问私有字段.

In the generated extension function use Reflection to access a private field.

这篇关于KotlinPoet:向现有类添加功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆