2013-02-27 2 views
5

Я пытаюсь написать макрос clojure, который будет использоваться для генерации нескольких классов Java во время компиляции. Я обнаружил, что я могу добавлять аннотации к классу, когда я вызываю gen-класс за пределами макроса. Однако, когда я пытаюсь использовать gen-класс внутри макроса, скомпилированный класс не имеет аннотаций.clojure macro using gen-class не создает аннотации

Я вареные мою проблему вниз к этому примеру:

(gen-class 
    :name ^{Deprecated true} Test1 
    :prefix Test1- 
    :methods [[^{Deprecated true} getValue [] Integer]]) 

(defn Test1-getValue [] 42) 

(defmacro create-test-class [name x] 
    (let [prefix (str name "-")] 
    `(do 
     (gen-class 
     :name ~(with-meta name {Deprecated true}) 
     :prefix ~(symbol prefix) 
     :methods [[~(with-meta 'getValue {Deprecated true}) [] Integer]]) 
     (defn ~(symbol (str prefix "getValue")) [] ~x)))) 

(create-test-class Test2 56) 

Когда я скомпилировать этот файл, он создает Test1.class и Test2.class - я осмотреть как с Eclipse, и обнаружили, что Test1 имеет как класс -level и method-level @Deprecated аннотации, но Test2.class, который не имеет аннотаций. Когда я использую MACROEXPAND, это выглядит, как будто мой Test2.class должен быть аннотированный:

user=> (set! *print-meta* true) 
true 
user=> (macroexpand '(create-test-class Test2 56)) 
(do (clojure.core/gen-class :name ^{java.lang.Deprecated true} Test2 :prefix Test2- :methods [[^{java.lang.Deprecated true} getValue [] java.lang.Integer]]) (user/defn Test2-getValue [] 56)) 

Что я здесь делаю неправильно?

+0

Могу ли я проверить на наличие аннотаций изнутри Clojure каким-то образом? (У меня нет затмения здесь) –

ответ

4

Meikel Brandmeyer ответил на вопрос здесь: "процитировать аннотацию в макрос (с-мета именем` {Устаревшие истинно}) Обратите внимание на обратные одиночные кавычки.".

https://groups.google.com/forum/#!topic/clojure/Ee1bVwcUT-c

Здесь работает макрос:

(defmacro create-test-class [name x] 
    (let [prefix (str name "-")] 
    `(do 
     (gen-class 
     :name ~(with-meta name `{Deprecated true}) 
     :prefix ~(symbol prefix) 
     :methods [[~(with-meta 'getValue `{Deprecated true}) [] Integer]]) 
     (defn ~(symbol (str prefix "getValue")) [] ~x))))