Author: Sam McCall Date: 2021-03-16T12:27:40+01:00 New Revision: 3b99731c4e7bb844699eda6640bd99344f800c79
URL: https://github.com/llvm/llvm-project/commit/3b99731c4e7bb844699eda6640bd99344f800c79 DIFF: https://github.com/llvm/llvm-project/commit/3b99731c4e7bb844699eda6640bd99344f800c79.diff LOG: [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 Added: Modified: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index cd13e013aa50..b4a5cf337296 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -518,6 +518,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, if (Params.capabilities.WorkDoneProgress) BackgroundIndexProgressState = BackgroundIndexProgress::Empty; BackgroundIndexSkipCreate = Params.capabilities.ImplicitProgressCreation; + Opts.ImplicitCancellation = !Params.capabilities.CancelsStaleRequests; llvm::json::Object ServerCaps{ {"textDocumentSync", diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 164e387bd454..e9724e7516aa 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -150,6 +150,8 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr), ClangTidyProvider(Opts.ClangTidyProvider), WorkspaceRoot(Opts.WorkspaceRoot), + Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate + : TUScheduler::NoInvalidation), DirtyFS(std::make_unique<DraftStoreFS>(TFS, DraftMgr)) { // Pass a callback into `WorkScheduler` to extract symbols from a newly // parsed file and rebuild the file index synchronously each time an AST @@ -593,7 +595,7 @@ void ClangdServer::enumerateTweaks( }; WorkScheduler->runWithAST("EnumerateTweaks", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, @@ -683,8 +685,7 @@ void ClangdServer::findDocumentHighlights( CB(clangd::findDocumentHighlights(InpAST->AST, Pos)); }; - WorkScheduler->runWithAST("Highlights", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + WorkScheduler->runWithAST("Highlights", File, std::move(Action), Transient); } void ClangdServer::findHover(PathRef File, Position Pos, @@ -698,8 +699,7 @@ void ClangdServer::findHover(PathRef File, Position Pos, CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index)); }; - WorkScheduler->runWithAST("Hover", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + WorkScheduler->runWithAST("Hover", File, std::move(Action), Transient); } void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve, @@ -771,7 +771,7 @@ void ClangdServer::documentSymbols(llvm::StringRef File, CB(clangd::getDocumentSymbols(InpAST->AST)); }; WorkScheduler->runWithAST("DocumentSymbols", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::foldingRanges(llvm::StringRef File, @@ -783,7 +783,7 @@ void ClangdServer::foldingRanges(llvm::StringRef File, CB(clangd::getFoldingRanges(InpAST->AST)); }; WorkScheduler->runWithAST("FoldingRanges", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::findImplementations( @@ -850,7 +850,7 @@ void ClangdServer::documentLinks(PathRef File, CB(clangd::getDocumentLinks(InpAST->AST)); }; WorkScheduler->runWithAST("DocumentLinks", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::semanticHighlights( @@ -862,7 +862,7 @@ void ClangdServer::semanticHighlights( CB(clangd::getSemanticHighlightings(InpAST->AST)); }; WorkScheduler->runWithAST("SemanticHighlights", File, std::move(Action), - TUScheduler::InvalidateOnUpdate); + Transient); } void ClangdServer::getAST(PathRef File, Range R, diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index e76ef65922ee..b633d3139683 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -146,6 +146,12 @@ class ClangdServer { /*RebuildRatio=*/1, }; + /// Cancel certain requests if the file changes before they begin running. + /// This is useful for "transient" actions like enumerateTweaks that were + /// likely implicitly generated, and avoids redundant work if clients forget + /// to cancel. Clients that always cancel stale requests should clear this. + bool ImplicitCancellation = true; + /// Clangd will execute compiler drivers matching one of these globs to /// fetch system include path. std::vector<std::string> QueryDriverGlobs; @@ -391,6 +397,8 @@ class ClangdServer { llvm::Optional<std::string> WorkspaceRoot; llvm::Optional<TUScheduler> WorkScheduler; + // Invalidation policy used for actions that we assume are "transient". + TUScheduler::ASTActionInvalidation Transient; // Store of the current versions of the open documents. // Only written from the main thread (despite being threadsafe). diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index b3ff124df4de..42ca721ebcbb 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -414,6 +414,12 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R, if (auto Implicit = Window->getBoolean("implicitWorkDoneProgressCreate")) R.ImplicitProgressCreation = *Implicit; } + if (auto *General = O->getObject("general")) { + if (auto *StaleRequestSupport = General->getObject("staleRequestSupport")) { + if (auto Cancel = StaleRequestSupport->getBoolean("cancel")) + R.CancelsStaleRequests = *Cancel; + } + } if (auto *OffsetEncoding = O->get("offsetEncoding")) { R.offsetEncoding.emplace(); if (!fromJSON(*OffsetEncoding, *R.offsetEncoding, diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index c6074abcb04e..1334ddf4b5ce 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -475,6 +475,10 @@ struct ClientCapabilities { /// window.implicitWorkDoneProgressCreate bool ImplicitProgressCreation = false; + /// Whether the client claims to cancel stale requests. + /// general.staleRequestSupport.cancel + bool CancelsStaleRequests = false; + /// Whether the client implementation supports a refresh request sent from the /// server to the client. bool SemanticTokenRefreshSupport = false; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits