clj-kondo 2024-12-16

What prior art is there for querying codebases via clj-kondo's static analysis cache? Examples: namespace usage count, var usage count

Thanks! That’s exactly it!

I kind of want to pipe this into SQLite 😁

when bb was very young, I did exactly that as an example :) https://github.com/babashka/babashka/blob/master/examples/sqlite.clj

❀️ 1

(there's better ways to do this now with the clj-kondo pod and sqlite pod)

I have been putting these outputs into TMD (https://github.com/techascent/tech.ml.dataset) to very good effect, tremendous fun

In linters.md the config example for :shadowed-var is this:

{:linters {:shadowed-var {:level :warning
                          :exclude [ns]
                          :suggest {name nom}}}}
Is [ns] a typo, or does it mean something different to how I interpret it? From reading the code, supplying a vector of namespaces to :exclude does not exclude vars in that namespace. But I think the example config implies it might?

Yes, this configuration is correct, such that it won't warn for (let [ns ...])

the :exclude list is a list of simple symbols that may be used in let bindings without warnings

Aah I think I know why I misunderstood. ns stands for names or somesuch rather than namespace?

well could be whatever, e.g.: (let [ns (find-ns ...)])

Understood, but my point is that ns (which is very commonly used to stand for namespace in the clojure world) doesn't specifically refer to namespace in this example config. The reason I ask is I think a config option such as :exclude-ns-refers could be useful. e.g. a list of namespaces whose referred simple symbols do not trigger :shadowed-var lint warnings when shadowed in let bindings. I would use that primarily for clojure.core because vars like name key val and meta get shadowed so often, but I'm only really interested in catching non-clojure.core shadowing. Come to think of it, as over-use of refer isn't great anyway, I wonder if just a boolean :exclude-clojure-core? config option could be nice to have?

πŸ€” 1

(more food for your thought...) I can think of 4 types of shadowing: β€’ A binding further up in the let binding (or in an ancestor let/loop etc) which doesn't reference the shadowed binding:

(let [x 1, x 2] ...)
β€’ A binding which does reference the shadowed binding
(let [x 1, x (* x 2)] ...)
β€’ A global def
(def x 1) (let [x 2] ...)
β€’ A referred def
(ns foo) (def x 1)
(ns bar (:require [foo :refer [x]])) (let [x 2] ...)
I think the reason I rarely use the :shadowed-var linter is that it conflates the first 2 and the second two. The third is sometimes ok, and the fourth is often ok (in the case of clojure.core, anyway) but the first (and probably the second too) are nearly always something I want flagged by a linter.

the first I would call :shadowed-binding (as in a binding that shadows a binding). I'm personally not interested in this though as I often shadow bindings on purpose

admittedly mostly in the second form

βž• 1

yeah, I think the default for any of these linters would be :off because I don't think it's a universally agreed standard. But having separate binding vs var linters could have some value. worth making an issue? or even a PR? feels like maybe it needs some hammock time.?

hammock time sounds good, I never really paid attention to this, let me check in my code if that is a pattern that makes sense. one question that's good to ask: would this linter really catch unintentional bugs that often?

πŸ‘ 1

What's the right way to call console.log in a .cljs? I ask because (js/console.log "Hello") is complained of thus: "warning: Unresolved var: js/console.log"

βœ… 2

this should not be complained about, except in a .clj or .cljc file

I didn't think so, but I have the latest version of kondo and I cannot figure out why I'm seeing this!

I hate to waste anyone's time with what is surely a local issue

No problem, but can you provide a repro project maybe? I'm pretty sure I can't reproduce this, but who knows

$ clj-kondo --lint - <<< '(js/console.log "foo")'
<stdin>:1:2: warning: Unresolved namespace js. Are you missing a require? [:unresolved-namespace]
linting took 41ms, errors: 0, warnings: 1
$ clj-kondo --lint - --lang cljs <<< '(js/console.log "foo")'
linting took 13ms, errors: 0, warnings: 0

yeah...

are you 100% sure you are in a .cljs file and not a .cljc file?

screenshot would perhaps also help (which includes the extension)

yes completely it's a .cljs and there are no reader conditionals in it.

gotta be something in deps.edn or shadow-cljs.edn because if I just copy it to an empty directory it links with no warnings.

do you have a namespace js defined perhaps?

can you see what version of clj-kondo clojure-lsp is using?

hmm just ripgreped for js and I'd say, no. Version-wise I ran clj-kondo direct from command line to remove the lsp from consideration. clj-kondo v2024.11.14

do you get the error on the command line with clj-kondo?

i do, yes:

clj-kondo --lint ./src/main/littlereader/core.cljs 
./src/main/littlereader/core.cljs:16:4: warning: Unresolved var: js/console.log
./src/main/littlereader/core.cljs:17:32: warning: Unresolved var: js/document.getElementById
linting took 15ms, errors: 0, warnings: 2

that's very weird. perhaps you can try this, not sure if it will help:

rm -rf .clj-kondo/.cache

and then lint again from the command line

well, that did it

lol how do I mark a thread as solved, thank you very much, not likely to help anyone else

thank you though. I was in the google weeds

don't know how this happened, but I'm glad it was solved. let me know if it happens again

I will; least I can do.

one day I'll get tab-completion figured out on these js globals...