lsp 2024-09-04

funny thing i've noticed: symbols that match clojure.core functions but end in * aren't marked as errors. given:

(ns lazytest.malli)

run!*

foo*

foo
clj-kondo and clojure-lsp differ with their reported errors:
noah@Noahs-MacBook-Pro ~/personal/lazytest  [master ≡ +0 ~2 -0 !]
$ clj-kondo --lint src
src/clojure/lazytest/malli.clj:3:1: error: Unresolved symbol: run!*
src/clojure/lazytest/malli.clj:5:1: error: Unresolved symbol: foo*
src/clojure/lazytest/malli.clj:7:1: error: Unresolved symbol: foo
linting took 76ms, errors: 3, warnings: 0

noah@Noahs-MacBook-Pro ~/personal/lazytest  [master ≡ +0 ~2 -0 !]
$ clojure-lsp diagnostics
[ 99%] Project analyzed            Finding diagnostics...
src/clojure/lazytest/malli.clj:5:1: error: [unresolved-symbol] Unresolved symbol: foo*
src/clojure/lazytest/malli.clj:7:1: error: [unresolved-symbol] Unresolved symbol: foo

yeah that's weird 😂 we rely on clj-kondo findings for that, maybe some bug in the api? any thoughts @borkdude?

this might be a leftover from the array notation thingie... let me check

are you using the newest clj-kondo?

I guess lsp is behind

$ clojure-lsp --version
clojure-lsp 2024.08.05-18.16.00
clj-kondo 2024.08.01

"is there a way to run the newest clj-kondo with lsp"? yes

yeah, i've set it up in the past, just don't have it configured right now

i don't mind, i run both clj-kondo and clojure-lsp in my CI, just noticed in my editor this wasn't getting flagged

Just pushed this bump to clojure-lsp, should be a #clojure-lsp-builds nightly build soon

@nbtheduke any reason why not use in your CI clojure-lsp diagnostics ?

we are using for all Nubank services and it works great

(it adds the option to have clj-depend and other custom linters as well)

btw @ericdallo can you bump to the latest master commit if you haven't? I fixed a post-release bug in there

Is there a way to somehow ignore the callers from the test namespaces? I would like to get rid of the unused functions, but if the functions are covered, then those functions are excluded from the list.

✅ 1

AFAICS the current implementation marks all the defs in all the test namespaces as unused

👀 1

Because only test namespaces are referring to test defined functions and defs

So I believe there the test references should not be excluded

gotcha, I was able to create a test scenario for this 😉 I'll have a look at it tomorrow, thanks for reporting it!

👍 1
🙏 1

Merged, @ikaraszi could you test a nightly build later #clojure-lsp-builds and confirm it fixed for you?

Thank you, I’ll try it. I didn’t have performance issues, so I can only test the functionality

So the string/includes? vs string/ends_with? was the culprit?

AFAICS this wont support cljs, right?

@andreribeirocamargo may have it, I don't remember exactly how we repro the problem when we found the regression, we should have commented on the issue

Hello, it was taking longer on some big internal Nubank projects. I'll have a look at this again and let's see how it goes.

👍 1

> So the string/includes? vs string/ends_with? was the culprit? no, the first algorithm is more resource-intensive than the new one. > AFAICS this wont support cljs, right? yes, it won't. is this an issue for you?

> yes, it won’t. is this an issue for you? That is not an issue for me, just thought it is worth to mention

Anyhow, I’ll give it a try

@andreribeirocamargo remember to update all-available-settings.edn

What should I change there? There's no :clojure-lsp/unused-public-var linter configuration there 🤔

hum, true, that only applies for clojure-lsp settings, nvm

I wonder if we should move this setting to clojure-lsp settings itself... as there are other features that need to know if file is a test, the code lens for example to know if show a reference as a test or not

I like the idea, let's think more about this

I've made some changes to the PR in order to implement this vision

👍 1

I can modify the settings and set the :source-paths to #{"src"}, but I was thinking a more convenient way to do this

https://clojure-lsp.io/settings/#clojure-lspunused-public-var You can use :exclude-when-defined-by or maybe :exclude

the main issue is: there is no canonical way to know if a function is using in a test, we can only infer that

Yes, I understand that part. So I could do:

:exclude-regex #{"my-ns/.*-test$"}

Yeah, I guess Maybe we could have a option for that since we already infer those for code lens

That would be great

Please create a issue so I can prioritize and discuss further more

Thanks, doing it now

But this should work, right?

:clojure-lsp/unused-public-var {:level :warning
                                :exclude #{dev}
                                :exclude-regex #{".*?-test$"}}

Not sure about the regex, but looks correct

I added the ? to turn off the greediness but I could not get it working

I didn't get that ? , shouldn't you use ".*-test$" to exclude everything that ends with -test ?

I tried that as well, didn’t work.

But I can try it again tomorrow

It works like a charm! Thank you very much! 🙏

👍 1

(re-matches #".*-test$" "foo.bar.something-test")
;; => "foo.bar.something-test"
user> (re-matches #".*?-test$" "foo.bar.something-test")
;; => "foo.bar.something-test"

both of them are matching, but I’ll try to modify my config

This is what I have in my .clj-kondo/config.edn:

:clojure-lsp/unused-public-var {:level :warning
                                :exclude #{dev}
                                :exclude-regex #{"metric.*-test.*"}}

Okay, I believe I misunderstood the intention of the :exclude, it excludes the warnings in these namespaces, and not as I thought excludes the namespaces from the callers list.

Then this is definitely a missing feature, I cannot have a workaround with a regex

Ah you are right, it's a different concept, maybe the flag should be: :disconsider-test-usages

or maybe we can flip the logic by saying :include-tests false and per default it is true?

but still it is orthogonal to the other exclude, so probably not the best choice

👍 1

I don't wanna change the default right now as there are lots of clients using this linter, but in the future it may be a good idea

naming is hard, gosh

:ignore-tests true?

or similar to your suggestion: :disregard-test-usages true

“disconsider” is a rarely used word, probably that’s why it’s sounds strange to me

👍 1

@ericdallo are you planning to bring back this feature?

sorry, what's the problem again?

You know that you implemented an exclusion solution so references only by test namespaces did not show as usages

And with this feature somebody could remove unused functions that only called from tests

You needed to remove this feature in a later release because of a performance regression

Ah right, I lost your comment about reopening the issue, we still need to check how to implement it without losing performance

Can I help in any ways?

well, you could try to re-implement https://github.com/clojure-lsp/clojure-lsp/commit/0f81895571bb1fb6fe77ca5746241942b17ab9d4 but try to improve the performance, unfortunately I don't have the answer on how to do it

yes, maybe you could do a perf flamegraph to understand what is taking so long

Yes, I’ll have time today. Thank you very much guys!

Something is still off with:

clojure-lsp 2025.04.01-20.27.48-nightly
clj-kondo 2025.02.21-SNAPSHOT

My take is: the namespace metric.test-fixtures doesn't follow https://guide.clojure.style/#test-ns-naming of having a suffix -test, so Clojure-LSP is considering that code as application code. I'd rather suggest you to change :test-locations-regex in .lsp/config.edn from #{"_test\.clj[a-z]?$"} to #{"/test/metric/"} . This change will make Clojure-LSP to consider all files with "/test/metric/" in their path as test code. Ideally, you'd tailor the :test-locations-regex to reflect where the tests live (it's a Clojure set, you can have multiple regexes). Give it a try on this and let me know how it goes 😉

Because that is a helper namespace that does not contain tests just functions that can be used in tests, but it is under the test folder. I’ll test the :test-locations-regex as you suggested.

I believe it works! 🎉

Awesome! Clojure doesn't differentiate application from test code. That's why we have this convention of appending -test to test namespaces and functions. This also prevents clashing tests with application code. So Clojure-LSP relies on :test-locations-regex to understand what is test and what is not.

do you have a repro?