summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2018-08-10 17:25:07 +0000
committerAlex Lorenz <arphaman@gmail.com>2018-08-10 17:25:07 +0000
commit8626d36f8c54ec8d1667e14cf3618edb183686ec (patch)
tree70bbb01301459c3cdf43c7174cd7054d4547f0a1
parent12a2911f621895358a3df435b1b25d231c0f6a14 (diff)
downloadbcm5719-llvm-8626d36f8c54ec8d1667e14cf3618edb183686ec.tar.gz
bcm5719-llvm-8626d36f8c54ec8d1667e14cf3618edb183686ec.zip
[clangd] extend the publishDiagnostics response to send back fixits to the
client if the client supports this extension This commit extends the 'textDocument/publishDiagnostics' notification sent from Clangd to the client. When it's enabled, Clangd sends out the fixits associated with the appropriate diagnostic in the body of the 'publishDiagnostics' notification. The client can enable this extension by setting 'clangdFixSupport' to true in the textDocument capabilities during initialization. Differential Revision: https://reviews.llvm.org/D50415 llvm-svn: 339454
-rw-r--r--clang-tools-extra/clangd/ClangdLSPServer.cpp18
-rw-r--r--clang-tools-extra/clangd/ClangdLSPServer.h2
-rw-r--r--clang-tools-extra/clangd/Diagnostics.h6
-rw-r--r--clang-tools-extra/clangd/Protocol.cpp10
-rw-r--r--clang-tools-extra/clangd/Protocol.h15
5 files changed, 50 insertions, 1 deletions
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 99353e6c5ca..0d3023be42f 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -82,6 +82,8 @@ void ClangdLSPServer::onInitialize(InitializeParams &Params) {
CCOpts.EnableSnippets =
Params.capabilities.textDocument.completion.completionItem.snippetSupport;
+ DiagOpts.EmbedFixesInDiagnostics =
+ Params.capabilities.textDocument.publishDiagnostics.clangdFixSupport;
if (Params.capabilities.workspace && Params.capabilities.workspace->symbol &&
Params.capabilities.workspace->symbol->symbolKind) {
@@ -486,11 +488,25 @@ void ClangdLSPServer::onDiagnosticsReady(PathRef File,
DiagnosticToReplacementMap LocalFixIts; // Temporary storage
for (auto &Diag : Diagnostics) {
toLSPDiags(Diag, [&](clangd::Diagnostic Diag, llvm::ArrayRef<Fix> Fixes) {
- DiagnosticsJSON.push_back(json::Object{
+ json::Object LSPDiag({
{"range", Diag.range},
{"severity", Diag.severity},
{"message", Diag.message},
});
+ // LSP extension: embed the fixes in the diagnostic.
+ if (DiagOpts.EmbedFixesInDiagnostics && !Fixes.empty()) {
+ json::Array ClangdFixes;
+ for (const auto &Fix : Fixes) {
+ WorkspaceEdit WE;
+ URIForFile URI{File};
+ WE.changes = {{URI.uri(), std::vector<TextEdit>(Fix.Edits.begin(),
+ Fix.Edits.end())}};
+ ClangdFixes.push_back(
+ json::Object{{"edit", toJSON(WE)}, {"title", Fix.Message}});
+ }
+ LSPDiag["clangd_fixes"] = std::move(ClangdFixes);
+ }
+ DiagnosticsJSON.push_back(std::move(LSPDiag));
auto &FixItsForDiagnostic = LocalFixIts[Diag];
std::copy(Fixes.begin(), Fixes.end(),
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h
index 3850e4a97b7..e4cbe5001a2 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -155,6 +155,8 @@ private:
RealFileSystemProvider FSProvider;
/// Options used for code completion
clangd::CodeCompleteOptions CCOpts;
+ /// Options used for diagnostics.
+ ClangdDiagnosticOptions DiagOpts;
/// The supported kinds of the client.
SymbolKindBitset SupportedSymbolKinds;
diff --git a/clang-tools-extra/clangd/Diagnostics.h b/clang-tools-extra/clangd/Diagnostics.h
index b43f04ae535..a08b9fe0465 100644
--- a/clang-tools-extra/clangd/Diagnostics.h
+++ b/clang-tools-extra/clangd/Diagnostics.h
@@ -23,6 +23,12 @@
namespace clang {
namespace clangd {
+struct ClangdDiagnosticOptions {
+ /// If true, Clangd uses an LSP extension to embed the fixes with the
+ /// diagnostics that are sent to the client.
+ bool EmbedFixesInDiagnostics = false;
+};
+
/// Contains basic information about a diagnostic.
struct DiagBase {
std::string Message;
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index 202fbfb08e0..698bb048902 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -178,6 +178,15 @@ bool fromJSON(const json::Value &Params, CompletionClientCapabilities &R) {
return true;
}
+bool fromJSON(const llvm::json::Value &Params,
+ PublishDiagnosticsClientCapabilities &R) {
+ json::ObjectMapper O(Params);
+ if (!O)
+ return false;
+ O.map("clangdFixSupport", R.clangdFixSupport);
+ return true;
+}
+
bool fromJSON(const json::Value &E, SymbolKind &Out) {
if (auto T = E.getAsInteger()) {
if (*T < static_cast<int>(SymbolKind::File) ||
@@ -240,6 +249,7 @@ bool fromJSON(const json::Value &Params, TextDocumentClientCapabilities &R) {
if (!O)
return false;
O.map("completion", R.completion);
+ O.map("publishDiagnostics", R.publishDiagnostics);
return true;
}
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index b0d810e87fe..f533c97f487 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -247,6 +247,18 @@ struct CompletionClientCapabilities {
};
bool fromJSON(const llvm::json::Value &, CompletionClientCapabilities &);
+struct PublishDiagnosticsClientCapabilities {
+ // Whether the client accepts diagnostics with related information.
+ // NOTE: not used by clangd at the moment.
+ // bool relatedInformation;
+
+ /// Whether the client accepts diagnostics with fixes attached using the
+ /// "clangd_fixes" extension.
+ bool clangdFixSupport = false;
+};
+bool fromJSON(const llvm::json::Value &,
+ PublishDiagnosticsClientCapabilities &);
+
/// A symbol kind.
enum class SymbolKind {
File = 1,
@@ -313,6 +325,9 @@ bool fromJSON(const llvm::json::Value &, WorkspaceClientCapabilities &);
struct TextDocumentClientCapabilities {
/// Capabilities specific to the `textDocument/completion`
CompletionClientCapabilities completion;
+
+ /// Capabilities specific to the 'textDocument/publishDiagnostics'
+ PublishDiagnosticsClientCapabilities publishDiagnostics;
};
bool fromJSON(const llvm::json::Value &, TextDocumentClientCapabilities &);
OpenPOWER on IntegriCloud