clj-kondo 2025-04-25

I have a macro that expands differently for clj and cljs, along these lines:

(defmacro my-macro [...]
  (if (:ns &env)
    `(...)
    `(...)))
Is there a way, in a :macroexpand hook or otherwise, to tell clj-kondo about the different expansions? (From my experimenting, it seems that (:ns &env) doesn’t work in a :macroexpand hook.)

in analyze-call hook there is a :lang argument if I'm not mistaking

OK; thanks. I will take a look at that.

Just to confirm — yes, there is a :lang argument.

Perhaps we could also add this to the &env argument in the macroexpand flow, but I think currently it's not there

I think it might be possible to do macroexpansion inside a analyze-call hook though...

no, that's currently also not exposed

This is what happens in the macroexpand hook basically:

(defn macroexpand [macro node bindings]
  (let [call (api/sexpr node)
        args (rest call)
        res (apply macro call bindings args)
        coerced (api/coerce res)
        annotated (annotate coerced (meta node))
        lifted (meta/lift-meta-content2 utils/*ctx* annotated)]
    ;;
    lifted))
The "annotate" and "lifted" steps aren't exposed, so you can't do this in user space. You'll lose a lot of location information if you do a manual macro-expansion inside of an analyze-call hook

So your only option right now is to write an analyze-call hook

OK. Making (:ns &env) work would be nice, but as you say I can do what I want as things are.

Adding :ns for deciding if it's CLJ or CLJS isn't a good idea for clj-kondo I think, since I might want to add more stuff to &env and it's kind of an implementation detail of CLJS

so perhaps it's best to expose the macroexpander to the analyze-call hook so you can do whatever you need with extra information and then call the macro yourself or so

OK; that makes sense

issue welcome

OK; I’ll create one — maybe not for a couple of days though