[Lldb-commits] [lldb] 6b4f675 - [lldb] Improve rendering of inline diagnostics on the same column (#116727)

via lldb-commits lldb-commits at lists.llvm.org
Tue Nov 19 09:13:04 PST 2024


Author: Adrian Prantl
Date: 2024-11-19T09:13:00-08:00
New Revision: 6b4f67545d87d5305cbbc20a678fb97ede995579

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

LOG: [lldb] Improve rendering of inline diagnostics on the same column (#116727)

depends on https://github.com/llvm/llvm-project/pull/116711

[lldb] Improve rendering of inline diagnostics on the same column by
fixing the indentation and printing these annotations in the original
order.

Before

    a+b+c;
    ^ ^ ^
    | | error: 3
    | |note: 2b
    | error: 2a
    error: 1

After

    a+b+c;
    ^ ^ ^
    | | error: 3
    | error: 2a
    | note: 2b
    error: 1

Added: 
    

Modified: 
    lldb/source/Utility/DiagnosticsRendering.cpp
    lldb/unittests/Utility/DiagnosticsRenderingTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Utility/DiagnosticsRendering.cpp b/lldb/source/Utility/DiagnosticsRendering.cpp
index dfc47ac460ac9f..a20d82ad4eb678 100644
--- a/lldb/source/Utility/DiagnosticsRendering.cpp
+++ b/lldb/source/Utility/DiagnosticsRendering.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Utility/DiagnosticsRendering.h"
+#include <cstdint>
 
 using namespace lldb_private;
 using namespace lldb;
@@ -98,7 +99,7 @@ void RenderDiagnosticDetails(Stream &stream,
   }
 
   // Sort the diagnostics.
-  auto sort = [](auto &ds) {
+  auto sort = [](std::vector<DiagnosticDetail> &ds) {
     std::stable_sort(ds.begin(), ds.end(), [](auto &d1, auto &d2) {
       auto l1 = d1.source_location.value_or(DiagnosticDetail::SourceLocation{});
       auto l2 = d2.source_location.value_or(DiagnosticDetail::SourceLocation{});
@@ -130,6 +131,25 @@ void RenderDiagnosticDetails(Stream &stream,
   }
   stream << '\n';
 
+  // Reverse the order within groups of diagnostics that are on the same column.
+  auto group = [](const std::vector<DiagnosticDetail> &details) {
+    uint16_t column = 0;
+    std::vector<DiagnosticDetail> result, group;
+    for (auto &d : details) {
+      if (d.source_location->column == column) {
+        group.push_back(d);
+        continue;
+      }
+      result.insert(result.end(), group.rbegin(), group.rend());
+      group.clear();
+      column = d.source_location->column;
+      group.push_back(d);
+    }
+    result.insert(result.end(), group.rbegin(), group.rend());
+    return result;
+  };
+  remaining_details = group(remaining_details);
+
   // Work through each detail in reverse order using the vector/stack.
   bool did_print = false;
   for (auto detail = remaining_details.rbegin();
@@ -142,14 +162,19 @@ void RenderDiagnosticDetails(Stream &stream,
     for (auto &remaining_detail :
          llvm::ArrayRef(remaining_details).drop_back(1)) {
       uint16_t column = remaining_detail.source_location->column;
-      if (x_pos <= column)
+      // Is this a note with the same column as another diagnostic?
+      if (column == detail->source_location->column)
+        continue;
+
+      if (column >= x_pos) {
         stream << std::string(column - x_pos, ' ') << vbar;
-      x_pos = column + 1;
+        x_pos = column + 1;
+      }
     }
 
-    // Print the line connecting the ^ with the error message.
     uint16_t column = detail->source_location->column;
-    if (x_pos <= column)
+    // Print the line connecting the ^ with the error message.
+    if (column >= x_pos)
       stream << std::string(column - x_pos, ' ') << joint << hbar << spacer;
 
     // Print a colorized string based on the message's severity type.

diff  --git a/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp b/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp
index 1187f3f65f27fd..4e5e0bb7dc3552 100644
--- a/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp
+++ b/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp
@@ -29,15 +29,22 @@ TEST_F(ErrorDisplayTest, RenderStatus) {
   {
     // Test that diagnostics on the same column can be handled and all
     // three errors are diagnosed.
-    SourceLocation loc1 = {FileSpec{"a.c"}, 13, 11, 0, false, true};
-    SourceLocation loc2 = {FileSpec{"a.c"}, 13, 13, 0, false, true};
+    SourceLocation loc1 = {FileSpec{"a.c"}, 13, 5, 0, false, true};
+    SourceLocation loc2 = {FileSpec{"a.c"}, 13, 7, 0, false, true};
+    SourceLocation loc3 = {FileSpec{"a.c"}, 13, 9, 0, false, true};
     std::string result =
         Render({DiagnosticDetail{loc1, eSeverityError, "1", "1"},
-                DiagnosticDetail{loc1, eSeverityError, "2", "2"},
-                DiagnosticDetail{loc2, eSeverityError, "3", "3"}});
-    ASSERT_TRUE(StringRef(result).contains("error: 1"));
-    ASSERT_TRUE(StringRef(result).contains("error: 2"));
-    ASSERT_TRUE(StringRef(result).contains("error: 3"));
+                DiagnosticDetail{loc2, eSeverityError, "2a", "2a"},
+                DiagnosticDetail{loc2, eSeverityInfo, "2b", "2b"},
+                DiagnosticDetail{loc3, eSeverityError, "3", "3"}});
+    llvm::SmallVector<StringRef> lines;
+    StringRef(result).split(lines, '\n');
+    //                1234567890123
+    ASSERT_EQ(lines[0], "    ^ ^ ^");
+    ASSERT_EQ(lines[1], "    | | error: 3");
+    ASSERT_EQ(lines[2], "    | error: 2a");
+    ASSERT_EQ(lines[3], "    | note: 2b");
+    ASSERT_EQ(lines[4], "    error: 1");
   }
   {
     // Test that diagnostics in reverse order are emitted correctly.
@@ -68,16 +75,12 @@ TEST_F(ErrorDisplayTest, RenderStatus) {
     std::string result =
         Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
                 DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
-    auto lines = StringRef(result).split('\n');
-    auto line1 = lines.first;
-    lines = lines.second.split('\n');
-    auto line2 = lines.first;
-    lines = lines.second.split('\n');
-    auto line3 = lines.first;
+    llvm::SmallVector<StringRef> lines;
+    StringRef(result).split(lines, '\n');
     //                1234567
-    ASSERT_EQ(line1, "^~~ ^~~");
-    ASSERT_EQ(line2, "|   error: Y");
-    ASSERT_EQ(line3, "error: X");
+    ASSERT_EQ(lines[0], "^~~ ^~~");
+    ASSERT_EQ(lines[1], "|   error: Y");
+    ASSERT_EQ(lines[2], "error: X");
   }
   {
     // Test diagnostics on the same line are emitted correctly.
@@ -86,15 +89,11 @@ TEST_F(ErrorDisplayTest, RenderStatus) {
     std::string result =
         Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
                 DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
-    auto lines = StringRef(result).split('\n');
-    auto line1 = lines.first;
-    lines = lines.second.split('\n');
-    auto line2 = lines.first;
-    lines = lines.second.split('\n');
-    auto line3 = lines.first;
+    llvm::SmallVector<StringRef> lines;
+    StringRef(result).split(lines, '\n');
     //                1234567
-    ASSERT_EQ(line1, " ^   ^");
-    ASSERT_EQ(line2, " |   error: Y");
-    ASSERT_EQ(line3, " error: X");
+    ASSERT_EQ(lines[0], " ^   ^");
+    ASSERT_EQ(lines[1], " |   error: Y");
+    ASSERT_EQ(lines[2], " error: X");
   }
 }


        


More information about the lldb-commits mailing list