【问题标题】:Use Groovy Category DSL implicitly in all methods of class在类的所有方法中隐式使用 Groovy Category DSL
【发布时间】:2015-06-07 04:31:41
【问题描述】:

我有一个复杂的 Groovy 类别,它定义了我的 DSL 语言。例如,它包含以下内容:

class MyDSL {

    static Expr getParse(String expr) {
        Parser.parse(expr)
    }

    static Expr plus(Expr a, Expr b){
        a.add(b)
    }

    ...
}

MyDSL 类别包含许多类型对象的 DSL 元素(不仅是 StringExpr)。我可以使用 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,但我需要在主类中做同样的事情。

【问题讨论】:

    标签: groovy metaprogramming dsl


    【解决方案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'
    

    【讨论】:

      猜你喜欢
      • 2011-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-08
      • 2015-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多