繁体   English   中英

如何在创建 Groovy DSL 时仅从特定闭包或 Scope 中使用 object 的方法

[英]How to make a method from an object available only from a specific Closure or Scope when creating a Groovy DSL

假设我有一个 class:

Foo {
 always()
 onlyScopeB()
}

而且我有不同的方法,它们采用不同的闭包: scopeAscopeB

foo = new Foo()

scopeA{
  foo.always()     // this should COMPILE
  foo.onlyScopeB() // this should NOT COMPILE
}

scopeB{
  foo.always()     // this should COMPILE
  foo.onlyScopeB() // this should COMPILE
}

无论如何在编译阶段实现这一目标? 我正在编写一个 DSL,并且我有与流程中的阶段相对应的范围,有时字段是null在一个 scope 中,然后其他时候它们not-null ,我试图提供最佳语义体验以轻松查找错误。

如果你想在编译阶段实现这一点,我能想到的唯一方法就是编写一个自定义的 AST Transformation

这与您声明的语法略有不同。 您可以将您的 Scope A 和 Scope B 方法划分为接口,并使用闭包委托来提供反馈。 如果有很多,像always()这样的通用方法可以移动到一个通用接口。 如果您在此脚本部分启用 Static 类型检查,您将收到编译器错误,而不仅仅是下划线。

interface Bar {
  void always()
  void onlyScopeA()
}
interface Baz {
  void always()
  void onlyScopeB()
}
@groovy.transform.AutoImplement
class Foo implements Bar, Baz {
}

void scopeA(@DelegatesTo.Target Bar bar, @DelegatesTo Closure block) {
  bar.with(block)
}
void scopeB(@DelegatesTo.Target Baz baz, @DelegatesTo Closure block) {
  baz.with(block)
}


def foo = new Foo()
scopeA(foo) {
  always()
  onlyScopeA()
  onlyScopeB()
}
scopeB(foo) {
  always()
  onlyScopeA()
  onlyScopeB()
}

IDE 反馈示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM