[clangd] Publish diagnostics with stale preambles
authorKadir Cetinkaya <kadircet@google.com>
Tue, 21 Feb 2023 08:44:25 +0000 (09:44 +0100)
committerKadir Cetinkaya <kadircet@google.com>
Wed, 22 Feb 2023 14:54:16 +0000 (15:54 +0100)
commit465ee9bfb26d46f2732d8b238dcbadc38373dbb3
tree08d7c2e840dbdf5643deb74b33a4337abd834244
parent8c2a12f7f9b6dc078bfb18df9333379fdf27c6a3
[clangd] Publish diagnostics with stale preambles

This patch achieves this by building an AST and invoking main file
callbacks on each update, in addition to preamble updates.

It means we might have some extra AST builds now (e.g. if an update was
with a stale preamble and there were no reads on it, we would only build
an AST once we had the fresh preamble. Now we'll build 2, once with the
stale preamble and another with the fresh one, but we'll have one more
diagnostics cycle in between.).

This patch preserves forward progress of diagnostics by always using the
latest main file contents when emitting diagnostics after preamble
builds. It also guarantees eventual consistency:
- if an update doesn't invalidate preamble, we'll emit diagnostics with
  fresh preamble already.
- if an update invalidates preamble, we'll first emit diagnostics with
  stale contents, and then once the preamble build finishes it'll emit
  diagnostics (as preamble has changed) with newest version.

This has implications on parsing callbacks, as previously onMainAST
callback was called at most once, now it can be called up to 2 times.
All of the existing clients can already deal with callback firing
multiple times.

Differential Revision: https://reviews.llvm.org/D144456
clang-tools-extra/clangd/TUScheduler.cpp
clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp