簡體   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