Finally got it working
(defn defcs
[{:keys [node]}]
(let [args (rest (:children node))
component-name (first args)
args (next args)
body (loop [args* args
mixins []]
(if (seq args*)
(let [a (first args*)]
(if (vector? (api/sexpr a))
(cons a (concat mixins (rest args*)))
(recur (rest args*)
(conj mixins a))))
args))
partial-state (api/list-node [(api/token-node 'partial)
(api/list-node (list* (api/token-node 'fn) body))
(api/token-node 'state)])
new-node (api/list-node
[(api/token-node 'let)
(api/vector-node
[(api/token-node 'state) (api/token-node {})])
(with-meta (api/list-node [(api/token-node 'def)
component-name
partial-state])
(meta node))])]
{:node new-node}))
Thank you for help @borkdude you are golden!
Cool! What is the partial state for?
It's for making sure that state is provided
I think this generates something like:
(let [state {}] (def my-component (partial (fn [...] ...) state)))
Why not:
(defn my-component [args] (let [state {}] body)
?Is there a difference?
Syntactically yes, clj-kondo can see the argument count this way for example?
So in partial it's not seen?
You might want to do:
(defn my-component [args] (let [state {}] state ... body ...)
to make state being used, so it won't be reported.No
Hmm....
Frankly I want the state to be reported
ah
that's ok then, don't use it
Ahh wait.
so if you don't use state, then you're going to use def-something-else in rum right?
So I can just ignore the first arg?
why would you want to ignore the first arg?
I think that we are talking past each other 😄
I think so too. Maybe it's better to talk in examples. Paste an example of Rum usage and the desired sexpr for clj-kondo
@borkdude My goal is to make sure that both not used state is reported and function that takes like 2 (except state) args then when I provide only one argument then I want clj-kondo to report that not all function parameters are passed. Let the demo.cljs be defined like so:
(rum/defcs SomeComponent <
{:did-mount (fn [state] state)}
[state input another]
(let [x "Hello"]
nil))
(rum/defc SomeComponent1 <
{:did-mount (fn [state] state)}
[input]
input)
(SomeComponent "hello")
After running clj-kondo I got the following things reported:
demo.cljs:9:4: warning: unused binding state
demo.cljs:9:10: warning: unused binding input
demo.cljs:9:16: warning: unused binding another
demo.cljs:10:9: warning: unused binding x
linting took 17ms, errors: 0, warnings: 4
That's perfectly fine. What I need more is just the warning that not all parameters to function has been passed.
My question is how I can have that last warning working? What I understand is that I should not use 'partial, but how should I construct sexpr?@karol.wojcik I think more like (defn my-component [args] (let [state {}] body)
, so more like how it was originally, but with the extra let around the body
(defsc foo [state x] body1 body2)
=> (defn foo [x] (let [state {}] body1 body2)
So you call it as (f 1)
and clj-kondo will think this is correct, since the generated form only receives one arg (or n-1 args in general) and state is still recognized as a valid binding.
and (f 1 2)
should trigger an arity warning
Thanks.. Will try to do it in free time
:thumbsup: