-
Notifications
You must be signed in to change notification settings - Fork 401
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
Move semantic tokens to LSP implementation #1806
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job, we can remove extra delegate commands now.
I'll try it later and below are some immediate thoughts.
- A monitor should be passed into AST provider, for cancellation and better progress indication.
- Some changes look unrelevant to semantic tokens. I suggest to create a separate PR if you think they are buggy.
- LSP4J is using wrapper objects instead of primitive types. I remember in our previous discussion we switched to use primitives for performance concern. We should double confirm whether there's any performance degradation.
org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/JDTLanguageServer.java
Show resolved
Hide resolved
org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/JDTLanguageServer.java
Show resolved
Hide resolved
...eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/SemanticTokensHandler.java
Outdated
Show resolved
Hide resolved
...eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/SemanticTokensHandler.java
Outdated
Show resolved
Hide resolved
ping~ |
Yes, I plan to look at this again in a few days. I've been quite busy recently so that's why I haven't responded yet. |
ca21621
to
7047a4d
Compare
Thanks, good catch!
Those changes don't affect the code, I was just trying to get rid of this warning:
I switched to primitives mainly because it seemed like the right thing to do while I was at it, but the main performance improvement probably came from avoiding to resolve bindings in some situations and using bitmasks for modifiers. If you want to test this then go ahead, but either way we would need upstream changes to LSP4J in order to use primitives, which I don't have time to deal with right now (and I'm not sure if the performance gain is worth it). After testing this PR again, I noticed that unfortunately redhat-developer/vscode-java#1597 is back, because now we don't have the client-side code in the extension to handle "stale" requests. We could re-implement the same workaround in the extension using Finally, I believe I've found the problem! This is what happens when we get a flicker of incorrect highlighting after frequent changes to the document:
The relevant code can be found here. By setting a breakpoint in the VS Code devtools and removing the changes from But this isn't necessarily a bug with VS Code. It just expects the semantic tokens returned by the server to be for the exact version of the document at the time of the request, not necessarily the latest version. Knowing this, I just removed the call to However, the issue could still be reproduced if the server updates the document before the AST is computed. It's not something I'm able to reproduce on my machine, and I don't know if it's possible at all to happen in a real-world scenario. But by inserting a simple The only way to work around this seems to be cancelling the request. But returning What do you think? The easiest fix would probably be to apply the old workaround in the extension, but it might be more "correct" to fix the problem on the server side depending on whether or not all clients expect the tokens to be for the version at the time of the request. Can't find anything about that in the spec though. |
It makes sense. Good job.
Sorry but I cannot reproduce it. In my test, after copy&paste for a couple of times, in the end vscode seems to always send an extra request to fetch tokens, and LS can return correct results. The only consequence by inserting above line is, a 1000ms flicker before I get correct highlighting.
Agree. |
3f62dd5
to
a6b1f1d
Compare
Yes, that flicker is the issue I was referring to. So only "part two" of the issue, not "part one" (see explanation here). I just pushed some changes to this PR which should fix this issue. It works by cancelling the request by throwing a You'll also need to use redhat-developer/vscode-java#2000, because the languageclient needed an update (microsoft/vscode-languageserver-node@dae62de). On the old version it just clears all tokens when receiving an error, which causes flickering (microsoft/vscode-languageserver-node#576). BTW, I realized that we do need to wait for document lifecycle jobs, because otherwise it's possible that the server has received the latest version of the document but hasn't processed it yet, leading to incorrect tokens that don't automatically repair themselves. |
Signed-off-by: 0dinD <[email protected]>
a6b1f1d
to
023a0a1
Compare
I'm ok with this PR. Just to ensure we don't have a regression. As for the flickering issue on vscode, if bumping vscode-languageclient can perfectly fix that, I suggest we get this PR merged, and update languageclient lib in vscode-java. |
Not sure if I completely understand your question, so to clarify and recap: This PR and redhat-developer/vscode-java#2000 started out as just removing the delegate commands and using LSP for semantic tokens instead. In doing so, I discovered that the offset bug with semantic tokens got introduced again, because the previous workaround was in the extension's client-side code. So I started investigating a more robust solution for how to solve the problem on the server-side, which relies on cancelling the request on the server side by returning an error with the The last problem was that when cancelling the request using the So yes, if you merge this PR, also merge redhat-developer/vscode-java#2000 or else there will be flickering. If you want to see the difference for yourself, make sure to completely rebuild the extension when changing the version of the languageclient. And because I finally understood in entirety the way the offset bug occurred, I believe all edge cases should be covered now, as opposed to the previous workaround in redhat-developer/vscode-java#1632 which just discards the tokens on the client-side and naively uses a timer to "wait out" the document changes before trying again. I can totally see there being edge cases with this workaround where the bug can still happen if a request is abnormally slow. |
There was misunderstanding, that I thought flickering issue was still there even after you apply this PR and update langaugeclient to v7.1.0-next.5. Now it's clear that you are talking about current workaround (delay) doesn't cover all edge cases.
This makes sense, as I saw no flickering issue last time when I tried with you both fixes in (#1806 & redhat-developer/vscode-java#2000).
I'll test this PR + [email protected], see if I can see the difference. |
test this please |
By inserting
flickering.mp4
This PR looks good to me, and I'm happy to get it merged as soon as possible. My only concern is, for those unpowerful machines, requests are slow and users might frequently see the flickering issue. This turns out to be a "regression" to them if they don't see flickering at the moment. Any idea to get this coverred? Let me know if I misunderstand anything. |
That to me sounds like you haven't applied this PR (or it hasn't been compiled successfully), I can't reproduce what you're showing in the video even with a The difference between the languageclient versions should be that when using the old version, the tokens flicker completely off for a second, i.e. you only see TextMate-based highlighting. That's because the old languageclient version clears the tokens when receiving the Could you please try again, making sure to include both PRs, and that the extension and server have been successfully recompiled? If you can still reproduce the error, can you share your settings/environment so I can try to reproduce this? |
languageclient 7.1.0-next.5: (works perfectly, unless I revert the offset fix by commenting out some code) offset-flicker.mp4languageclient 7.0.0: (flashes of no semantic tokens, notice the package names) textmate-flicker.mp4Again, note that when changing the version of the languageclient you need to do a full recompile, i.e. kill the watch task and start the build again after running |
I'm able to see it now, it's working as expected! (I was probably using an early commit without DocumentMonitor...) |
test this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Kudos to your work.
CI failed, tracking in #1869 |
Thanks @0dinD! |
Requires eclipse-jdt/eclipse.jdt.ui#335 Closes eclipse-jdtls#1806 Signed-off-by: David Thompson <[email protected]>
Requires eclipse-jdt/eclipse.jdt.ui#335 Closes eclipse-jdtls#1806 Signed-off-by: David Thompson <[email protected]>
Requires eclipse-jdt/eclipse.jdt.ui#335 Closes eclipse-jdtls#1806 Signed-off-by: David Thompson <[email protected]>
Requires eclipse-jdt/eclipse.jdt.ui#335 Closes eclipse-jdtls#1806 Signed-off-by: David Thompson <[email protected]>
Requires eclipse-jdt/eclipse.jdt.ui#335 Closes #1806 Signed-off-by: David Thompson <[email protected]>
Fixes #1678
Fixes redhat-developer/vscode-java#1999
This PR moves the semantic tokens implementation from a custom command to the proper LSP 3.16 implementation.
Perhaps someone could update the LSP support wiki page once this PR is merged? Currently, we only support
textDocument/semanticTokens/full
, nottextDocument/semanticTokens/full/range
ortextDocument/semanticTokens/delta
.