Skip to content

Commit

Permalink
Merge pull request #290 from cap10morgan/v0.10
Browse files Browse the repository at this point in the history
Backport bug fixes from master for 0.10.2 release
  • Loading branch information
bbatsov committed Jan 27, 2016
2 parents 37106b6 + 1134092 commit 439f278
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 46 deletions.
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/tools.nrepl "0.2.12"]
[org.tcrawley/dynapath "0.2.3"]
^:source-dep [compliment "0.2.5"]
^:source-dep [compliment "0.2.6"]
^:source-dep [cljs-tooling "0.1.9"]
^:source-dep [cljfmt "0.3.0"]
^:source-dep [org.clojure/java.classpath "0.2.3"]
Expand Down
51 changes: 34 additions & 17 deletions src/cider/nrepl/middleware/debug.clj
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,22 @@
If an exception is thrown, it is caught and sent to the client, and
this function returns nil."
[form]
(try
(eval `(let ~(vec (mapcat #(list % `(*locals* '~%))
(keys *locals*)))
~form))
(catch Exception e
;; Borrowed from interruptible-eval/evaluate.
(let [root-ex (#'clojure.main/root-cause e)]
(when-not (instance? ThreadDeath root-ex)
(debugger-send
{:status :eval-error
:causes [(let [causes (stacktrace/analyze-causes e 50 50)]
(when (coll? causes) (last causes)))]})))
nil)))
(let [ns (ns-name *ns*)]
(try
(eval `(let ~(vec (mapcat #(list % `(*locals* '~%))
(keys *locals*)))
~form))
(catch Exception e
;; Borrowed from `interruptible-eval/evaluate`.
(let [root-ex (#'clojure.main/root-cause e)]
(when-not (instance? ThreadDeath root-ex)
(debugger-send
{:status :eval-error
:causes [(let [causes (stacktrace/analyze-causes e 50 50)]
(when (coll? causes) (last causes)))]})))
nil)
(finally
(in-ns ns)))))

(defn- read-debug-eval-expression
"Read and eval an expression from the client.
Expand All @@ -196,9 +199,11 @@
This `read-debug-command` is passed `value` and the `extras` map
with the result of the inspection `assoc`ed in."
[value extras page-size inspect-value]
(let [i (pr-str (:rendered (swap-inspector! @debugger-message
#(-> (assoc % :page-size page-size)
(inspect/start inspect-value)))))]
(let [i (binding [*print-length* nil
*print-level* nil]
(->> #(inspect/start (assoc % :page-size page-size) inspect-value)
(swap-inspector! @debugger-message)
:rendered pr-str))]
(read-debug-command value (assoc extras :inspect i))))

(defn read-debug-command
Expand Down Expand Up @@ -262,12 +267,24 @@
:file file, :line line, :column column})
:debug-value (pr-short val#)))))))

(defmacro breakpoint-if-not-core
"Wrap form in a breakpoint unless it is a symbol that resolves to `clojure.core`.
This takes the namespace shadowing and local vars into account."
[form coor]
(if (and (symbol? form)
(try
(-> (resolve form) meta :ns ns-name (= 'clojure.core))
(catch Exception _ nil))
(not (contains? &env form)))
form
`(breakpoint ~form ~coor)))

;;; Data readers
;; Set in `src/data_readers.clj`.
(defn breakpoint-reader
"#break reader. Mark `form` for breakpointing."
[form]
(ins/with-meta-safe form {:cider-breakfunction #'breakpoint}))
(ins/with-meta-safe form {:cider-breakfunction #'breakpoint-if-not-core}))

(defn debug-reader
"#dbg reader. Mark all forms in `form` for breakpointing.
Expand Down
4 changes: 2 additions & 2 deletions src/cider/nrepl/middleware/stacktrace.clj
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
to `clojure.lang.Compiler` or `clojure.tools.nrepl.*` as `:tooling` to
distinguish compilation and nREPL middleware frames from user code."
[frames]
(let [tool-regex #"clojure.lang.Compiler|clojure.tools.nrepl"
(let [tool-regex #"^clojure\.lang\.Compiler|^clojure\.tools\.nrepl|^cider\."
tool? #(re-find tool-regex (or (:name %) ""))
flag #(update-in % [:flags] (comp set conj) :tooling)
[user & tools] (partition-by (complement tool?) frames)]
Expand Down Expand Up @@ -113,7 +113,7 @@
[{:keys [class message] :as cause}]
(if (= class "clojure.lang.Compiler$CompilerException")
(let [[_ msg file line column]
(re-find #".*?: (.*?), compiling:\((.*):(\d+):(\d+)\)" message)]
(re-find #"(.*?), compiling:\((.*):(\d+):(\d+)\)" message)]
(assoc cause
:message msg :file file
:path (relative-path file)
Expand Down
20 changes: 2 additions & 18 deletions src/cider/nrepl/middleware/util/instrument.clj
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,6 @@

;;; We'll probably want to expand this variable. It is used to
;;; determine uninteresting symbols.
(def core-publics
"Set of all public symbols from the clojure.core namespace."
(into #{} (map second (ns-publics 'clojure.core))))

(defn- interesting-symbol?
"Non-nil if the value of symbol might be interesting.
These are symbols we wrap breakpoints around. An example of
uninsteresting symbols is a keyword or the name of a built-in
function."
[symbol]
(not (or (keyword? symbol)
(when-let [resolved (ns-resolve *ns* symbol)]
(core-publics resolved)))))

(defn with-meta-safe
"Non-throwing version of (vary-meta obj merge meta)."
[obj meta]
Expand Down Expand Up @@ -143,7 +129,7 @@
;;; form-types and special cases. The idea here is that we walk
;;; through collections and function arguments looking for interesting
;;; things around which we'll wrap a breakpoint. Interesting things
;;; are most function-forms and vars satisfying `interesting-symbol?`.
;;; are most function-forms and vars.
(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
Expand Down Expand Up @@ -224,9 +210,7 @@
(condp #(%1 %2) form
;; Function call, macro call, or special form.
listy? (doall (instrument-function-like-form form))
symbol? (if (interesting-symbol? form)
(with-break form)
form)
symbol? (with-break form)
;; Other coll types are safe, so we go inside them and only
;; instrument what's interesting.
;; Do we also need to check for seq?
Expand Down
20 changes: 20 additions & 0 deletions test/clj/cider/nrepl/middleware/stacktrace_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,23 @@
(testing "compilation errors"
(is (re-find #"Unable to resolve symbol: not-defined in this context"
(:message (first causes3))))))

(deftest compilation-errors
(testing "extract-location"
(is (= {:class "clojure.lang.Compiler$CompilerException"
:message "java.lang.RuntimeException: Unable to resolve symbol: foo in this context"
:file "/foo/bar/baz.clj"
:path "/foo/bar/baz.clj"
:line 1
:column 42}
(extract-location {:class "clojure.lang.Compiler$CompilerException"
:message "java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(/foo/bar/baz.clj:1:42)"})))

(is (= {:class "clojure.lang.Compiler$CompilerException"
:message "java.lang.NegativeArraySizeException"
:file "/foo/bar/baz.clj"
:path "/foo/bar/baz.clj"
:line 1
:column 42}
(extract-location {:class "clojure.lang.Compiler$CompilerException"
:message "java.lang.NegativeArraySizeException, compiling:(/foo/bar/baz.clj:1:42)"})))))
8 changes: 0 additions & 8 deletions test/clj/cider/nrepl/middleware/util/instrument_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@
{}
#{}))

(deftest interesting-symbol?
(are [x] (not (#'t/interesting-symbol? x))
'map 'range 'inc 'dec
:batman :scarecrow)
(are [x] (#'t/interesting-symbol? x)
'killer-croc
'hannah-montana))

(def bp-tracker (atom #{}))
(defmacro bp [value coor]
(swap! bp-tracker conj [value coor])
Expand Down

0 comments on commit 439f278

Please sign in to comment.