mirror of https://github.com/logseq/logseq
69 lines
2.4 KiB
Clojure
69 lines
2.4 KiB
Clojure
(ns hooks.rum
|
|
(:require [clj-kondo.hooks-api :as api]))
|
|
|
|
(defn fn-body? [x]
|
|
(and (seq? x)
|
|
(vector? (first x))))
|
|
|
|
(defn rewrite-body [mixins body defcs?]
|
|
(if defcs?
|
|
(let [[binding-vec & body] (:children body)
|
|
[state-arg & rest-args] (:children binding-vec)
|
|
;; the original vector without the state argument
|
|
fn-args (assoc binding-vec :children rest-args)
|
|
body (api/list-node
|
|
(list* (api/token-node 'let*)
|
|
(api/vector-node [state-arg (api/token-node nil)])
|
|
state-arg
|
|
(concat mixins body)))
|
|
body (api/list-node [fn-args body])]
|
|
body)
|
|
(let [[binding-vec & body] (:children body)]
|
|
(api/list-node (cons binding-vec (concat mixins body))))))
|
|
|
|
(defn rewrite
|
|
([node] (rewrite node false))
|
|
([node defcs?]
|
|
(let [args (rest (:children node))
|
|
component-name (first args)
|
|
?docstring (when (string? (api/sexpr (second args)))
|
|
(second args))
|
|
args (if ?docstring
|
|
(nnext args)
|
|
(next args))
|
|
bodies
|
|
(loop [args* (seq args)
|
|
mixins []
|
|
bodies []]
|
|
(if args*
|
|
(let [a (first args*)
|
|
a-sexpr (api/sexpr a)]
|
|
(cond (vector? a-sexpr) ;; a-sexpr is a binding vec and the rest is the body of the function
|
|
[(rewrite-body mixins (api/list-node args*) defcs?)]
|
|
(fn-body? a-sexpr)
|
|
(recur (next args*)
|
|
mixins
|
|
(conj bodies (rewrite-body mixins a defcs?)))
|
|
;; assume mixin
|
|
:else (recur (next args*)
|
|
(conj mixins a)
|
|
bodies)))
|
|
bodies))
|
|
new-node (with-meta
|
|
(api/list-node
|
|
(list* (api/token-node 'defn)
|
|
component-name
|
|
(if ?docstring
|
|
(cons ?docstring bodies)
|
|
bodies)))
|
|
(meta node))]
|
|
new-node)))
|
|
|
|
(defn defc [{:keys [:node]}]
|
|
(let [new-node (rewrite node)]
|
|
{:node new-node}))
|
|
|
|
(defn defcs [{:keys [:node]}]
|
|
(let [new-node (rewrite node true)]
|
|
{:node new-node}))
|