Skip to content

Commit 3b99731

Browse files
committed
[clangd] Turn off implicit cancellation based on client capabilities
Capability is in upcoming 3.17: https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/ (This is also useful for C++ embedders) Differential Revision: https://reviews.llvm.org/D98414
1 parent 953bb5e commit 3b99731

File tree

5 files changed

+28
-9
lines changed

5 files changed

+28
-9
lines changed

clang-tools-extra/clangd/ClangdLSPServer.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
518518
if (Params.capabilities.WorkDoneProgress)
519519
BackgroundIndexProgressState = BackgroundIndexProgress::Empty;
520520
BackgroundIndexSkipCreate = Params.capabilities.ImplicitProgressCreation;
521+
Opts.ImplicitCancellation = !Params.capabilities.CancelsStaleRequests;
521522

522523
llvm::json::Object ServerCaps{
523524
{"textDocumentSync",

clang-tools-extra/clangd/ClangdServer.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
150150
DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr),
151151
ClangTidyProvider(Opts.ClangTidyProvider),
152152
WorkspaceRoot(Opts.WorkspaceRoot),
153+
Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate
154+
: TUScheduler::NoInvalidation),
153155
DirtyFS(std::make_unique<DraftStoreFS>(TFS, DraftMgr)) {
154156
// Pass a callback into `WorkScheduler` to extract symbols from a newly
155157
// parsed file and rebuild the file index synchronously each time an AST
@@ -593,7 +595,7 @@ void ClangdServer::enumerateTweaks(
593595
};
594596

595597
WorkScheduler->runWithAST("EnumerateTweaks", File, std::move(Action),
596-
TUScheduler::InvalidateOnUpdate);
598+
Transient);
597599
}
598600

599601
void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
@@ -683,8 +685,7 @@ void ClangdServer::findDocumentHighlights(
683685
CB(clangd::findDocumentHighlights(InpAST->AST, Pos));
684686
};
685687

686-
WorkScheduler->runWithAST("Highlights", File, std::move(Action),
687-
TUScheduler::InvalidateOnUpdate);
688+
WorkScheduler->runWithAST("Highlights", File, std::move(Action), Transient);
688689
}
689690

690691
void ClangdServer::findHover(PathRef File, Position Pos,
@@ -698,8 +699,7 @@ void ClangdServer::findHover(PathRef File, Position Pos,
698699
CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index));
699700
};
700701

701-
WorkScheduler->runWithAST("Hover", File, std::move(Action),
702-
TUScheduler::InvalidateOnUpdate);
702+
WorkScheduler->runWithAST("Hover", File, std::move(Action), Transient);
703703
}
704704

705705
void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve,
@@ -771,7 +771,7 @@ void ClangdServer::documentSymbols(llvm::StringRef File,
771771
CB(clangd::getDocumentSymbols(InpAST->AST));
772772
};
773773
WorkScheduler->runWithAST("DocumentSymbols", File, std::move(Action),
774-
TUScheduler::InvalidateOnUpdate);
774+
Transient);
775775
}
776776

777777
void ClangdServer::foldingRanges(llvm::StringRef File,
@@ -783,7 +783,7 @@ void ClangdServer::foldingRanges(llvm::StringRef File,
783783
CB(clangd::getFoldingRanges(InpAST->AST));
784784
};
785785
WorkScheduler->runWithAST("FoldingRanges", File, std::move(Action),
786-
TUScheduler::InvalidateOnUpdate);
786+
Transient);
787787
}
788788

789789
void ClangdServer::findImplementations(
@@ -850,7 +850,7 @@ void ClangdServer::documentLinks(PathRef File,
850850
CB(clangd::getDocumentLinks(InpAST->AST));
851851
};
852852
WorkScheduler->runWithAST("DocumentLinks", File, std::move(Action),
853-
TUScheduler::InvalidateOnUpdate);
853+
Transient);
854854
}
855855

856856
void ClangdServer::semanticHighlights(
@@ -862,7 +862,7 @@ void ClangdServer::semanticHighlights(
862862
CB(clangd::getSemanticHighlightings(InpAST->AST));
863863
};
864864
WorkScheduler->runWithAST("SemanticHighlights", File, std::move(Action),
865-
TUScheduler::InvalidateOnUpdate);
865+
Transient);
866866
}
867867

868868
void ClangdServer::getAST(PathRef File, Range R,

clang-tools-extra/clangd/ClangdServer.h

+8
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ class ClangdServer {
146146
/*RebuildRatio=*/1,
147147
};
148148

149+
/// Cancel certain requests if the file changes before they begin running.
150+
/// This is useful for "transient" actions like enumerateTweaks that were
151+
/// likely implicitly generated, and avoids redundant work if clients forget
152+
/// to cancel. Clients that always cancel stale requests should clear this.
153+
bool ImplicitCancellation = true;
154+
149155
/// Clangd will execute compiler drivers matching one of these globs to
150156
/// fetch system include path.
151157
std::vector<std::string> QueryDriverGlobs;
@@ -391,6 +397,8 @@ class ClangdServer {
391397

392398
llvm::Optional<std::string> WorkspaceRoot;
393399
llvm::Optional<TUScheduler> WorkScheduler;
400+
// Invalidation policy used for actions that we assume are "transient".
401+
TUScheduler::ASTActionInvalidation Transient;
394402

395403
// Store of the current versions of the open documents.
396404
// Only written from the main thread (despite being threadsafe).

clang-tools-extra/clangd/Protocol.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R,
414414
if (auto Implicit = Window->getBoolean("implicitWorkDoneProgressCreate"))
415415
R.ImplicitProgressCreation = *Implicit;
416416
}
417+
if (auto *General = O->getObject("general")) {
418+
if (auto *StaleRequestSupport = General->getObject("staleRequestSupport")) {
419+
if (auto Cancel = StaleRequestSupport->getBoolean("cancel"))
420+
R.CancelsStaleRequests = *Cancel;
421+
}
422+
}
417423
if (auto *OffsetEncoding = O->get("offsetEncoding")) {
418424
R.offsetEncoding.emplace();
419425
if (!fromJSON(*OffsetEncoding, *R.offsetEncoding,

clang-tools-extra/clangd/Protocol.h

+4
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,10 @@ struct ClientCapabilities {
475475
/// window.implicitWorkDoneProgressCreate
476476
bool ImplicitProgressCreation = false;
477477

478+
/// Whether the client claims to cancel stale requests.
479+
/// general.staleRequestSupport.cancel
480+
bool CancelsStaleRequests = false;
481+
478482
/// Whether the client implementation supports a refresh request sent from the
479483
/// server to the client.
480484
bool SemanticTokenRefreshSupport = false;

0 commit comments

Comments
 (0)