|
@@ -0,0 +1,68 @@
|
|
|
+(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}))
|