在 class 的所有方法中隐式使用 Groovy 类别 DSL
Use Groovy Category DSL implicitly in all methods of class
我有一个复杂的 Groovy 类别,它定义了我的 DSL 语言。例如它包含如下内容:
class MyDSL {
static Expr getParse(String expr) {
Parser.parse(expr)
}
static Expr plus(Expr a, Expr b){
a.add(b)
}
...
}
MyDSL
类别包含许多对象类型的 DSL 元素(不仅是 String
和 Expr
)。我可以通过使用 use
关键字在另一个 class 中使用我的 DSL:
class MyAlgorithm {
Expr method1(Expr expr) {
use(MyDSL) {
def sum = 'x + y'.parse
return sum + expr
}
Expr method2(String t) {
use(MyDSL) {
def x = t.parse
return method1(x) + x
}
...
}
我可以做些什么来避免在每个方法中每次都写 use
关键字吗?我还希望在我的 IDE 中仍然有代码完成和语法突出显示(IntelliJ 完全识别 use
中的 DSL)。
关于在单元测试中避免 use
有类似的问题 Use Groovy Category implicitly in all instance methods of class,但我需要在主要 classes 中做同样的事情。
除了使用 AST 将其自动插入到每个方法中之外,我看不出有什么方法可以实现它。即便如此,我怀疑 IntelliJ 会识别它。
另一条 IntelliJ 永远无法识别的路径正在拦截 invokeMethod
:
class Captain {
def sayWot() {
"my string".foo()
}
def sayNigh() {
9.bar()
}
}
Captain.metaClass.invokeMethod = { String name, args ->
def self = delegate
def method = self.metaClass.getMetaMethod name, args
use(MyCategory) {
method.invoke self, args
}
}
class MyCategory {
static foo(String s) {
s + " foo"
}
static bar(Integer i) {
i + " bar"
}
}
c = new Captain()
assert c.sayWot() == 'my string foo'
assert c.sayNigh() == '9 bar'
我有一个复杂的 Groovy 类别,它定义了我的 DSL 语言。例如它包含如下内容:
class MyDSL {
static Expr getParse(String expr) {
Parser.parse(expr)
}
static Expr plus(Expr a, Expr b){
a.add(b)
}
...
}
MyDSL
类别包含许多对象类型的 DSL 元素(不仅是 String
和 Expr
)。我可以通过使用 use
关键字在另一个 class 中使用我的 DSL:
class MyAlgorithm {
Expr method1(Expr expr) {
use(MyDSL) {
def sum = 'x + y'.parse
return sum + expr
}
Expr method2(String t) {
use(MyDSL) {
def x = t.parse
return method1(x) + x
}
...
}
我可以做些什么来避免在每个方法中每次都写 use
关键字吗?我还希望在我的 IDE 中仍然有代码完成和语法突出显示(IntelliJ 完全识别 use
中的 DSL)。
关于在单元测试中避免 use
有类似的问题 Use Groovy Category implicitly in all instance methods of class,但我需要在主要 classes 中做同样的事情。
除了使用 AST 将其自动插入到每个方法中之外,我看不出有什么方法可以实现它。即便如此,我怀疑 IntelliJ 会识别它。
另一条 IntelliJ 永远无法识别的路径正在拦截 invokeMethod
:
class Captain {
def sayWot() {
"my string".foo()
}
def sayNigh() {
9.bar()
}
}
Captain.metaClass.invokeMethod = { String name, args ->
def self = delegate
def method = self.metaClass.getMetaMethod name, args
use(MyCategory) {
method.invoke self, args
}
}
class MyCategory {
static foo(String s) {
s + " foo"
}
static bar(Integer i) {
i + " bar"
}
}
c = new Captain()
assert c.sayWot() == 'my string foo'
assert c.sayNigh() == '9 bar'