mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-07 13:45:51 +00:00
formatter: handle tabs
Transform these into whitespace so we can sensibly align the ^^ markers with the text. Change-Id: I151c0e55bc0a02c1cff6e381cb9839c9f9abdaf6 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48694 Commit-Queue: Ben Clayton <bclayton@google.com> Auto-Submit: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
3fe2779402
commit
4c0b7807f8
@ -211,33 +211,52 @@ void Formatter::format(const Diagnostic& diag, State& state) const {
|
|||||||
state.newline();
|
state.newline();
|
||||||
state.set_style({Color::kDefault, false});
|
state.set_style({Color::kDefault, false});
|
||||||
|
|
||||||
for (size_t line = rng.begin.line; line <= rng.end.line; line++) {
|
for (size_t line_num = rng.begin.line;
|
||||||
if (line < src.file_content->lines.size() + 1) {
|
(line_num <= rng.end.line) && (src.file_content->lines.size() + 1);
|
||||||
auto len = src.file_content->lines[line - 1].size();
|
line_num++) {
|
||||||
|
auto& line = src.file_content->lines[line_num - 1];
|
||||||
|
auto line_len = line.size();
|
||||||
|
|
||||||
state << src.file_content->lines[line - 1];
|
for (auto c : line) {
|
||||||
|
if (c == '\t') {
|
||||||
state.newline();
|
state.repeat(' ', style_.tab_width);
|
||||||
state.set_style({Color::kCyan, false});
|
|
||||||
|
|
||||||
if (line == rng.begin.line && line == rng.end.line) {
|
|
||||||
// Single line
|
|
||||||
state.repeat(' ', rng.begin.column - 1);
|
|
||||||
state.repeat('^',
|
|
||||||
std::max<size_t>(rng.end.column - rng.begin.column, 1));
|
|
||||||
} else if (line == rng.begin.line) {
|
|
||||||
// Start of multi-line
|
|
||||||
state.repeat(' ', rng.begin.column - 1);
|
|
||||||
state.repeat('^', len - (rng.begin.column - 1));
|
|
||||||
} else if (line == rng.end.line) {
|
|
||||||
// End of multi-line
|
|
||||||
state.repeat('^', rng.end.column - 1);
|
|
||||||
} else {
|
} else {
|
||||||
// Middle of multi-line
|
state << c;
|
||||||
state.repeat('^', len);
|
|
||||||
}
|
}
|
||||||
state.newline();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.newline();
|
||||||
|
state.set_style({Color::kCyan, false});
|
||||||
|
|
||||||
|
// Count the number of glyphs in the line span.
|
||||||
|
// start and end use 1-based indexing .
|
||||||
|
auto num_glyphs = [&](size_t start, size_t end) {
|
||||||
|
size_t count = 0;
|
||||||
|
start = (start > 0) ? (start - 1) : 0;
|
||||||
|
end = (end > 0) ? (end - 1) : 0;
|
||||||
|
for (size_t i = start; (i < end) && (i < line_len); i++) {
|
||||||
|
count += (line[i] == '\t') ? style_.tab_width : 1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (line_num == rng.begin.line && line_num == rng.end.line) {
|
||||||
|
// Single line
|
||||||
|
state.repeat(' ', num_glyphs(1, rng.begin.column));
|
||||||
|
state.repeat('^', std::max<size_t>(
|
||||||
|
num_glyphs(rng.begin.column, rng.end.column), 1));
|
||||||
|
} else if (line_num == rng.begin.line) {
|
||||||
|
// Start of multi-line
|
||||||
|
state.repeat(' ', num_glyphs(1, rng.begin.column));
|
||||||
|
state.repeat('^', num_glyphs(rng.begin.column, line_len + 1));
|
||||||
|
} else if (line_num == rng.end.line) {
|
||||||
|
// End of multi-line
|
||||||
|
state.repeat('^', num_glyphs(1, rng.end.column));
|
||||||
|
} else {
|
||||||
|
// Middle of multi-line
|
||||||
|
state.repeat('^', num_glyphs(1, line_len + 1));
|
||||||
|
}
|
||||||
|
state.newline();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.set_style({});
|
state.set_style({});
|
||||||
|
@ -37,6 +37,8 @@ class Formatter {
|
|||||||
bool print_line = true;
|
bool print_line = true;
|
||||||
/// print a newline at the end of a diagnostic list
|
/// print a newline at the end of a diagnostic list
|
||||||
bool print_newline_at_end = true;
|
bool print_newline_at_end = true;
|
||||||
|
/// width of a tab character
|
||||||
|
size_t tab_width = 2u;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Constructor for the formatter using a default style.
|
/// Constructor for the formatter using a default style.
|
||||||
|
@ -21,11 +21,11 @@ namespace tint {
|
|||||||
namespace diag {
|
namespace diag {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr const char* content =
|
constexpr const char* content = // Note: words are tab-delimited
|
||||||
R"(the cat says meow
|
R"(the cat says meow
|
||||||
the dog says woof
|
the dog says woof
|
||||||
the snake says quack
|
the snake says quack
|
||||||
the snail says ???
|
the snail says ???
|
||||||
)";
|
)";
|
||||||
|
|
||||||
class DiagFormatterTest : public testing::Test {
|
class DiagFormatterTest : public testing::Test {
|
||||||
@ -96,16 +96,16 @@ TEST_F(DiagFormatterTest, WithLine) {
|
|||||||
Formatter fmt{{false, false, true, false}};
|
Formatter fmt{{false, false, true, false}};
|
||||||
auto got = fmt.format(List{diag_note, diag_warn, diag_err});
|
auto got = fmt.format(List{diag_note, diag_warn, diag_err});
|
||||||
auto* expect = R"(1:14: purr
|
auto* expect = R"(1:14: purr
|
||||||
the cat says meow
|
the cat says meow
|
||||||
^
|
^
|
||||||
|
|
||||||
2:14: grrr
|
2:14: grrr
|
||||||
the dog says woof
|
the dog says woof
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
3:16 abc123: hiss
|
3:16 abc123: hiss
|
||||||
the snake says quack
|
the snake says quack
|
||||||
^^^^^
|
^^^^^
|
||||||
)";
|
)";
|
||||||
ASSERT_EQ(expect, got);
|
ASSERT_EQ(expect, got);
|
||||||
}
|
}
|
||||||
@ -114,16 +114,16 @@ TEST_F(DiagFormatterTest, BasicWithFileSeverityLine) {
|
|||||||
Formatter fmt{{true, true, true, false}};
|
Formatter fmt{{true, true, true, false}};
|
||||||
auto got = fmt.format(List{diag_note, diag_warn, diag_err});
|
auto got = fmt.format(List{diag_note, diag_warn, diag_err});
|
||||||
auto* expect = R"(file.name:1:14 note: purr
|
auto* expect = R"(file.name:1:14 note: purr
|
||||||
the cat says meow
|
the cat says meow
|
||||||
^
|
^
|
||||||
|
|
||||||
file.name:2:14 warning: grrr
|
file.name:2:14 warning: grrr
|
||||||
the dog says woof
|
the dog says woof
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
file.name:3:16 error abc123: hiss
|
file.name:3:16 error abc123: hiss
|
||||||
the snake says quack
|
the snake says quack
|
||||||
^^^^^
|
^^^^^
|
||||||
)";
|
)";
|
||||||
ASSERT_EQ(expect, got);
|
ASSERT_EQ(expect, got);
|
||||||
}
|
}
|
||||||
@ -135,12 +135,47 @@ TEST_F(DiagFormatterTest, BasicWithMultiLine) {
|
|||||||
Formatter fmt{{false, false, true, false}};
|
Formatter fmt{{false, false, true, false}};
|
||||||
auto got = fmt.format(List{multiline});
|
auto got = fmt.format(List{multiline});
|
||||||
auto* expect = R"(2:9: multiline
|
auto* expect = R"(2:9: multiline
|
||||||
the dog says woof
|
the dog says woof
|
||||||
^^^^^^^^^
|
^^^^^^^^^^
|
||||||
the snake says quack
|
the snake says quack
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
the snail says ???
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
)";
|
||||||
|
ASSERT_EQ(expect, got);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DiagFormatterTest, BasicWithFileSeverityLineTab4) {
|
||||||
|
Formatter fmt{{true, true, true, false, 4u}};
|
||||||
|
auto got = fmt.format(List{diag_note, diag_warn, diag_err});
|
||||||
|
auto* expect = R"(file.name:1:14 note: purr
|
||||||
|
the cat says meow
|
||||||
|
^
|
||||||
|
|
||||||
|
file.name:2:14 warning: grrr
|
||||||
|
the dog says woof
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
file.name:3:16 error abc123: hiss
|
||||||
|
the snake says quack
|
||||||
|
^^^^^
|
||||||
|
)";
|
||||||
|
ASSERT_EQ(expect, got);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DiagFormatterTest, BasicWithMultiLineTab4) {
|
||||||
|
Diagnostic multiline{Severity::Warning,
|
||||||
|
Source{Source::Range{{2, 9}, {4, 15}}, &file},
|
||||||
|
"multiline"};
|
||||||
|
Formatter fmt{{false, false, true, false, 4u}};
|
||||||
|
auto got = fmt.format(List{multiline});
|
||||||
|
auto* expect = R"(2:9: multiline
|
||||||
|
the dog says woof
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
the snake says quack
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
the snail says ???
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
the snail says ???
|
|
||||||
^^^^^^^^^^^^^^
|
|
||||||
)";
|
)";
|
||||||
ASSERT_EQ(expect, got);
|
ASSERT_EQ(expect, got);
|
||||||
}
|
}
|
||||||
@ -149,8 +184,8 @@ TEST_F(DiagFormatterTest, ICE) {
|
|||||||
Formatter fmt{{}};
|
Formatter fmt{{}};
|
||||||
auto got = fmt.format(List{diag_ice});
|
auto got = fmt.format(List{diag_ice});
|
||||||
auto* expect = R"(file.name:4:16 internal compiler error: unreachable
|
auto* expect = R"(file.name:4:16 internal compiler error: unreachable
|
||||||
the snail says ???
|
the snail says ???
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
********************************************************************
|
********************************************************************
|
||||||
* The tint shader compiler has encountered an unexpected error. *
|
* The tint shader compiler has encountered an unexpected error. *
|
||||||
@ -167,8 +202,8 @@ TEST_F(DiagFormatterTest, Fatal) {
|
|||||||
Formatter fmt{{}};
|
Formatter fmt{{}};
|
||||||
auto got = fmt.format(List{diag_fatal});
|
auto got = fmt.format(List{diag_fatal});
|
||||||
auto* expect = R"(file.name:4:16 fatal: nothing
|
auto* expect = R"(file.name:4:16 fatal: nothing
|
||||||
the snail says ???
|
the snail says ???
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
********************************************************************
|
********************************************************************
|
||||||
* The tint shader compiler has encountered an unexpected error. *
|
* The tint shader compiler has encountered an unexpected error. *
|
||||||
|
Loading…
x
Reference in New Issue
Block a user