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.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 0930c80da06..fd5b3444f34 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -22,14 +22,18 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SHA1.h"
#include "llvm/Support/ScopedPrinter.h"
#include <cstddef>
+#include <memory>
#include <string>
+#include <vector>
namespace clang {
namespace clangd {
@@ -127,6 +131,21 @@ llvm::Error validateEdits(const DraftStore &DraftMgr, const Tweak::Effect &E) {
llvm::to_string(InvalidFileCount - 1) + " others)");
}
+// Converts a list of Ranges to a LinkedList of SelectionRange.
+SelectionRange render(const std::vector<Range> &Ranges) {
+ if (Ranges.empty())
+ return {};
+ SelectionRange Result;
+ Result.range = Ranges[0];
+ auto *Next = &Result.parent;
+ for (const auto &R : llvm::make_range(Ranges.begin() + 1, Ranges.end())) {
+ *Next = std::make_unique<SelectionRange>();
+ Next->get()->range = R;
+ Next = &Next->get()->parent;
+ }
+ return Result;
+}
+
} // namespace
// MessageHandler dispatches incoming LSP messages.
@@ -536,6 +555,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
{"documentHighlightProvider", true},
{"hoverProvider", true},
{"renameProvider", std::move(RenameProvider)},
+ {"selectionRangeProvider", true},
{"documentSymbolProvider", true},
{"workspaceSymbolProvider", true},
{"referencesProvider", true},
@@ -1125,6 +1145,30 @@ void ClangdLSPServer::onSymbolInfo(const TextDocumentPositionParams &Params,
std::move(Reply));
}
+void ClangdLSPServer::onSelectionRange(
+ const SelectionRangeParams &Params,
+ Callback<std::vector<SelectionRange>> Reply) {
+ if (Params.positions.size() != 1) {
+ elog("{0} positions provided to SelectionRange. Supports exactly one "
+ "position.",
+ Params.positions.size());
+ return Reply(llvm::make_error<LSPError>(
+ "SelectionRange supports exactly one position",
+ ErrorCode::InvalidRequest));
+ }
+ Server->semanticRanges(
+ Params.textDocument.uri.file(), Params.positions[0],
+ [Reply = std::move(Reply)](
+ llvm::Expected<std::vector<Range>> Ranges) mutable {
+ if (!Ranges) {
+ return Reply(Ranges.takeError());
+ }
+ std::vector<SelectionRange> Result;
+ Result.emplace_back(render(std::move(*Ranges)));
+ return Reply(std::move(Result));
+ });
+}
+
ClangdLSPServer::ClangdLSPServer(
class Transport &Transp, const FileSystemProvider &FSProvider,
const clangd::CodeCompleteOptions &CCOpts,
@@ -1167,6 +1211,7 @@ ClangdLSPServer::ClangdLSPServer(
MsgHandler->bind("textDocument/symbolInfo", &ClangdLSPServer::onSymbolInfo);
MsgHandler->bind("textDocument/typeHierarchy", &ClangdLSPServer::onTypeHierarchy);
MsgHandler->bind("typeHierarchy/resolve", &ClangdLSPServer::onResolveTypeHierarchy);
+ MsgHandler->bind("textDocument/selectionRange", &ClangdLSPServer::onSelectionRange);
// clang-format on
}
OpenPOWER on IntegriCloud