This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-02-29
Channels
- # announcements (6)
- # babashka (7)
- # beginners (24)
- # calva (2)
- # cider (21)
- # clj-kondo (49)
- # cljdoc (29)
- # clojure (56)
- # clojure-dev (2)
- # clojure-europe (15)
- # clojure-nl (6)
- # clojure-norway (27)
- # clojure-uk (3)
- # clojuredesign-podcast (6)
- # clojurescript (1)
- # conjure (1)
- # core-async (8)
- # cryogen (2)
- # cursive (6)
- # data-science (1)
- # datomic (12)
- # events (1)
- # fulcro (16)
- # graalvm (28)
- # hyperfiddle (2)
- # lambdaisland (4)
- # leiningen (20)
- # observability (1)
- # off-topic (24)
- # pathom (5)
- # pedestal (10)
- # portal (7)
- # practicalli (1)
- # reitit (5)
- # rewrite-clj (20)
- # shadow-cljs (18)
- # vim (8)
- # xtdb (9)
Can rewrite-clj read metadata? I'm particularly interested in ^:deprecated
and ^:added
- I wrote a tiny documentation generator using Babashka, and that' the only bit that I'm missing and I couldn't figure out how to do. I did notice that the ^:deprecated
string appears when I use rewrite-clj.node
but I don't see an obvious way of reading that programmatically without using regexes (uh)
btw you could maybe also use the clj-kondo analysis data, this spits out data about vars as well by reading rewrite-clj nodes
I noticed that your doc generator uses kondo pod, I was thinking of taking that route eventually but just for my own education I'd love to learn to how to do this just with rewrite-clj :-)
(I also looked into how Kondo does this, but couldn't dive that deep because of time constraints)
user=> (p/parse-string "^:deprecated x")
<meta: ^:deprecated x>
This returns a meta nodethat part, I get but it's not clear how to read the meta part, here's the relevant part of my code: https://gist.github.com/lukaszkorecki/bddc0c296e044b9e6d0ddfc5623adfd7
I see, the above works, but why this doesn't?
# bb
Babashka v1.3.188 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.
user=> (require '[rewrite-clj.zip :as z] '[rewrite-clj.parser :as p])
user=> (meta (z/sexpr (z/of-string "(defn ^:deprecated create \"some doc\" [] :x)")))
nil
user=>
I assumed I can do something like (into [] (s/expr (z/of-string ...fn source...)))
and read the meta that way
thank you @U04V15CAJ, that was super useful, final impl looks like this:
(defn get-fns-info [parsed]
(let [fn-info (atom [])]
(-> parsed
(z/prewalk (fn [thing]
(when (and
(z/list? thing)
(= "defn" (str (first (z/sexpr thing)))))
(let [sexpr (z/sexpr thing)
[_f name docstring & _rest] sexpr
node (z/node thing)
metadata (when-let [meta? (first (filter #(= :meta (:tag %)) (remove n/whitespace? (n/children node))))]
(meta (n/sexpr meta?)))
source (str node)
position (zipmap [:line :column] (z/position thing))]
(swap! fn-info conj
{:name name
:metadata metadata
:position position
:source source
:docstring (when (string? docstring)
docstring)})))
thing)))
(sort-by #(-> % :position :line) (deref fn-info))))