简体   繁体   中英

clojure macro using gen-class doesn't create annotations

I'm trying to write a clojure macro that will be used to generate multiple Java classes at compile time. I've found that I can add annotations to a class when I invoke gen-class outside of a macro. However, when I try to use gen-class inside a macro, the compiled class doesn't have annotations.

I boiled my problem down to this example:

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

When I compile this file, it creates a Test1.class and Test2.class - I inspect both with Eclipse, and find that Test1 has both class-level and method-level @Deprecated annotations, but Test2.class that has no annotations. When I use macroexpand, it looks as though my Test2.class should be annotated:

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

What am I doing wrong here?

Meikel Brandmeyer answered the question here:

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

"quote the annotation in the macro. (with-meta name `{Deprecated true}). Note the backtick."

Here is the working macro:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM