This is an archive of the discontinued LLVM Phabricator instance.

clangd: Set a diagnostic on a code action resulting from a tweak
ClosedPublic

Authored by ckandeler on Feb 4 2022, 1:43 AM.

Details

Summary

... if there is a match.
This is needed to that clients can can make a connection between a
diagnostic and an associated quickfix-tweak.
Ideally, quickfix-kind tweak code actions would be provided inline along
with the non-tweak fixes, but this doesn't seem easily achievable.

Diff Detail

Event Timeline

ckandeler created this revision.Feb 4 2022, 1:43 AM
ckandeler requested review of this revision.Feb 4 2022, 1:43 AM

This is assuming a semantic connection that we don't know exists.
Without any more specific reason to draw this connection, this seems like a heuristic that could equally be applied by the client.

Is there a particular action/diagnostic pair you want this for?

This is assuming a semantic connection that we don't know exists.
Without any more specific reason to draw this connection, this seems like a heuristic that could equally be applied by the client.

The difference being that the client would have to poke around in the technically opaque Command structure to find the range.
Seems possible, but presumably there are no guarantees about the properties?

Is there a particular action/diagnostic pair you want this for?

Yes, -Wswitch/PopulateSwitch (which is the only quickfix kind of tweak at the moment).

TL;DR: I think this makes sense to add, but we should make it slightly more restrictive.

This is assuming a semantic connection that we don't know exists.
Without any more specific reason to draw this connection, this seems like a heuristic that could equally be applied by the client.

The difference being that the client would have to poke around in the technically opaque Command structure to find the range.
Seems possible, but presumably there are no guarantees about the properties?

FWIW, I don't think poking in command is required: the test you're adding here is that:

  • tweak kind is quickfix: tweak kind is exposed as CodeAction.kind
  • diag range == params.range: both diag and params are supplied by the client

However the protocol is complicated enough here as it is without adding client-side heuristics, we should probably have the server signal them explicitly if we think they're safe.

Is there a particular action/diagnostic pair you want this for?

Yes, -Wswitch/PopulateSwitch (which is the only quickfix kind of tweak at the moment).

Yes, makes sense. I think we added the "preferred" logic as a hack.
FWIW, VSCode accepts this as associating the diagnostic with the fix, even without CodeAction.Diagnostics set.

But doing this with CodeAction.diagnostics makes at least as much sense, so let's support that.

clang-tools-extra/clangd/ClangdLSPServer.cpp
1011

This loop is closely related to what you're doing (and the one above isn't).

Maybe we can refactor/combine as something like:

Optional<CodeAction *> OnlyFix; // nullptr means multiple fixes
// ... loop over actions and set OnlyFix ...
if (OnlyFix && *OnlyFix) {
  (*OnlyFix)->isPreferred = true;
  if (Diags.size() == 1 && Diags.front().range == Selection)
    (*OnlyFix)->diagnostics = {Diags.front()];
}

Note this adds the conditions:

  • should be only one diagnostic in context
  • should be only one quickfix action

I think these reduce the chance of false positives.

ckandeler updated this revision to Diff 405911.Feb 4 2022, 3:19 AM

Formatting & logic.

clang-tools-extra/clangd/ClangdLSPServer.cpp
1011

Done. Though it seems the code would work just as well with OnlyFix staying a normal pointer. Did I misunderstand something?

sammccall accepted this revision.Feb 4 2022, 4:56 AM
sammccall added inline comments.
clang-tools-extra/clangd/ClangdLSPServer.cpp
1011

Oops, I missed the break in the loop.
Yes a normal pointer would be better, thanks!

This revision is now accepted and ready to land.Feb 4 2022, 4:56 AM
ckandeler updated this revision to Diff 405929.Feb 4 2022, 5:13 AM

Simplified code.

ckandeler marked an inline comment as done.Feb 4 2022, 5:13 AM
ckandeler updated this revision to Diff 406359.Feb 7 2022, 2:11 AM

Fixed Lint complaints

It'd be great if you could merge this, as I don't have the necessary privileges.