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

Cursive cannot resolve methods from defprotocol that has both :extend-via-metadata true and docstring if docstring is not first in defprotocol #2429

Open
jffry opened this issue Sep 12, 2020 · 0 comments

Comments

@jffry
Copy link

jffry commented Sep 12, 2020

For defprotocols with both :extend-via-metadata true and a docstring, Cursive fails to parse when the docstring comes after the other options for the defprotocol.

I was initially a little confused becuase the docs for defprotocol do make it seem like the docstring should come first, but the implementation is written to acommodate either order and I've found docstring-after in the wild (for example, here in next.jdbc)

(defmacro defprotocol 
  "A protocol is a named set of named methods and their signatures:
  (defprotocol AProtocolName

    ;optional doc string
    "A doc string for AProtocol abstraction"

   ;options
   :extend-via-metadata true

  ;method signatures
    (bar [this a b] "bar docs")
    (baz [this a] [this a b] [this a b c] "baz docs"))
  ..." ,,,)

Environment

  • IntelliJ IDEA: 2020.2.1
  • Cursive: 1.9.4-eap3-2020.2

Steps to reproduce

Add this to any namespace and edit with Cursive:

;; Docstring AFTER other deprotocol options = sad cursive
(defprotocol ProtocolAfter
  :extend-via-metadata true
  "docstring is after options"
  (demo-after [this]))
(defrecord RecordAfter []
  ProtocolAfter
  (demo-after [this] "broken"))

(println "demo-after record:" (demo-after (RecordAfter.)))
(let [o (with-meta {} {`demo-after (constantly "also broken")})]
  (println "demo-after with-meta:" (demo-after o)))

;; Docstring BEFORE other deprotocol options = just fine
(defprotocol ProtocolBefore
  "docstring is before options"
  :extend-via-metadata true
  (demo-before [this]))
(defrecord RecordBefore []
  ProtocolBefore
  (demo-before [this] "working"))

(println "demo-before record:" (demo-before (RecordBefore.)))
(let [o (with-meta {} {`demo-before (constantly "also working")})]
  (println "demo-before with-meta:" (demo-before o)))

Load and evaluate the NS in your REPL just to make sure that the metadata extension is functioning as expected:

demo-after record: broken
demo-after with-meta: also broken
demo-before record: working
demo-before with-meta: also working

See that Cursive is not resolving the first protocol, which was defined with a docstring after :extend-via-metadata true

image

Expected behavior

Cursive can understand defprotocols regardless of whether the docstring comes before or after :extend-via-metadata true.

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

1 participant