reader/wgsl: Abort after raising too many errors
Change-Id: I641ee8c2e34e059a02742d06c24f96acecb39cd3 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/33720 Commit-Queue: David Neto <dneto@google.com> Reviewed-by: David Neto <dneto@google.com> Auto-Submit: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
c489875ff0
commit
1e87fe5517
|
@ -83,13 +83,15 @@ class List {
|
|||
void add(Diagnostic&& diag) {
|
||||
entries_.emplace_back(std::move(diag));
|
||||
if (diag.severity >= Severity::Error) {
|
||||
contains_errors_ = true;
|
||||
error_count_++;
|
||||
}
|
||||
}
|
||||
|
||||
/// @returns true iff the diagnostic list contains errors diagnostics (or of
|
||||
/// higher severity).
|
||||
bool contains_errors() const { return contains_errors_; }
|
||||
bool contains_errors() const { return error_count_ > 0; }
|
||||
/// @returns the number of error diagnostics (or of higher severity).
|
||||
size_t error_count() const { return error_count_; }
|
||||
/// @returns the number of entries in the list.
|
||||
size_t count() const { return entries_.size(); }
|
||||
/// @returns the first diagnostic in the list.
|
||||
|
@ -99,7 +101,7 @@ class List {
|
|||
|
||||
private:
|
||||
std::vector<Diagnostic> entries_;
|
||||
bool contains_errors_ = false;
|
||||
size_t error_count_ = 0;
|
||||
};
|
||||
|
||||
} // namespace diag
|
||||
|
|
|
@ -238,8 +238,17 @@ bool ParserImpl::Parse() {
|
|||
// translation_unit
|
||||
// : global_decl* EOF
|
||||
void ParserImpl::translation_unit() {
|
||||
while (!peek().IsEof() && synchronized_) {
|
||||
while (synchronized_) {
|
||||
auto p = peek();
|
||||
if (p.IsEof()) {
|
||||
break;
|
||||
}
|
||||
expect_global_decl();
|
||||
if (diags_.error_count() >= max_errors_) {
|
||||
add_error(Source{{}, p.source().file},
|
||||
"stopping after " + std::to_string(max_errors_) + " errors");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(module_.IsValid());
|
||||
|
|
|
@ -233,6 +233,15 @@ class ParserImpl {
|
|||
/// @returns true if the parse was successful, false otherwise.
|
||||
bool Parse();
|
||||
|
||||
/// set_max_diagnostics sets the maximum number of reported errors before
|
||||
/// aborting parsing.
|
||||
/// @param limit the new maximum number of errors
|
||||
void set_max_errors(size_t limit) { max_errors_ = limit; }
|
||||
|
||||
/// @return the number of maximum number of reported errors before aborting
|
||||
/// parsing.
|
||||
size_t get_max_errors() const { return max_errors_; }
|
||||
|
||||
/// @returns true if an error was encountered.
|
||||
bool has_error() const { return diags_.contains_errors(); }
|
||||
|
||||
|
@ -779,6 +788,7 @@ class ParserImpl {
|
|||
int silence_errors_ = 0;
|
||||
std::unordered_map<std::string, ast::type::Type*> registered_constructs_;
|
||||
ast::Module module_;
|
||||
size_t max_errors_ = 25;
|
||||
};
|
||||
|
||||
} // namespace wgsl
|
||||
|
|
|
@ -28,6 +28,7 @@ class ParserImplErrorTest : public ParserImplTest {};
|
|||
std::string source = SOURCE; \
|
||||
std::string expected = EXPECTED; \
|
||||
auto p = parser(source); \
|
||||
p->set_max_errors(5); \
|
||||
EXPECT_EQ(false, p->Parse()); \
|
||||
EXPECT_EQ(true, p->diagnostics().contains_errors()); \
|
||||
EXPECT_EQ(expected, diag::Formatter().format(p->diagnostics())); \
|
||||
|
@ -1168,6 +1169,26 @@ TEST_F(ParserImplErrorTest, LoopMissingRBrace) {
|
|||
" ^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, MaxErrorsReached) {
|
||||
EXPECT("x; x; x; x; x; x; x; x;",
|
||||
"test.wgsl:1:1 error: unexpected token\n"
|
||||
"x; x; x; x; x; x; x; x;\n"
|
||||
"^\n\n"
|
||||
"test.wgsl:1:4 error: unexpected token\n"
|
||||
"x; x; x; x; x; x; x; x;\n"
|
||||
" ^\n\n"
|
||||
"test.wgsl:1:7 error: unexpected token\n"
|
||||
"x; x; x; x; x; x; x; x;\n"
|
||||
" ^\n\n"
|
||||
"test.wgsl:1:10 error: unexpected token\n"
|
||||
"x; x; x; x; x; x; x; x;\n"
|
||||
" ^\n\n"
|
||||
"test.wgsl:1:13 error: unexpected token\n"
|
||||
"x; x; x; x; x; x; x; x;\n"
|
||||
" ^\n\n"
|
||||
"test.wgsl error: stopping after 5 errors");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, MemberExprMissingIdentifier) {
|
||||
EXPECT("fn f() -> void { x = a.; }",
|
||||
"test.wgsl:1:24 error: expected identifier for member accessor\n"
|
||||
|
|
Loading…
Reference in New Issue