KotlinPoet:如何生成带参数的DSL



我正在尝试生成这个Kotlin代码,它包含一个带参数的DSL:

listOf(
navArgument(QUERY_PARAM) {
type = NavType.StringType
nullable = true
defaultValue = null
},
)

有没有比手动构建字符串更好的方法向DSL提供参数?

CodeBlock.builder()
.addStatement("listOf(")
.indent()
.beginControlFlow("%M(${queryParam})", MEMBER_NAME_NAV_ARGUMENT)
.addStatement([...])
.endControlFlow()
.unindent()
.add(")")
.build(),

KotlinPoet的API主要建模语言构造-类型、函数、属性,没有很多专门的API来建模函数体、构造函数等。也就是说,除了格式修饰符之外,CodeBlock中有一些方法可以帮助减少手动构建的字符串的数量。以下是我的想法,希望其中的一些内容会有所帮助:

@Test fun dsl() {
val queryParam = "QUERY_PARAM"
val navArgument = MemberName(packageName = "", simpleName = "navArgument")
val stringType = ClassName(packageName = "", simpleNames = listOf("NavType", "StringType"))
val navArgumentConfiguration = listOf(
CodeBlock.of("type = %T", stringType),
CodeBlock.of("nullable = %L", true),
Companion.of("defaultValue = %L", null),
)
val navArgumentCall = CodeBlock.builder() 
.beginControlFlow("%M(%L)", navArgument, queryParam)
.add(navArgumentConfiguration.joinToCode(separator = "n", suffix = "n"))
.endControlFlow()
.build() 
.trim()
val navArgumentCalls = listOf(navArgumentCall)
.joinToCode(prefix = "listOf(⇥n", separator = ",n", suffix = ",⇤n)")
assertThat(navArgumentCalls.toString()).isEqualTo(
"""
listOf(
navArgument(QUERY_PARAM) {
type = NavType.StringType
nullable = true
defaultValue = null
}
,
)
""".trimIndent()
)
}

注意悬挂的,——这似乎是我刚刚提交的一个bug。

最新更新