cloverage / cloverage

Clojure test coverage tool
Eclipse Public License 2.0
506 stars 101 forks source link

Cloverage failing to compile custom try-let macro #189

Open tjscollins opened 7 years ago

tjscollins commented 7 years ago

I'm using the try-let macro from https://github.com/rufoa/try-let to handle errors in let bindings.

(defmacro try-let
  [bindings & body]
  (assert (even? (count bindings))
          "try-let needs an even number of forms in binding vector")
  (let [bindings-ls (take-nth 2 bindings)
        gensyms (take (count bindings-ls) (repeatedly gensym))
        [thens stanzas] (split-with #(not (and (list? %) (= (first %) 'catch))) body)]
    `(let [[ok# ~@gensyms]
           (try
             (let [~@bindings] [true ~@bindings-ls])
             ~@(map
                (fn [stanza]
                  (assert (>= (count stanza) 3)
                          "Malformed stanza")
                  (let [[x y z & body] stanza]
                    (assert (= x 'catch)
                            "Only catch stanzas are allowed")
                    `(~x ~y ~z [false (do ~@body)])))
                stanzas))]
       (if ok#
         (let [~@(interleave bindings-ls gensyms)]
           ~@thens)
         ~(first gensyms)))))

Cloverage's instrumenting doesn't recognize the try-let macro (even if I define it in the same file instead of using the library), and so ignores it, but then collapses when it gets to the catch statements:

2017-08-18 02:48:40,472 [main] WARN  cloverage.instrument - Unknown special form (catch Exception e (println e)) 
2017-08-18 02:48:40,541 [main] WARN  cloverage.instrument - Unknown special form (catch Exception e (println e)) 
2017-08-18 02:48:40,543 [main] WARN  cloverage.instrument - Unknown special form (catch java.sql.BatchUpdateException e

resulting a failed compilation:

Caused by: java.lang.RuntimeException: Unable to resolve symbol: catch in this context, compiling:(webtools/routes/api.clj:121:29)

I don't understand the instrumentation well enough to guess how to make this work, but it's preventing me from being able to use cloverage at all. Regular try-catch macros seem to work fine (of course, the try-let macro itself compiles fine normally, i.e. lein run, lein test, lein repl, etc.).

lvh commented 7 years ago

I think the issue here is a toplevel let in the expanded form.

lvh commented 7 years ago

Related, but with do: https://github.com/cloverage/cloverage/issues/85