From 852d7c3fd445071ae66165f8382e486fe3a8343f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20V=C3=A4is=C3=A4nen?= Date: Fri, 8 Sep 2023 09:04:10 +0300 Subject: [PATCH 1/3] Use clj-kondo `:seqable` for `:+`, `:*`, and `:?` not `{:op :rest}` Update clj-kondo type generation. `{:op :rest}` should be used only for varargs. ``` This can be used to match remaining arguments in vararg signatures. https://github.com/clj-kondo/clj-kondo/blob/master/doc/types.md ``` --- src/malli/clj_kondo.cljc | 6 +++--- test/malli/clj_kondo_test.cljc | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/malli/clj_kondo.cljc b/src/malli/clj_kondo.cljc index bc251ec99..a994db60b 100644 --- a/src/malli/clj_kondo.cljc +++ b/src/malli/clj_kondo.cljc @@ -124,9 +124,9 @@ (defmethod accept :qualified-symbol [_ _ _ _] :symbol) (defmethod accept :uuid [_ _ _ _] :any) ;;?? -(defmethod accept :+ [_ _ [child] _] {:op :rest, :spec child}) -(defmethod accept :* [_ _ [child] _] {:op :rest, :spec child}) -(defmethod accept :? [_ _ [child] _] {:op :rest, :spec child}) +(defmethod accept :+ [_ _ _ _] :seqable) +(defmethod accept :* [_ _ _ _] :seqable) +(defmethod accept :? [_ _ _ _] :seqable) (defmethod accept :repeat [_ _ [child] _] {:op :rest, :spec child}) (defmethod accept :cat [_ _ children _] children) (defmethod accept :catn [_ _ children _] (mapv last children)) diff --git a/test/malli/clj_kondo_test.cljc b/test/malli/clj_kondo_test.cljc index 9a3493eed..a80827509 100644 --- a/test/malli/clj_kondo_test.cljc +++ b/test/malli/clj_kondo_test.cljc @@ -40,6 +40,18 @@ (m/=> siren [:=> [:cat ifn? coll?] map?]) +(defn clj-kondo-issue-1922-1 [_x]) +(m/=> clj-kondo-issue-1922-1 + [:=> [:cat [:map [:keys [:+ :keyword]]]] :nil]) + +(defn clj-kondo-issue-1922-2 [_x]) +(m/=> clj-kondo-issue-1922-2 + [:=> [:cat [:map [:keys [:* :int]]]] :nil]) + +(defn clj-kondo-issue-1922-3 [_x]) +(m/=> clj-kondo-issue-1922-3 + [:=> [:cat [:map [:keys [:? :string]]]] :nil]) + (deftest clj-kondo-integration-test (is (= {:op :keys, @@ -63,11 +75,27 @@ {'kikka {:arities {1 {:args [:int], :ret :int}, - :varargs {:args [:int :int {:op :rest, :spec :int}], + :varargs {:args [:int :int :seqable], :ret :int, :min-arity 2}}} 'siren - {:arities {2 {:args [:ifn :coll], :ret :map}}}}}] + {:arities {2 {:args [:ifn :coll], :ret :map}}} + + 'clj-kondo-issue-1922-1 + {:arities {1 {:args [{:op :keys + :req {:keys :seqable}}] + :ret :nil}}} + + 'clj-kondo-issue-1922-2 + {:arities {1 {:args [{:op :keys + :req {:keys :seqable}}] + :ret :nil}}} + + 'clj-kondo-issue-1922-3 + {:arities {1 {:args [{:op :keys + :req {:keys :seqable}}] + :ret :nil}}}}}] + #?(:clj (is (= expected-out (-> 'malli.clj-kondo-test From 68d1a824df70b94b6a18093b9774684d35c096a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20V=C3=A4is=C3=A4nen?= Date: Fri, 22 Sep 2023 22:06:39 +0300 Subject: [PATCH 2/3] Pass arity as an option to `clj-kondo/transform` - use arity to decide whether to use `{:op :rest}` or `:seqable` --- src/malli/clj_kondo.cljc | 16 +++++++++++----- test/malli/clj_kondo_test.cljc | 23 ++++++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/malli/clj_kondo.cljc b/src/malli/clj_kondo.cljc index a994db60b..0e824fb37 100644 --- a/src/malli/clj_kondo.cljc +++ b/src/malli/clj_kondo.cljc @@ -124,10 +124,16 @@ (defmethod accept :qualified-symbol [_ _ _ _] :symbol) (defmethod accept :uuid [_ _ _ _] :any) ;;?? -(defmethod accept :+ [_ _ _ _] :seqable) -(defmethod accept :* [_ _ _ _] :seqable) -(defmethod accept :? [_ _ _ _] :seqable) -(defmethod accept :repeat [_ _ [child] _] {:op :rest, :spec child}) +(defn -seqable-or-rest [_ _ [child] {:keys [arity]}] + (if (= arity :varargs) + {:op :rest :spec child} + :seqable)) + +(defmethod accept :+ [_ _ children options] (-seqable-or-rest nil nil children options)) +(defmethod accept :* [_ _ children options] (-seqable-or-rest nil nil children options)) +(defmethod accept :? [_ _ children options] (-seqable-or-rest nil nil children options)) +(defmethod accept :repeat [_ _ children options] (-seqable-or-rest nil nil children options)) + (defmethod accept :cat [_ _ children _] children) (defmethod accept :catn [_ _ children _] (mapv last children)) (defmethod accept :alt [_ _ _ _] :any) ;;?? @@ -169,7 +175,7 @@ (reduce (fn [acc schema] (let [{:keys [input output arity min]} (m/-function-info schema) - args (transform input) + args (transform input {:arity arity}) ret (transform output)] (conj acc (cond-> {:ns ns-name :name name diff --git a/test/malli/clj_kondo_test.cljc b/test/malli/clj_kondo_test.cljc index a80827509..d08e895d2 100644 --- a/test/malli/clj_kondo_test.cljc +++ b/test/malli/clj_kondo_test.cljc @@ -52,6 +52,12 @@ (m/=> clj-kondo-issue-1922-3 [:=> [:cat [:map [:keys [:? :string]]]] :nil]) +(defn clj-kondo-issue-1922-4 [_x]) +(m/=> clj-kondo-issue-1922-4 + [:function + [:=> [:cat :int :int] :nil] + [:=> [:cat :int :int [:repeat :int]] :nil]]) + (deftest clj-kondo-integration-test (is (= {:op :keys, @@ -75,7 +81,7 @@ {'kikka {:arities {1 {:args [:int], :ret :int}, - :varargs {:args [:int :int :seqable], + :varargs {:args [:int :int {:op :rest :spec :int}], :ret :int, :min-arity 2}}} 'siren @@ -94,7 +100,14 @@ 'clj-kondo-issue-1922-3 {:arities {1 {:args [{:op :keys :req {:keys :seqable}}] - :ret :nil}}}}}] + :ret :nil}}} + + 'clj-kondo-issue-1922-4 + {:arities {2 {:args [:int :int] + :ret :nil} + :varargs {:args [:int :int {:op :rest :spec :int}] + :ret :nil + :min-arity 2}}}}}] #?(:clj (is (= expected-out @@ -110,11 +123,11 @@ (clj-kondo/linter-config) (get-in [:linters :type-mismatch :namespaces])))))) (testing "sequential elements" - (is (= {:op :rest :spec :int} + (is (= :seqable (clj-kondo/transform [:repeat :int]))) - (is (= {:op :rest :spec {:op :keys :req {:price :int}}} + (is (= :seqable (clj-kondo/transform [:repeat [:map [:price :int]]]))) - (is (= {:op :rest :spec [:int]} + (is (= :seqable (clj-kondo/transform [:repeat [:tuple :int]])))) (testing "regular expressions" From c35d44e5924e10c03f431c4c2cd4aa79c6785b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20V=C3=A4is=C3=A4nen?= Date: Sat, 23 Sep 2023 10:02:47 +0300 Subject: [PATCH 3/3] Update `-seqable-or-rest` arg list no need to match accept argument signature use only children and opts. --- src/malli/clj_kondo.cljc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/malli/clj_kondo.cljc b/src/malli/clj_kondo.cljc index 0e824fb37..102dbdbe3 100644 --- a/src/malli/clj_kondo.cljc +++ b/src/malli/clj_kondo.cljc @@ -124,15 +124,15 @@ (defmethod accept :qualified-symbol [_ _ _ _] :symbol) (defmethod accept :uuid [_ _ _ _] :any) ;;?? -(defn -seqable-or-rest [_ _ [child] {:keys [arity]}] +(defn -seqable-or-rest [[child] {:keys [arity]}] (if (= arity :varargs) {:op :rest :spec child} :seqable)) -(defmethod accept :+ [_ _ children options] (-seqable-or-rest nil nil children options)) -(defmethod accept :* [_ _ children options] (-seqable-or-rest nil nil children options)) -(defmethod accept :? [_ _ children options] (-seqable-or-rest nil nil children options)) -(defmethod accept :repeat [_ _ children options] (-seqable-or-rest nil nil children options)) +(defmethod accept :+ [_ _ children options] (-seqable-or-rest children options)) +(defmethod accept :* [_ _ children options] (-seqable-or-rest children options)) +(defmethod accept :? [_ _ children options] (-seqable-or-rest children options)) +(defmethod accept :repeat [_ _ children options] (-seqable-or-rest children options)) (defmethod accept :cat [_ _ children _] children) (defmethod accept :catn [_ _ children _] (mapv last children))