This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-14
Channels
- # adventofcode (12)
- # aleph (8)
- # announcements (6)
- # babashka (16)
- # beginners (217)
- # biff (7)
- # calva (30)
- # chlorine-clover (4)
- # cider (3)
- # clj-kondo (15)
- # cljdoc (6)
- # clojure (50)
- # clojure-europe (86)
- # clojure-finland (2)
- # clojure-nl (1)
- # clojure-norway (37)
- # clojure-uk (2)
- # clojurescript (8)
- # cursive (10)
- # datomic (13)
- # emacs (1)
- # fulcro (41)
- # helix (1)
- # humbleui (2)
- # joyride (7)
- # juxt (4)
- # lsp (19)
- # off-topic (47)
- # pathom (14)
- # polylith (5)
- # portal (7)
- # reagent (10)
- # releases (4)
- # sci (1)
- # scittle (18)
- # shadow-cljs (54)
- # test-check (2)
- # tools-deps (28)
Hello folks, I wanted to get some help to understand how to implement a custom linter a bit tricky using clj-kondo (and if it is possible as a whole). I have a situation where given a macro (lets call it foo
here), and a list of forbidden__ vars (qualified with namespaces), I want to check that none of those are being called inside foo
, up until this point everything is mostly fine. The biggest problem is: I want to be able to identify also “indirect calls”, that is, if bar
is a forbidden__ function, and baz
(another function) call bar
, then baz
should not be allowed to be called too. Example:
(defn bar []
)
(def baz []
(bar))
(foo
(baz)) ;; This should raise a linter warning/error
I wanted to have this as custom warning on lsp editors and lint runs. Any clues if this sounds feasible, and if so, where should I start looking?@leoiacovini you could possibly lint the direct calls inside the macro using :config-in-call {;discouraged-var {ns/foo true ns/bar true}}
It seems to be a start, but creating the dependency graph to trace back indirect calls is still a challenge, right? Just to bring a bit more of color, I am wanting to build a linter to precent blocking call inside core.async go
blocks mainly, not sure if this could fit into clj-kondo core as a whole
You could probably do this using clj-kondo as a tool, using it's analysis, but it's hard to implement this as a custom linter that you will use in your editor.
@UKFSJSM38 AFAIK clj-depend integration with clojure-lsp is also made using this approach, any chances of us being able to leverage a similar mechanic?
Probably we would need to do something custom using kondo analysis I think, @leoiacovini, recently clojure-lsp added the dump
feature, which mostly offer things that clojure-lsp knows about the project including kondo analysis normalized for the project.
One idea is to use this on CI and export the data to some kind of datalake where custom tools could use that info and do more smarter findings like your idea.
With clj-kondo analysis dump it should be fairly easy to get this recursive search, the thing that I am missing is the capability to give users realtime smart feedbacks in their editors. I am not sure how this would look from a performance perspective though
Yeah, for that we would probably need something bigger on clojure-lsp or kondo side, where given a bunch of project analysis would do a custom lint. It's like kondo hooks but smarter, since kondo already have all the hooks infrastructure maybe could support something like, a function call that given some project analysis would do a custom lint for a macro.
@UKFSJSM38 or people could get an lsp hook (interpreted via SCI like clj-kondo hooks) where they have access to the entire in memory data of lsp
Yes, I'd like to just avoid creating a monster, kondo hooks are already pretty complex for some users, I'd like to avoid having LSP hooks implementing same kondo logic, so it'd be nice to leverage kondo existing hooks with the capacity of just passing analysis which LSP could do, WDYT?
@UKFSJSM38 yes, that's a nice idea :) the hooks get access to a map and we can pass additional things in that map
looks interesting indeed, I tried running clojure-lsp dump
but it have me a ~60mb output 🤯 , there is a way to narrow down the scope of it to project only files? (I guess it is recursively getting all classpath data).