From cdb6ad32bcf8a7b0cf8a7e0b46b027e9ea4f4e37 Mon Sep 17 00:00:00 2001 From: Hugo Duncan Date: Thu, 9 Dec 2021 09:08:41 -0500 Subject: [PATCH 1/5] fix: remove the possible duplicate output introduced in a052dd8 Output to the original output outside of the with-out-binding loop. --- src/cider/nrepl/middleware/out.clj | 42 +++++++++++------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/src/cider/nrepl/middleware/out.clj b/src/cider/nrepl/middleware/out.clj index 14aebdb8..5dde010d 100644 --- a/src/cider/nrepl/middleware/out.clj +++ b/src/cider/nrepl/middleware/out.clj @@ -40,6 +40,17 @@ Please do not inline; they must not be recomputed at runtime."} (catch Exception ~'e (unsubscribe-session ~'session)))))) +(defn dispatch-write + ([^Writer writer x] + (cond + (string? x) (.write writer ^String x) + (integer? x) (.write writer ^int x) + :else (.write writer ^{:tag "[C"} x))) + ([^Writer writer x ^Integer off ^Integer len] + (if (string? x) + (.write writer ^String x off len) + (.write writer ^{:tag "[C"} x off len)))) + (defn forking-printer "Returns a PrintWriter suitable for binding as *out* or *err*. All operations are forwarded to all output bindings in the sessions of @@ -54,36 +65,13 @@ Please do not inline; they must not be recomputed at runtime."} ;; as `int` and `char[]` aren't supported by proxy. (write ([x] + (dispatch-write (original-output type) x) (with-out-binding [printer messages type] - (cond - (string? x) - (do - (.write ^Writer (original-output type) ^String x) - (.write printer ^String x)) - - (integer? x) - (do - (.write ^Writer (original-output type) ^int x) - (.write printer ^int x)) - :else - (do - (.write ^Writer (original-output type) - ^{:tag "[C"} x) - (.write printer ^{:tag "[C"} x))))) + (dispatch-write printer x))) ([x ^Integer off ^Integer len] + (dispatch-write (original-output type) x off len) (with-out-binding [printer messages type] - (cond - (string? x) - (do - (.write ^Writer (original-output type) - ^String x off len) - (.write printer ^String x off len)) - - :else - (do - (.write ^Writer (original-output type) - ^{:tag "[C"} x off len) - (.write printer ^{:tag "[C"} x off len)))))) + (dispatch-write printer x off len)))) (flush [] (.flush ^Writer (original-output type)) (with-out-binding [printer messages type] From 79e215310b0100c365d1129e33b8b10759ba1f10 Mon Sep 17 00:00:00 2001 From: Hugo Duncan Date: Thu, 9 Dec 2021 19:33:45 -0500 Subject: [PATCH 2/5] improve tests to cover multiple messages and :err --- test/clj/cider/nrepl/middleware/out_test.clj | 84 ++++++++++++++------ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/test/clj/cider/nrepl/middleware/out_test.clj b/test/clj/cider/nrepl/middleware/out_test.clj index 5425f6d0..422c75da 100644 --- a/test/clj/cider/nrepl/middleware/out_test.clj +++ b/test/clj/cider/nrepl/middleware/out_test.clj @@ -47,58 +47,92 @@ (defn- forking-printer-test-streams [] (let [out-writer (StringWriter.) - message-writer (StringWriter.) - message {:session (atom {#'*out* message-writer})} - printer (o/forking-printer [message] :out)] + message-writers [(StringWriter.) (StringWriter.)] + messages [{:session (atom {#'*out* (message-writers 0)})} + {:session (atom {#'*err* (message-writers 1)})}] + printers [(o/forking-printer [(messages 0)(messages 1)] :out) + (o/forking-printer [(messages 0)(messages 1)] :err)]] {:out-writer out-writer - :message-writer message-writer - :printer printer})) + :message-writers message-writers + :printers printers})) + +(set! *warn-on-reflection* true) (deftest forking-printer-test (testing "forking-printer prints to all message streams and original stream" (testing "with String argument " (let [{:keys [^StringWriter out-writer - ^StringWriter message-writer - ^PrintWriter printer]} + message-writers + printers]} (forking-printer-test-streams)] (with-original-output [{:out out-writer}] - (.write printer "Hello") + (.write ^PrintWriter (printers 0) "Hello") (is (= "Hello" (.toString out-writer))) - (is (= "Hello" (.toString message-writer)))))) + (is (= "Hello" (.toString ^StringWriter (message-writers 0)))) + (is (= "" (.toString ^StringWriter (message-writers 1))))) + (with-original-output [{:err out-writer}] + (.write ^PrintWriter (printers 1) "Hello") + (is (= "HelloHello" (.toString out-writer))) + (is (= "Hello" (.toString ^StringWriter (message-writers 0)))) + (is (= "Hello" (.toString ^StringWriter (message-writers 1))))))) (testing "with int" (let [{:keys [^StringWriter out-writer - ^StringWriter message-writer - ^PrintWriter printer]} + message-writers + printers]} (forking-printer-test-streams) an-int (int 32)] (with-original-output [{:out out-writer}] - (.write printer an-int) + (.write ^PrintWriter (printers 0) an-int) (is (= " " (.toString out-writer))) - (is (= " " (.toString message-writer)))))) + (is (= " " (.toString ^StringWriter (message-writers 0)))) + (is (= "" (.toString ^StringWriter (message-writers 1))))) + (with-original-output [{:err out-writer}] + (.write ^PrintWriter (printers 1) an-int) + (is (= " " (.toString out-writer))) + (is (= " " (.toString ^StringWriter (message-writers 0)))) + (is (= " " (.toString ^StringWriter (message-writers 1))))))) (testing "with char array" (let [{:keys [^StringWriter out-writer - ^StringWriter message-writer - ^PrintWriter printer]} + message-writers + printers]} (forking-printer-test-streams)] (with-original-output [{:out out-writer}] - (.write printer (char-array "and")) + (.write ^PrintWriter (printers 0) (char-array "and")) (is (= "and" (.toString out-writer))) - (is (= "and" (.toString message-writer)))))) + (is (= "and" (.toString ^StringWriter (message-writers 0)))) + (is (= "" (.toString ^StringWriter (message-writers 1))))) + (with-original-output [{:err out-writer}] + (.write ^PrintWriter (printers 1) (char-array "and")) + (is (= "andand" (.toString out-writer))) + (is (= "and" (.toString ^StringWriter (message-writers 0)))) + (is (= "and" (.toString ^StringWriter (message-writers 1))))))) (testing "with String with offsets" (let [{:keys [^StringWriter out-writer - ^StringWriter message-writer - ^PrintWriter printer]} + message-writers + printers]} (forking-printer-test-streams)] (with-original-output [{:out out-writer}] - (.write printer "12 good34" 3 4) + (.write ^PrintWriter (printers 0) "12 good34" 3 4) (is (= "good" (.toString out-writer))) - (is (= "good" (.toString message-writer)))))) + (is (= "good" (.toString ^StringWriter (message-writers 0)))) + (is (= "" (.toString ^StringWriter (message-writers 1))))) + (with-original-output [{:err out-writer}] + (.write ^PrintWriter (printers 1) "12 good34" 3 4) + (is (= "goodgood" (.toString out-writer))) + (is (= "good" (.toString ^StringWriter (message-writers 0)))) + (is (= "good" (.toString ^StringWriter (message-writers 1))))))) (testing "with char array with offsets" (let [{:keys [^StringWriter out-writer - ^StringWriter message-writer - ^PrintWriter printer]} + message-writers + printers]} (forking-printer-test-streams)] (with-original-output [{:out out-writer}] - (.write printer (char-array " bye67") 1 3) + (.write ^PrintWriter (printers 0) (char-array " bye67") 1 3) (is (= "bye" (.toString out-writer))) - (is (= "bye" (.toString message-writer)))))))) + (is (= "bye" (.toString ^StringWriter (message-writers 0)))) + (is (= "" (.toString ^StringWriter (message-writers 1))))) + (with-original-output [{:err out-writer}] + (.write ^PrintWriter (printers 1) (char-array " bye67") 1 3) + (is (= "byebye" (.toString out-writer))) + (is (= "bye" (.toString ^StringWriter (message-writers 0)))) + (is (= "bye" (.toString ^StringWriter (message-writers 1))))))))) From 287a6653bdcad62dd6b252e3b081a558018e4b18 Mon Sep 17 00:00:00 2001 From: Hugo Duncan Date: Thu, 9 Dec 2021 21:37:05 -0500 Subject: [PATCH 3/5] make dispatch more efficient --- src/cider/nrepl/middleware/out.clj | 48 ++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/cider/nrepl/middleware/out.clj b/src/cider/nrepl/middleware/out.clj index 5dde010d..922b27e7 100644 --- a/src/cider/nrepl/middleware/out.clj +++ b/src/cider/nrepl/middleware/out.clj @@ -40,16 +40,31 @@ Please do not inline; they must not be recomputed at runtime."} (catch Exception ~'e (unsubscribe-session ~'session)))))) -(defn dispatch-write - ([^Writer writer x] - (cond - (string? x) (.write writer ^String x) - (integer? x) (.write writer ^int x) - :else (.write writer ^{:tag "[C"} x))) - ([^Writer writer x ^Integer off ^Integer len] - (if (string? x) - (.write writer ^String x off len) - (.write writer ^{:tag "[C"} x off len)))) +(defn- dispatch-string + ([messages type ^String x] + (.write ^Writer (original-output type) x) + (with-out-binding [printer messages type] + (.write printer x))) + ([messages type ^String x ^Integer off ^Integer len] + (.write ^Writer (original-output type) x off len) + (with-out-binding [printer messages type] + (.write printer x off len)))) + +(defn- dispatch-int + ([messages type ^Integer x] + (.write ^Writer (original-output type) x) + (with-out-binding [printer messages type] + (.write printer x)))) + +(defn- dispatch-chars + ([messages type ^{:tag "[C"} x] + (.write ^Writer (original-output type) x) + (with-out-binding [printer messages type] + (.write printer x))) + ([messages type ^{:tag "[C"} x ^Integer off ^Integer len] + (.write ^Writer (original-output type) x off len) + (with-out-binding [printer messages type] + (.write printer x off len)))) (defn forking-printer "Returns a PrintWriter suitable for binding as *out* or *err*. All @@ -65,13 +80,14 @@ Please do not inline; they must not be recomputed at runtime."} ;; as `int` and `char[]` aren't supported by proxy. (write ([x] - (dispatch-write (original-output type) x) - (with-out-binding [printer messages type] - (dispatch-write printer x))) + (cond + (string? x) (dispatch-string messages type x) + (integer? x) (dispatch-int messages type x) + :else (dispatch-chars messages type x))) ([x ^Integer off ^Integer len] - (dispatch-write (original-output type) x off len) - (with-out-binding [printer messages type] - (dispatch-write printer x off len)))) + (if (string? x) + (dispatch-string messages type x off len) + (dispatch-chars messages type x off len)))) (flush [] (.flush ^Writer (original-output type)) (with-out-binding [printer messages type] From b35336d853441178d6d2ed6c032e20d0adb6d7c4 Mon Sep 17 00:00:00 2001 From: Hugo Duncan Date: Thu, 9 Dec 2021 22:16:52 -0500 Subject: [PATCH 4/5] remove warn-on-reflection --- test/clj/cider/nrepl/middleware/out_test.clj | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/clj/cider/nrepl/middleware/out_test.clj b/test/clj/cider/nrepl/middleware/out_test.clj index 422c75da..da5dd826 100644 --- a/test/clj/cider/nrepl/middleware/out_test.clj +++ b/test/clj/cider/nrepl/middleware/out_test.clj @@ -56,8 +56,6 @@ :message-writers message-writers :printers printers})) -(set! *warn-on-reflection* true) - (deftest forking-printer-test (testing "forking-printer prints to all message streams and original stream" (testing "with String argument " From a71ff9e1b7a90fc9074bf8d22bcb42130b20e5c5 Mon Sep 17 00:00:00 2001 From: Hugo Duncan Date: Thu, 9 Dec 2021 22:26:17 -0500 Subject: [PATCH 5/5] formatting --- test/clj/cider/nrepl/middleware/out_test.clj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/clj/cider/nrepl/middleware/out_test.clj b/test/clj/cider/nrepl/middleware/out_test.clj index da5dd826..2539b03a 100644 --- a/test/clj/cider/nrepl/middleware/out_test.clj +++ b/test/clj/cider/nrepl/middleware/out_test.clj @@ -50,8 +50,8 @@ message-writers [(StringWriter.) (StringWriter.)] messages [{:session (atom {#'*out* (message-writers 0)})} {:session (atom {#'*err* (message-writers 1)})}] - printers [(o/forking-printer [(messages 0)(messages 1)] :out) - (o/forking-printer [(messages 0)(messages 1)] :err)]] + printers [(o/forking-printer [(messages 0) (messages 1)] :out) + (o/forking-printer [(messages 0) (messages 1)] :err)]] {:out-writer out-writer :message-writers message-writers :printers printers})) @@ -60,7 +60,7 @@ (testing "forking-printer prints to all message streams and original stream" (testing "with String argument " (let [{:keys [^StringWriter out-writer - message-writers + message-writers printers]} (forking-printer-test-streams)] (with-original-output [{:out out-writer}] @@ -91,7 +91,7 @@ (is (= " " (.toString ^StringWriter (message-writers 1))))))) (testing "with char array" (let [{:keys [^StringWriter out-writer - message-writers + message-writers printers]} (forking-printer-test-streams)] (with-original-output [{:out out-writer}] @@ -106,7 +106,7 @@ (is (= "and" (.toString ^StringWriter (message-writers 1))))))) (testing "with String with offsets" (let [{:keys [^StringWriter out-writer - message-writers + message-writers printers]} (forking-printer-test-streams)] (with-original-output [{:out out-writer}] @@ -121,7 +121,7 @@ (is (= "good" (.toString ^StringWriter (message-writers 1))))))) (testing "with char array with offsets" (let [{:keys [^StringWriter out-writer - message-writers + message-writers printers]} (forking-printer-test-streams)] (with-original-output [{:out out-writer}]