所以 traits 是一个非常酷的特性,但我想看看如何将它们用作我正在处理的 DSL 的插件。但是以这种方式使用特征意味着在运行时添加特征。文档清楚地演示了如何使用:
def combinedTraits = person.withTraits TraitA, TraitB
这很好,但是这一切都是通过动态类型完成的,这使得 IDE 很难帮助完成代码或使用 CompileStatic。如果 Groovy 有类型联合,我可以想出它如何以类型安全的方式工作的唯一方法。我正在尝试创建类似于以下内容的 DSL:
pipeline( Plugin1, Plugin2 ) {
step("Step1") { Map row ->
accept( row )
}
methodFromPlugin1("....", 123)
methodFromPlugin2("....", 456)
}
然后在 DSL 中执行以下操作:
public class PipelineDsl {
void pipeline( List<Class> traits, Closure closure ) {
closure.resolveStrategy =
closure.delegate = this.withTraits( traits )
closure.call()
}
}
但是如果我想帮助 IDE 完成代码完成工作,我需要在 Closure 参数上添加 @DelegatesTo 注释,我不能在那里硬编码 Traits。另一个版本可能是这样的:
pipeline {
step("Step1") { Map row ->
}
fromPlugin( Plugin1 ) { Plugin1 p ->
p.methodFromPlugin1("....", 123)
}
fromPlugin( Plugin2 ) { Plugin2 p ->
p.methodFromPlugin2("....", 456)
}
}
有点笨拙,因为我必须在闭包上声明参数类型,而且我不能轻易使用提供的注释来简化它(@DelegatesTo 或 @ClosureParam 等)。
虽然这个模型反映了 Gradle 的 task name(type: PluginTask) {...}
插件和 IDE 定义,但通常可以遵循这些定义。但我不知道 Gradle 正在做什么来帮助解决这个问题。如果我可以简化笨重的案例(比如删除 Closure 参数上的类型),那么我也可以实现更优雅的案例。
有更好的主意吗?