wgsl: Make colon optional for case statements
Fixed: tint:1485 Change-Id: I76af5a284cb455170bed27e852a4bab47c5dc491 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/85525 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
b7e560dea0
commit
e6c7fd7110
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
* Parentheses are no longer required around expressions for if and switch statements [tint:1424](crbug.com/tint/1424)
|
* Parentheses are no longer required around expressions for if and switch statements [tint:1424](crbug.com/tint/1424)
|
||||||
* Compound assignment statements are now supported. [tint:1325](https://crbug.com/tint/1325)
|
* Compound assignment statements are now supported. [tint:1325](https://crbug.com/tint/1325)
|
||||||
|
* The colon in case statements is now optional. [tint:1485](crbug.com/tint/1485)
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
|
||||||
|
|
|
@ -1761,8 +1761,8 @@ Maybe<const ast::SwitchStatement*> ParserImpl::switch_stmt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch_body
|
// switch_body
|
||||||
// : CASE case_selectors COLON BRACKET_LEFT case_body BRACKET_RIGHT
|
// : CASE case_selectors COLON? BRACKET_LEFT case_body BRACKET_RIGHT
|
||||||
// | DEFAULT COLON BRACKET_LEFT case_body BRACKET_RIGHT
|
// | DEFAULT COLON? BRACKET_LEFT case_body BRACKET_RIGHT
|
||||||
Maybe<const ast::CaseStatement*> ParserImpl::switch_body() {
|
Maybe<const ast::CaseStatement*> ParserImpl::switch_body() {
|
||||||
if (!peek_is(Token::Type::kCase) && !peek_is(Token::Type::kDefault))
|
if (!peek_is(Token::Type::kCase) && !peek_is(Token::Type::kDefault))
|
||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
|
@ -1779,11 +1779,10 @@ Maybe<const ast::CaseStatement*> ParserImpl::switch_body() {
|
||||||
selector_list = std::move(selectors.value);
|
selector_list = std::move(selectors.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consume the optional colon if present.
|
||||||
|
match(Token::Type::kColon);
|
||||||
|
|
||||||
const char* use = "case statement";
|
const char* use = "case statement";
|
||||||
|
|
||||||
if (!expect(use, Token::Type::kColon))
|
|
||||||
return Failure::kErrored;
|
|
||||||
|
|
||||||
auto body = expect_brace_block(use, [&] { return case_body(); });
|
auto body = expect_brace_block(use, [&] { return case_body(); });
|
||||||
|
|
||||||
if (body.errored)
|
if (body.errored)
|
||||||
|
|
|
@ -1174,14 +1174,6 @@ fn f() { switch(1) { case false: } }
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, SwitchStmtCaseMissingColon) {
|
|
||||||
EXPECT("fn f() { switch(1) { case 1 {} } }",
|
|
||||||
R"(test.wgsl:1:29 error: expected ':' for case statement
|
|
||||||
fn f() { switch(1) { case 1 {} } }
|
|
||||||
^
|
|
||||||
)");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplErrorTest, SwitchStmtCaseMissingLBrace) {
|
TEST_F(ParserImplErrorTest, SwitchStmtCaseMissingLBrace) {
|
||||||
EXPECT("fn f() { switch(1) { case 1: } }",
|
EXPECT("fn f() { switch(1) { case 1: } }",
|
||||||
R"(test.wgsl:1:30 error: expected '{' for case statement
|
R"(test.wgsl:1:30 error: expected '{' for case statement
|
||||||
|
|
|
@ -20,6 +20,22 @@ namespace wgsl {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Case) {
|
TEST_F(ParserImplTest, SwitchBody_Case) {
|
||||||
|
auto p = parser("case 1 { a = 4; }");
|
||||||
|
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());
|
||||||
|
auto* stmt = e->As<ast::CaseStatement>();
|
||||||
|
ASSERT_EQ(stmt->selectors.size(), 1u);
|
||||||
|
EXPECT_EQ(stmt->selectors[0]->ValueAsU32(), 1u);
|
||||||
|
ASSERT_EQ(e->body->statements.size(), 1u);
|
||||||
|
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, SwitchBody_Case_WithColon) {
|
||||||
auto p = parser("case 1: { a = 4; }");
|
auto p = parser("case 1: { a = 4; }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
|
@ -36,6 +52,21 @@ TEST_F(ParserImplTest, SwitchBody_Case) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma) {
|
TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma) {
|
||||||
|
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());
|
||||||
|
auto* stmt = e->As<ast::CaseStatement>();
|
||||||
|
ASSERT_EQ(stmt->selectors.size(), 2u);
|
||||||
|
EXPECT_EQ(stmt->selectors[0]->ValueAsU32(), 1u);
|
||||||
|
EXPECT_EQ(stmt->selectors[1]->ValueAsU32(), 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma_WithColon) {
|
||||||
auto p = parser("case 1, 2,: { }");
|
auto p = parser("case 1, 2,: { }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
|
@ -80,17 +111,17 @@ TEST_F(ParserImplTest, SwitchBody_Case_MissingConstLiteral) {
|
||||||
EXPECT_EQ(p->error(), "1:5: unable to parse case selectors");
|
EXPECT_EQ(p->error(), "1:5: unable to parse case selectors");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Case_MissingColon) {
|
TEST_F(ParserImplTest, SwitchBody_Case_MissingBracketLeft) {
|
||||||
auto p = parser("case 1 { a = 4; }");
|
auto p = parser("case 1 a = 4; }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_TRUE(e.errored);
|
EXPECT_TRUE(e.errored);
|
||||||
EXPECT_FALSE(e.matched);
|
EXPECT_FALSE(e.matched);
|
||||||
EXPECT_EQ(e.value, nullptr);
|
EXPECT_EQ(e.value, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:8: expected ':' for case statement");
|
EXPECT_EQ(p->error(), "1:8: expected '{' for case statement");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Case_MissingBracketLeft) {
|
TEST_F(ParserImplTest, SwitchBody_Case_MissingBracketLeft_WithColon) {
|
||||||
auto p = parser("case 1: a = 4; }");
|
auto p = parser("case 1: a = 4; }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
|
@ -121,6 +152,21 @@ TEST_F(ParserImplTest, SwitchBody_Case_InvalidCaseBody) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors) {
|
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->statements.size(), 0u);
|
||||||
|
ASSERT_EQ(e->selectors.size(), 2u);
|
||||||
|
ASSERT_EQ(e->selectors[0]->ValueAsI32(), 1);
|
||||||
|
ASSERT_EQ(e->selectors[1]->ValueAsI32(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors_WithColon) {
|
||||||
auto p = parser("case 1, 2: { }");
|
auto p = parser("case 1, 2: { }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
|
@ -135,16 +181,6 @@ TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors) {
|
||||||
ASSERT_EQ(e->selectors[1]->ValueAsI32(), 2);
|
ASSERT_EQ(e->selectors[1]->ValueAsI32(), 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) {
|
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsMissingComma) {
|
||||||
auto p = parser("case 1 2: { }");
|
auto p = parser("case 1 2: { }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
|
@ -152,7 +188,7 @@ TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsMissingComma) {
|
||||||
EXPECT_TRUE(e.errored);
|
EXPECT_TRUE(e.errored);
|
||||||
EXPECT_FALSE(e.matched);
|
EXPECT_FALSE(e.matched);
|
||||||
EXPECT_EQ(e.value, nullptr);
|
EXPECT_EQ(e.value, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:8: expected ':' for case statement");
|
EXPECT_EQ(p->error(), "1:8: expected '{' for case statement");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsStartsWithComma) {
|
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsStartsWithComma) {
|
||||||
|
@ -166,6 +202,19 @@ TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsStartsWithComma) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Default) {
|
TEST_F(ParserImplTest, SwitchBody_Default) {
|
||||||
|
auto p = parser("default { a = 4; }");
|
||||||
|
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_TRUE(e->IsDefault());
|
||||||
|
ASSERT_EQ(e->body->statements.size(), 1u);
|
||||||
|
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, SwitchBody_Default_WithColon) {
|
||||||
auto p = parser("default: { a = 4; }");
|
auto p = parser("default: { a = 4; }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
EXPECT_FALSE(p->has_error()) << p->error();
|
EXPECT_FALSE(p->has_error()) << p->error();
|
||||||
|
@ -178,17 +227,17 @@ TEST_F(ParserImplTest, SwitchBody_Default) {
|
||||||
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
|
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Default_MissingColon) {
|
TEST_F(ParserImplTest, SwitchBody_Default_MissingBracketLeft) {
|
||||||
auto p = parser("default { a = 4; }");
|
auto p = parser("default a = 4; }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_TRUE(e.errored);
|
EXPECT_TRUE(e.errored);
|
||||||
EXPECT_FALSE(e.matched);
|
EXPECT_FALSE(e.matched);
|
||||||
EXPECT_EQ(e.value, nullptr);
|
EXPECT_EQ(e.value, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:9: expected ':' for case statement");
|
EXPECT_EQ(p->error(), "1:9: expected '{' for case statement");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SwitchBody_Default_MissingBracketLeft) {
|
TEST_F(ParserImplTest, SwitchBody_Default_MissingBracketLeft_WithColon) {
|
||||||
auto p = parser("default: a = 4; }");
|
auto p = parser("default: a = 4; }");
|
||||||
auto e = p->switch_body();
|
auto e = p->switch_body();
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
|
|
Loading…
Reference in New Issue