如何使用 traits 作为插件并保留静态类型?

问题描述 投票:0回答:0

所以 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 参数上的类型),那么我也可以实现更优雅的案例。

有更好的主意吗?

groovy traits
© www.soinside.com 2019 - 2024. All rights reserved.