diff --git a/src/cider/nrepl/middleware/util/instrument.clj b/src/cider/nrepl/middleware/util/instrument.clj index 70d42aa71..573353214 100644 --- a/src/cider/nrepl/middleware/util/instrument.clj +++ b/src/cider/nrepl/middleware/util/instrument.clj @@ -468,6 +468,18 @@ out (into (empty coll) out)))) +(defn- instrument-function-call + "Instrument a regular function call sexp. + This must be a sexp that starts with a symbol which is not a macro + nor a special form. + This includes regular function forms, like `(range 10)`, and also + includes calls to Java methods, like `(System/currentTimeMillis)`." + [{:keys [coor] :as ex} [name & args]] + (cons name + (map #(instrument (assoc ex :coor (conj coor %1)) %2) + (range 1 (inc (count args))) + args))) + (defn with-break "Return form and ex wrapped in a breakpoint. If function is given, use it to instrument form before wrapping. The @@ -501,15 +513,20 @@ (defn- instrument-function-like-form "Instrument form representing a function/macro call or special-form." [ex [name & args :as form]] - (if (symbol? name) + (if-not (symbol? name) + ;; If the car is not a symbol, nothing fancy is going on and we + ;; can instrument everything. + (with-break instrument-coll form ex) (let [name (or (ns-resolve *ns* name) name)] (if (or (resolve-special name) (:macro (meta name))) + ;; If macro or special form, thread with care. (if (dont-break? form) (instrument-special-form ex form) (with-break instrument-special-form form ex)) - (with-break instrument-coll form ex))) - (with-break instrument-coll form ex))) + ;; Otherwise, probably just a function. Just leave the + ;; function name and instrument the args. + (with-break instrument-function-call form ex))))) (defn instrument "Walk through form and return it instrumented with breakpoints. diff --git a/test/clj/cider/nrepl/middleware/util/instrument_test.clj b/test/clj/cider/nrepl/middleware/util/instrument_test.clj index ec25fefe8..a93383e4f 100644 --- a/test/clj/cider/nrepl/middleware/util/instrument_test.clj +++ b/test/clj/cider/nrepl/middleware/util/instrument_test.clj @@ -197,3 +197,17 @@ 'tarzan '(false false)) (is (= (#'t/specifier-destructure "bindings") (#'t/specifier-destructure "binding")))) + +(deftest instrument-function-call + (is (= '(System/currentTimeMillis) + (#'t/instrument + {:coor [] :breakfunction 'b} + '(System/currentTimeMillis)))) + (is (eval + (#'t/instrument + {:coor [] + :breakfunction #'cider.nrepl.middleware.debug/breakpoint} + '(defn test-fn [] + (let [start-time (System/currentTimeMillis)] + (Thread/sleep 1000) + (- (System/currentTimeMillis) start-time)))))))