diff --git a/src/marginalia/parser.clj b/src/marginalia/parser.clj index 40f9b522a..9c116c7e7 100644 --- a/src/marginalia/parser.clj +++ b/src/marginalia/parser.clj @@ -281,10 +281,17 @@ (defmethod dispatch-form 'defprotocol [form raw nspace-sym] - (let [[ds r s] (extract-common-docstring form raw nspace-sym)] - (let [internal-dses (if ds - (extract-internal-docstrings (nthnext form 3)) - (extract-internal-docstrings (nthnext form 2)))] + (let [[ds r s] (extract-common-docstring form raw nspace-sym) + ;; Clojure 1.10 added `:extend-via-metadata` to the `defprotocol` macro. + ;; If the flag is present, `extract-internal-docstrings` needs to start + ;; 2 forms later, to account for the presence of a keyword, + ;; `:extend-via-metadata` and a boolean `true` in the macro body. + evm (contains? (set form) :extend-via-metadata)] + (let [internal-dses (cond + (and evm ds) (extract-internal-docstrings (nthnext form 5)) + evm (extract-internal-docstrings (nthnext form 4)) + ds (extract-internal-docstrings (nthnext form 3)) + :else (extract-internal-docstrings (nthnext form 2)))] (with-meta [ds r s] {:internal-docstrings internal-dses})))) diff --git a/test/marginalia/test/parse.clj b/test/marginalia/test/parse.clj index 627255734..bbed903d5 100644 --- a/test/marginalia/test/parse.clj +++ b/test/marginalia/test/parse.clj @@ -11,6 +11,8 @@ (is (= (count (marginalia.parser/parse "(ns test)\n\"some string\"")) 1)) (is (= (count (marginalia.parser/parse "(ns test (:require [marginalia.parser :as parser]))\n(defn foo [] ::parser/foo)")) 1))) +(deftest extend-via-metadata + (is (marginalia.parser/parse "(ns test)\n(defprotocol Foo \"Does a Foo\" :extend-via-metadata true (do-foo! [_ opts] \"Foo!\"))"))) (def simple-fn "(defn some-fn