1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/ast/struct_block_decoration.h"
16 #include "src/reader/wgsl/parser_impl_test_helper.h"
17
18 namespace tint {
19 namespace reader {
20 namespace wgsl {
21 namespace {
22
TEST_F(ParserImplTest,StructDecl_Parses)23 TEST_F(ParserImplTest, StructDecl_Parses) {
24 auto p = parser(R"(
25 struct S {
26 a : i32;
27 b : f32;
28 })");
29 auto decos = p->decoration_list();
30 EXPECT_FALSE(decos.errored);
31 EXPECT_FALSE(decos.matched);
32 ASSERT_EQ(decos.value.size(), 0u);
33
34 auto s = p->struct_decl(decos.value);
35 EXPECT_FALSE(p->has_error());
36 EXPECT_FALSE(s.errored);
37 EXPECT_TRUE(s.matched);
38 ASSERT_NE(s.value, nullptr);
39 ASSERT_EQ(s->name, p->builder().Symbols().Register("S"));
40 ASSERT_EQ(s->members.size(), 2u);
41 EXPECT_EQ(s->members[0]->symbol, p->builder().Symbols().Register("a"));
42 EXPECT_EQ(s->members[1]->symbol, p->builder().Symbols().Register("b"));
43 }
44
TEST_F(ParserImplTest,StructDecl_ParsesWithDecoration)45 TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
46 auto p = parser(R"(
47 [[block]] struct B {
48 a : f32;
49 b : f32;
50 })");
51 auto decos = p->decoration_list();
52 EXPECT_FALSE(decos.errored);
53 EXPECT_TRUE(decos.matched);
54 ASSERT_EQ(decos.value.size(), 1u);
55
56 auto s = p->struct_decl(decos.value);
57 EXPECT_FALSE(p->has_error());
58 EXPECT_FALSE(s.errored);
59 EXPECT_TRUE(s.matched);
60 ASSERT_NE(s.value, nullptr);
61 ASSERT_EQ(s->name, p->builder().Symbols().Register("B"));
62 ASSERT_EQ(s->members.size(), 2u);
63 EXPECT_EQ(s->members[0]->symbol, p->builder().Symbols().Register("a"));
64 EXPECT_EQ(s->members[1]->symbol, p->builder().Symbols().Register("b"));
65 ASSERT_EQ(s->decorations.size(), 1u);
66 EXPECT_TRUE(s->decorations[0]->Is<ast::StructBlockDecoration>());
67 }
68
TEST_F(ParserImplTest,StructDecl_ParsesWithMultipleDecoration)69 TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
70 auto p = parser(R"(
71 [[block]]
72 [[block]] struct S {
73 a : f32;
74 b : f32;
75 })");
76 auto decos = p->decoration_list();
77 EXPECT_FALSE(decos.errored);
78 EXPECT_TRUE(decos.matched);
79 ASSERT_EQ(decos.value.size(), 2u);
80
81 auto s = p->struct_decl(decos.value);
82 EXPECT_FALSE(p->has_error());
83 EXPECT_FALSE(s.errored);
84 EXPECT_TRUE(s.matched);
85 ASSERT_NE(s.value, nullptr);
86 ASSERT_EQ(s->name, p->builder().Symbols().Register("S"));
87 ASSERT_EQ(s->members.size(), 2u);
88 EXPECT_EQ(s->members[0]->symbol, p->builder().Symbols().Register("a"));
89 EXPECT_EQ(s->members[1]->symbol, p->builder().Symbols().Register("b"));
90 ASSERT_EQ(s->decorations.size(), 2u);
91 EXPECT_TRUE(s->decorations[0]->Is<ast::StructBlockDecoration>());
92 EXPECT_TRUE(s->decorations[1]->Is<ast::StructBlockDecoration>());
93 }
94
TEST_F(ParserImplTest,StructDecl_EmptyMembers)95 TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
96 auto p = parser("struct S {}");
97 auto decos = p->decoration_list();
98 EXPECT_FALSE(decos.errored);
99 EXPECT_FALSE(decos.matched);
100 ASSERT_EQ(decos.value.size(), 0u);
101
102 auto s = p->struct_decl(decos.value);
103 EXPECT_FALSE(p->has_error());
104 EXPECT_FALSE(s.errored);
105 EXPECT_TRUE(s.matched);
106 ASSERT_NE(s.value, nullptr);
107 ASSERT_EQ(s->members.size(), 0u);
108 }
109
TEST_F(ParserImplTest,StructDecl_MissingIdent)110 TEST_F(ParserImplTest, StructDecl_MissingIdent) {
111 auto p = parser("struct {}");
112 auto decos = p->decoration_list();
113 EXPECT_FALSE(decos.errored);
114 EXPECT_FALSE(decos.matched);
115 ASSERT_EQ(decos.value.size(), 0u);
116
117 auto s = p->struct_decl(decos.value);
118 EXPECT_TRUE(s.errored);
119 EXPECT_FALSE(s.matched);
120 EXPECT_EQ(s.value, nullptr);
121
122 EXPECT_TRUE(p->has_error());
123 EXPECT_EQ(p->error(), "1:8: expected identifier for struct declaration");
124 }
125
TEST_F(ParserImplTest,StructDecl_MissingBracketLeft)126 TEST_F(ParserImplTest, StructDecl_MissingBracketLeft) {
127 auto p = parser("struct S }");
128 auto decos = p->decoration_list();
129 EXPECT_FALSE(decos.errored);
130 EXPECT_FALSE(decos.matched);
131 ASSERT_EQ(decos.value.size(), 0u);
132
133 auto s = p->struct_decl(decos.value);
134 EXPECT_TRUE(s.errored);
135 EXPECT_FALSE(s.matched);
136 EXPECT_EQ(s.value, nullptr);
137
138 EXPECT_TRUE(p->has_error());
139 EXPECT_EQ(p->error(), "1:10: expected '{' for struct declaration");
140 }
141
TEST_F(ParserImplTest,StructDecl_InvalidDecorationDecl)142 TEST_F(ParserImplTest, StructDecl_InvalidDecorationDecl) {
143 auto p = parser("[[block struct S { a : i32; }");
144 auto decos = p->decoration_list();
145 EXPECT_TRUE(decos.errored);
146 EXPECT_FALSE(decos.matched);
147
148 auto s = p->struct_decl(decos.value);
149 EXPECT_FALSE(s.errored);
150 EXPECT_TRUE(s.matched);
151 EXPECT_NE(s.value, nullptr);
152
153 EXPECT_TRUE(p->has_error());
154 EXPECT_EQ(p->error(), "1:9: expected ']]' for decoration list");
155 }
156
TEST_F(ParserImplTest,StructDecl_MissingStruct)157 TEST_F(ParserImplTest, StructDecl_MissingStruct) {
158 auto p = parser("[[block]] S {}");
159 auto decos = p->decoration_list();
160 EXPECT_FALSE(decos.errored);
161 EXPECT_TRUE(decos.matched);
162 ASSERT_EQ(decos.value.size(), 1u);
163
164 auto s = p->struct_decl(decos.value);
165 EXPECT_FALSE(s.errored);
166 EXPECT_FALSE(s.matched);
167 EXPECT_EQ(s.value, nullptr);
168
169 EXPECT_FALSE(p->has_error());
170 }
171
172 } // namespace
173 } // namespace wgsl
174 } // namespace reader
175 } // namespace tint
176