wgsl-reader: support multiple case selectors

Bug: tint:454
Change-Id: I5a046e19f66b5807723e96593ea6ba107ef69e6c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38261
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Vasyl Teliman 2021-01-20 21:53:13 +00:00 committed by Commit Bot service account
parent afb8cfb254
commit e1abcb4564
2 changed files with 69 additions and 1 deletions

View File

@ -1856,13 +1856,26 @@ Expect<ast::CaseSelectorList> ParserImpl::expect_case_selectors() {
for (;;) {
auto t = peek();
auto matched_comma = match(Token::Type::kComma);
if (selectors.empty() && matched_comma)
return add_error(t, "a selector is expected before the comma");
if (matched_comma)
t = peek();
auto cond = const_literal();
if (cond.errored)
return Failure::kErrored;
if (!cond.matched)
if (!cond.matched) {
if (matched_comma) {
return add_error(t, "a selector is expected after the comma");
}
break;
}
if (!cond->Is<ast::IntLiteral>())
return add_error(t, "invalid case selector must be an integer value");
if (!selectors.empty() && !matched_comma)
return add_error(t, "expected a comma after the previous selector");
selectors.push_back(cond.value->As<ast::IntLiteral>());
}

View File

@ -105,6 +105,61 @@ TEST_F(ParserImplTest, SwitchBody_Case_InvalidCaseBody) {
EXPECT_EQ(p->error(), "1:11: expected '}' for case statement");
}
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors) {
auto p = parser("case 1, 2: { }");
auto e = p->switch_body();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::CaseStatement>());
EXPECT_FALSE(e->IsDefault());
ASSERT_EQ(e->body()->size(), 0u);
ASSERT_EQ(e->selectors().size(), 2u);
ASSERT_EQ(e->selectors()[0]->to_str(), "1");
ASSERT_EQ(e->selectors()[1]->to_str(), "2");
}
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsMissingColon) {
auto p = parser("case 1, 2 { }");
auto e = p->switch_body();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:11: expected ':' for case statement");
}
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsMissingComma) {
auto p = parser("case 1 2: { }");
auto e = p->switch_body();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:8: expected a comma after the previous selector");
}
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsEndsWithComma) {
auto p = parser("case 1, 2,: { }");
auto e = p->switch_body();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:11: a selector is expected after the comma");
}
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsStartsWithComma) {
auto p = parser("case , 1, 2: { }");
auto e = p->switch_body();
EXPECT_TRUE(p->has_error());
EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:6: a selector is expected before the comma");
}
TEST_F(ParserImplTest, SwitchBody_Default) {
auto p = parser("default: { a = 4; }");
auto e = p->switch_body();