Fork me on GitHub
#clj-kondo
<
2024-02-29
>
Noah Bogart15:02:46

Could it be possible to add "current namespace" info to the context of hooks? i'd like to know if a given symbol's namespace is an alias or not

borkdude15:02:50

There is a function called api/resolve which you can feed a symbol

Noah Bogart16:02:09

Oh interesting, let me see if that does what I need

Noah Bogart16:02:34

yes, that works great, thank you

👍 1
Noah Bogart13:03:01

coming back to this, api/resolve will resolve the namespace, but it won't resolve the symbol.

Noah Bogart13:03:31

given:

(ns example.foo
  (:require [example.bar :as e.bar]))

(defn create-service
  [this]
  (with-meta this {`e.bar/real-function identity}))
if I write e.baa/real-function, api/resolve will return {:ns nil :name real-function}. however, if i write e.bar/fake-function, it will return {:ns example.bar :name fake-function}.

Noah Bogart13:03:56

i realize this is outside of my original request

borkdude13:03:08

you can check api/ns-analysis if the var exists or not, but if the analysis is there, depends on if the namespace has already been linted before

👍 1
Noah Bogart14:03:14

a little awkward but works great

Noah Bogart14:03:17

thanks so much

Noah Bogart16:02:32

Would you be interested in supporting making (load "some_file") / in-ns work for analysis? i'm thinking about how there's no way to "go to definition" in clojure-lsp on certain core functions (`defrecord` is my current example) because clj-kondo doesn't provide analysis about it or at least it doesn't "merge" them together

borkdude16:02:10

Do you mean if I'm interested in receiving a PR for it?

Noah Bogart16:02:27

well, i'm not going to write a PR if you wouldn't merge it lol

Noah Bogart16:02:50

i'd prefer to check if you're like "no, not interested at all" vs "maybe if it's workable", you know?

borkdude16:02:36

I'm not sure if this pattern is common enough (and applicable across dialects) to make huge changes. Perhaps we can just make bespoke support for some of the namespaces in clojure that use this pattern, but I'm open to having it generally supported. Not sure how easy that is though

👍 1
Noah Bogart16:02:53

yeah, with parallel analysis, i don't think it's possible, so i'm not sure how it would work in that case.

borkdude16:02:48

parallel analysis doesn't lint stuff in parallel from the same jar file or directory

Noah Bogart16:02:23

oh really? so passing --parallel when linting my src folder doesn't do anything?

borkdude16:02:31

that's correct

😅 1
😭 1
😮 1
Noah Bogart16:02:05

okay, then maybe this is possible.

Noah Bogart16:02:06

i missed that!

borkdude16:02:26

the strategy for parallel linting could be entirely based on topological sorting

borkdude16:02:05

this is probably not an issue that can be tackled in a few hours though, but willing to think about it for the long term

👍 1
hiredman17:02:39

topological sorting dependencies in the face of load-file is very chicken and the egg

Noah Bogart18:02:45

To properly handle it, you’d have to sort of duplicate the evaluation logic of clojure, right? Take in a file, process each form one at a time, load files when encountering load/require/use etc

hiredman18:02:00

sure, meaning you would need to do analysis to determine dependencies (it is already the case you need to at least analyze the ns form) and you need dependencies in order to do some kind of topo sort, and you need some kind of topo sort to determine what is safe to analyze in parallel

Noah Bogart21:03:25

I implemented this in splint, it didn’t increase serial linting time noticeably (~100ms per 100 files), but it did remove the ability to lint files in parallel (which i do across all files (not just per directory like in clj-kondo))

hiredman21:03:08

have you seen the build system's a la carte paper? (https://www.microsoft.com/en-us/research/uploads/prod/2018/03/build-systems.pdf) it is very haskell, but it might give you some interesting ideas for structuring analysis where dependencies might be dynamically discoverable, and if I recall one of the concerns presented is wanting to parallelize builds

👍 1
Noah Bogart21:03:40

I’ve not, I’ll give that a read.

Noah Bogart21:03:23

The code complexity increase was mild to moderate: instead of just linting each form recursively, i had to first check if a given form was one that loaded other files, and then actually update the ctx with the files to lint and files that have been linted. The code that processed loading was pretty easy tho it required a bit of work to fake a classpath awareness

Noah Bogart21:03:48

I haven’t merged the code because it’s currently only a speed decrease for no gain (i don’t do any var/locals tracking), but it was good to see that it’s both possible and fairly easy

Noah Bogart21:03:28

I could try doing this in clj-kondo if @U04V15CAJ is interested

borkdude21:03:18

yeah. I think identifying groups of dependencies that still can be linted in parallel might also be nice

👍 1
Noah Bogart00:03:58

this won't mean much without knowing splint's internals, but here's the PR i did showing "loading in dependency order": https://github.com/NoahTheDuke/splint/pull/9

Noah Bogart18:02:49

I searched the issues and didn't see any requests, so checking before I open one: would you be interested in supporting linting a project (from a project file) instead of by directory/file?

bringe18:02:17

Hello 👋. A project I'm working in has a custom macro defined for defining graphql resolvers, called defresolver. The pattern used in this project with this macro is to name the symbols for field resolvers field/<field-name> . For these symbols, clj-kondo reports syntax warnings like Function name must be simple symbol but got: field/account-name. Is there a way to tell clj-kondo to stop reporting these warnings across the project without squelching all syntax warnings across the project?

bringe18:02:54

Example form:

(defresolver field/account-name
  [...]
  ...)

borkdude18:02:11

try:

{:config-in-call {foobar/defresolver {:linters {:syntax {:level :off}}}}}
or so

bringe18:02:23

Thanks. Will that disable syntax warnings for the whole defresolver form? There's no way to be more fine-grained about what to disable, right?

bringe18:02:08

Or rather, there's no way to tell clj-kondo "A / in a symbol is ok in this foobar/defresolver"? I assume not, but just checking.

borkdude18:02:36

currently there is no fine-grained way

borkdude18:02:56

you could however write a hook for it and transform the expression to something else

Noah Bogart18:02:22

here's a hook i wrote which does this:

(ns hooks.noahtheduke.splint.rules
  (:require
    [clj-kondo.hooks-api :as api]))

(defn defrule
  [{:keys [node]}]
  (let [[defrule rule-name & body] (:children node)
        new-node (api/list-node
                   (list* (with-meta (api/token-node 'def) (meta defrule))
                          (with-meta (api/token-node (symbol (name (api/sexpr rule-name))))
                                     (meta rule-name))
                          body))]
    {:node (with-meta new-node (meta node))}))

Noah Bogart18:02:17

given (defrule style/eq-nil ...), it'll be treated as (def eq-nil ...)

Noah Bogart18:02:27

this works for me because i have each defrule in separate files. if you need them to be in the same file, you could transform in some other way