Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:extend-via-metadata in protocols breaks Marginalia #176

Open
eigenhombre opened this issue Feb 24, 2021 · 3 comments
Open

:extend-via-metadata in protocols breaks Marginalia #176

eigenhombre opened this issue Feb 24, 2021 · 3 comments

Comments

@eigenhombre
Copy link

(ns broke.core
  (:require [marginalia.core :as m]))

(defprotocol Foo
  :extend-via-metadata true
  (baz [_] :foobaz))

(m/run-marginalia [])

this throws

2. Unhandled clojure.lang.Compiler$CompilerException
   Error compiling /tmp/broke/src/broke/core.clj at (8:1)
   #:clojure.error{:phase :compile-syntax-check,
                   :line 8,
                   :column 1,
                   :source "/tmp/broke/src/broke/core.clj"}
             Compiler.java: 7648  clojure.lang.Compiler/load
                      REPL:    1  broke.core/eval15444
                      REPL:    1  broke.core/eval15444
             Compiler.java: 7177  clojure.lang.Compiler/eval
             Compiler.java: 7132  clojure.lang.Compiler/eval
                  core.clj: 3214  clojure.core/eval
                  core.clj: 3210  clojure.core/eval
    interruptible_eval.clj:   82  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  665  clojure.core/apply
                  core.clj: 1973  clojure.core/with-bindings*
                  core.clj: 1973  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   82  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  437  clojure.main/repl/read-eval-print
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  458  clojure.main/repl
                  main.clj:  368  clojure.main/repl
               RestFn.java:  137  clojure.lang.RestFn/applyTo
                  core.clj:  665  clojure.core/apply
                  core.clj:  660  clojure.core/apply
                regrow.clj:   20  refactor-nrepl.ns.slam.hound.regrow/wrap-clojure-repl/fn
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   79  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  145  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  202  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  201  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  748  java.lang.Thread/run

1. Caused by java.lang.IllegalArgumentException
   Don't know how to create ISeq from: clojure.lang.Keyword

                   RT.java:  557  clojure.lang.RT/seqFrom
                   RT.java:  537  clojure.lang.RT/seq
                   RT.java:  723  clojure.lang.RT/more
                  core.clj:   73  clojure.core/rest
                  core.clj:   73  clojure.core/rest
                parser.clj:  238  marginalia.parser/extract-impl-docstring
                parser.clj:  236  marginalia.parser/extract-impl-docstring
                parser.clj:  242  marginalia.parser/extract-internal-docstrings/fn
                  core.clj: 2755  clojure.core/map/fn
              LazySeq.java:   42  clojure.lang.LazySeq/sval
              LazySeq.java:   51  clojure.lang.LazySeq/seq
                   RT.java:  535  clojure.lang.RT/seq
                  core.clj:  137  clojure.core/seq
                  core.clj:  660  clojure.core/apply
                  core.clj: 2783  clojure.core/mapcat
                  core.clj: 2783  clojure.core/mapcat
               RestFn.java:  423  clojure.lang.RestFn/invoke
                parser.clj:  242  marginalia.parser/extract-internal-docstrings
                parser.clj:  240  marginalia.parser/extract-internal-docstrings
                parser.clj:  250  marginalia.parser/eval13366/fn
              MultiFn.java:  239  clojure.lang.MultiFn/invoke
                parser.clj:  315  marginalia.parser/extract-docstring
                parser.clj:  312  marginalia.parser/extract-docstring
                parser.clj:  378  marginalia.parser/arrange-in-sections
                parser.clj:  337  marginalia.parser/arrange-in-sections
                parser.clj:  399  marginalia.parser/parse
                parser.clj:  387  marginalia.parser/parse
                parser.clj:  425  marginalia.parser/parse-file
                parser.clj:  422  marginalia.parser/parse-file
                  core.clj:  177  marginalia.core/path-to-doc
                  core.clj:  175  marginalia.core/path-to-doc
                  core.clj: 2753  clojure.core/map/fn
              LazySeq.java:   42  clojure.lang.LazySeq/sval
              LazySeq.java:   51  clojure.lang.LazySeq/seq
                   RT.java:  535  clojure.lang.RT/seq
                  core.clj:  137  clojure.core/seq
                  core.clj: 2746  clojure.core/map/fn
              LazySeq.java:   42  clojure.lang.LazySeq/sval
              LazySeq.java:   51  clojure.lang.LazySeq/seq
                   RT.java:  535  clojure.lang.RT/seq
                  core.clj:  137  clojure.core/seq
                  core.clj: 2746  clojure.core/map/fn
              LazySeq.java:   42  clojure.lang.LazySeq/sval
              LazySeq.java:   51  clojure.lang.LazySeq/seq
                   RT.java:  535  clojure.lang.RT/seq
                  core.clj:  137  clojure.core/seq
                  core.clj:  660  clojure.core/apply
                  core.clj:  660  clojure.core/apply
                hiccup.clj:   99  marginalia.hiccup/eval12872/fn
              MultiFn.java:  229  clojure.lang.MultiFn/invoke
                  Var.java:  384  clojure.lang.Var/invoke
                  html.clj:  198  marginalia.html/toc-html
                  html.clj:  197  marginalia.html/toc-html
                  html.clj:  409  marginalia.html/uberdoc-html
                  html.clj:  401  marginalia.html/uberdoc-html
                  core.clj:  206  marginalia.core/uberdoc!
                  core.clj:  196  marginalia.core/uberdoc!
                  core.clj:  311  marginalia.core/run-marginalia
                  core.clj:  248  marginalia.core/run-marginalia
               RestFn.java:  410  clojure.lang.RestFn/invoke
                  core.clj:    8  broke.core/eval15486
                  core.clj:    8  broke.core/eval15486
             Compiler.java: 7177  clojure.lang.Compiler/eval
             Compiler.java: 7636  clojure.lang.Compiler/load
                      REPL:    1  broke.core/eval15444
                      REPL:    1  broke.core/eval15444
             Compiler.java: 7177  clojure.lang.Compiler/eval
             Compiler.java: 7132  clojure.lang.Compiler/eval
                  core.clj: 3214  clojure.core/eval
                  core.clj: 3210  clojure.core/eval
    interruptible_eval.clj:   82  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  665  clojure.core/apply
                  core.clj: 1973  clojure.core/with-bindings*
                  core.clj: 1973  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   82  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  437  clojure.main/repl/read-eval-print
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  458  clojure.main/repl
                  main.clj:  368  clojure.main/repl
               RestFn.java:  137  clojure.lang.RestFn/applyTo
                  core.clj:  665  clojure.core/apply
                  core.clj:  660  clojure.core/apply
                regrow.clj:   20  refactor-nrepl.ns.slam.hound.regrow/wrap-clojure-repl/fn
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   79  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  145  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  202  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  201  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  748  java.lang.Thread/run

Without :extend-via-metadata (added in Clojure 1.10), it works fine.

@ALai57
Copy link
Contributor

ALai57 commented Oct 18, 2022

@eigenhombre Ever find a solution for this one? Just stumbled across it, and I'm hitting the same issue.

@ALai57
Copy link
Contributor

ALai57 commented Oct 18, 2022

Seems like you can override the parser/dispatch-form multimethod for 'defprotocol, so maybe I'll do that and submit a PR

@ALai57
Copy link
Contributor

ALai57 commented Oct 18, 2022

  (require '[marginalia.parser :as p])

;; Override the existing multimethod - proposal for a new multimethod that works with `:extend-via-metadata`
  (defmethod p/dispatch-form 'defprotocol
    [form raw nspace-sym]
    (let [[ds r s] (#'p/extract-common-docstring form raw nspace-sym)
          ewm      (contains? (set form) :extend-via-metadata)]
      (let [internal-dses (cond
                         ;; Sharp quotes because I was working outside of the parser ns, and the var is private
                            (and ewm ds) (#'p/extract-internal-docstrings (nthnext form 5))
                            ewm          (#'p/extract-internal-docstrings (nthnext form 4))
                            ds           (#'p/extract-internal-docstrings (nthnext form 3))
                            :else        (#'p/extract-internal-docstrings (nthnext form 2)))]
        (with-meta
          [ds r s]
          {:internal-docstrings internal-dses}))))

;; A test example proving it works
  (ns broke.core)

  (def broken-string
    "(defprotocol Foo
    \"Does a Foo\"
    :extend-via-metadata true
    (do-foo! [_ opts] \"Foo!\"))")

  (p/dispatch-form (read-string broken-string)
                   broken-string
                   'broke.core)
  ;; => ["Does a Foo"
  ;;     "(defprotocol Foo\n    :extend-via-metadata true\n    (do-foo! [_ opts] \"Foo!\"))"
  ;;     broke.core]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants