Fork me on GitHub

I'm out of practice with the internals of analysis, but is it possible to know that a macro like myfor is treated as clojure.core/for I think not? Here's my problem: I was hoping to handle extracting vars (`move-to-let` in clojure-lsp) into (for [:let []]) bindings when appropriate, right now we just match raw symbols but analysis could improve that (similar issues exist identifying let like macros). The other thing I'm thinking of is how a cond-let macro would/should behave with extract var refactors, but it'd be nice to enable it. Maybe something could be annotated with like-let or like-for or like-params and that way hooks could take part (but I don't think the various vectors appear in analysis)?


Maybe the way hook expansion works, I would see a clojure.core/let ? Before I go digging in again, just wondering if there's anything existing to be aware of?


Custom macros like cond-let are best handled using hooks and then you would indeed see the locals as a normal let, usually


Maybe you can demontrate your question/problem using a repro showing that something is or is not possible using the current state of affairs, I'm not really sure from the top of my head

👍 1

@UKFSJSM38 has been dealing a lot with analysis as well


Here's an example @U04V15CAJ given this file and config:

(ns scratch.core)

(defmacro forv [& args]
  `(vec (for [email protected])))

(forv [n [1 2 3]] (inc n))
:lint-as {scratch.core/forv clojure.core/for} If I put the cursor on the (inc n) and perform move-to-let / extract var refactor, I would want to transform it to (forv [n [1 2 3] :let [m (inc n)]] m) but without knowing that I should treat forv as for I can only do (forv [n [1 2 3]] (let [m (inc n)] m))


Dumping the analysis for it, I can't see how to draw that connection that lint-as provides with what's there.


Hum, got it, we would need something just like we know a var-definiton was defined-by clojure.core/deftest for example, but for a var-usage


It may even be trickier, because we probably need to know the binding vector itself can be treated like for 's (or let or params etc.. Imagine this one with a weird first arg.

(defmacro forv [message & args]
  `(do (println ~message) (vec (for [email protected]))))


isn't move-to-let a bit ambiguous here? it could also mean: move to an outer let:

(let [x 1] (forv ...))


that one with the first weird arg would not be possible with lint-as, so you would need to write a hook for that one


I think it's reasonable to expect these refactorings to work for core macros and less so for custom macros

👍 2

It's probably best to wait for people to really complain about this, I could imagine that it isn't worth the trouble of solving this at all


Yeah, I'm not too sympathetic to weird macros. But every large code base ive run into builds their own lint-as like macros. I guess if we focus on lint-as maybe we could just use the kondo config itself and not need analysis. wdyt @UKFSJSM38?

👍 1

that's maybe a good idea initially