1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- (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}))
|