2013-02-27 5 views
5

Sto provando a scrivere una macro clojure che verrà utilizzata per generare più classi Java in fase di compilazione. Ho scoperto che posso aggiungere annotazioni a una classe quando invoco gen-class al di fuori di una macro. Tuttavia, quando provo a usare gen-class in una macro, la classe compilata non ha annotazioni.macro clojure utilizzando gen-class non crea annotazioni

ho bollito mio problema fino a questo esempio:

(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) 

Quando compilo questo file, si crea un Test1.class e Test2.class - ho ispezionare entrambi con Eclipse, e scoprire che Test1 ha sia di classe livello @ livello e annotazioni personalizzate @ metodo, ma Test2.class che non ha annotazioni. Quando uso macroexpand, sembra come se il mio Test2.class deve essere annotato:

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)) 

che cosa sto facendo male qui?

+0

Posso verificare la presenza dell'annotazione dall'interno Clojure in qualche modo? (Non ho eclissi qui) –

risposta

4

Meikel Brandmeyer ha risposto alla domanda qui: "citare l'annotazione nella macro (con-meta name` {Sconsigliata true}) Si noti il ​​backtick.".

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

Ecco la macro di lavoro:

(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))))