diff options
Diffstat (limited to 'clang-tools-extra/clangd/ClangdLSPServer.cpp')
-rw-r--r-- | clang-tools-extra/clangd/ClangdLSPServer.cpp | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index a72e8c7cd9b..78466f4f3ad 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -13,6 +13,7 @@ #include "Trace.h" #include "URI.h" #include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" @@ -93,6 +94,7 @@ public: MessageHandler(ClangdLSPServer &Server) : Server(Server) {} bool onNotify(llvm::StringRef Method, llvm::json::Value Params) override { + WithContext HandlerContext(handlerContext()); log("<-- {0}", Method); if (Method == "exit") return false; @@ -109,6 +111,7 @@ public: bool onCall(llvm::StringRef Method, llvm::json::Value Params, llvm::json::Value ID) override { + WithContext HandlerContext(handlerContext()); // Calls can be canceled by the client. Add cancellation context. WithContext WithCancel(cancelableRequestContext(ID)); trace::Span Tracer(Method); @@ -129,6 +132,7 @@ public: bool onReply(llvm::json::Value ID, llvm::Expected<llvm::json::Value> Result) override { + WithContext HandlerContext(handlerContext()); // We ignore replies, just log them. if (Result) log("<-- reply({0})", ID); @@ -259,6 +263,13 @@ private: if (It != RequestCancelers.end()) It->second.first(); // Invoke the canceler. } + + Context handlerContext() const { + return Context::current().derive( + kCurrentOffsetEncoding, + Server.NegotiatedOffsetEncoding.getValueOr(OffsetEncoding::UTF16)); + } + // We run cancelable requests in a context that does two things: // - allows cancellation using RequestCancelers[ID] // - cleans up the entry in RequestCancelers when it's no longer needed @@ -302,6 +313,20 @@ void ClangdLSPServer::notify(llvm::StringRef Method, llvm::json::Value Params) { void ClangdLSPServer::onInitialize(const InitializeParams &Params, Callback<llvm::json::Value> Reply) { + // Determine character encoding first as it affects constructed ClangdServer. + if (Params.capabilities.offsetEncoding && !NegotiatedOffsetEncoding) { + NegotiatedOffsetEncoding = OffsetEncoding::UTF16; // fallback + for (OffsetEncoding Supported : *Params.capabilities.offsetEncoding) + if (Supported != OffsetEncoding::UnsupportedEncoding) { + NegotiatedOffsetEncoding = Supported; + break; + } + } + llvm::Optional<WithContextValue> WithOffsetEncoding; + if (NegotiatedOffsetEncoding) + WithOffsetEncoding.emplace(kCurrentOffsetEncoding, + *NegotiatedOffsetEncoding); + if (Params.rootUri && *Params.rootUri) ClangdServerOpts.WorkspaceRoot = Params.rootUri->file(); else if (Params.rootPath && !Params.rootPath->empty()) @@ -331,7 +356,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, SupportsHierarchicalDocumentSymbol = Params.capabilities.HierarchicalDocumentSymbol; SupportFileStatus = Params.initializationOptions.FileStatus; - Reply(llvm::json::Object{ + llvm::json::Object Result{ {{"capabilities", llvm::json::Object{ {"textDocumentSync", (int)TextDocumentSyncKind::Incremental}, @@ -369,7 +394,10 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, ExecuteCommandParams::CLANGD_APPLY_TWEAK}}, }}, {"typeHierarchyProvider", true}, - }}}}); + }}}}; + if (NegotiatedOffsetEncoding) + Result["offsetEncoding"] = *NegotiatedOffsetEncoding; + Reply(std::move(Result)); } void ClangdLSPServer::onShutdown(const ShutdownParams &Params, @@ -875,19 +903,19 @@ void ClangdLSPServer::onSymbolInfo(const TextDocumentPositionParams &Params, std::move(Reply)); } -ClangdLSPServer::ClangdLSPServer(class Transport &Transp, - const FileSystemProvider &FSProvider, - const clangd::CodeCompleteOptions &CCOpts, - llvm::Optional<Path> CompileCommandsDir, - bool UseDirBasedCDB, - const ClangdServer::Options &Opts) +ClangdLSPServer::ClangdLSPServer( + class Transport &Transp, const FileSystemProvider &FSProvider, + const clangd::CodeCompleteOptions &CCOpts, + llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB, + llvm::Optional<OffsetEncoding> ForcedOffsetEncoding, + const ClangdServer::Options &Opts) : Transp(Transp), MsgHandler(new MessageHandler(*this)), FSProvider(FSProvider), CCOpts(CCOpts), SupportedSymbolKinds(defaultSymbolKinds()), SupportedCompletionItemKinds(defaultCompletionItemKinds()), UseDirBasedCDB(UseDirBasedCDB), - CompileCommandsDir(std::move(CompileCommandsDir)), - ClangdServerOpts(Opts) { + CompileCommandsDir(std::move(CompileCommandsDir)), ClangdServerOpts(Opts), + NegotiatedOffsetEncoding(ForcedOffsetEncoding) { // clang-format off MsgHandler->bind("initialize", &ClangdLSPServer::onInitialize); MsgHandler->bind("shutdown", &ClangdLSPServer::onShutdown); |