Skip to content

Commit e5a495b

Browse files
committed
feat(repl): add clojure.repl/stack-element-str over cljw frame maps
Smell-audited: 1: cljw has no StackTraceElement (ADR-0059) so it takes the cljw-native frame map; render string is duplicated with clojure.stacktrace/print-trace-element (both fixed by ADR-0140), kept inline + cross-referenced rather than adding a load-order-sensitive stacktrace->repl dep for a stable 1-line format. stack-element-str was missing. cljw has only Clojure frames (ADR-0120), so it takes the cljw-native frame map {:ns :fn :file :line} (as returned by stack-trace) and renders <ns>/<fn> (<file>:<line>), exactly clj's Clojure-frame output (verified vs oracle: clojure.core/map (core.clj:2743)). placement.yaml regenerated; CHANGELOG [Unreleased] + repl_test.clj cover it.
1 parent 6b161db commit e5a495b

4 files changed

Lines changed: 33 additions & 2 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ first stable `1.0.0` tag; pre-1.0 `alpha` / `rc` tags may still change surfaces.
1515
`(munge "foo-bar?")` is `"foo_bar_QMARK_"`. cljw carried `namespace-munge`
1616
and `demunge` but not the full `munge`; found while writing dev tooling.
1717

18+
- **`clojure.repl/stack-element-str`.** Renders one stack frame as
19+
`<ns>/<fn> (<file>:<line>)`. cljw has no JVM `StackTraceElement` and only
20+
Clojure frames, so it takes the cljw-native frame map `{:ns :fn :file :line}`
21+
(as returned by `stack-trace`) and produces exactly clj's Clojure-frame form,
22+
e.g. `"clojure.core/map (core.clj:2743)"`.
23+
1824
### Fixed
1925

2026
- **`clojure.repl/demunge` maps the `$` nested-class separator to `/`.**

‎data/placement.yaml‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
schema_version: "2.0"
2525
summary:
2626
namespaces_required: 34
27-
total: 1420
27+
total: 1421
2828
zig: 405
29-
clj: 794
29+
clj: 795
3030
value: 215
3131
unbound: 6
3232
vars:
@@ -1039,6 +1039,7 @@ vars:
10391039
"clojure.repl/root-cause": { impl: clj, flags: "-" }
10401040
"clojure.repl/source": { impl: clj, flags: "macro" }
10411041
"clojure.repl/source-fn": { impl: clj, flags: "-" }
1042+
"clojure.repl/stack-element-str": { impl: clj, flags: "-" }
10421043
"clojure.set/difference": { impl: clj, flags: "-" }
10431044
"clojure.set/index": { impl: clj, flags: "-" }
10441045
"clojure.set/intersect2": { impl: clj, flags: "private" }

‎src/lang/clj/clojure/repl.clj‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@
2828
(clojure.string/replace "$" "/")
2929
(clojure.string/replace "_" "-")))
3030

31+
;; `stack-element-str` renders one cljw stack frame map {:ns :fn :file :line}
32+
;; as `<ns>/<fn> (<file>:<line>)`. clj takes a JVM StackTraceElement and yields
33+
;; `class.method (file:line)` for a Java frame or a demunged `ns/fn` for a
34+
;; Clojure frame; cljw has no StackTraceElement and only Clojure frames
35+
;; (ADR-0059 / ADR-0120), so it takes the cljw-native frame map and produces
36+
;; exactly clj's Clojure-frame form. Same render string as
37+
;; clojure.stacktrace/print-trace-element (both fixed by ADR-0140).
38+
(defn stack-element-str
39+
"Returns a string representation of one cljw stack frame map
40+
{:ns :fn :file :line}, as `<ns>/<fn> (<file>:<line>)`."
41+
[{:keys [ns fn file line]}]
42+
(str (when ns (str ns "/")) fn " (" (or file "") ":" line ")"))
43+
3144
(defn dir-fn
3245
"Returns a sorted seq of symbols naming public vars in
3346
a namespace or namespace alias."

‎test/clj/suites/repl_test.clj‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,14 @@
3333
(is (= "ok" (munge "ok"))))
3434
(testing "munge then demunge round-trips a hyphenated name"
3535
(is (= "foo-bar" (repl/demunge (munge "foo-bar"))))))
36+
37+
;; --- stack-element-str (cljw-native frame map input) ---
38+
;; clj takes a JVM StackTraceElement; cljw has only Clojure frames, so it
39+
;; takes a frame map and produces clj's Clojure-frame render string.
40+
(deftest stack-element-str-renders-a-frame
41+
(testing "a frame map renders as ns/fn (file:line)"
42+
(is (= "clojure.core/map (core.clj:2743)"
43+
(repl/stack-element-str {:ns "clojure.core" :fn "map" :file "core.clj" :line 2743}))))
44+
(testing "a frame with no ns omits the ns/ prefix"
45+
(is (= "eval1 (NO_SOURCE_FILE:1)"
46+
(repl/stack-element-str {:fn "eval1" :file "NO_SOURCE_FILE" :line 1})))))

0 commit comments

Comments
 (0)