summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/ClangdLSPServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/ClangdLSPServer.cpp')
-rw-r--r--clang-tools-extra/clangd/ClangdLSPServer.cpp48
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);
OpenPOWER on IntegriCloud