From da95e10ab969c70afe6e585d1132c50aad6dde87 Mon Sep 17 00:00:00 2001 From: Michael Griffiths Date: Tue, 5 Jan 2016 14:21:25 +0000 Subject: [PATCH 1/7] Fix regex in extract-location Fixes an edge case where the cause of a CompilerException has no message. --- src/cider/nrepl/middleware/stacktrace.clj | 2 +- .../nrepl/middleware/stacktrace_test.clj | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/cider/nrepl/middleware/stacktrace.clj b/src/cider/nrepl/middleware/stacktrace.clj index 04ddaafa2..cfa145420 100644 --- a/src/cider/nrepl/middleware/stacktrace.clj +++ b/src/cider/nrepl/middleware/stacktrace.clj @@ -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) diff --git a/test/clj/cider/nrepl/middleware/stacktrace_test.clj b/test/clj/cider/nrepl/middleware/stacktrace_test.clj index cb1c1347a..6f1437c73 100644 --- a/test/clj/cider/nrepl/middleware/stacktrace_test.clj +++ b/test/clj/cider/nrepl/middleware/stacktrace_test.clj @@ -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)"}))))) From 52d4e2e0d130149a0ca7571c3da09ccc9234a836 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Thu, 7 Jan 2016 14:39:28 +0200 Subject: [PATCH 2/7] Bump the compliment dep to 0.2.6 --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 765fc0be7..eb2d1f785 100644 --- a/project.clj +++ b/project.clj @@ -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"] From 3c5a7d2d10d3b0a8a665298cc44d3714451bb0cc Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 8 Jan 2016 17:58:13 +0000 Subject: [PATCH 3/7] [Fix #1428] Debugger no longer skips local vars that shadow a core var --- src/cider/nrepl/middleware/debug.clj | 14 ++++++++++++- .../nrepl/middleware/util/instrument.clj | 20 ++----------------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/cider/nrepl/middleware/debug.clj b/src/cider/nrepl/middleware/debug.clj index 1a662620e..e0bd664da 100644 --- a/src/cider/nrepl/middleware/debug.clj +++ b/src/cider/nrepl/middleware/debug.clj @@ -262,12 +262,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. diff --git a/src/cider/nrepl/middleware/util/instrument.clj b/src/cider/nrepl/middleware/util/instrument.clj index 4945f5cf2..34da56ba1 100644 --- a/src/cider/nrepl/middleware/util/instrument.clj +++ b/src/cider/nrepl/middleware/util/instrument.clj @@ -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] @@ -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 @@ -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? From cdd2ce290a479565378aa45b757b03136e106f23 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 8 Jan 2016 19:26:18 +0000 Subject: [PATCH 4/7] Ensure that `eval-with-locals` doesn't change the namespace --- src/cider/nrepl/middleware/debug.clj | 29 +++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/cider/nrepl/middleware/debug.clj b/src/cider/nrepl/middleware/debug.clj index e0bd664da..9a69e00ae 100644 --- a/src/cider/nrepl/middleware/debug.clj +++ b/src/cider/nrepl/middleware/debug.clj @@ -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. From b4703bcd0d4a9095c61714b1e6b3f59c61f729a8 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 16 Dec 2015 23:08:01 +0000 Subject: [PATCH 5/7] Fix local-vars inspection cutting short --- src/cider/nrepl/middleware/debug.clj | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cider/nrepl/middleware/debug.clj b/src/cider/nrepl/middleware/debug.clj index 9a69e00ae..3fef5f12d 100644 --- a/src/cider/nrepl/middleware/debug.clj +++ b/src/cider/nrepl/middleware/debug.clj @@ -199,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 From 330c4a4e19e7b6694a7873b32fe6802c39ebe4ef Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 19 Jan 2016 12:51:39 +0000 Subject: [PATCH 6/7] In stacktrace frames, also flag cider namespaces as tooling --- src/cider/nrepl/middleware/stacktrace.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cider/nrepl/middleware/stacktrace.clj b/src/cider/nrepl/middleware/stacktrace.clj index cfa145420..dc2822886 100644 --- a/src/cider/nrepl/middleware/stacktrace.clj +++ b/src/cider/nrepl/middleware/stacktrace.clj @@ -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)] From 113409249fea3a94beb2286ca6be04a8608e5e78 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 15 Jan 2016 23:59:32 +0000 Subject: [PATCH 7/7] Remove an obsolete test --- test/clj/cider/nrepl/middleware/util/instrument_test.clj | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/clj/cider/nrepl/middleware/util/instrument_test.clj b/test/clj/cider/nrepl/middleware/util/instrument_test.clj index ebbae1dea..ee066734c 100644 --- a/test/clj/cider/nrepl/middleware/util/instrument_test.clj +++ b/test/clj/cider/nrepl/middleware/util/instrument_test.clj @@ -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])