diff --git a/src/malli/clj_kondo.cljc b/src/malli/clj_kondo.cljc index bc251ec99..102dbdbe3 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 :+ [_ _ [child] _] {:op :rest, :spec child}) -(defmethod accept :* [_ _ [child] _] {:op :rest, :spec child}) -(defmethod accept :? [_ _ [child] _] {:op :rest, :spec child}) -(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 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)) (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 9a3493eed..d08e895d2 100644 --- a/test/malli/clj_kondo_test.cljc +++ b/test/malli/clj_kondo_test.cljc @@ -40,6 +40,24 @@ (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]) + +(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, @@ -63,11 +81,34 @@ {'kikka {:arities {1 {:args [:int], :ret :int}, - :varargs {:args [:int :int {:op :rest, :spec :int}], + :varargs {:args [:int :int {:op :rest :spec :int}], :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-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 (-> 'malli.clj-kondo-test @@ -82,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"