mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Cache calculated file state in LSP (#4897)
Add caching of parsed documents, and testing of the textDocument handlers. This is based on #4896, which splits out some of the boilerplate to calls. Note, this caches the entire parse state because we'll want to try to emit diagnostics when we see the update, without waiting. It may be helpful to do that asynchronously, but we don't want to wait for another call (such as documentSymbol). Really, we'll probably want to also add check for diagnostics, at least.
This commit is contained in:
@@ -9,17 +9,58 @@ namespace Carbon::LanguageServer {
|
||||
auto HandleDidOpenTextDocument(
|
||||
Context& context, const clang::clangd::DidOpenTextDocumentParams& params)
|
||||
-> void {
|
||||
context.files().Update(params.textDocument.uri.file(),
|
||||
params.textDocument.text);
|
||||
llvm::StringRef filename = params.textDocument.uri.file();
|
||||
if (!filename.ends_with(".carbon")) {
|
||||
// Ignore non-Carbon files.
|
||||
return;
|
||||
}
|
||||
|
||||
auto insert_result = context.files().Insert(
|
||||
filename, [&] { return Context::File(filename.str()); });
|
||||
insert_result.value().SetText(context, params.textDocument.text);
|
||||
if (!insert_result.is_inserted()) {
|
||||
CARBON_DIAGNOSTIC(LanguageServerOpenDuplicateFile, Warning,
|
||||
"duplicate open file request; updating content");
|
||||
context.file_emitter().Emit(filename, LanguageServerOpenDuplicateFile);
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleDidChangeTextDocument(
|
||||
Context& context, const clang::clangd::DidChangeTextDocumentParams& params)
|
||||
-> void {
|
||||
llvm::StringRef filename = params.textDocument.uri.file();
|
||||
if (!filename.ends_with(".carbon")) {
|
||||
// Ignore non-Carbon files.
|
||||
return;
|
||||
}
|
||||
|
||||
// Full text is sent if full sync is specified in capabilities.
|
||||
CARBON_CHECK(params.contentChanges.size() == 1);
|
||||
context.files().Update(params.textDocument.uri.file(),
|
||||
params.contentChanges[0].text);
|
||||
if (params.contentChanges.size() != 1) {
|
||||
CARBON_DIAGNOSTIC(LanguageServerUnsupportedChanges, Warning,
|
||||
"received unsupported contentChanges count: {0}", int);
|
||||
context.file_emitter().Emit(filename, LanguageServerUnsupportedChanges,
|
||||
params.contentChanges.size());
|
||||
return;
|
||||
}
|
||||
if (auto* file = context.LookupFile(filename)) {
|
||||
file->SetText(context, params.contentChanges[0].text);
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleDidCloseTextDocument(
|
||||
Context& context, const clang::clangd::DidCloseTextDocumentParams& params)
|
||||
-> void {
|
||||
llvm::StringRef filename = params.textDocument.uri.file();
|
||||
if (!filename.ends_with(".carbon")) {
|
||||
// Ignore non-Carbon files.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context.files().Erase(filename)) {
|
||||
CARBON_DIAGNOSTIC(LanguageServerCloseUnknownFile, Warning,
|
||||
"tried closing unknown file; ignoring request");
|
||||
context.file_emitter().Emit(filename, LanguageServerCloseUnknownFile);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Carbon::LanguageServer
|
||||
|
||||
Reference in New Issue
Block a user