Fork me on GitHub
#clj-kondo
<
2022-03-21
>
snoe16:03:04

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)?

snoe16:03:18

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?

borkdude16:03:15

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

borkdude16:03:01

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
borkdude16:03:39

@UKFSJSM38 has been dealing a lot with analysis as well

snoe21:03:12

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

(ns scratch.core)

(defmacro forv [& args]
  `(vec (for ~@args)))

(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))

snoe21:03:18

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

ericdallo21:03:42

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

snoe21:03:19

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 ~@args))))

borkdude21:03:53

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

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

borkdude21:03:52

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

borkdude21:03:46

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

👍 2
borkdude21:03:11

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

snoe21:03:28

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
borkdude22:03:02

that's maybe a good idea initially