• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/break_statement.h"
16 #include "src/ast/continue_statement.h"
17 #include "src/ast/discard_statement.h"
18 #include "src/reader/wgsl/parser_impl_test_helper.h"
19 
20 namespace tint {
21 namespace reader {
22 namespace wgsl {
23 namespace {
24 
TEST_F(ParserImplTest,Statement)25 TEST_F(ParserImplTest, Statement) {
26   auto p = parser("return;");
27   auto e = p->statement();
28   ASSERT_FALSE(p->has_error()) << p->error();
29   EXPECT_TRUE(e.matched);
30   EXPECT_FALSE(e.errored);
31   ASSERT_TRUE(e->Is<ast::ReturnStatement>());
32 }
33 
TEST_F(ParserImplTest,Statement_Semicolon)34 TEST_F(ParserImplTest, Statement_Semicolon) {
35   auto p = parser(";");
36   p->statement();
37   ASSERT_FALSE(p->has_error()) << p->error();
38 }
39 
TEST_F(ParserImplTest,Statement_Return_NoValue)40 TEST_F(ParserImplTest, Statement_Return_NoValue) {
41   auto p = parser("return;");
42   auto e = p->statement();
43   ASSERT_FALSE(p->has_error()) << p->error();
44   EXPECT_TRUE(e.matched);
45   EXPECT_FALSE(e.errored);
46   ASSERT_TRUE(e->Is<ast::ReturnStatement>());
47   auto* ret = e->As<ast::ReturnStatement>();
48   ASSERT_EQ(ret->value, nullptr);
49 }
50 
TEST_F(ParserImplTest,Statement_Return_Value)51 TEST_F(ParserImplTest, Statement_Return_Value) {
52   auto p = parser("return a + b * (.1 - .2);");
53   auto e = p->statement();
54   ASSERT_FALSE(p->has_error()) << p->error();
55 
56   EXPECT_TRUE(e.matched);
57   EXPECT_FALSE(e.errored);
58   ASSERT_TRUE(e->Is<ast::ReturnStatement>());
59   auto* ret = e->As<ast::ReturnStatement>();
60   ASSERT_NE(ret->value, nullptr);
61   EXPECT_TRUE(ret->value->Is<ast::BinaryExpression>());
62 }
63 
TEST_F(ParserImplTest,Statement_Return_MissingSemi)64 TEST_F(ParserImplTest, Statement_Return_MissingSemi) {
65   auto p = parser("return");
66   auto e = p->statement();
67   EXPECT_TRUE(p->has_error());
68   EXPECT_TRUE(e.errored);
69   EXPECT_FALSE(e.matched);
70   EXPECT_EQ(e.value, nullptr);
71   EXPECT_EQ(p->error(), "1:7: expected ';' for return statement");
72 }
73 
TEST_F(ParserImplTest,Statement_Return_Invalid)74 TEST_F(ParserImplTest, Statement_Return_Invalid) {
75   auto p = parser("return if(a) {};");
76   auto e = p->statement();
77   EXPECT_TRUE(p->has_error());
78   EXPECT_TRUE(e.errored);
79   EXPECT_FALSE(e.matched);
80   EXPECT_EQ(e.value, nullptr);
81   EXPECT_EQ(p->error(), "1:8: expected ';' for return statement");
82 }
83 
TEST_F(ParserImplTest,Statement_If)84 TEST_F(ParserImplTest, Statement_If) {
85   auto p = parser("if (a) {}");
86   auto e = p->statement();
87   ASSERT_FALSE(p->has_error()) << p->error();
88   EXPECT_TRUE(e.matched);
89   EXPECT_FALSE(e.errored);
90   ASSERT_TRUE(e->Is<ast::IfStatement>());
91 }
92 
TEST_F(ParserImplTest,Statement_If_Invalid)93 TEST_F(ParserImplTest, Statement_If_Invalid) {
94   auto p = parser("if (a) { fn main() -> {}}");
95   auto e = p->statement();
96   EXPECT_TRUE(p->has_error());
97   EXPECT_TRUE(e.errored);
98   EXPECT_FALSE(e.matched);
99   EXPECT_EQ(e.value, nullptr);
100   EXPECT_EQ(p->error(), "1:10: expected '}'");
101 }
102 
TEST_F(ParserImplTest,Statement_Variable)103 TEST_F(ParserImplTest, Statement_Variable) {
104   auto p = parser("var a : i32 = 1;");
105   auto e = p->statement();
106   ASSERT_FALSE(p->has_error()) << p->error();
107   EXPECT_TRUE(e.matched);
108   EXPECT_FALSE(e.errored);
109   ASSERT_TRUE(e->Is<ast::VariableDeclStatement>());
110 }
111 
TEST_F(ParserImplTest,Statement_Variable_Invalid)112 TEST_F(ParserImplTest, Statement_Variable_Invalid) {
113   auto p = parser("var a : i32 =;");
114   auto e = p->statement();
115   EXPECT_TRUE(p->has_error());
116   EXPECT_TRUE(e.errored);
117   EXPECT_FALSE(e.matched);
118   EXPECT_EQ(e.value, nullptr);
119   EXPECT_EQ(p->error(), "1:14: missing constructor for variable declaration");
120 }
121 
TEST_F(ParserImplTest,Statement_Variable_MissingSemicolon)122 TEST_F(ParserImplTest, Statement_Variable_MissingSemicolon) {
123   auto p = parser("var a : i32");
124   auto e = p->statement();
125   EXPECT_TRUE(p->has_error());
126   EXPECT_TRUE(e.errored);
127   EXPECT_FALSE(e.matched);
128   EXPECT_EQ(e.value, nullptr);
129   EXPECT_EQ(p->error(), "1:12: expected ';' for variable declaration");
130 }
131 
TEST_F(ParserImplTest,Statement_Switch)132 TEST_F(ParserImplTest, Statement_Switch) {
133   auto p = parser("switch (a) {}");
134   auto e = p->statement();
135   ASSERT_FALSE(p->has_error()) << p->error();
136   EXPECT_TRUE(e.matched);
137   EXPECT_FALSE(e.errored);
138   ASSERT_TRUE(e->Is<ast::SwitchStatement>());
139 }
140 
TEST_F(ParserImplTest,Statement_Switch_Invalid)141 TEST_F(ParserImplTest, Statement_Switch_Invalid) {
142   auto p = parser("switch (a) { case: {}}");
143   auto e = p->statement();
144   EXPECT_TRUE(p->has_error());
145   EXPECT_TRUE(e.errored);
146   EXPECT_FALSE(e.matched);
147   EXPECT_EQ(e.value, nullptr);
148   EXPECT_EQ(p->error(), "1:18: unable to parse case selectors");
149 }
150 
TEST_F(ParserImplTest,Statement_Loop)151 TEST_F(ParserImplTest, Statement_Loop) {
152   auto p = parser("loop {}");
153   auto e = p->statement();
154   ASSERT_FALSE(p->has_error()) << p->error();
155   EXPECT_TRUE(e.matched);
156   EXPECT_FALSE(e.errored);
157   ASSERT_TRUE(e->Is<ast::LoopStatement>());
158 }
159 
TEST_F(ParserImplTest,Statement_Loop_Invalid)160 TEST_F(ParserImplTest, Statement_Loop_Invalid) {
161   auto p = parser("loop discard; }");
162   auto e = p->statement();
163   EXPECT_TRUE(p->has_error());
164   EXPECT_TRUE(e.errored);
165   EXPECT_FALSE(e.matched);
166   EXPECT_EQ(e.value, nullptr);
167   EXPECT_EQ(p->error(), "1:6: expected '{' for loop");
168 }
169 
TEST_F(ParserImplTest,Statement_Assignment)170 TEST_F(ParserImplTest, Statement_Assignment) {
171   auto p = parser("a = b;");
172   auto e = p->statement();
173   ASSERT_FALSE(p->has_error()) << p->error();
174   EXPECT_TRUE(e.matched);
175   EXPECT_FALSE(e.errored);
176   ASSERT_TRUE(e->Is<ast::AssignmentStatement>());
177 }
178 
TEST_F(ParserImplTest,Statement_Assignment_Invalid)179 TEST_F(ParserImplTest, Statement_Assignment_Invalid) {
180   auto p = parser("a = if(b) {};");
181   auto e = p->statement();
182   EXPECT_TRUE(p->has_error());
183   EXPECT_TRUE(e.errored);
184   EXPECT_FALSE(e.matched);
185   EXPECT_EQ(e.value, nullptr);
186   EXPECT_EQ(p->error(), "1:5: unable to parse right side of assignment");
187 }
188 
TEST_F(ParserImplTest,Statement_Assignment_MissingSemicolon)189 TEST_F(ParserImplTest, Statement_Assignment_MissingSemicolon) {
190   auto p = parser("a = b");
191   auto e = p->statement();
192   EXPECT_TRUE(p->has_error());
193   EXPECT_TRUE(e.errored);
194   EXPECT_FALSE(e.matched);
195   EXPECT_EQ(e.value, nullptr);
196   EXPECT_EQ(p->error(), "1:6: expected ';' for assignment statement");
197 }
198 
TEST_F(ParserImplTest,Statement_Break)199 TEST_F(ParserImplTest, Statement_Break) {
200   auto p = parser("break;");
201   auto e = p->statement();
202   ASSERT_FALSE(p->has_error()) << p->error();
203   EXPECT_TRUE(e.matched);
204   EXPECT_FALSE(e.errored);
205   ASSERT_TRUE(e->Is<ast::BreakStatement>());
206 }
207 
TEST_F(ParserImplTest,Statement_Break_MissingSemicolon)208 TEST_F(ParserImplTest, Statement_Break_MissingSemicolon) {
209   auto p = parser("break");
210   auto e = p->statement();
211   EXPECT_TRUE(p->has_error());
212   EXPECT_TRUE(e.errored);
213   EXPECT_FALSE(e.matched);
214   EXPECT_EQ(e.value, nullptr);
215   EXPECT_EQ(p->error(), "1:6: expected ';' for break statement");
216 }
217 
TEST_F(ParserImplTest,Statement_Continue)218 TEST_F(ParserImplTest, Statement_Continue) {
219   auto p = parser("continue;");
220   auto e = p->statement();
221   ASSERT_FALSE(p->has_error()) << p->error();
222   EXPECT_TRUE(e.matched);
223   EXPECT_FALSE(e.errored);
224   ASSERT_TRUE(e->Is<ast::ContinueStatement>());
225 }
226 
TEST_F(ParserImplTest,Statement_Continue_MissingSemicolon)227 TEST_F(ParserImplTest, Statement_Continue_MissingSemicolon) {
228   auto p = parser("continue");
229   auto e = p->statement();
230   EXPECT_TRUE(p->has_error());
231   EXPECT_TRUE(e.errored);
232   EXPECT_FALSE(e.matched);
233   EXPECT_EQ(e.value, nullptr);
234   EXPECT_EQ(p->error(), "1:9: expected ';' for continue statement");
235 }
236 
TEST_F(ParserImplTest,Statement_Discard)237 TEST_F(ParserImplTest, Statement_Discard) {
238   auto p = parser("discard;");
239   auto e = p->statement();
240   ASSERT_FALSE(p->has_error()) << p->error();
241   ASSERT_NE(e.value, nullptr);
242   EXPECT_TRUE(e.matched);
243   EXPECT_FALSE(e.errored);
244   ASSERT_TRUE(e->Is<ast::DiscardStatement>());
245 }
246 
TEST_F(ParserImplTest,Statement_Discard_MissingSemicolon)247 TEST_F(ParserImplTest, Statement_Discard_MissingSemicolon) {
248   auto p = parser("discard");
249   auto e = p->statement();
250   EXPECT_TRUE(p->has_error());
251   EXPECT_EQ(e.value, nullptr);
252   EXPECT_TRUE(e.errored);
253   EXPECT_FALSE(e.matched);
254   EXPECT_EQ(p->error(), "1:8: expected ';' for discard statement");
255 }
256 
TEST_F(ParserImplTest,Statement_Body)257 TEST_F(ParserImplTest, Statement_Body) {
258   auto p = parser("{ var i: i32; }");
259   auto e = p->statement();
260   ASSERT_FALSE(p->has_error()) << p->error();
261   EXPECT_TRUE(e.matched);
262   EXPECT_FALSE(e.errored);
263   ASSERT_TRUE(e->Is<ast::BlockStatement>());
264   EXPECT_TRUE(e->As<ast::BlockStatement>()
265                   ->statements[0]
266                   ->Is<ast::VariableDeclStatement>());
267 }
268 
TEST_F(ParserImplTest,Statement_Body_Invalid)269 TEST_F(ParserImplTest, Statement_Body_Invalid) {
270   auto p = parser("{ fn main() -> {}}");
271   auto e = p->statement();
272   EXPECT_TRUE(p->has_error());
273   EXPECT_TRUE(e.errored);
274   EXPECT_FALSE(e.matched);
275   EXPECT_EQ(e.value, nullptr);
276   EXPECT_EQ(p->error(), "1:3: expected '}'");
277 }
278 
279 }  // namespace
280 }  // namespace wgsl
281 }  // namespace reader
282 }  // namespace tint
283