2015-04-02 2 views
2

У меня сложная категория Groovy, которая определяет мой язык DSL. Например, он содержит что-то вроде:Использовать 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). Я могу использовать DSL в другом классе, используя ключевое слово use:

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 отлично распознает DSL внутри use).

Существует аналогичный вопрос Use Groovy Category implicitly in all instance methods of class об исключении use в модульных тестах, но мне нужно сделать то же самое в основных классах.

ответ

1

Я не вижу возможности реализовать это, кроме использования АСТ, чтобы автоматически вставлять его в каждый метод. Даже тогда я сомневаюсь, что 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' 
Смежные вопросы