rum.clj 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. (ns hooks.rum
  2. (:require [clj-kondo.hooks-api :as api]))
  3. (defn fn-body? [x]
  4. (and (seq? x)
  5. (vector? (first x))))
  6. (defn rewrite-body [mixins body defcs?]
  7. (if defcs?
  8. (let [[binding-vec & body] (:children body)
  9. [state-arg & rest-args] (:children binding-vec)
  10. ;; the original vector without the state argument
  11. fn-args (assoc binding-vec :children rest-args)
  12. body (api/list-node
  13. (list* (api/token-node 'let*)
  14. (api/vector-node [state-arg (api/token-node nil)])
  15. state-arg
  16. (concat mixins body)))
  17. body (api/list-node [fn-args body])]
  18. body)
  19. (let [[binding-vec & body] (:children body)]
  20. (api/list-node (cons binding-vec (concat mixins body))))))
  21. (defn rewrite
  22. ([node] (rewrite node false))
  23. ([node defcs?]
  24. (let [args (rest (:children node))
  25. component-name (first args)
  26. ?docstring (when (string? (api/sexpr (second args)))
  27. (second args))
  28. args (if ?docstring
  29. (nnext args)
  30. (next args))
  31. bodies
  32. (loop [args* (seq args)
  33. mixins []
  34. bodies []]
  35. (if args*
  36. (let [a (first args*)
  37. a-sexpr (api/sexpr a)]
  38. (cond (vector? a-sexpr) ;; a-sexpr is a binding vec and the rest is the body of the function
  39. [(rewrite-body mixins (api/list-node args*) defcs?)]
  40. (fn-body? a-sexpr)
  41. (recur (next args*)
  42. mixins
  43. (conj bodies (rewrite-body mixins a defcs?)))
  44. ;; assume mixin
  45. :else (recur (next args*)
  46. (conj mixins a)
  47. bodies)))
  48. bodies))
  49. new-node (with-meta
  50. (api/list-node
  51. (list* (api/token-node 'defn)
  52. component-name
  53. (if ?docstring
  54. (cons ?docstring bodies)
  55. bodies)))
  56. (meta node))]
  57. new-node)))
  58. (defn defc [{:keys [:node]}]
  59. (let [new-node (rewrite node)]
  60. {:node new-node}))
  61. (defn defcs [{:keys [:node]}]
  62. (let [new-node (rewrite node true)]
  63. {:node new-node}))