This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Support config over LSP.
Changes PlannedPublic

Authored by sammccall on Jul 14 2020, 3:08 PM.

Details

Reviewers
kadircet
Summary

We support sending fragments in initialize and workspace/didChangeConfiguration.
Sadly no workspace/configuration yet, we'd want to send that request on
didOpen and we'd have to block on getting the answer, which is much more
invasive.

Diff Detail

Event Timeline

sammccall created this revision.Jul 14 2020, 3:08 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 14 2020, 3:08 PM
kadircet added inline comments.Jul 15 2020, 3:28 AM
clang-tools-extra/clangd/ClangdLSPServer.cpp
1220

nit: maybe just set ReparseAllFiles in here too, and change the condition below to only return ReparseAllFiles

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

it feels like clients will only be using two types of keys, a "global" one for sending over (likely project-specific) user preferences and another for directory/file specific configs. The latter is likely to have the path as a key, whereas the former will likely be a special identifier. I am glad that ! comes before both / and any capital letters(letter drives).

I think it is only important to have a distinction between these two types (a subset of what you describe here). Current design makes it really easy on our side, I am just afraid of confusing clients. Maybe we should just have an enum/boolean tag saying if the fragment is global or not instead of relying on the key orderings ?

sammccall marked 2 inline comments as done.Jul 17 2020, 5:26 AM
sammccall added inline comments.
clang-tools-extra/clangd/ClangdLSPServer.cpp
1220

Is the idea here that triggering spurious reparses is cheap enough?
Or that if it's cheap enough for our "future-facing" extension, we should be able to stop optimizing it for the existing one?

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

If we go down this path, where do we draw the line?
(this isn't a slipper-slope argument - I think it's a reasonable idea and we should work out how far we want to take it)

If we're encoding this file/directory use case in the protocol somehow, why wouldn't we *require* the key to be a path, and no longer require a condition to be set for that? This is like how .clangd files are handled.

Then we'd have a more natural way of dealing with priority between file/dir-specific entries (actually, maybe it coincides with sort order, ha!).

But this model starts to look something much closer to the workspace/configuration server->client request, which has a scope URI attached. The recommendation from LSP folks is that actual configuration flow over that endpoint, and didChangeConfiguration just be used to notify of changes.

That hasn't seemed feasible for us as we imagine all the requests issues by background index, and the bother of making everything consuming config asynchronous. But:

  • if we restricted per-URI config to per-directory, not per-file, the number of requests aren't overwhelming (assuming caching). It's still possible to achieve per-file config with conditions...
  • async seems fundamentally solvable, given that we only create config on TUScheduler threads and background-index threads now, never the main thread (unless in sync mode...). Technical details to work out of course (if the server doesn't get a response it'll want to time out, but what thread does the timeout handler run on?)

It would help there were some clearer practical goal we were driving towards. Propagating, say, vscode extension settings live into clangd can be done this way, but it's a sledgehammer for a peanut. Maybe live-configuring *workspace* properties is an interesting thing, but I'm not sure how much value there is when .clangd exists.

kadircet added inline comments.Jul 17 2020, 8:10 AM
clang-tools-extra/clangd/ClangdLSPServer.cpp
1220

none :( sorry i misread this and thought the code below was doing ModifiedFiles.size() != 0 (that's way the comment was a nit)

OTOH, as you noted spurious reparses are cheap(still some IO and a task in the queue). We expect the usage of updating compile commands to migrate towards configs in the future, so in theory we won't be using that optimization most of the time.

Even though we've got enough info to prevent spurious reparses here, we might not in the future (e.g. reparses resulting from a config change). So I would drop the optimization(the whole Old-New comparison logic) to increase readability.

but definitely not something we should do now (probably ever), so feel free to ignore.

There are lots of choices and overlapping ideas for how the protocol should look, little urgency (it isn't going to make clangd 11), and few concrete use cases to evaluate the options.

Let's table this for now and let the ideas sink in and more use cases crop up. I definitely think we should have this, probably for clangd 12, but it's worth getting right.

sammccall planned changes to this revision.Jul 17 2020, 8:47 AM