Skip to content

Commit aed2bd0

Browse files
committed
[lldb] Improve rendering of inline diagnostics on the 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
1 parent cd31204 commit aed2bd0

File tree

2 files changed

+53
-29
lines changed

2 files changed

+53
-29
lines changed

lldb/source/Utility/DiagnosticsRendering.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "lldb/Utility/DiagnosticsRendering.h"
10+
#include <cstdint>
1011

1112
using namespace lldb_private;
1213
using namespace lldb;
@@ -130,6 +131,25 @@ void RenderDiagnosticDetails(Stream &stream,
130131
}
131132
stream << '\n';
132133

134+
// Reverse the order within groups of diagnostics that are on the same column.
135+
auto group = [](auto &ds) {
136+
uint16_t column = 0;
137+
std::vector<DiagnosticDetail> result, group;
138+
for (auto d : ds) {
139+
if (d.source_location->column == column) {
140+
group.push_back(d);
141+
continue;
142+
}
143+
result.insert(result.end(), group.rbegin(), group.rend());
144+
group.clear();
145+
column = d.source_location->column;
146+
group.push_back(d);
147+
}
148+
result.insert(result.end(), group.rbegin(), group.rend());
149+
return result;
150+
};
151+
remaining_details = group(remaining_details);
152+
133153
// Work through each detail in reverse order using the vector/stack.
134154
bool did_print = false;
135155
for (auto detail = remaining_details.rbegin();
@@ -142,14 +162,19 @@ void RenderDiagnosticDetails(Stream &stream,
142162
for (auto &remaining_detail :
143163
llvm::ArrayRef(remaining_details).drop_back(1)) {
144164
uint16_t column = remaining_detail.source_location->column;
145-
if (x_pos <= column)
165+
// Is this a note with the same column as another diagnostic?
166+
if (column == detail->source_location->column)
167+
continue;
168+
169+
if (column >= x_pos) {
146170
stream << std::string(column - x_pos, ' ') << vbar;
147-
x_pos = column + 1;
171+
x_pos = column + 1;
172+
}
148173
}
149174

150-
// Print the line connecting the ^ with the error message.
151175
uint16_t column = detail->source_location->column;
152-
if (x_pos <= column)
176+
// Print the line connecting the ^ with the error message.
177+
if (column >= x_pos)
153178
stream << std::string(column - x_pos, ' ') << joint << hbar << spacer;
154179

155180
// Print a colorized string based on the message's severity type.

lldb/unittests/Utility/DiagnosticsRenderingTest.cpp

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,22 @@ TEST_F(ErrorDisplayTest, RenderStatus) {
2929
{
3030
// Test that diagnostics on the same column can be handled and all
3131
// three errors are diagnosed.
32-
SourceLocation loc1 = {FileSpec{"a.c"}, 13, 11, 0, false, true};
33-
SourceLocation loc2 = {FileSpec{"a.c"}, 13, 13, 0, false, true};
32+
SourceLocation loc1 = {FileSpec{"a.c"}, 13, 5, 0, false, true};
33+
SourceLocation loc2 = {FileSpec{"a.c"}, 13, 7, 0, false, true};
34+
SourceLocation loc3 = {FileSpec{"a.c"}, 13, 9, 0, false, true};
3435
std::string result =
3536
Render({DiagnosticDetail{loc1, eSeverityError, "1", "1"},
36-
DiagnosticDetail{loc1, eSeverityError, "2", "2"},
37-
DiagnosticDetail{loc2, eSeverityError, "3", "3"}});
38-
ASSERT_TRUE(StringRef(result).contains("error: 1"));
39-
ASSERT_TRUE(StringRef(result).contains("error: 2"));
40-
ASSERT_TRUE(StringRef(result).contains("error: 3"));
37+
DiagnosticDetail{loc2, eSeverityError, "2a", "2a"},
38+
DiagnosticDetail{loc2, eSeverityInfo, "2b", "2b"},
39+
DiagnosticDetail{loc3, eSeverityError, "3", "3"}});
40+
llvm::SmallVector<StringRef> lines;
41+
StringRef(result).split(lines, '\n');
42+
// 1234567890123
43+
ASSERT_EQ(lines[0], " ^ ^ ^");
44+
ASSERT_EQ(lines[1], " | | error: 3");
45+
ASSERT_EQ(lines[2], " | error: 2a");
46+
ASSERT_EQ(lines[3], " | note: 2b");
47+
ASSERT_EQ(lines[4], " error: 1");
4148
}
4249
{
4350
// Test that diagnostics in reverse order are emitted correctly.
@@ -68,16 +75,12 @@ TEST_F(ErrorDisplayTest, RenderStatus) {
6875
std::string result =
6976
Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
7077
DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
71-
auto lines = StringRef(result).split('\n');
72-
auto line1 = lines.first;
73-
lines = lines.second.split('\n');
74-
auto line2 = lines.first;
75-
lines = lines.second.split('\n');
76-
auto line3 = lines.first;
78+
llvm::SmallVector<StringRef> lines;
79+
StringRef(result).split(lines, '\n');
7780
// 1234567
78-
ASSERT_EQ(line1, "^~~ ^~~");
79-
ASSERT_EQ(line2, "| error: Y");
80-
ASSERT_EQ(line3, "error: X");
81+
ASSERT_EQ(lines[0], "^~~ ^~~");
82+
ASSERT_EQ(lines[1], "| error: Y");
83+
ASSERT_EQ(lines[2], "error: X");
8184
}
8285
{
8386
// Test diagnostics on the same line are emitted correctly.
@@ -86,15 +89,11 @@ TEST_F(ErrorDisplayTest, RenderStatus) {
8689
std::string result =
8790
Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
8891
DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
89-
auto lines = StringRef(result).split('\n');
90-
auto line1 = lines.first;
91-
lines = lines.second.split('\n');
92-
auto line2 = lines.first;
93-
lines = lines.second.split('\n');
94-
auto line3 = lines.first;
92+
llvm::SmallVector<StringRef> lines;
93+
StringRef(result).split(lines, '\n');
9594
// 1234567
96-
ASSERT_EQ(line1, " ^ ^");
97-
ASSERT_EQ(line2, " | error: Y");
98-
ASSERT_EQ(line3, " error: X");
95+
ASSERT_EQ(lines[0], " ^ ^");
96+
ASSERT_EQ(lines[1], " | error: Y");
97+
ASSERT_EQ(lines[2], " error: X");
9998
}
10099
}

0 commit comments

Comments
 (0)