我有一个复杂的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
关键字在另一个班级中使用我的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 Groovy Category implicitly in all instance methods of class关于避免use
,但我需要在主类中做同样的事情。
答案 0 :(得分:1)
除了使用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'