This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-06-03
Channels
- # aws (12)
- # beginners (12)
- # biff (10)
- # calva (1)
- # cider (10)
- # cljfx (1)
- # clojure (2)
- # clojure-conj (1)
- # clojure-europe (25)
- # clojure-madison (1)
- # clojure-nl (1)
- # clojure-norway (12)
- # clojure-sweden (4)
- # clojure-uk (6)
- # datomic (11)
- # dev-tooling (3)
- # emacs (5)
- # gratitude (1)
- # introduce-yourself (7)
- # java (3)
- # jobs (1)
- # london-clojurians (2)
- # lsp (23)
- # off-topic (4)
- # practicalli (9)
- # quil (6)
- # re-frame (3)
- # reagent (4)
- # remote-jobs (1)
- # ring (1)
- # shadow-cljs (18)
- # squint (67)
- # tools-deps (5)
- # xtdb (4)
- # yamlscript (12)
(perhaps this has been discussed before) Is it possible to navigate to the original Java sources from .clj
files when doing interop?
Background:
• Using leiningen
• Have [some.lib "1.0"]
and [some.lib "1.0" :classifier "sources"]
in project.clj
• Tried both eglot
and lsp-mode
With cider
, I can e.g. cider-doc
when over a Java class name to open a doc buffer, which shows the original javadoc descriptions. This buffer also includes a link to the original (non-decompiled) sources under ~/.m2/..
, which allows me to browse the original java sources
But when I try something similar with LSP (e.g. xref-find-definitions
): I get a buffer with decompiled Java sources ("Decompiled with CFR 0.152.")
I tried setting :java {:decompile-jar-as-project? false}
in my config, but it does not seem to have any effect
Actually, it seems like sometimes navigation to sources works as expected :thinking_face:
If I open a project (or restart eglot/lsp-mode), navigating to a class from a (let [^SomeClass foo (get-foo)] ..
seems to work fine and I get the sources for SomeClass
. However, if later in the code I try the same for (SomeClass/staticMethod)
then I get the decompiled sources. And if I go back to the earlier line (the let
example) then that now also links to the decompiled sources.
So it feels like sometimes some references trigger the decompilation and once that happens, the original sources are no longer available and the decompiled sources are preferred
if we have the original java source code, we should not decompile, it's probably a bug I'm interested in solving if it's happening
any chance you make a repro in https://github.com/ericdallo/clojure-sample in a branch or any other public repo?
I was lazy so I just published this very WIP project I'm working on: https://github.com/lassemaatta/murmeli/blob/master/project.clj
the core.clj
contains a bunch of interop, https://github.com/lassemaatta/murmeli/blob/master/src/murmeli/core.clj
I also included the .lsp/config.edn
In summary (at least on my machine):
• xref-find-definitions
on something like ^MongoClients
-> Opens the proper java sources
◦ Under ~/.emacs.d/workspace/.cache/com.mongodb.client.MongoClients.java
(in lsp-mode)
◦ Under ~/.m2/repository/org/mongodb-driver-sync/.../MongoClients.java
(in eglot)
• xref-find-definitions
on something like ServerApiVersion/V1
(or (ServerApi/builder)
) -> Opens the decompiled sources
◦ Under .lsp/.cache/java/decompiled/com/mongodb/client/MongoClients.java
BTW as a fun fact: there is a lsp-mode command I created called lsp-clojure-cursor-info
, which will tell what's the token at cursor and its definition, pretty useful to debug if analysis are correct for that buffer
with that, we can see that we have java source analysis for com.mongodb.client
package but not for com.mongodb
, that's why we decompile it.
Is the classes of that package also available?
What about MongoClients/create
here https://github.com/lassemaatta/murmeli/blob/master/src/murmeli/core.clj#L29?
that's what I get for lsp-clojure-cursor-info
, yet I get the decompiled sources when I navigate to it
hum, it works for me, it goes to the source MongoClients/create
:thinking_face:
{:node
{:value MongoClients/create,
:string-value "MongoClients/create",
:map-qualifier nil},
:elements
[{:element
{:end-row 29,
:name-end-col 45,
:external? false,
:name-end-row 29,
:call true,
:method-name "create",
:name-row 29,
:lang :clj,
:col 25,
:class "com.mongodb.client.MongoClients",
:name-col 26,
:uri
"file:///home/greg/dev/clojure-lsp-java-source-issue/src/murmeli/core.clj",
:end-col 55,
:bucket :java-class-usages,
:row 29},
:definition
{:end-row 41,
:name-end-col 0,
:external? true,
:name-end-row 0,
:name-row 0,
:return-type "MongoClient",
:name "create",
:col 5,
:class "com.mongodb.client.MongoClients",
:name-col 0,
:uri
"jar:file:///home/greg/.m2/repository/org/mongodb/mongodb-driver-sync/5.1.0/mongodb-driver-sync-5.1.0-sources.jar!/com/mongodb/client/MongoClients.java",
:end-col 5,
:flags #{:method :public :static},
:doc
"/**\n * Creates a new client with the default connection string \"\".\n *\n * @return the client\n */",
:parameters [],
:bucket :java-member-definitions,
:row 39},
:semantic-tokens [{:token-type :class, :token-modifier []}]}]}
Mine is happening because of https://github.com/clojure-lsp/clojure-lsp/blob/8ac7b42f6e4e8afb34bb7b669891f96a38653cb0/lib/src/clojure_lsp/queries.clj#L342, the only thing I can think is that for some reason, there are no java-class-definitions
or java-member-definitions
for your project when starting it, can you try to clean the .lsp/.cache to see if it changes anything?