Skip to content

Commit d0dda30

Browse files
authored
info and eldoc ops: accept a Compliment-style context parameter (#815)
Fixes #812
1 parent 0756b2a commit d0dda30

File tree

8 files changed

+183
-106
lines changed

8 files changed

+183
-106
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ out
1111
*.class
1212
.cljs_nashorn_repl
1313
.inline-deps
14+
.no-pedantic
1415
.lein-deps-sum
1516
.lein-failures
1617
.lein-plugins
1718
.lein-repl-history
1819
.nrepl-port
1920
.source-deps
2021
.clj-kondo/.cache
22+
/.no-mranderson

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
* `info` and `eldoc` ops: also return `:doc-fragments`, `:doc-first-sentence-fragments`, `:doc-first-sentence-fragments` attributes when available.
88
* These are explained in https://github.com/clojure-emacs/orchard/blob/v0.15.0/src-newer-jdks/orchard/java/parser_next.clj#L2-L20
99
* These typically are only available when running a modern JDK through enrich-classpath.
10+
* `info` and `eldoc` ops: accept a Compliment-style `context` parameter that helps infering the Java class of the object being queried.
1011
* Bump `orchard` to [1.5.0](https://github.com/clojure-emacs/orchard/blob/v0.15.0/CHANGELOG.md#0150-2023-09-20).
11-
* Bump `compliment` to [0.4.2](https://github.com/alexander-yakushev/compliment/blob/f7d872d/CHANGELOG.md#042-2023-09-17).
12+
* Bump `compliment` to [0.4.3](https://github.com/alexander-yakushev/compliment/blob/0.4.3/CHANGELOG.md#043-2023-09-21).
1213

1314
## 0.37.1 (2023-09-08)
1415

Makefile

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ test/resources/cider/nrepl/clojuredocs/export.edn:
1919
dump-version:
2020
echo '"$(PROJECT_VERSION)"' > resources/cider/nrepl/version.edn
2121

22-
.inline-deps: dump-version clean
23-
lein with-profile -user,-dev,+mranderson inline-deps
24-
touch .inline-deps
25-
26-
inline-deps: .inline-deps
22+
.inline-deps: project.clj clean
23+
rm -f .no-mranderson
24+
lein with-profile -user,-dev inline-deps
25+
touch $@
2726

2827
test: clean .inline-deps test/resources/cider/nrepl/clojuredocs/export.edn
29-
lein with-profile -user,-dev,+$(CLOJURE_VERSION),+test,+mranderson,+plugin.mranderson/config test
28+
rm -f .no-mranderson
29+
lein with-profile -user,-dev,+$(CLOJURE_VERSION),+test,+plugin.mranderson/config test
3030

3131
quick-test: clean
3232
lein with-profile -user,-dev,+$(CLOJURE_VERSION),+test test
@@ -44,33 +44,42 @@ cljfmt:
4444

4545
.make_kondo_prep: project.clj .clj-kondo/config.edn
4646
touch .no-pedantic
47+
touch .no-mranderson
4748
lein with-profile -user,-dev,+test,+clj-kondo,+deploy,+$(CLOJURE_VERSION) clj-kondo --copy-configs --dependencies --lint '$$classpath' > $@
48-
rm .no-pedantic
49+
rm -f .no-pedantic
50+
rm -f .no-mranderson
4951

5052
kondo: .make_kondo_prep clean
5153
touch .no-pedantic
54+
touch .no-mranderson
5255
lein with-profile -user,-dev,+test,+clj-kondo,+deploy,+$(CLOJURE_VERSION) clj-kondo
53-
rm .no-pedantic
56+
rm -f .no-pedantic
57+
rm -f .no-mranderson
5458

5559
# A variation that does not analyze the classpath, as it OOMs otherwise on CircleCI.
5660
light-kondo: clean
5761
touch .no-pedantic
62+
touch .no-mranderson
5863
lein with-profile -user,-dev,+test,+clj-kondo,+deploy,+$(CLOJURE_VERSION) clj-kondo
59-
rm .no-pedantic
64+
rm -f .no-pedantic
65+
rm -f .no-mranderson
6066

6167
lint: kondo cljfmt eastwood
6268

6369
# PROJECT_VERSION=0.37.1 make install
64-
install: check-install-env .inline-deps
70+
install: dump-version check-install-env .inline-deps
71+
rm -f .no-mranderson
6572
touch .no-pedantic
66-
lein with-profile -user,-dev,+$(CLOJURE_VERSION),+mranderson,+plugin.mranderson/config install
73+
lein with-profile -user,-dev,+$(CLOJURE_VERSION),+plugin.mranderson/config install
6774
touch .no-pedantic
6875
make clean
76+
git checkout resources/cider/nrepl/version.edn
6977

7078
# PROJECT_VERSION=0.37.1 make fast-install
7179
fast-install: dump-version check-install-env
7280
lein with-profile -user,-dev,+$(CLOJURE_VERSION) install
7381
make clean
82+
git checkout resources/cider/nrepl/version.edn
7483

7584
smoketest: install
7685
cd test/smoketest && \
@@ -87,7 +96,8 @@ detect_timeout:
8796
# Deployment is performed via CI by creating a git tag prefixed with "v".
8897
# Please do not deploy locally as it skips various measures (particularly around mranderson).
8998
deploy: check-env .inline-deps
90-
lein with-profile -user,+$(CLOJURE_VERSION),+mranderson,+plugin.mranderson/config deploy clojars
99+
rm -f .no-mranderson
100+
lein with-profile -user,+$(CLOJURE_VERSION),+plugin.mranderson/config deploy clojars
91101

92102
check-env:
93103
ifndef CLOJARS_USERNAME
@@ -109,7 +119,6 @@ clean:
109119
lein with-profile -user clean
110120
cd test/smoketest && lein with-profile -user clean
111121
rm -f .inline-deps
112-
git checkout resources/cider/nrepl/version.edn
113122

114123
# Create and cache a `java` command. project.clj is mandatory; the others are optional but are taken into account for cache recomputation.
115124
# It's important not to silence with step with @ syntax, so that Enrich progress can be seen as it resolves dependencies.

doc/modules/ROOT/pages/nrepl-api/ops.adoc

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,13 +306,20 @@ Returns::
306306
Return a map of information about the specified symbol.
307307

308308
Required parameters::
309+
{blank}
310+
311+
Optional parameters::
312+
* `:class` A Java class. If ``:ns`` is passed, it will be used for fully-qualifiying the class, if necessary.
313+
* `:context` A Compliment completion context, just like the ones already passed for the "complete" op,
314+
with the difference that the symbol at point should be entirely replaced by "\__prefix__".
315+
316+
For Java interop queries, it helps inferring the precise type of the object the ``:sym`` or ``:member`` refers to,
317+
making the results more accurate (and less numerous).
318+
* `:member` A Java class member.
309319
* `:ns` The current namespace
310320
* `:sym` The symbol to lookup
311321

312322

313-
Optional parameters::
314-
{blank}
315-
316323
Returns::
317324
* `:doc-block-tags-fragments` May be absent. Represent the 'param', 'returns' and 'throws' sections a Java doc comment. It's a vector of fragments, where fragment is a map with ``:type`` ('text' or 'html') and ``:content`` plain text or html markup, respectively
318325
* `:doc-first-sentence-fragments` May be absent. Represents the first sentence of a Java doc comment. It's a vector of fragments, where fragment is a map with ``:type`` ('text' or 'html') and ``:content`` plain text or html markup, respectively
@@ -434,13 +441,20 @@ Returns::
434441
Return a map of information about the specified symbol.
435442

436443
Required parameters::
444+
{blank}
445+
446+
Optional parameters::
447+
* `:class` A Java class. If ``:ns`` is passed, it will be used for fully-qualifiying the class, if necessary.
448+
* `:context` A Compliment completion context, just like the ones already passed for the "complete" op,
449+
with the difference that the symbol at point should be entirely replaced by "\__prefix__".
450+
451+
For Java interop queries, it helps inferring the precise type of the object the ``:sym`` or ``:member`` refers to,
452+
making the results more accurate (and less numerous).
453+
* `:member` A Java class member.
437454
* `:ns` The current namespace
438455
* `:sym` The symbol to lookup
439456

440457

441-
Optional parameters::
442-
{blank}
443-
444458
Returns::
445459
* `:doc-block-tags-fragments` May be absent. Represent the 'param', 'returns' and 'throws' sections a Java doc comment. It's a vector of fragments, where fragment is a map with ``:type`` ('text' or 'html') and ``:content`` plain text or html markup, respectively
446460
* `:doc-first-sentence-fragments` May be absent. Represents the first sentence of a Java doc comment. It's a vector of fragments, where fragment is a map with ``:type`` ('text' or 'html') and ``:content`` plain text or html markup, respectively

project.clj

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
^:inline-dep [thunknyc/profile "0.5.2"]
1414
^:inline-dep [mvxcvi/puget "1.3.4"]
1515
^:inline-dep [fipp ~fipp-version] ; can be removed in unresolved-tree mode
16-
^:inline-dep [compliment "0.4.2"]
16+
^:inline-dep [compliment "0.4.3"]
1717
^:inline-dep [org.rksm/suitable "0.5.0" :exclusions [org.clojure/clojurescript]]
1818
^:inline-dep [cljfmt "0.9.2" :exclusions [org.clojure/clojurescript]]
1919
^:inline-dep [org.clojure/tools.namespace "1.3.0"]
@@ -28,6 +28,17 @@
2828
;; :pedantic? can be problematic for certain local dev workflows:
2929
false)
3030

31+
;; mranderson cannot be put in a profile (as the other plugins),
32+
;; so we conditionally disable it, because otherwise clj-kondo cannot run.
33+
:plugins ~(if (-> ".no-mranderson" java.io.File. .exists)
34+
[]
35+
'[[thomasa/mranderson "0.5.4-SNAPSHOT"]])
36+
37+
:mranderson {:project-prefix "cider.nrepl.inlined.deps"
38+
:overrides {[mvxcvi/puget fipp] [fipp ~fipp-version]} ; only takes effect in unresolved-tree mode
39+
:expositions [[mvxcvi/puget fipp]] ; only takes effect unresolved-tree mode
40+
:unresolved-tree false}
41+
3142
:filespecs [{:type :bytes :path "cider/cider-nrepl/project.clj" :bytes ~(slurp "project.clj")}]
3243

3344
:source-paths ["src"]
@@ -45,7 +56,9 @@
4556
true))))
4657
:debugger :debugger}
4758

48-
:aliases {"docs" ["with-profile" "+maint" "run" "-m" "cider.nrepl.impl.docs" "--file"
59+
:aliases {"bump-version" ["change" "version" "leiningen.release/bump-version"]
60+
"mranderson" ["with-profile" "+plugin.mranderson/config"]
61+
"docs" ["with-profile" "+maint" "run" "-m" "cider.nrepl.impl.docs" "--file"
4962
~(clojure.java.io/as-relative-path
5063
(clojure.java.io/file "doc" "modules" "ROOT" "pages" "nrepl-api" "ops.adoc"))]}
5164

@@ -71,12 +84,6 @@
7184
[com.google.code.findbugs/jsr305 "3.0.2"]]
7285
:test-paths ["test/spec"]}
7386

74-
:mranderson {:plugins [[thomasa/mranderson "0.5.4-SNAPSHOT"]]
75-
:mranderson {:project-prefix "cider.nrepl.inlined.deps"
76-
:overrides {[mvxcvi/puget fipp] [fipp ~fipp-version]} ;; only takes effect in unresolved-tree mode
77-
:expositions [[mvxcvi/puget fipp]] ;; only takes effect unresolved-tree mode
78-
:unresolved-tree false}}
79-
8087
:1.8 {:dependencies [[org.clojure/clojure "1.8.0"]
8188
[org.clojure/clojurescript "1.10.520" :scope "provided"]
8289
[javax.xml.bind/jaxb-api "2.3.1" :scope "provided"]]}

src/cider/nrepl.clj

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,18 +213,27 @@ Depending on the type of the return value of the evaluation this middleware may
213213
"doc-first-sentence-fragments" (str "May be absent. Represents the first sentence of a Java doc comment. " fragments-desc)
214214
"doc-block-tags-fragments" (str "May be absent. Represent the 'param', 'returns' and 'throws' sections a Java doc comment. " fragments-desc)})
215215

216+
(def info-params
217+
{"sym" "The symbol to lookup"
218+
"ns" "The current namespace"
219+
"context" "A Compliment completion context, just like the ones already passed for the \"complete\" op,
220+
with the difference that the symbol at point should be entirely replaced by \"__prefix__\".
221+
222+
For Java interop queries, it helps inferring the precise type of the object the `:sym` or `:member` refers to,
223+
making the results more accurate (and less numerous)."
224+
"class" "A Java class. If `:ns` is passed, it will be used for fully-qualifiying the class, if necessary."
225+
"member" "A Java class member."})
226+
216227
(def-wrapper wrap-info cider.nrepl.middleware.info/handle-info
217228
(cljs/requires-piggieback
218229
{:requires #{#'session}
219230
:handles {"info"
220231
{:doc "Return a map of information about the specified symbol."
221-
:requires {"sym" "The symbol to lookup"
222-
"ns" "The current namespace"}
232+
:optional info-params
223233
:returns (merge {"status" "done"} fragments-doc)}
224234
"eldoc"
225235
{:doc "Return a map of information about the specified symbol."
226-
:requires {"sym" "The symbol to lookup"
227-
"ns" "The current namespace"}
236+
:optional info-params
228237
:returns (merge {"status" "done"} fragments-doc)}
229238
"eldoc-datomic-query"
230239
{:doc "Return a map containing the inputs of the datomic query."

src/cider/nrepl/middleware/info.clj

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
(ns cider.nrepl.middleware.info
22
(:require
3+
[compliment.context]
4+
[compliment.sources.class-members]
35
[cider.nrepl.middleware.util :as util]
46
[cider.nrepl.middleware.util.cljs :as cljs]
57
[cider.nrepl.middleware.util.error-handling :refer [with-safe-transport]]
@@ -57,9 +59,47 @@
5759
blacklist
5860
util/transform-value))))
5961

62+
(defn- extract-class-from-compliment
63+
"Given a Compliment-style `context`, returns the inferred class name
64+
of the object placed at __prefix__."
65+
[ns-str context]
66+
(when (and (seq ns-str)
67+
(seq context))
68+
(try
69+
(when-let [ns-obj (find-ns (symbol ns-str))]
70+
(let [c (compliment.context/cache-context context)
71+
^Class c (compliment.sources.class-members/try-get-object-class ns-obj c)]
72+
(some-> c .getName)))
73+
(catch Exception _
74+
;; We can always be analyzing a broken context.
75+
nil))))
76+
6077
(defn info
61-
[{:keys [ns sym symbol class member] :as msg}]
62-
(let [[ns sym class member] (map misc/as-sym [ns (or sym symbol) class member])
78+
[{:keys [ns sym class member context]
79+
legacy-sym :symbol
80+
:as msg}]
81+
(let [sym (or (not-empty legacy-sym)
82+
(not-empty sym))
83+
class (try
84+
(or (when (and (seq class)
85+
(seq ns)
86+
(find-ns (symbol ns)))
87+
(some-> ^Class (ns-resolve (find-ns (symbol ns))
88+
(symbol class))
89+
.getName))
90+
(not-empty class)
91+
(when (some-> sym (str/starts-with? "."))
92+
(extract-class-from-compliment ns context)))
93+
(catch Exception e
94+
nil))
95+
java? (seq class)
96+
[ns sym class member] (mapv misc/as-sym [ns
97+
(cond-> sym
98+
(and (seq sym)
99+
java?)
100+
(str/replace #"^\." ""))
101+
class
102+
member])
63103
env (cljs/grab-cljs-env msg)
64104
info-params (merge {:dialect :clj
65105
:ns ns
@@ -68,10 +108,9 @@
68108
{:env env
69109
:dialect :cljs}))]
70110
(cond
111+
java? (info/info-java class (or member sym))
71112
(and ns sym) (info/info* info-params)
72-
(and class member) (info/info-java class member)
73-
:else (throw (Exception.
74-
"Either \"symbol\", or (\"class\", \"member\") must be supplied")))))
113+
:else nil)))
75114

76115
(defn info-reply
77116
[msg]

0 commit comments

Comments
 (0)