[clang-tools-extra] r372753 - [clangd] Add semantic selection to ClangdLSPServer.
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 24 06:38:33 PDT 2019
Author: usaxena95
Date: Tue Sep 24 06:38:33 2019
New Revision: 372753
URL: http://llvm.org/viewvc/llvm-project?rev=372753&view=rev
Log:
[clangd] Add semantic selection to ClangdLSPServer.
Summary:
This adds semantic selection to the LSP Server.
Adds support for serialization of input request and the output reply.
Also adds regression tests for the feature.
Currently we do not support multi cursor.The LSP Server only accepts single position in the request as opposed to many position in the spec.
Spec:
https://github.com/microsoft/language-server-protocol/blob/dbaeumer/3.15/specification.md#textDocument_selectionRange
Reviewers: hokein
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D67720
Added:
clang-tools-extra/trunk/clangd/test/selection-range.test
Modified:
clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
clang-tools-extra/trunk/clangd/ClangdLSPServer.h
clang-tools-extra/trunk/clangd/Protocol.cpp
clang-tools-extra/trunk/clangd/Protocol.h
clang-tools-extra/trunk/clangd/test/initialize-params.test
Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=372753&r1=372752&r2=372753&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Tue Sep 24 06:38:33 2019
@@ -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 DraftSto
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
{"documentHighlightProvider", true},
{"hoverProvider", true},
{"renameProvider", std::move(RenameProvider)},
+ {"selectionRangeProvider", true},
{"documentSymbolProvider", true},
{"workspaceSymbolProvider", true},
{"referencesProvider", true},
@@ -1125,6 +1145,30 @@ void ClangdLSPServer::onSymbolInfo(const
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
}
Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=372753&r1=372752&r2=372753&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Tue Sep 24 06:38:33 2019
@@ -107,6 +107,8 @@ private:
void onChangeConfiguration(const DidChangeConfigurationParams &);
void onSymbolInfo(const TextDocumentPositionParams &,
Callback<std::vector<SymbolDetails>>);
+ void onSelectionRange(const SelectionRangeParams &,
+ Callback<std::vector<SelectionRange>>);
std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
Modified: clang-tools-extra/trunk/clangd/Protocol.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=372753&r1=372752&r2=372753&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.cpp (original)
+++ clang-tools-extra/trunk/clangd/Protocol.cpp Tue Sep 24 06:38:33 2019
@@ -1073,5 +1073,18 @@ llvm::json::Value toJSON(const SemanticH
};
}
+bool fromJSON(const llvm::json::Value &Params, SelectionRangeParams &P) {
+ llvm::json::ObjectMapper O(Params);
+ return O && O.map("textDocument", P.textDocument) &&
+ O.map("positions", P.positions);
+}
+
+llvm::json::Value toJSON(const SelectionRange &Out) {
+ if (Out.parent) {
+ return llvm::json::Object{{"range", Out.range},
+ {"parent", toJSON(*Out.parent)}};
+ }
+ return llvm::json::Object{{"range", Out.range}};
+}
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/Protocol.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=372753&r1=372752&r2=372753&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.h (original)
+++ clang-tools-extra/trunk/clangd/Protocol.h Tue Sep 24 06:38:33 2019
@@ -30,6 +30,7 @@
#include "llvm/Support/JSON.h"
#include "llvm/Support/raw_ostream.h"
#include <bitset>
+#include <memory>
#include <string>
#include <vector>
@@ -1222,6 +1223,28 @@ struct SemanticHighlightingParams {
};
llvm::json::Value toJSON(const SemanticHighlightingParams &Highlighting);
+struct SelectionRangeParams {
+ /// The text document.
+ TextDocumentIdentifier textDocument;
+
+ /// The positions inside the text document.
+ std::vector<Position> positions;
+};
+bool fromJSON(const llvm::json::Value &, SelectionRangeParams &);
+
+struct SelectionRange {
+ /**
+ * The range of this selection range.
+ */
+ Range range;
+ /**
+ * The parent selection range containing this range. Therefore `parent.range`
+ * must contain `this.range`.
+ */
+ std::unique_ptr<SelectionRange> parent;
+};
+llvm::json::Value toJSON(const SelectionRange &);
+
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/test/initialize-params.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/test/initialize-params.test?rev=372753&r1=372752&r2=372753&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/test/initialize-params.test (original)
+++ clang-tools-extra/trunk/clangd/test/initialize-params.test Tue Sep 24 06:38:33 2019
@@ -33,6 +33,7 @@
# CHECK-NEXT: "hoverProvider": true,
# CHECK-NEXT: "referencesProvider": true,
# CHECK-NEXT: "renameProvider": true,
+# CHECK-NEXT: "selectionRangeProvider": true,
# CHECK-NEXT: "signatureHelpProvider": {
# CHECK-NEXT: "triggerCharacters": [
# CHECK-NEXT: "(",
Added: clang-tools-extra/trunk/clangd/test/selection-range.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/test/selection-range.test?rev=372753&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/test/selection-range.test (added)
+++ clang-tools-extra/trunk/clangd/test/selection-range.test Tue Sep 24 06:38:33 2019
@@ -0,0 +1,39 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void func() {\n}"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/selectionRange","params":{"textDocument":{"uri":"test:///main.cpp"},"positions":[{"line":1,"character":0}]}}
+# CHECK: "id": 1
+# CHECK-NEXT: "jsonrpc": "2.0",
+# CHECK-NEXT: "result": [
+# CHECK-NEXT: {
+# CHECK-NEXT: "parent": {
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 1,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 0,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: },
+# CHECK-NEXT: "range": {
+# CHECK-NEXT: "end": {
+# CHECK-NEXT: "character": 1,
+# CHECK-NEXT: "line": 1
+# CHECK-NEXT: },
+# CHECK-NEXT: "start": {
+# CHECK-NEXT: "character": 12,
+# CHECK-NEXT: "line": 0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT:}
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
More information about the cfe-commits
mailing list