This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Add batch fixes for include-cleaner diagnostics
ClosedPublic

Authored by hokein on Apr 6 2023, 12:12 AM.

Details

Summary

For each unused-include/missing-include diagnostic, we provide fix-all
alternative to them.

Diff Detail

Event Timeline

hokein created this revision.Apr 6 2023, 12:12 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 6 2023, 12:12 AM
hokein requested review of this revision.Apr 6 2023, 12:12 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 6 2023, 12:12 AM

The UI in VSCode looks like

  • unused-include:

  • missing-include:

kadircet added inline comments.Apr 17 2023, 10:13 AM
clang-tools-extra/clangd/IncludeCleaner.cpp
439

can we also derive these from an llvm::ArrayRef<Diag> ? to make sure there can't be a discrepancy between sum of these and individual unused include fixes

441

i think we should drop # (same for add all case)

455

rather than copying all the fixes and then sorting/deleting them, can we have a map here to make sure we're copying only 1 edit per Edit::newText ?

472

what if there's none? (same for add all)

479

again fixall shouldn't be attached if either of the sets is empty

479

this is quite wordy, what about just fix includes ?

hokein updated this revision to Diff 516382.Apr 24 2023, 6:20 AM
hokein marked 6 inline comments as done.
  • address review comments
  • add LSP's ChangeAnnotations support and use it in the include-cleaner batch fix
hokein updated this revision to Diff 516384.Apr 24 2023, 6:24 AM

some cleanups.

I have extended this patch a bit more (including the LSP ChangeAnnotation support part), it is based on https://reviews.llvm.org/D148783), and it implements a full workflow of batch fixes (verified it with VSCode). I hope it is not too big to review, happy to split it if you want.

can you also add test coverage for the new LSP fields?

clang-tools-extra/clangd/IncludeCleaner.cpp
454

nit: E.annotationId.emplace(RemoveAllUnusedID); (same for others)

458

rather than an empty label, let's duplicate RemoveAll.Message here. As that context will probably be lost after executing the code action.

479

i think you want to populate AddAllMissing.Edits from Edits first

483

unless we want a really wordy description, this would actually require us to attach one annotation per edit, rather than using the same annotation for all the edits.
can you check what changes in the UI when we have multiple annotations for a single workspace edit?

499

again let's use FixAll.Message as label

508

can you declare these right before their use sides, rather than on the same line?

511

UnusedIncludes.size() > 1

516

MissingIncludeDiags.size() > 1

clang-tools-extra/clangd/Protocol.h
253

rather than packing up a new field here, can we have a struct AnnotatedTextEdit : TextEdit ?

it's surely more convenient this way but creates some confusion in call sites that're trying to create a regular textedit.

also we can use the empty string again, no need for optional.

265

nit: triple slashes, here and elsewhere

275

no need for optional here, we can use the empty string

1028

i don't think there's any difference between an empty map and a nullopt here, right?

hokein updated this revision to Diff 517093.Apr 26 2023, 1:44 AM
hokein marked 8 inline comments as done.

address review comments:

  • emit one annotation per textedit;
  • remove unnecessary std::optional in the protocol structure
  • add a lit test
hokein updated this revision to Diff 517096.Apr 26 2023, 1:46 AM

more cleanup

clang-tools-extra/clangd/IncludeCleaner.cpp
458

I don't see much value on setting the label the the RemoveAll message (the preview window shows the content diff, it is clear enough for users to understand the purpose by viewing the diff).

And since we use one annotation per edit, the RemoveAll message doesn't seem to suit anymore.

479

oops, good catch!

483

as discussed, there is not UI difference (at least in VSCode) between these two, but we should swich to one annotation per edit (since the UI is based on the annotation, and we want each edit is controlled by the user).

kadircet added inline comments.Apr 26 2023, 4:25 AM
clang-tools-extra/clangd/IncludeCleaner.cpp
458

I don't see much value on setting the label the the RemoveAll message (the preview window shows the content diff, it is clear enough for users to understand the purpose by viewing the diff).

i think you're focusing too much on the way VSCode chooses to implement this interaction.

Showing the diff in the edit panel is a strategy chosen by VSCode, not per LSP. Spec indicates label as A human-readable string describing the actual change. The string is rendered prominent in the user interface.. So there's a good chance an editor might chose to just display the label. This makes even more sense especially when changes are complicated and don't fit a single line.

And since we use one annotation per edit, the RemoveAll message doesn't seem to suit anymore.

Right, but we actually now have the opportunity to describe each fix properly. We can change the fix message we generate in generateUnusedIncludeDiagnostics to contain proper include and use them as annotation labels instead. We already have the logic inside Diagnostics.cpp to synthesize messages for fixes (this would also unify the behaviour), i think we should re-use it here by exposing it in diagnostics.h. WDYT?

478

similar to above, let's at least mention the fix properly in label.

486

nit: you can std::move(It.getValue()) if you drop the const from It.

496

why are we creating new annotations here? rather than just merging everything from RemoveAllUnused and AddAllMissing ?

clang-tools-extra/clangd/Protocol.h
253

despite keeping this one as-is, we still don't need to optional, right?

hokein updated this revision to Diff 517154.Apr 26 2023, 6:46 AM
hokein marked 2 inline comments as done.

address comments.

hokein updated this revision to Diff 517157.Apr 26 2023, 6:49 AM

fix the lit-test uri path on windows

clang-tools-extra/clangd/IncludeCleaner.cpp
458

Thanks, the plan sounds good to me. As discussed, I will address it in a followup patch (added a FIXME here).

496

right, we can do that, it is simpler.

clang-tools-extra/clangd/Protocol.h
253

right, I missed this field when updating other fields.

kadircet accepted this revision.Apr 26 2023, 6:54 AM

thanks!

This revision is now accepted and ready to land.Apr 26 2023, 6:54 AM
This revision was landed with ongoing or failed builds.Apr 27 2023, 3:10 AM
This revision was automatically updated to reflect the committed changes.