mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-12 14:46:08 +00:00
[WGSL] Allow default as a case selector
This CL updates the WGSL parser to parse `default` as a case selector value. Bug: tint:1633 Change-Id: I57661d25924e36bec5c03f96399c557fb7bbf760 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/106382 Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@google.com> Auto-Submit: Dan Sinclair <dsinclair@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
d27151d333
commit
f148f0891b
@@ -3024,7 +3024,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||
for (size_t i = last_clause_index;; --i) {
|
||||
// Create a list of integer literals for the selector values leading to
|
||||
// this case clause.
|
||||
utils::Vector<const ast::Expression*, 4> selectors;
|
||||
utils::Vector<const ast::CaseSelector*, 4> selectors;
|
||||
const bool has_selectors = clause_heads[i]->case_values.has_value();
|
||||
if (has_selectors) {
|
||||
auto values = clause_heads[i]->case_values.value();
|
||||
@@ -3034,15 +3034,26 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||
// The Tint AST handles 32-bit values.
|
||||
const uint32_t value32 = uint32_t(value & 0xFFFFFFFF);
|
||||
if (selector.type->IsUnsignedScalarOrVector()) {
|
||||
selectors.Push(create<ast::IntLiteralExpression>(
|
||||
Source{}, value32, ast::IntLiteralExpression::Suffix::kU));
|
||||
selectors.Push(create<ast::CaseSelector>(
|
||||
Source{}, create<ast::IntLiteralExpression>(
|
||||
Source{}, value32, ast::IntLiteralExpression::Suffix::kU)));
|
||||
} else {
|
||||
selectors.Push(
|
||||
selectors.Push(create<ast::CaseSelector>(
|
||||
Source{},
|
||||
create<ast::IntLiteralExpression>(Source{}, static_cast<int32_t>(value32),
|
||||
ast::IntLiteralExpression::Suffix::kI));
|
||||
ast::IntLiteralExpression::Suffix::kI)));
|
||||
}
|
||||
}
|
||||
|
||||
if ((default_info == clause_heads[i]) && construct->ContainsPos(default_info->pos)) {
|
||||
// Generate a default selector
|
||||
selectors.Push(create<ast::CaseSelector>(Source{}));
|
||||
}
|
||||
} else {
|
||||
// Generate a default selector
|
||||
selectors.Push(create<ast::CaseSelector>(Source{}));
|
||||
}
|
||||
TINT_ASSERT(Reader, !selectors.IsEmpty());
|
||||
|
||||
// Where does this clause end?
|
||||
const auto end_id =
|
||||
@@ -3057,17 +3068,6 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||
swch->cases[case_idx] = create<ast::CaseStatement>(Source{}, selectors, body);
|
||||
});
|
||||
|
||||
if ((default_info == clause_heads[i]) && has_selectors &&
|
||||
construct->ContainsPos(default_info->pos)) {
|
||||
// Generate a default clause with a just fallthrough.
|
||||
auto* stmts = create<ast::BlockStatement>(
|
||||
Source{}, StatementList{
|
||||
create<ast::FallthroughStatement>(Source{}),
|
||||
});
|
||||
auto* case_stmt = create<ast::CaseStatement>(Source{}, utils::Empty, stmts);
|
||||
swch->cases.Push(case_stmt);
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -9349,10 +9349,7 @@ switch(42u) {
|
||||
case 20u: {
|
||||
var_1 = 20u;
|
||||
}
|
||||
default: {
|
||||
fallthrough;
|
||||
}
|
||||
case 30u: {
|
||||
case 30u, default: {
|
||||
var_1 = 30u;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1393,10 +1393,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_InMerge_PredecessorsDominatdB
|
||||
auto got = test::ToString(p->program(), ast_body);
|
||||
auto* expect = R"(var x_41 : u32;
|
||||
switch(1u) {
|
||||
default: {
|
||||
fallthrough;
|
||||
}
|
||||
case 0u: {
|
||||
case 0u, default: {
|
||||
fallthrough;
|
||||
}
|
||||
case 1u: {
|
||||
|
||||
@@ -2129,6 +2129,9 @@ Maybe<const ast::CaseStatement*> ParserImpl::switch_body() {
|
||||
}
|
||||
|
||||
selector_list = std::move(selectors.value);
|
||||
} else {
|
||||
// Push the default case selector
|
||||
selector_list.Push(create<ast::CaseSelector>(t.source()));
|
||||
}
|
||||
|
||||
// Consume the optional colon if present.
|
||||
@@ -2148,12 +2151,12 @@ Maybe<const ast::CaseStatement*> ParserImpl::switch_body() {
|
||||
}
|
||||
|
||||
// case_selectors
|
||||
// : expression (COMMA expression)* COMMA?
|
||||
// : case_selector (COMMA case_selector)* COMMA?
|
||||
Expect<ParserImpl::CaseSelectorList> ParserImpl::expect_case_selectors() {
|
||||
CaseSelectorList selectors;
|
||||
|
||||
while (continue_parsing()) {
|
||||
auto expr = expression();
|
||||
auto expr = case_selector();
|
||||
if (expr.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
@@ -2168,12 +2171,32 @@ Expect<ParserImpl::CaseSelectorList> ParserImpl::expect_case_selectors() {
|
||||
}
|
||||
|
||||
if (selectors.IsEmpty()) {
|
||||
return add_error(peek(), "unable to parse case selectors");
|
||||
return add_error(peek(), "expected case selector expression or `default`");
|
||||
}
|
||||
|
||||
return selectors;
|
||||
}
|
||||
|
||||
// case_selector
|
||||
// : DEFAULT
|
||||
// | expression
|
||||
Maybe<const ast::CaseSelector*> ParserImpl::case_selector() {
|
||||
auto& p = peek();
|
||||
|
||||
if (match(Token::Type::kDefault)) {
|
||||
return create<ast::CaseSelector>(p.source());
|
||||
}
|
||||
|
||||
auto expr = expression();
|
||||
if (expr.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
if (!expr.matched) {
|
||||
return Failure::kNoMatch;
|
||||
}
|
||||
return create<ast::CaseSelector>(p.source(), expr.value);
|
||||
}
|
||||
|
||||
// case_body
|
||||
// :
|
||||
// | statement case_body
|
||||
|
||||
@@ -74,7 +74,7 @@ class ParserImpl {
|
||||
/// Pre-determined small vector sizes for AST pointers
|
||||
//! @cond Doxygen_Suppress
|
||||
using AttributeList = utils::Vector<const ast::Attribute*, 4>;
|
||||
using CaseSelectorList = utils::Vector<const ast::Expression*, 4>;
|
||||
using CaseSelectorList = utils::Vector<const ast::CaseSelector*, 4>;
|
||||
using CaseStatementList = utils::Vector<const ast::CaseStatement*, 4>;
|
||||
using ExpressionList = utils::Vector<const ast::Expression*, 8>;
|
||||
using ParameterList = utils::Vector<const ast::Parameter*, 8>;
|
||||
@@ -573,6 +573,9 @@ class ParserImpl {
|
||||
/// Parses a `case_selectors` grammar element
|
||||
/// @returns the list of literals
|
||||
Expect<CaseSelectorList> expect_case_selectors();
|
||||
/// Parses a `case_selector` grammar element
|
||||
/// @returns the selector
|
||||
Maybe<const ast::CaseSelector*> case_selector();
|
||||
/// Parses a `case_body` grammar element
|
||||
/// @returns the parsed statements
|
||||
Maybe<const ast::BlockStatement*> case_body();
|
||||
|
||||
@@ -1333,7 +1333,7 @@ fn f() { switch(1) {
|
||||
|
||||
TEST_F(ParserImplErrorTest, SwitchStmtInvalidCase) {
|
||||
EXPECT("fn f() { switch(1) { case ^: } }",
|
||||
R"(test.wgsl:1:27 error: unable to parse case selectors
|
||||
R"(test.wgsl:1:27 error: expected case selector expression or `default`
|
||||
fn f() { switch(1) { case ^: } }
|
||||
^
|
||||
)");
|
||||
|
||||
@@ -143,7 +143,7 @@ TEST_F(ParserImplTest, Statement_Switch_Invalid) {
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
EXPECT_EQ(e.value, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:18: unable to parse case selectors");
|
||||
EXPECT_EQ(p->error(), "1:18: expected case selector expression or `default`");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, Statement_Loop) {
|
||||
|
||||
@@ -25,13 +25,16 @@ TEST_F(ParserImplTest, SwitchBody_Case) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_FALSE(e->IsDefault());
|
||||
EXPECT_FALSE(e->ContainsDefault());
|
||||
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.Length(), 1u);
|
||||
ASSERT_TRUE(stmt->selectors[0]->Is<ast::IntLiteralExpression>());
|
||||
|
||||
auto* expr = stmt->selectors[0]->As<ast::IntLiteralExpression>();
|
||||
auto* sel = stmt->selectors[0];
|
||||
EXPECT_FALSE(sel->IsDefault());
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
|
||||
auto* expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
EXPECT_EQ(expr->value, 1);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
ASSERT_EQ(e->body->statements.Length(), 1u);
|
||||
@@ -46,12 +49,16 @@ TEST_F(ParserImplTest, SwitchBody_Case_Expression) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_FALSE(e->IsDefault());
|
||||
EXPECT_FALSE(e->ContainsDefault());
|
||||
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.Length(), 1u);
|
||||
ASSERT_TRUE(stmt->selectors[0]->Is<ast::BinaryExpression>());
|
||||
auto* expr = stmt->selectors[0]->As<ast::BinaryExpression>();
|
||||
|
||||
auto* sel = stmt->selectors[0];
|
||||
EXPECT_FALSE(sel->IsDefault());
|
||||
|
||||
ASSERT_TRUE(sel->expr->Is<ast::BinaryExpression>());
|
||||
auto* expr = sel->expr->As<ast::BinaryExpression>();
|
||||
|
||||
EXPECT_EQ(ast::BinaryOp::kAdd, expr->op);
|
||||
auto* v = expr->lhs->As<ast::IntLiteralExpression>();
|
||||
@@ -74,13 +81,16 @@ TEST_F(ParserImplTest, SwitchBody_Case_WithColon) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_FALSE(e->IsDefault());
|
||||
EXPECT_FALSE(e->ContainsDefault());
|
||||
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.Length(), 1u);
|
||||
ASSERT_TRUE(stmt->selectors[0]->Is<ast::IntLiteralExpression>());
|
||||
auto* sel = stmt->selectors[0];
|
||||
EXPECT_FALSE(sel->IsDefault());
|
||||
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
auto* expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
|
||||
auto* expr = stmt->selectors[0]->As<ast::IntLiteralExpression>();
|
||||
EXPECT_EQ(expr->value, 1);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
ASSERT_EQ(e->body->statements.Length(), 1u);
|
||||
@@ -95,17 +105,20 @@ TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_FALSE(e->IsDefault());
|
||||
EXPECT_FALSE(e->ContainsDefault());
|
||||
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.Length(), 2u);
|
||||
ASSERT_TRUE(stmt->selectors[0]->Is<ast::IntLiteralExpression>());
|
||||
auto* sel = stmt->selectors[0];
|
||||
|
||||
auto* expr = stmt->selectors[0]->As<ast::IntLiteralExpression>();
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
auto* expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
EXPECT_EQ(expr->value, 1);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(stmt->selectors[1]->Is<ast::IntLiteralExpression>());
|
||||
expr = stmt->selectors[1]->As<ast::IntLiteralExpression>();
|
||||
sel = stmt->selectors[1];
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
EXPECT_EQ(expr->value, 2);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
@@ -118,18 +131,20 @@ TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma_WithColon) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_FALSE(e->IsDefault());
|
||||
EXPECT_FALSE(e->ContainsDefault());
|
||||
|
||||
auto* stmt = e->As<ast::CaseStatement>();
|
||||
ASSERT_EQ(stmt->selectors.Length(), 2u);
|
||||
ASSERT_TRUE(stmt->selectors[0]->Is<ast::IntLiteralExpression>());
|
||||
auto* sel = stmt->selectors[0];
|
||||
|
||||
auto* expr = stmt->selectors[0]->As<ast::IntLiteralExpression>();
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
auto* expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
EXPECT_EQ(expr->value, 1);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(stmt->selectors[1]->Is<ast::IntLiteralExpression>());
|
||||
expr = stmt->selectors[1]->As<ast::IntLiteralExpression>();
|
||||
sel = stmt->selectors[1];
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
EXPECT_EQ(expr->value, 2);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
@@ -141,7 +156,7 @@ TEST_F(ParserImplTest, SwitchBody_Case_Invalid) {
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
EXPECT_EQ(e.value, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:6: unable to parse case selectors");
|
||||
EXPECT_EQ(p->error(), "1:6: expected case selector expression or `default`");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_MissingConstLiteral) {
|
||||
@@ -151,7 +166,7 @@ TEST_F(ParserImplTest, SwitchBody_Case_MissingConstLiteral) {
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
EXPECT_EQ(e.value, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:5: unable to parse case selectors");
|
||||
EXPECT_EQ(p->error(), "1:5: expected case selector expression or `default`");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_MissingBracketLeft) {
|
||||
@@ -202,17 +217,46 @@ TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_FALSE(e->IsDefault());
|
||||
EXPECT_FALSE(e->ContainsDefault());
|
||||
ASSERT_EQ(e->body->statements.Length(), 0u);
|
||||
ASSERT_EQ(e->selectors.Length(), 2u);
|
||||
ASSERT_TRUE(e->selectors[0]->Is<ast::IntLiteralExpression>());
|
||||
|
||||
auto* expr = e->selectors[0]->As<ast::IntLiteralExpression>();
|
||||
auto* sel = e->selectors[0];
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
auto* expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
ASSERT_EQ(expr->value, 1);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(e->selectors[1]->Is<ast::IntLiteralExpression>());
|
||||
expr = e->selectors[1]->As<ast::IntLiteralExpression>();
|
||||
sel = e->selectors[1];
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
ASSERT_EQ(expr->value, 2);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors_with_default) {
|
||||
auto p = parser("case 1, default, 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_TRUE(e->ContainsDefault());
|
||||
ASSERT_EQ(e->body->statements.Length(), 0u);
|
||||
ASSERT_EQ(e->selectors.Length(), 3u);
|
||||
|
||||
auto* sel = e->selectors[0];
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
auto* expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
ASSERT_EQ(expr->value, 1);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
EXPECT_TRUE(e->selectors[1]->IsDefault());
|
||||
|
||||
sel = e->selectors[2];
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
ASSERT_EQ(expr->value, 2);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
@@ -225,17 +269,19 @@ TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors_WithColon) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_FALSE(e->IsDefault());
|
||||
EXPECT_FALSE(e->ContainsDefault());
|
||||
ASSERT_EQ(e->body->statements.Length(), 0u);
|
||||
ASSERT_EQ(e->selectors.Length(), 2u);
|
||||
ASSERT_TRUE(e->selectors[0]->Is<ast::IntLiteralExpression>());
|
||||
|
||||
auto* expr = e->selectors[0]->As<ast::IntLiteralExpression>();
|
||||
auto* sel = e->selectors[0];
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
auto* expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
ASSERT_EQ(expr->value, 1);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
|
||||
ASSERT_TRUE(e->selectors[1]->Is<ast::IntLiteralExpression>());
|
||||
expr = e->selectors[1]->As<ast::IntLiteralExpression>();
|
||||
sel = e->selectors[1];
|
||||
ASSERT_TRUE(sel->expr->Is<ast::IntLiteralExpression>());
|
||||
expr = sel->expr->As<ast::IntLiteralExpression>();
|
||||
ASSERT_EQ(expr->value, 2);
|
||||
EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
|
||||
}
|
||||
@@ -257,7 +303,7 @@ TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsStartsWithComma) {
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_FALSE(e.matched);
|
||||
EXPECT_EQ(e.value, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:6: unable to parse case selectors");
|
||||
EXPECT_EQ(p->error(), "1:6: expected case selector expression or `default`");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Default) {
|
||||
@@ -268,7 +314,7 @@ TEST_F(ParserImplTest, SwitchBody_Default) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_TRUE(e->IsDefault());
|
||||
EXPECT_TRUE(e->ContainsDefault());
|
||||
ASSERT_EQ(e->body->statements.Length(), 1u);
|
||||
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
|
||||
}
|
||||
@@ -281,7 +327,7 @@ TEST_F(ParserImplTest, SwitchBody_Default_WithColon) {
|
||||
EXPECT_FALSE(e.errored);
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::CaseStatement>());
|
||||
EXPECT_TRUE(e->IsDefault());
|
||||
EXPECT_TRUE(e->ContainsDefault());
|
||||
ASSERT_EQ(e->body->statements.Length(), 1u);
|
||||
EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ TEST_F(ParserImplTest, SwitchStmt_WithoutDefault) {
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::SwitchStatement>());
|
||||
ASSERT_EQ(e->body.Length(), 2u);
|
||||
EXPECT_FALSE(e->body[0]->IsDefault());
|
||||
EXPECT_FALSE(e->body[1]->IsDefault());
|
||||
EXPECT_FALSE(e->body[0]->ContainsDefault());
|
||||
EXPECT_FALSE(e->body[1]->ContainsDefault());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchStmt_Empty) {
|
||||
@@ -58,9 +58,24 @@ TEST_F(ParserImplTest, SwitchStmt_DefaultInMiddle) {
|
||||
ASSERT_TRUE(e->Is<ast::SwitchStatement>());
|
||||
|
||||
ASSERT_EQ(e->body.Length(), 3u);
|
||||
ASSERT_FALSE(e->body[0]->IsDefault());
|
||||
ASSERT_TRUE(e->body[1]->IsDefault());
|
||||
ASSERT_FALSE(e->body[2]->IsDefault());
|
||||
ASSERT_FALSE(e->body[0]->ContainsDefault());
|
||||
ASSERT_TRUE(e->body[1]->ContainsDefault());
|
||||
ASSERT_FALSE(e->body[2]->ContainsDefault());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchStmt_Default_Mixed) {
|
||||
auto p = parser(R"(switch a {
|
||||
case 1, default, 2: {}
|
||||
})");
|
||||
auto e = p->switch_statement();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::SwitchStatement>());
|
||||
|
||||
ASSERT_EQ(e->body.Length(), 1u);
|
||||
ASSERT_TRUE(e->body[0]->ContainsDefault());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchStmt_WithParens) {
|
||||
@@ -123,7 +138,7 @@ TEST_F(ParserImplTest, SwitchStmt_InvalidBody) {
|
||||
EXPECT_TRUE(e.errored);
|
||||
EXPECT_EQ(e.value, nullptr);
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), "2:7: unable to parse case selectors");
|
||||
EXPECT_EQ(p->error(), "2:7: expected case selector expression or `default`");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user