[Mlir-commits] [mlir] [mlir-lsp] Add DiagnosticTag from LSP spec (PR #91396)
Lily Brown
llvmlistbot at llvm.org
Tue May 7 13:49:51 PDT 2024
https://github.com/AmaranthineCodices created https://github.com/llvm/llvm-project/pull/91396
Adds the [DiagnosticTag][diagtag] LSP construct to the LSP support headers. I also added a unit test file to validate that the `tags` array is omitted entirely if it's empty.
The LSP spec requires that `Diagnostic::tags` be an array; in order to conform to that I used `std::vector`, as `SmallVector` doesn't have JSON decoding support (you can encode it to JSON, but not decode it from JSON).
[diagtag]: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnosticTag
>From 362e79e443083899f16457a7547264224841ff00 Mon Sep 17 00:00:00 2001
From: Lily Brown <lbrown at modular.com>
Date: Mon, 6 May 2024 12:03:18 -0700
Subject: [PATCH] [mlir-lsp] Add DiagnosticTag from LSP spec
Adds the [DiagnosticTag][diagtag] LSP construct to the LSP support
headers. I also added a unit test file to validate that the `tags` array
is omitted entirely if it's empty.
The LSP spec requires that `Diagnostic::tags` be an array; in order to
conform to that I used `std::vector`, as `SmallVector` doesn't have JSON
decoding support (you can encode it to JSON, but not decode it from
JSON).
[diagtag]: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnosticTag
---
.../mlir/Tools/lsp-server-support/Protocol.h | 12 +++++
.../lib/Tools/lsp-server-support/Protocol.cpp | 19 ++++++-
.../Tools/lsp-server-support/CMakeLists.txt | 1 +
.../Tools/lsp-server-support/Protocol.cpp | 51 +++++++++++++++++++
4 files changed, 82 insertions(+), 1 deletion(-)
create mode 100644 mlir/unittests/Tools/lsp-server-support/Protocol.cpp
diff --git a/mlir/include/mlir/Tools/lsp-server-support/Protocol.h b/mlir/include/mlir/Tools/lsp-server-support/Protocol.h
index 839d82bb02b87..06205326a5a1f 100644
--- a/mlir/include/mlir/Tools/lsp-server-support/Protocol.h
+++ b/mlir/include/mlir/Tools/lsp-server-support/Protocol.h
@@ -677,6 +677,15 @@ enum class DiagnosticSeverity {
Hint = 4
};
+enum class DiagnosticTag {
+ Unnecessary = 1,
+ Deprecated = 2,
+};
+
+llvm::json::Value toJSON(DiagnosticTag tag);
+bool fromJSON(const llvm::json::Value &value, DiagnosticTag &result,
+ llvm::json::Path path);
+
struct Diagnostic {
/// The source range where the message applies.
Range range;
@@ -696,6 +705,9 @@ struct Diagnostic {
/// a scope collide all definitions can be marked via this property.
std::optional<std::vector<DiagnosticRelatedInformation>> relatedInformation;
+ /// Additional metadata about the diagnostic.
+ std::vector<DiagnosticTag> tags;
+
/// The diagnostic's category. Can be omitted.
/// An LSP extension that's used to send the name of the category over to the
/// client. The category typically describes the compilation stage during
diff --git a/mlir/lib/Tools/lsp-server-support/Protocol.cpp b/mlir/lib/Tools/lsp-server-support/Protocol.cpp
index e110fdd97a38f..f478dd6ec05bc 100644
--- a/mlir/lib/Tools/lsp-server-support/Protocol.cpp
+++ b/mlir/lib/Tools/lsp-server-support/Protocol.cpp
@@ -646,6 +646,20 @@ llvm::json::Value mlir::lsp::toJSON(const DiagnosticRelatedInformation &info) {
// Diagnostic
//===----------------------------------------------------------------------===//
+llvm::json::Value mlir::lsp::toJSON(DiagnosticTag tag) {
+ return static_cast<int>(tag);
+}
+
+bool mlir::lsp::fromJSON(const llvm::json::Value &value, DiagnosticTag &result,
+ llvm::json::Path path) {
+ if (auto i = value.getAsInteger()) {
+ result = (DiagnosticTag)*i;
+ return true;
+ }
+
+ return false;
+}
+
llvm::json::Value mlir::lsp::toJSON(const Diagnostic &diag) {
llvm::json::Object result{
{"range", diag.range},
@@ -658,6 +672,8 @@ llvm::json::Value mlir::lsp::toJSON(const Diagnostic &diag) {
result["source"] = diag.source;
if (diag.relatedInformation)
result["relatedInformation"] = *diag.relatedInformation;
+ if (!diag.tags.empty())
+ result["tags"] = diag.tags;
return std::move(result);
}
@@ -675,7 +691,8 @@ bool mlir::lsp::fromJSON(const llvm::json::Value &value, Diagnostic &result,
mapOptOrNull(value, "category", result.category, path) &&
mapOptOrNull(value, "source", result.source, path) &&
mapOptOrNull(value, "relatedInformation", result.relatedInformation,
- path);
+ path) &&
+ mapOptOrNull(value, "tags", result.tags, path);
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/unittests/Tools/lsp-server-support/CMakeLists.txt b/mlir/unittests/Tools/lsp-server-support/CMakeLists.txt
index 3aa8b9c4bc773..f777873ff7c65 100644
--- a/mlir/unittests/Tools/lsp-server-support/CMakeLists.txt
+++ b/mlir/unittests/Tools/lsp-server-support/CMakeLists.txt
@@ -1,4 +1,5 @@
add_mlir_unittest(MLIRLspServerSupportTests
+ Protocol.cpp
Transport.cpp
)
target_link_libraries(MLIRLspServerSupportTests
diff --git a/mlir/unittests/Tools/lsp-server-support/Protocol.cpp b/mlir/unittests/Tools/lsp-server-support/Protocol.cpp
new file mode 100644
index 0000000000000..f426fca0d62da
--- /dev/null
+++ b/mlir/unittests/Tools/lsp-server-support/Protocol.cpp
@@ -0,0 +1,51 @@
+//===- Protocol.cpp - LSP JSON protocol unit tests ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Tools/lsp-server-support/Protocol.h"
+
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::lsp;
+using namespace testing;
+
+namespace {
+
+TEST(ProtocolTest, DiagnosticTagPresent) {
+ Diagnostic diagnostic;
+ diagnostic.tags.push_back(DiagnosticTag::Unnecessary);
+
+ llvm::json::Value json = toJSON(diagnostic);
+ const llvm::json::Object *o = json.getAsObject();
+ const auto *v = o->get("tags")->getAsArray();
+ EXPECT_EQ(*v, llvm::json::Array{1});
+
+ Diagnostic parsed;
+ auto root = llvm::json::Path::Root();
+ bool success = fromJSON(json, parsed, llvm::json::Path(root));
+ EXPECT_TRUE(success);
+ ASSERT_EQ(parsed.tags.size(), 1);
+ EXPECT_EQ(parsed.tags.at(0), DiagnosticTag::Unnecessary);
+}
+
+TEST(ProtocolTest, DiagnosticTagNotPresent) {
+ Diagnostic diagnostic;
+
+ llvm::json::Value json = toJSON(diagnostic);
+ const llvm::json::Object *o = json.getAsObject();
+ const auto *v = o->get("tags");
+ EXPECT_EQ(v, nullptr);
+
+ Diagnostic parsed;
+ auto root = llvm::json::Path::Root();
+ bool success = fromJSON(json, parsed, llvm::json::Path(root));
+ EXPECT_TRUE(success);
+ EXPECT_TRUE(parsed.tags.empty());
+}
+
+} // namespace
More information about the Mlir-commits
mailing list