tint/reader/wgsl: Improve errors when parsing access controls

If the access control doesn't parse, then generate an error message that includes the list of possible values, and a suggestion if there was a close match.

Change-Id: I12fdbe0f73762b51e670b5b1b0f087f3a9157339
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/105330
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2022-10-12 11:17:56 +00:00 committed by Dawn LUCI CQ
parent 501d082c8b
commit fafeb9a327
4 changed files with 15 additions and 24 deletions

View File

@ -760,7 +760,7 @@ Maybe<const ast::Type*> ParserImpl::texture_and_sampler_types() {
return Failure::kErrored; return Failure::kErrored;
} }
auto access = expect_access_mode("access control"); auto access = expect_access_mode(use);
if (access.errored) { if (access.errored) {
return Failure::kErrored; return Failure::kErrored;
} }
@ -967,22 +967,7 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_ident_with_type_specifier
// | 'write' // | 'write'
// | 'read_write' // | 'read_write'
Expect<ast::Access> ParserImpl::expect_access_mode(std::string_view use) { Expect<ast::Access> ParserImpl::expect_access_mode(std::string_view use) {
auto ident = expect_ident(use); return expect_enum("access control", ast::ParseAccess, ast::kAccessStrings, use);
if (ident.errored) {
return Failure::kErrored;
}
if (ident.value == "read") {
return {ast::Access::kRead, ident.source};
}
if (ident.value == "write") {
return {ast::Access::kWrite, ident.source};
}
if (ident.value == "read_write") {
return {ast::Access::kReadWrite, ident.source};
}
return add_error(ident.source, "invalid value for access control");
} }
// variable_qualifier // variable_qualifier
@ -1281,7 +1266,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_specifier_pointer(const Source&
} }
if (match(Token::Type::kComma)) { if (match(Token::Type::kComma)) {
auto ac = expect_access_mode("access control"); auto ac = expect_access_mode(use);
if (ac.errored) { if (ac.errored) {
return Failure::kErrored; return Failure::kErrored;
} }

View File

@ -228,7 +228,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidTypeSuggest) {
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);
EXPECT_EQ(p->error(), R"(1:20: expected texel format for storage texture type. Did you mean 'rg32float'? EXPECT_EQ(p->error(),
R"(1:20: expected texel format for storage texture type. Did you mean 'rg32float'?
Possible values: 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')"); Possible values: 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
} }
@ -238,7 +239,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidAccess) {
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);
EXPECT_EQ(p->error(), "1:30: invalid value for access control"); EXPECT_EQ(p->error(), R"(1:30: expected access control for storage texture type. Did you mean 'read'?
Possible values: 'read', 'read_write', 'write')");
} }
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingType) { TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingType) {

View File

@ -293,7 +293,8 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingAccess) {
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr); ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:20: expected identifier for access control"); ASSERT_EQ(p->error(), R"(1:20: expected access control for ptr declaration
Possible values: 'read', 'read_write', 'write')");
} }
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) { TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) {
@ -326,7 +327,8 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_BadAccess) {
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr); ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:20: invalid value for access control"); ASSERT_EQ(p->error(), R"(1:20: expected access control for ptr declaration
Possible values: 'read', 'read_write', 'write')");
} }
TEST_F(ParserImplTest, TypeDecl_Atomic) { TEST_F(ParserImplTest, TypeDecl_Atomic) {

View File

@ -284,7 +284,8 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingAccess) {
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr); ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:20: expected identifier for access control"); ASSERT_EQ(p->error(), R"(1:20: expected access control for ptr declaration
Possible values: 'read', 'read_write', 'write')");
} }
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingParams) { TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingParams) {
@ -317,7 +318,8 @@ TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_BadAccess) {
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
ASSERT_EQ(t.value, nullptr); ASSERT_EQ(t.value, nullptr);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:20: invalid value for access control"); ASSERT_EQ(p->error(), R"(1:20: expected access control for ptr declaration
Possible values: 'read', 'read_write', 'write')");
} }
TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic) { TEST_F(ParserImplTest, TypeDeclWithoutIdent_Atomic) {