-
Notifications
You must be signed in to change notification settings - Fork 54
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
Quick fixes get corrupted when code actions from multiple Language Servers are relevant to one Java file. #866
Comments
That's an interesting case. Do you think you could reproduce the issue in some unit test? LanguageServerProjectExecutor executor = LanguageServers.forProject(file.getProject())
.withCapability(ServerCapabilities::getCodeActionProvider)
// try to use same LS as the one that created the marker
.withPreferredServer(LanguageServersRegistry.getInstance().getDefinition((String) attributes[0])); Please make sure that the |
This all looks correct stepping through in the debugger. The limited info of the JSON-RPC flows in the LS logs too in Eclipse seems to confirm my understanding.
This looks to be "working" as far as it's implemented, but it might not be to enforce much of a "preference". The
does use this "preferred" server to establish an order (to call the preferred one first). According to the comments in the computeFirst(...) method, (which I admit I can't confirm just by reading and inspecting the source code at this point), the first (non empty/null) result to return will be used.
But since the calls are all async it doesn't mean all that much in terms of establishing order to make an async call to LS 1 then to LS 2; the LS2 here has plenty of chance to return first. In this case LSP4Jakarta has over 70 code actions while LSP4MP has under 20. Since there is some looping through the actions maybe this makes it likely for LSP4MP to return first, even though LSP4Jakarta is "preferred" here. Does it seem like it might make more sense to "wait" for the preferred LS to reply with a non-empty/null, and only then if it doesn't to loop through and call the remaining ones? I don't immediately know how to do that but it'd be helpful to hear your thoughts at a high level before spending time on it. Would we want/need to include some kind of wait "timeout" because we wouldn't want to block too long waiting for the preferred LS to return? BTW, I see the recent blame shows some changes in this area: #780 but just reading the description, I'm guessing it isn't fundamentally related to the problem in this issue. (It seems to be about cancellation support). Thx for your insights here. |
What about we just query |
That seems like a good next step to attempt. Not sure when I could get to trying around to trying it, but it makes sense at a high level.
It sounds like you might not be aware of concrete usages of this just yet. I'm open to the idea that this is useful. One thing to note about my particular case though is that it's not quite a case where LS "A" has a fix targeting a diagnostic from LS "B". It's merely a case where LS "A" has a fix that doesn't include a targetDiagnostic at all, so it's more of a "generic" fix. See code
And this might get into overlap of the other issue: #867 I opened since this is case also involves a "source" code action rather than a "quickfix" kind action. |
Yes, I think if we use |
Background
I'm working on Liberty Tools Eclipse which pulls in each of the LSP4Jakarta and LSP4MP language servers.
In this issue I noted that the Quick Fix that should be generated by the LSP4Jakarta is getting handled/produced/displayed incorrectly because of the presence of LSP4MP and its code action.
Instead of the "Quick Fix" I expect from the LSP4Jakarta code action, I see a mix of a Quick Fix from a LSP4MP code action and the LSP4Jakarta diagnostic I think incorrectly displayed (see the screenshot in the above issue in Liberty Tools Eclipse).
Environment:
Suspected area of code
I have debugged into the code to have a rough idea of where things might be going wrong, but still have some gaps in my knowledge.
I'm thinking this code is likely related to my problem, since it seems to be content to use the first response by the first LS (via
executor.computeFirst(...)
) .The LSP4MP has a code action that is not scoped to any particular diagnostic:
whereas the LSP4Jakarta code action is related to a specific diagnostic identified by the LSP4Jakarta.
Furthermore, this code changed was changed in this PR: https://github.com/eclipse/lsp4e/pull/535/files which was from around the time I first noticed the problem, in the v4.27 release from 1Q23. (However at the time I was running with a different level of lsp4e from the one in the standard package so I do NOT really have a "clean" bug report from the v4.27 release).
Other notes
UPDATE: I deleted my previous paragaraph here. All I was observing was that the marker had an attribute, 'lspCodeActions' with value mapping onto an LSP4MP code action, while having another attribute 'lspDiagnostic', with value mapping to an LSP4Jakarta diagnostic. I don't think this marker handling attribute merging is another issue in and of itself.
Next step
I'm continuing to look at this in the debugger, but figured I'd stop and write this up in case someone already understands the problem based on that description, and/or can share some pointers.
The text was updated successfully, but these errors were encountered: