Nice trick, you can tweak linter settings per language in a .cljc
file by using conditionals:
(ns clj-kondo-cljs-macros.ns2.ns
#?(:clj {:clj-kondo/config '{:linters {:unused-binding {:level :off}}}}))
(defn foo [x y]
#?(:cljs x))
If anyone feels like adding clj-kondo to this page: https://analysis-tools.dev/tag/clojure, go ahead
Are these warnings wrong? If so, I can create an issue.
I get the following warnings:
src/main_ns.cljc:3:14: warning: namespace required-ns is required but never used
src/main_ns.cljc:5:17: warning: Unused private var main-ns/my-fun
The macro expansion has a use of my-fun
and a use of the r
alias, so I don’t think there should be any warnings.Can you please post the code as text? This is easier for me to try out
Sure, give me a sec.
Either look at https://github.com/simon-katz/nomis-clj-kondo-cljc-macros-2 Or:
(ns required-ns)
(defn foo [] 42)
(ns main-ns
#?(:cljs (:require-macros [main-ns :refer [my-macro]]))
(:require [required-ns :as r]))
(defn ^:private my-fun [x]
(inc x))
#?(:clj
(defmacro my-macro []
`(my-fun (r/foo))))
I already see the problem. You are only using required-ns
in Clojure. So why not wrap that in a #?(:clj ...)
No wait, let me take another look ;)
The expansion of the macro uses the req…. Oh, OK, I’ll wait 🙂
If I run (my-macro)
, I get a result of 43
in both CLJ and CLJS, so I’m pretty sure that both my-fun
and r/foo
are used in both CLJ and CLJS.
@nomiskatz It's an interesting edge case fore sure. You can fix it with a local config:
(ns main-ns
{:clj-kondo/config '{:linters {:unused-private-var {:exclude [main-ns/my-fun]}
:unused-namespace {:exclude [required-ns]}}}}
#?(:cljs (:require-macros [main-ns :refer [my-macro]]))
(:require [required-ns :as r]))
And feel free to post this edge case as an issue.I'm not sure if this is fixable since it depends on runtime usage of the macro if the namespace + private var will be really used.
@borkdude Thanks for confirming, and for the workaround. I’ll post an issue, but I understand why it might be a tough one.