nice to have more examples. @lee am finding yours to be particularly instructive, thanks 🙂
i'm looking at examples of tweaking behavior of :unresolved-symbol
here: https://github.com/borkdude/clj-kondo/blob/master/src/clj_kondo/impl/config.clj#L42-L53
it looks like by using :exclude
, one can ignore instances globally or within the context of a specific call (or calls).
i don't suppose it's possible to ignore instances within specific files...
the use case is when there is a file that has no ns
form and is using in-ns
instead, e.g. clojure's core_deftype.clj, core_print.clj, core_proxy.clj, etc.
is there some good way to have the unresolved symbol errors turned off only within those files without modifying them? (i'd rather not turn off the unresolved symbols linting for specific symbols across all of clojure's source if possible.)
@sogaiu you can ignore files in the output but that will ignore the entire file
ok thanks
@sogaiu Maybe it might sense to also allow namespace local config in config.edn under :namespaces {clojure {pprint {:linters {...} :lint-as {}}}}
but this is generally only useful for sources you don't control
on the other hand, it might be nice if you don't want to have your config in the source
that sounds interesting -- perhaps it can be noted as a future possibility. if there are other requests for it may be it can be revisited.
I'm also thinking about this in the context of REPL-assisted static analysis like https://github.com/clj-kondo/inspector.
Right now it only dumps types for the :type-mismatch
linter but we could have like a reverse analysis output format that clj-kondo can take in for linting.
https://github.com/borkdude/clj-kondo/issues/1004 https://github.com/borkdude/clj-kondo/issues/1005
@borkdude i don't see the connection yet, but hopefully will get it in a bit 🙂 btw, regarding hooks and handling macros, have you had a look at colinfleming's 2015 conj talk: https://www.youtube.com/watch?v=kt4haSH2xcs ?
I've seen it yes
ok, was curious as it has some mention of parsing macros.
there is this repository that he released after too: https://github.com/cursive-ide/error-test
the connection between those two issues is: inform clj-kondo about vars in your namespace. either by suppressing things or really telling it what's there
ah ok, thanks for the explanation.
I've considered that approach, and implemented a sexpr-based solution initally, but that didn't work since not all things can carry location metadata. So preserving the rewrite-clj nodes is better for linting and having a full Clojure environment for transforming those nodes is far more powerful than some DSL
We can still add clojure spec to the hooks API if you want to do validation on the sexpr directly
ah, too bad that didn't work out. i guess if it means i get my real-time notification from clj-kondo, the being tied to rewrite-clj is a trade-off i'm ok with. (ofc, i am a rewrite-clj* fan 🙂 )
The hooks API is rather thin, so switching to some other solution than rewrite-clj might still be possible in the future (but I doubt it)
ok -- well, i doubt i'll come up with anything useful, but a non-library specific approach has some application to other tooling so i'm interested in other ideas.
#lsp has a DSL for it
but they're switching to clj-kondo now for linting and possibly also analysis
I think they ran into some edge cases which couldn't be expressed in the DSL (@snoe)
ah i didn't know about the lsp dsl thing -- thanks for the tip.
we can still support something like that as an easier thing instead of hooks which then writes the lower level hooks code for you
one benefit of hooks is also that you can emit custom warnings based on your macro input
there's already examples of this in the config repo
yes i saw that -- looks cool.
i have been studying the examples and trying to make something for defdirectives in clojure's source
I want to add predicates api/vector?
, api/symbol?
etc so people rely less on api/sexpr
which can be a footgun
in emacs-lisp, to get edebug to work with macros they have this way for macro definitions (i think) to express info about how to understand them: https://www.gnu.org/software/emacs/manual/html_node/elisp/Specification-List.html#Specification-List
yeah, that makes sense
i'm sure lread will be happier to see sexpr used less
this rewrite-cljc-playground issue is related, right? https://github.com/lread/rewrite-cljc-playground/issues/5
Ah yes, thanks
Initially in the hooks API I called api/sexpr on the node, while also adding location as metadata. So people could write hooks directly on the sexpr. After transformation I printed this to a string including metadata and then read this in again using rewrite-clj
It works for a lot of the code, but not when you had expressions like (inc 1)
in your macro arguments
That's mostly why I abandoned that approach
else you could have almost used your macro as is for expansion
the current approach sounds safer
i need to think a lot more about this -- was mostly curious about background. sorry i was so late to the party 🙂
no problem. I think it's pretty cool that we can now run a Clojure interpreter in a binary version of clj-kondo :)
yes, i thought was pretty neat too!
@borkdude so i don't see map-node
here: https://github.com/borkdude/clj-kondo/blob/master/src/clj_kondo/impl/hooks.clj
is that something that would be ok to add? or may be it's available some other way?
I think we could add that, but so far I've often found other ways of dealing with this
maybe you could give the example
of what's the input and how you are rewriting it
https://gist.github.com/sogaiu/2be50c906e52a686699c154d4423c91d#file-gistfile1-txt-L25-L44
so defdirectives i think is supposed to expand to:
(def directive-table {,,,})
why is it important that you expand exactly like that macro
clj-kondo doesn't do anything with that right
lol -- no idea actually. may be it will be fine to do just (def directive-table nil)
?
happier to do less work 🙂
I would probably do this:
(defdirectives
(\A
[:mincol [0 Integer]
:colinc [1 Integer]
:minpad [0 Integer]
:padchar [\space Character]]
#{:at :colon :both}
{}
#(format-ascii print-str %1 %2 %3))
)
;; =>
[[\A
[:mincol [0 Integer]
:colinc [1 Integer]
:minpad [0 Integer]
:padchar [\space Character]]]
#{:at :colon :both}
{}
#(format-ascii print-str %1 %2 %3)]
it's important that all usages are still visible to clj-kondo
else you'll get warnings about unused imports, etc.
i think i get what you're saying -- though perhaps it's sensible to wrap the bottom thing in a def
form?
sure
ok, i'll give that a try. thanks!
that's one of the 💡 in writing hooks: you don't have to conform to the semantics of the original macro at all
yes, i was noticing that in lread's example but i guess there were two parts of my brain that weren't communicating well 🙂
should make things faster
there's also a time
macro to measure performance
thanks for the tip
@borkdude ok, your suggested approach is mostly working out.
there is one type of thing though that seems to lead to warnings: https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/cl_format.clj#L1373-L1379
those bits get wrapped in a fn
form -- https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/cl_format.clj#L1326
using a list-node with a fn token node and a vector followed by the form to wrap seems to work ok.
does that sound sane?
very
what kind of warning did you get?
one example is:
src/clj/clojure/pprint/cl_format.clj:1375:22: error: unresolved symbol params
i think that corresponds to: https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/cl_format.clj#L1375
right, so it expects some fixed set of named args it seems. someone went really wild with their macros there..
ha ha ha
i think with this, the number of errors when linting cl_format.clj are reduced: https://gist.github.com/sogaiu/2be50c906e52a686699c154d4423c91d
i guess cl_format.clj is from a long while back -- it has defstruct
about 20 lines of code, doesn't seem that bad: https://gist.github.com/sogaiu/2be50c906e52a686699c154d4423c91d#file-defdirectives-clj-L80-L99
thanks to your tip!
Rum hooks for defc
and defcs
now support multi-arity definitions at https://github.com/clj-kondo/config
Cool, someone wrote a hook to suggest turning long ->>
chains into transducer equivalents: https://github.com/borkdude/clj-kondo/issues/323#issuecomment-691247062