|
10 | 10 | (:refer-clojure :exclude [print print-str])
|
11 | 11 | (:import
|
12 | 12 | (clojure.core Eduction)
|
13 |
| - (clojure.lang AFunction Compiler IDeref IPending IPersistentMap |
14 |
| - IPersistentSet IPersistentVector IRecord Keyword Symbol |
15 |
| - TaggedLiteral Var) |
| 13 | + (clojure.lang AFunction Compiler IDeref IPending IPersistentMap MultiFn |
| 14 | + IPersistentSet IPersistentVector IRecord Keyword Namespace |
| 15 | + Symbol TaggedLiteral Var) |
| 16 | + (java.io Writer) |
16 | 17 | (java.util List Map Map$Entry)
|
17 | 18 | (mx.cider.orchard TruncatingStringWriter
|
18 | 19 | TruncatingStringWriter$TotalLimitExceeded))
|
|
50 | 51 | (defn- print-coll-item
|
51 | 52 | "Print an item in the context of a collection. When printing a map, don't print
|
52 | 53 | `[]` characters around map entries."
|
53 |
| - [^TruncatingStringWriter w, x, map?] |
| 54 | + [^Writer w, x, map?] |
54 | 55 | (if (and map? (instance? Map$Entry x))
|
55 | 56 | (do (print (.getKey ^Map$Entry x) w)
|
56 | 57 | (.write w " ")
|
|
60 | 61 | (defn- print-coll
|
61 | 62 | ([w x sep prefix suffix]
|
62 | 63 | (print-coll w x sep prefix suffix false))
|
63 |
| - ([^TruncatingStringWriter w, ^Iterable x, ^String sep, ^String prefix, |
| 64 | + ([^Writer w, ^Iterable x, ^String sep, ^String prefix, |
64 | 65 | ^String suffix, map?]
|
65 | 66 | (let [level *print-level*]
|
66 | 67 | (when-not (nil? level)
|
|
89 | 90 | (finally (when-not (nil? level)
|
90 | 91 | (set! *print-level* level)))))))
|
91 | 92 |
|
92 |
| -(defmethod print nil [_ ^TruncatingStringWriter w] |
| 93 | +(defmethod print nil [_ ^Writer w] |
93 | 94 | (.write w "nil"))
|
94 | 95 |
|
95 |
| -(defmethod print :string [^String x, ^TruncatingStringWriter w] |
| 96 | +(defmethod print :string [^String x, ^Writer w] |
96 | 97 | (let [len (.length x)
|
97 | 98 | max-len *max-atom-length*
|
98 | 99 | truncate? (and max-len (< max-len len))
|
|
106 | 107 | (.write w "..."))
|
107 | 108 | (.append w \")))
|
108 | 109 |
|
109 |
| -(defmethod print :scalar [^Object x, ^TruncatingStringWriter w] |
| 110 | +(defmethod print :scalar [^Object x, ^Writer w] |
110 | 111 | (.write w (.toString x)))
|
111 | 112 |
|
112 | 113 | (defmethod print :persistent-map [x w]
|
|
132 | 133 | (defmethod print :map [^Map x, w]
|
133 | 134 | (print-map x w))
|
134 | 135 |
|
135 |
| -(defmethod print :record [x, ^TruncatingStringWriter w] |
| 136 | +(defmethod print :record [x, ^Writer w] |
136 | 137 | (.write w "#")
|
137 | 138 | (.write w (.getSimpleName (class x)))
|
138 | 139 | (print-map x w))
|
139 | 140 |
|
140 |
| -(defmethod print :array [x, ^TruncatingStringWriter w] |
| 141 | +(defmethod print :array [x, ^Writer w] |
141 | 142 | (let [ct (.getName (or (.getComponentType (class x)) Object))
|
142 | 143 | as-seq (seq x)]
|
143 | 144 | (.write w ct)
|
144 | 145 | (if as-seq
|
145 | 146 | (print-coll w as-seq ", " "[] {" "}")
|
146 | 147 | (.write w "[] {}"))))
|
147 | 148 |
|
148 |
| -(defmethod print IDeref [^IDeref x, ^TruncatingStringWriter w] |
| 149 | +(defmethod print IDeref [^IDeref x, ^Writer w] |
149 | 150 | (let [pending (and (instance? IPending x)
|
150 | 151 | (not (.isRealized ^IPending x)))
|
151 | 152 | [ex val]
|
152 | 153 | (when-not pending
|
153 | 154 | (try [false (deref x)]
|
154 | 155 | (catch Throwable e
|
155 |
| - [true e])))] |
| 156 | + [true e]))) |
| 157 | + full-name (.getName (class x)) |
| 158 | + name (cond (str/starts-with? full-name "clojure.core$future_call") "future" |
| 159 | + (str/starts-with? full-name "clojure.core$promise") "promise" |
| 160 | + :else (str/lower-case (.getSimpleName (class x))))] |
156 | 161 | (.write w "#")
|
157 |
| - (.write w (.getSimpleName (class x))) |
| 162 | + (.write w name) |
158 | 163 | (print [(cond (or ex
|
159 | 164 | (and (instance? clojure.lang.Agent x)
|
160 | 165 | (agent-error x)))
|
|
168 | 173 | (defmethod print Class [x w]
|
169 | 174 | (print-method x w))
|
170 | 175 |
|
171 |
| -(defmethod print AFunction [x, ^TruncatingStringWriter w] |
| 176 | +(defmethod print AFunction [x, ^Writer w] |
172 | 177 | (.write w "#function[")
|
173 | 178 | (.write w (Compiler/demunge (.getName (class x))))
|
174 | 179 | (.write w "]"))
|
175 | 180 |
|
| 181 | +(def ^:private multifn-name-field |
| 182 | + (delay (doto (.getDeclaredField MultiFn "name") |
| 183 | + (.setAccessible true)))) |
| 184 | + |
| 185 | +(defn- multifn-name [^MultiFn mfn] |
| 186 | + (try (.get ^java.lang.reflect.Field @multifn-name-field mfn) |
| 187 | + (catch SecurityException _ "_"))) |
| 188 | + |
| 189 | +(defmethod print MultiFn [x, ^Writer w] |
| 190 | + (.write w "#multifn[") |
| 191 | + (.write w (multifn-name x)) |
| 192 | + ;; MultiFn names are not unique so we keep the identity to ensure it's unique. |
| 193 | + (.write w (format " 0x%x]" (System/identityHashCode x)))) |
| 194 | + |
176 | 195 | (defmethod print TaggedLiteral [x w]
|
177 | 196 | (print-method x w))
|
178 | 197 |
|
179 |
| -(defmethod print Throwable [^Throwable x, ^TruncatingStringWriter w] |
180 |
| - (.write w "#Error[") |
| 198 | +(defmethod print Namespace [x, ^Writer w] |
| 199 | + (.write w "#namespace[") |
| 200 | + (.write w (str (ns-name x))) |
| 201 | + ;; MultiFn names are not unique so we keep the identity to ensure it's unique. |
| 202 | + (.write w "]")) |
| 203 | + |
| 204 | +(defmethod print Throwable [^Throwable x, ^Writer w] |
| 205 | + (.write w "#error[") |
181 | 206 | (.write w (str (.getName (class x)) " "))
|
182 | 207 | (loop [cause x, msg nil]
|
183 | 208 | (if cause
|
|
191 | 216 | (print (str first-frame) w))
|
192 | 217 | (.write w "]"))
|
193 | 218 |
|
194 |
| -(defmethod print :default [^Object x, ^TruncatingStringWriter w] |
| 219 | +(defmethod print :default [^Object x, ^Writer w] |
195 | 220 | (.write w (.toString x)))
|
196 | 221 |
|
197 | 222 | (defn print-str
|
|
0 commit comments