[Mlir-commits] [mlir] f492c35 - [mlir-lsp-server] Add support for hover on region operations

River Riddle llvmlistbot at llvm.org
Mon Jun 7 14:10:54 PDT 2021


Author: River Riddle
Date: 2021-06-07T14:07:41-07:00
New Revision: f492c35965036d67833dae3c21498dcd1c1ed1fe

URL: https://github.com/llvm/llvm-project/commit/f492c35965036d67833dae3c21498dcd1c1ed1fe
DIFF: https://github.com/llvm/llvm-project/commit/f492c35965036d67833dae3c21498dcd1c1ed1fe.diff

LOG: [mlir-lsp-server] Add support for hover on region operations

This revision adds support for hover on region operations, by temporarily removing the regions during printing. This revision also tweaks the hover format for operations to include symbol information, now that FuncOp can be shown in the hover.

Differential Revision: https://reviews.llvm.org/D103727

Added: 
    

Modified: 
    mlir/include/mlir/IR/SymbolTable.h
    mlir/lib/IR/SymbolTable.cpp
    mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
    mlir/test/mlir-lsp-server/hover.test

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/IR/SymbolTable.h b/mlir/include/mlir/IR/SymbolTable.h
index 0e123ad8ad74..97c87a43c385 100644
--- a/mlir/include/mlir/IR/SymbolTable.h
+++ b/mlir/include/mlir/IR/SymbolTable.h
@@ -212,6 +212,8 @@ class SymbolTable {
   unsigned uniquingCounter = 0;
 };
 
+raw_ostream &operator<<(raw_ostream &os, SymbolTable::Visibility visibility);
+
 //===----------------------------------------------------------------------===//
 // SymbolTableCollection
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/IR/SymbolTable.cpp b/mlir/lib/IR/SymbolTable.cpp
index e6924414465b..aef7b92bce8c 100644
--- a/mlir/lib/IR/SymbolTable.cpp
+++ b/mlir/lib/IR/SymbolTable.cpp
@@ -375,6 +375,18 @@ Operation *SymbolTable::lookupNearestSymbolFrom(Operation *from,
   return symbolTableOp ? lookupSymbolIn(symbolTableOp, symbol) : nullptr;
 }
 
+raw_ostream &mlir::operator<<(raw_ostream &os,
+                              SymbolTable::Visibility visibility) {
+  switch (visibility) {
+  case SymbolTable::Visibility::Public:
+    return os << "public";
+  case SymbolTable::Visibility::Private:
+    return os << "private";
+  case SymbolTable::Visibility::Nested:
+    return os << "nested";
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // SymbolTable Trait Types
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
index d4b61372552d..3ff363374605 100644
--- a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
+++ b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
@@ -474,21 +474,34 @@ Optional<lsp::Hover> MLIRDocument::findHover(const lsp::URIForFile &uri,
 
 Optional<lsp::Hover> MLIRDocument::buildHoverForOperation(
     const AsmParserState::OperationDefinition &op) {
-  // Don't show hovers for operations with regions to avoid huge hover  blocks.
-  // TODO: Should we add support for printing an op without its regions?
-  if (llvm::any_of(op.op->getRegions(),
-                   [](Region &region) { return !region.empty(); }))
-    return llvm::None;
-
   lsp::Hover hover(getRangeFromLoc(sourceMgr, op.loc));
   llvm::raw_string_ostream os(hover.contents.value);
 
-  // For hovers on an operation, show the generic form.
-  os << "```mlir\n";
+  // Add the operation name to the hover.
+  os << "\"" << op.op->getName() << "\"";
+  if (SymbolOpInterface symbol = dyn_cast<SymbolOpInterface>(op.op))
+    os << " : " << symbol.getVisibility() << " @" << symbol.getName() << "";
+  os << "\n\n";
+
+  os << "Generic Form:\n\n```mlir\n";
+
+  // Temporary drop the regions of this operation so that they don't get
+  // printed in the output. This helps keeps the size of the output hover
+  // small.
+  SmallVector<std::unique_ptr<Region>> regions;
+  for (Region &region : op.op->getRegions()) {
+    regions.emplace_back(std::make_unique<Region>());
+    regions.back()->takeBody(region);
+  }
+
   op.op->print(
       os, OpPrintingFlags().printGenericOpForm().elideLargeElementsAttrs());
   os << "\n```\n";
 
+  // Move the regions back to the current operation.
+  for (Region &region : op.op->getRegions())
+    region.takeBody(*regions.back());
+
   return hover;
 }
 

diff  --git a/mlir/test/mlir-lsp-server/hover.test b/mlir/test/mlir-lsp-server/hover.test
index 71008c8d9ab2..9e5a89bc3b44 100644
--- a/mlir/test/mlir-lsp-server/hover.test
+++ b/mlir/test/mlir-lsp-server/hover.test
@@ -18,7 +18,7 @@
 // CHECK-NEXT:  "result": {
 // CHECK-NEXT:    "contents": {
 // CHECK-NEXT:      "kind": "markdown",
-// CHECK-NEXT:      "value": "```mlir\n%true = \"std.constant\"() {value = true} : () -> i1\n```\n"
+// CHECK-NEXT:      "value": "\"std.constant\"\n\nGeneric Form:\n\n```mlir\n%true = \"std.constant\"() {value = true} : () -> i1\n```\n"
 // CHECK-NEXT:    },
 // CHECK-NEXT:    "range": {
 // CHECK-NEXT:      "end": {
@@ -33,11 +33,11 @@
 // CHECK-NEXT:  }
 // -----
 // Hover on an operation result.
-{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{
+{"jsonrpc":"2.0","id":2,"method":"textDocument/hover","params":{
   "textDocument":{"uri":"test:///foo.mlir"},
   "position":{"line":1,"character":2}
 }}
-//      CHECK:  "id": 1,
+//      CHECK:  "id": 2,
 // CHECK-NEXT:  "jsonrpc": "2.0",
 // CHECK-NEXT:  "result": {
 // CHECK-NEXT:    "contents": {
@@ -57,11 +57,11 @@
 // CHECK-NEXT:  }
 // -----
 // Hover on a Block.
-{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{
+{"jsonrpc":"2.0","id":3,"method":"textDocument/hover","params":{
   "textDocument":{"uri":"test:///foo.mlir"},
   "position":{"line":3,"character":2}
 }}
-//      CHECK:  "id": 1,
+//      CHECK:  "id": 3,
 // CHECK-NEXT:  "jsonrpc": "2.0",
 // CHECK-NEXT:  "result": {
 // CHECK-NEXT:    "contents": {
@@ -81,11 +81,11 @@
 // CHECK-NEXT:  }
 // -----
 // Hover on a Block argument.
-{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{
+{"jsonrpc":"2.0","id":4,"method":"textDocument/hover","params":{
   "textDocument":{"uri":"test:///foo.mlir"},
   "position":{"line":0,"character":12}
 }}
-//      CHECK:  "id": 1,
+//      CHECK:  "id": 4,
 // CHECK-NEXT:  "jsonrpc": "2.0",
 // CHECK-NEXT:  "result": {
 // CHECK-NEXT:    "contents": {
@@ -104,6 +104,30 @@
 // CHECK-NEXT:    }
 // CHECK-NEXT:  }
 // -----
-{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+// Hover on a region operation.
+{"jsonrpc":"2.0","id":5,"method":"textDocument/hover","params":{
+  "textDocument":{"uri":"test:///foo.mlir"},
+  "position":{"line":0,"character":1}
+}}
+//      CHECK:  "id": 5,
+// CHECK-NEXT:  "jsonrpc": "2.0",
+// CHECK-NEXT:  "result": {
+// CHECK-NEXT:    "contents": {
+// CHECK-NEXT:      "kind": "markdown",
+// CHECK-NEXT:      "value": "\"func\" : public @foo\n\nGeneric Form:\n\n```mlir\n\"func\"() ( {\n}) {sym_name = \"foo\", type = (i1) -> ()} : () -> ()\n```\n"
+// CHECK-NEXT:    },
+// CHECK-NEXT:    "range": {
+// CHECK-NEXT:      "end": {
+// CHECK-NEXT:        "character": 4,
+// CHECK-NEXT:        "line": 0
+// CHECK-NEXT:      },
+// CHECK-NEXT:      "start": {
+// CHECK-NEXT:        "character": 0,
+// CHECK-NEXT:        "line": 0
+// CHECK-NEXT:      }
+// CHECK-NEXT:    }
+// CHECK-NEXT:  }
+// -----
+{"jsonrpc":"2.0","id":6,"method":"shutdown"}
 // -----
 {"jsonrpc":"2.0","method":"exit"}


        


More information about the Mlir-commits mailing list