[clangd] Rearrange type, returntype and parameters in hover card
authorKadir Cetinkaya <kadircet@google.com>
Mon, 13 Jan 2020 16:21:31 +0000 (17:21 +0100)
committerKadir Cetinkaya <kadircet@google.com>
Wed, 15 Jan 2020 14:55:46 +0000 (15:55 +0100)
Summary:
Moves type/returntype into its own line as it is more readable in cases
where the type is long.

Also gives parameter lists a heading, `Parameters:` to make them stand out.

Leaves the `right arrow` instead of `Returns: ` before Return Type to make
output more symmetric.

```
function foo

Returns: ret_type
Parameters:
- int x
```

vs

```
function foo

🡺 ret_type
Parameters:
- int x
```

Reviewers: sammccall, ilya-biryukov

Subscribers: MaskRay, jkorous, arphaman, usaxena95, cfe-commits

Tags: #clang

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

clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/test/hover.test
clang-tools-extra/clangd/unittests/HoverTests.cpp

index 2981418..118d585 100644 (file)
@@ -510,13 +510,14 @@ llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
 markup::Document HoverInfo::present() const {
   markup::Document Output;
   // Header contains a text of the form:
-  // variable `var` : `int`
+  // variable `var`
   //
   // class `X`
   //
-  // function `foo` â†’ `int`
+  // function `foo`
+  //
+  // expression
   //
-  // expression : `int`
   // Note that we are making use of a level-3 heading because VSCode renders
   // level 1 and 2 headers in a huge font, see
   // https://github.com/microsoft/vscode/issues/88417 for details.
@@ -524,27 +525,30 @@ markup::Document HoverInfo::present() const {
   Header.appendText(index::getSymbolKindString(Kind));
   assert(!Name.empty() && "hover triggered on a nameless symbol");
   Header.appendCode(Name);
-  if (ReturnType) {
-    Header.appendText("→");
-    Header.appendCode(*ReturnType);
-  } else if (Type) {
-    Header.appendText(":");
-    Header.appendCode(*Type);
-  }
 
   // Put a linebreak after header to increase readability.
   Output.addRuler();
-  // For functions we display signature in a list form, e.g.:
-  // - `bool param1`
-  // - `int param2 = 5`
-  if (Parameters && !Parameters->empty()) {
-    markup::BulletList &L = Output.addBulletList();
-    for (const auto &Param : *Parameters) {
-      std::string Buffer;
-      llvm::raw_string_ostream OS(Buffer);
-      OS << Param;
-      L.addItem().addParagraph().appendCode(std::move(OS.str()));
+  // Print Types on their own lines to reduce chances of getting line-wrapped by
+  // editor, as they might be long.
+  if (ReturnType) {
+    // For functions we display signature in a list form, e.g.:
+    // ðŸ¡º `x`
+    // Parameters:
+    // - `bool param1`
+    // - `int param2 = 5`
+    Output.addParagraph().appendText("🡺").appendCode(*ReturnType);
+    if (Parameters && !Parameters->empty()) {
+      Output.addParagraph().appendText("Parameters:");
+      markup::BulletList &L = Output.addBulletList();
+      for (const auto &Param : *Parameters) {
+        std::string Buffer;
+        llvm::raw_string_ostream OS(Buffer);
+        OS << Param;
+        L.addItem().addParagraph().appendCode(std::move(OS.str()));
+      }
     }
+  } else if (Type) {
+    Output.addParagraph().appendText("Type: ").appendCode(*Type);
   }
 
   if (Value) {
index 2162ff9..79f7a01 100644 (file)
@@ -9,7 +9,7 @@
 # CHECK-NEXT:  "result": {\r
 # CHECK-NEXT:    "contents": {\r
 # CHECK-NEXT:      "kind": "plaintext",\r
-# CHECK-NEXT:      "value": "function foo â†’ void\n\nvoid foo()"\r
+# CHECK-NEXT:      "value": "function foo\n\n🡺 void\n\nvoid foo()"\r
 # CHECK-NEXT:    },\r
 # CHECK-NEXT:    "range": {\r
 # CHECK-NEXT:      "end": {\r
index bca8dc4..0898b31 100644 (file)
@@ -1722,8 +1722,10 @@ template <typename T, typename C = bool> class Foo {})",
             HI.NamespaceScope = "ns::";
             HI.Definition = "ret_type foo(params) {}";
           },
-          R"(function foo â†’ ret_type
+          R"(function foo
 
+🡺 ret_type
+Parameters:
 - 
 - type
 - type foo
@@ -1741,8 +1743,9 @@ ret_type foo(params) {})",
             HI.Type = "type";
             HI.Definition = "def";
           },
-          R"(variable foo : type
+          R"(variable foo
 
+Type: type
 Value = value
 
 // In test::bar
@@ -1763,9 +1766,8 @@ TEST(Hover, PresentHeadings) {
   HoverInfo HI;
   HI.Kind = index::SymbolKind::Variable;
   HI.Name = "foo";
-  HI.Type = "type";
 
-  EXPECT_EQ(HI.present().asMarkdown(), "### variable `foo` \\: `type`");
+  EXPECT_EQ(HI.present().asMarkdown(), "### variable `foo`");
 }
 
 // This is a separate test as rulers behave differently in markdown vs