This is an archive of the discontinued LLVM Phabricator instance.

[clang] Add `forceReload` clangd extension to 'textDocument/didChange'
ClosedPublic

Authored by dgoldman on Feb 3 2020, 12:17 PM.

Details

Summary
  • This option forces a preamble rebuild to handle the odd case of a missing header file being added

Diff Detail

Event Timeline

dgoldman created this revision.Feb 3 2020, 12:17 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 3 2020, 12:17 PM
dgoldman updated this revision to Diff 242155.Feb 3 2020, 12:19 PM
  • Fix comment

Unit tests: pass. 62418 tests passed, 0 failed and 845 were skipped.

clang-tidy: fail. clang-tidy found 0 errors and 2 warnings. 2 of them are added as review comments below (why?).

clang-format: fail. Please format your changes with clang-format by running git-clang-format HEAD^ or applying this patch.

Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

Pre-merge checks is in beta. Report issue. Please join beta or enable it for your project.

Unit tests: pass. 62418 tests passed, 0 failed and 845 were skipped.

clang-tidy: fail. clang-tidy found 0 errors and 2 warnings. 2 of them are added as review comments below (why?).

clang-format: fail. Please format your changes with clang-format by running git-clang-format HEAD^ or applying this patch.

Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

Pre-merge checks is in beta. Report issue. Please join beta or enable it for your project.

Thanks for this. It makes me a bit sad but I don't really see a clean way to make this "just work".

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

Rather than plumbing this down many levels as yet-another-bool-param, can we shove it into either ParseInputs or ParseOptions?
e.g. bool ParseInputs::AllowCached = true; and set it to false here?

It's kind of a stretch for the API as we won't make use of it everywhere that ParseInputs is used, but I think it's better than adding a niche boolean param everywhere.

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

Nit: the preamble is an implementation detail here, an even higher-level description would be e.g.

Force a complete rebuild of the file, ignoring all cached state. Slow!
This is useful to defeat clangd's assumption that missing headers stay missing.

661

just bool forceReload = false; - we don't bother modelling this as a tristate if there's a well-defined defaut.

(Though I'm sure there are places where we are inconsistent...)

661

somehow "rebuild" seems clearer than "reload" to me, because we're not being very specific about what we're loading.

Also allowCache (with inverted sense) might be clearer.

clang-tools-extra/clangd/TUScheduler.cpp
434

no need to pass a separate parameter through to buildPreamble - if you're forcing a preamble rebuild then just don't bother getting the old preamble. OldPreamble is null and you get the behaviour you want.

(The logging will be slightly off - "first preamble" - but I don't think it's worth fixing)

dgoldman updated this revision to Diff 243251.Feb 7 2020, 11:25 AM
dgoldman marked 5 inline comments as done.
  • Refactor to use forceRebuild and ParseOptions
dgoldman marked an inline comment as done.Feb 7 2020, 11:26 AM
dgoldman added inline comments.
clang-tools-extra/clangd/ClangdLSPServer.cpp
650

Done, this cleaned up the tests

Looks pretty good now, thanks! Test needs to be more precise (doesn't actually test the behavior at present, I think).

clang-tools-extra/clangd/Compiler.h
41

Hmm, on thinking further I do think this belongs in ParseInputs next to Contents or CompileCommands, as these things are things that affect the parse but *don't* invalidate caches.

41

this is a good place for a comment explaining what this does specifically (prevents reuse of cached preamble/ast)

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

= false, and remove "disabled by default" from comment

clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
618

This test doesn't actually verify that the preamble was rebuilt, just that the AST was.
Checking the actual diagnostics would do that.

630

I don't think this abstraction is useful since you just have 3 calls and two of them need the actual diagnostics.

You could have diag callbacks inline easily enough:

vector<vector<Diag>> diags;
update(..., [] { diags.push_back(...) })
update(..., [] { ADD_FAILURE(...) })
update(..., [] { diags.push_back(...) })
blockUntilIdle();
EXPECT_THAT(diags, ElementsAre(
  /* First */ElementsAre(...missing header...),
  /* Last */IsEmpty());
dgoldman updated this revision to Diff 243595.Feb 10 2020, 9:16 AM
dgoldman marked 3 inline comments as done.
  • Fixes for tests and InputFiles
dgoldman marked 2 inline comments as done.Feb 10 2020, 9:16 AM
sammccall accepted this revision.Feb 10 2020, 9:36 AM

LG, thanks! Just a nit about further simplifying the test, up to you.

clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
629

this still feels just a bit obfuscated, what about more directly:

ParseInputs I = getInputs(Source, SourceContents);
updateWithDiags(..., I, [] { ... });
Files[Header] = ...;
updateWithDiags(...);
I.ForceRebuild = true;
updateWithDiags(...);
This revision is now accepted and ready to land.Feb 10 2020, 9:36 AM
dgoldman updated this revision to Diff 243619.Feb 10 2020, 10:21 AM
  • Minor test fixes
dgoldman marked 2 inline comments as done.Feb 10 2020, 10:23 AM
dgoldman added inline comments.
clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
629

still needed to recreate ParseInputs but done

This revision was automatically updated to reflect the committed changes.
dgoldman marked an inline comment as done.
nridge added a subscriber: nridge.Feb 18 2020, 1:48 PM

Which client(s) use or plan to use this extension?

Which client(s) use or plan to use this extension?

SourceKit-LSP https://github.com/apple/sourcekit-lsp/pull/242