如何从Kotlin DSL gradle脚本中的插件访问属性?

时间:2018-09-20 08:06:17

标签: gradle properties kotlin gradle-kotlin-dsl

我有一个kts gradle构建脚本,其中使用了这个plugin

该插件将project.version属性设置为字符串,并添加了一些其他属性:

  

虽然version属性是一个字符串,但它确实暴露了一些其他属性   属性。它们是snapshotmajorminorpatch和   preRelease

现在,如何从build.gradle.kts访问这些属性?

由于Kotlin是静态键入的,因此尝试val major = project.version.major as Integer之类的操作总是失败:

  

未解决的参考文献:专业

有什么方法可以访问这些属性,还是必须回到基于Groovy的gradle.build构建脚本?

1 个答案:

答案 0 :(得分:1)

有趣的问题。该插件正在使用Groovy元编程将这些属性(主要,次要,补丁...)添加到version属性中。
据我所知,Kotlin无法访问Groovy的MetaClass属性。
插件应该为version属性使用普通的类结构,或者(希望保留版本为String对象)向项目添加一个专用属性,该属性包含这些值作为新类的属性。但是当前的实现似乎与Gradle Kotlin DSL不兼容。

这是代码部分,他们在其中设置project.version并将属性添加到其MetaClass(Source code):

project.version = semanticBuildVersion as String

// Attach snapshot boolean-property to version - says whether version is snapshot or not
project.version.metaClass.snapshot = semanticBuildVersion.snapshot

// Attach version components
def versionComponents = project.version.split(/[.-]/, 4)
project.version.metaClass.major = versionComponents[VersionComponent.MAJOR.index] as int
project.version.metaClass.minor = versionComponents[VersionComponent.MINOR.index] as int
project.version.metaClass.patch = versionComponents[VersionComponent.PATCH.index] as int

Groovy官方文档实际上记录了其他JVM语言不可见运行时元编程,而编译时元编程将可见(link):

Groovy中的编译时元编程允许在编译时生成代码。这些转换正在改变程序的抽象语法树(AST),这就是为什么在Groovy中我们将其称为AST转换。 AST转换使您可以进入编译过程,修改AST并继续编译过程以生成常规字节码。与运行时元编程相比,这具有使更改在类文件本身(即在字节码中)可见的优点。例如,如果您希望将转换作为类协定的一部分(实现接口,扩展抽象类等),或者需要从Java(或其他JVM语言)调用类,则使其在字节码中可见非常重要。 )。例如,AST转换可以将方法添加到类中。 如果使用运行时元编程进行此操作,则只能从Groovy中看到新方法。如果使用编译时元编程进行此操作,则该方法也将从Java中可见。最后但并非最不重要的一点是,编译时元编程的性能可能会更好(因为不需要初始化阶段)。