• 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/reader/wgsl/parser_impl_test_helper.h"
16 
17 namespace tint {
18 namespace reader {
19 namespace wgsl {
20 namespace {
21 
TEST_F(ParserImplTest,Decoration_Location)22 TEST_F(ParserImplTest, Decoration_Location) {
23   auto p = parser("location(4)");
24   auto deco = p->decoration();
25   EXPECT_TRUE(deco.matched);
26   EXPECT_FALSE(deco.errored);
27   ASSERT_NE(deco.value, nullptr);
28   auto* var_deco = deco.value->As<ast::Decoration>();
29   ASSERT_NE(var_deco, nullptr);
30   ASSERT_FALSE(p->has_error());
31   ASSERT_TRUE(var_deco->Is<ast::LocationDecoration>());
32 
33   auto* loc = var_deco->As<ast::LocationDecoration>();
34   EXPECT_EQ(loc->value, 4u);
35 }
36 
TEST_F(ParserImplTest,Decoration_Location_MissingLeftParen)37 TEST_F(ParserImplTest, Decoration_Location_MissingLeftParen) {
38   auto p = parser("location 4)");
39   auto deco = p->decoration();
40   EXPECT_FALSE(deco.matched);
41   EXPECT_TRUE(deco.errored);
42   EXPECT_EQ(deco.value, nullptr);
43   EXPECT_TRUE(p->has_error());
44   EXPECT_EQ(p->error(), "1:10: expected '(' for location decoration");
45 }
46 
TEST_F(ParserImplTest,Decoration_Location_MissingRightParen)47 TEST_F(ParserImplTest, Decoration_Location_MissingRightParen) {
48   auto p = parser("location(4");
49   auto deco = p->decoration();
50   EXPECT_FALSE(deco.matched);
51   EXPECT_TRUE(deco.errored);
52   EXPECT_EQ(deco.value, nullptr);
53   EXPECT_TRUE(p->has_error());
54   EXPECT_EQ(p->error(), "1:11: expected ')' for location decoration");
55 }
56 
TEST_F(ParserImplTest,Decoration_Location_MissingValue)57 TEST_F(ParserImplTest, Decoration_Location_MissingValue) {
58   auto p = parser("location()");
59   auto deco = p->decoration();
60   EXPECT_FALSE(deco.matched);
61   EXPECT_TRUE(deco.errored);
62   EXPECT_EQ(deco.value, nullptr);
63   EXPECT_TRUE(p->has_error());
64   EXPECT_EQ(p->error(),
65             "1:10: expected signed integer literal for location decoration");
66 }
67 
TEST_F(ParserImplTest,Decoration_Location_MissingInvalid)68 TEST_F(ParserImplTest, Decoration_Location_MissingInvalid) {
69   auto p = parser("location(nan)");
70   auto deco = p->decoration();
71   EXPECT_FALSE(deco.matched);
72   EXPECT_TRUE(deco.errored);
73   EXPECT_EQ(deco.value, nullptr);
74   EXPECT_TRUE(p->has_error());
75   EXPECT_EQ(p->error(),
76             "1:10: expected signed integer literal for location decoration");
77 }
78 
79 struct BuiltinData {
80   const char* input;
81   ast::Builtin result;
82 };
operator <<(std::ostream & out,BuiltinData data)83 inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
84   out << std::string(data.input);
85   return out;
86 }
87 
88 class BuiltinTest : public ParserImplTestWithParam<BuiltinData> {};
89 
TEST_P(BuiltinTest,Decoration_Builtin)90 TEST_P(BuiltinTest, Decoration_Builtin) {
91   auto params = GetParam();
92   auto p = parser(std::string("builtin(") + params.input + ")");
93 
94   auto deco = p->decoration();
95   EXPECT_TRUE(deco.matched);
96   EXPECT_FALSE(deco.errored);
97   ASSERT_NE(deco.value, nullptr);
98   auto* var_deco = deco.value->As<ast::Decoration>();
99   ASSERT_FALSE(p->has_error()) << p->error();
100   ASSERT_NE(var_deco, nullptr);
101   ASSERT_TRUE(var_deco->Is<ast::BuiltinDecoration>());
102 
103   auto* builtin = var_deco->As<ast::BuiltinDecoration>();
104   EXPECT_EQ(builtin->builtin, params.result);
105 }
106 INSTANTIATE_TEST_SUITE_P(
107     ParserImplTest,
108     BuiltinTest,
109     testing::Values(
110         BuiltinData{"position", ast::Builtin::kPosition},
111         BuiltinData{"vertex_index", ast::Builtin::kVertexIndex},
112         BuiltinData{"instance_index", ast::Builtin::kInstanceIndex},
113         BuiltinData{"front_facing", ast::Builtin::kFrontFacing},
114         BuiltinData{"frag_depth", ast::Builtin::kFragDepth},
115         BuiltinData{"local_invocation_id", ast::Builtin::kLocalInvocationId},
116         BuiltinData{"local_invocation_idx",
117                     ast::Builtin::kLocalInvocationIndex},
118         BuiltinData{"local_invocation_index",
119                     ast::Builtin::kLocalInvocationIndex},
120         BuiltinData{"global_invocation_id", ast::Builtin::kGlobalInvocationId},
121         BuiltinData{"workgroup_id", ast::Builtin::kWorkgroupId},
122         BuiltinData{"num_workgroups", ast::Builtin::kNumWorkgroups},
123         BuiltinData{"sample_index", ast::Builtin::kSampleIndex},
124         BuiltinData{"sample_mask", ast::Builtin::kSampleMask}));
125 
TEST_F(ParserImplTest,Decoration_Builtin_MissingLeftParen)126 TEST_F(ParserImplTest, Decoration_Builtin_MissingLeftParen) {
127   auto p = parser("builtin position)");
128   auto deco = p->decoration();
129   EXPECT_FALSE(deco.matched);
130   EXPECT_TRUE(deco.errored);
131   EXPECT_EQ(deco.value, nullptr);
132   EXPECT_TRUE(p->has_error());
133   EXPECT_EQ(p->error(), "1:9: expected '(' for builtin decoration");
134 }
135 
TEST_F(ParserImplTest,Decoration_Builtin_MissingRightParen)136 TEST_F(ParserImplTest, Decoration_Builtin_MissingRightParen) {
137   auto p = parser("builtin(position");
138   auto deco = p->decoration();
139   EXPECT_FALSE(deco.matched);
140   EXPECT_TRUE(deco.errored);
141   EXPECT_EQ(deco.value, nullptr);
142   EXPECT_TRUE(p->has_error());
143   EXPECT_EQ(p->error(), "1:17: expected ')' for builtin decoration");
144 }
145 
TEST_F(ParserImplTest,Decoration_Builtin_MissingValue)146 TEST_F(ParserImplTest, Decoration_Builtin_MissingValue) {
147   auto p = parser("builtin()");
148   auto deco = p->decoration();
149   EXPECT_FALSE(deco.matched);
150   EXPECT_TRUE(deco.errored);
151   EXPECT_EQ(deco.value, nullptr);
152   EXPECT_TRUE(p->has_error());
153   EXPECT_EQ(p->error(), "1:9: expected identifier for builtin");
154 }
155 
TEST_F(ParserImplTest,Decoration_Builtin_InvalidValue)156 TEST_F(ParserImplTest, Decoration_Builtin_InvalidValue) {
157   auto p = parser("builtin(other_thingy)");
158   auto deco = p->decoration();
159   EXPECT_FALSE(deco.matched);
160   EXPECT_TRUE(deco.errored);
161   EXPECT_EQ(deco.value, nullptr);
162   EXPECT_TRUE(p->has_error());
163   EXPECT_EQ(p->error(), "1:9: invalid value for builtin decoration");
164 }
165 
TEST_F(ParserImplTest,Decoration_Builtin_MissingInvalid)166 TEST_F(ParserImplTest, Decoration_Builtin_MissingInvalid) {
167   auto p = parser("builtin(3)");
168   auto deco = p->decoration();
169   EXPECT_FALSE(deco.matched);
170   EXPECT_TRUE(deco.errored);
171   EXPECT_EQ(deco.value, nullptr);
172   EXPECT_TRUE(p->has_error());
173   EXPECT_EQ(p->error(), "1:9: expected identifier for builtin");
174 }
175 
TEST_F(ParserImplTest,Decoration_Interpolate_Flat)176 TEST_F(ParserImplTest, Decoration_Interpolate_Flat) {
177   auto p = parser("interpolate(flat)");
178   auto deco = p->decoration();
179   EXPECT_TRUE(deco.matched);
180   EXPECT_FALSE(deco.errored);
181   ASSERT_NE(deco.value, nullptr);
182   auto* var_deco = deco.value->As<ast::Decoration>();
183   ASSERT_NE(var_deco, nullptr);
184   ASSERT_FALSE(p->has_error());
185   ASSERT_TRUE(var_deco->Is<ast::InterpolateDecoration>());
186 
187   auto* interp = var_deco->As<ast::InterpolateDecoration>();
188   EXPECT_EQ(interp->type, ast::InterpolationType::kFlat);
189   EXPECT_EQ(interp->sampling, ast::InterpolationSampling::kNone);
190 }
191 
TEST_F(ParserImplTest,Decoration_Interpolate_Perspective_Center)192 TEST_F(ParserImplTest, Decoration_Interpolate_Perspective_Center) {
193   auto p = parser("interpolate(perspective, center)");
194   auto deco = p->decoration();
195   EXPECT_TRUE(deco.matched);
196   EXPECT_FALSE(deco.errored);
197   ASSERT_NE(deco.value, nullptr);
198   auto* var_deco = deco.value->As<ast::Decoration>();
199   ASSERT_NE(var_deco, nullptr);
200   ASSERT_FALSE(p->has_error());
201   ASSERT_TRUE(var_deco->Is<ast::InterpolateDecoration>());
202 
203   auto* interp = var_deco->As<ast::InterpolateDecoration>();
204   EXPECT_EQ(interp->type, ast::InterpolationType::kPerspective);
205   EXPECT_EQ(interp->sampling, ast::InterpolationSampling::kCenter);
206 }
207 
TEST_F(ParserImplTest,Decoration_Interpolate_Perspective_Centroid)208 TEST_F(ParserImplTest, Decoration_Interpolate_Perspective_Centroid) {
209   auto p = parser("interpolate(perspective, centroid)");
210   auto deco = p->decoration();
211   EXPECT_TRUE(deco.matched);
212   EXPECT_FALSE(deco.errored);
213   ASSERT_NE(deco.value, nullptr);
214   auto* var_deco = deco.value->As<ast::Decoration>();
215   ASSERT_NE(var_deco, nullptr);
216   ASSERT_FALSE(p->has_error());
217   ASSERT_TRUE(var_deco->Is<ast::InterpolateDecoration>());
218 
219   auto* interp = var_deco->As<ast::InterpolateDecoration>();
220   EXPECT_EQ(interp->type, ast::InterpolationType::kPerspective);
221   EXPECT_EQ(interp->sampling, ast::InterpolationSampling::kCentroid);
222 }
223 
TEST_F(ParserImplTest,Decoration_Interpolate_Linear_Sample)224 TEST_F(ParserImplTest, Decoration_Interpolate_Linear_Sample) {
225   auto p = parser("interpolate(linear, sample)");
226   auto deco = p->decoration();
227   EXPECT_TRUE(deco.matched);
228   EXPECT_FALSE(deco.errored);
229   ASSERT_NE(deco.value, nullptr);
230   auto* var_deco = deco.value->As<ast::Decoration>();
231   ASSERT_NE(var_deco, nullptr);
232   ASSERT_FALSE(p->has_error());
233   ASSERT_TRUE(var_deco->Is<ast::InterpolateDecoration>());
234 
235   auto* interp = var_deco->As<ast::InterpolateDecoration>();
236   EXPECT_EQ(interp->type, ast::InterpolationType::kLinear);
237   EXPECT_EQ(interp->sampling, ast::InterpolationSampling::kSample);
238 }
239 
TEST_F(ParserImplTest,Decoration_Interpolate_MissingLeftParen)240 TEST_F(ParserImplTest, Decoration_Interpolate_MissingLeftParen) {
241   auto p = parser("interpolate flat)");
242   auto deco = p->decoration();
243   EXPECT_FALSE(deco.matched);
244   EXPECT_TRUE(deco.errored);
245   EXPECT_EQ(deco.value, nullptr);
246   EXPECT_TRUE(p->has_error());
247   EXPECT_EQ(p->error(), "1:13: expected '(' for interpolate decoration");
248 }
249 
TEST_F(ParserImplTest,Decoration_Interpolate_MissingRightParen)250 TEST_F(ParserImplTest, Decoration_Interpolate_MissingRightParen) {
251   auto p = parser("interpolate(flat");
252   auto deco = p->decoration();
253   EXPECT_FALSE(deco.matched);
254   EXPECT_TRUE(deco.errored);
255   EXPECT_EQ(deco.value, nullptr);
256   EXPECT_TRUE(p->has_error());
257   EXPECT_EQ(p->error(), "1:17: expected ')' for interpolate decoration");
258 }
259 
TEST_F(ParserImplTest,Decoration_Interpolate_MissingFirstValue)260 TEST_F(ParserImplTest, Decoration_Interpolate_MissingFirstValue) {
261   auto p = parser("interpolate()");
262   auto deco = p->decoration();
263   EXPECT_FALSE(deco.matched);
264   EXPECT_TRUE(deco.errored);
265   EXPECT_EQ(deco.value, nullptr);
266   EXPECT_TRUE(p->has_error());
267   EXPECT_EQ(p->error(), "1:13: invalid interpolation type");
268 }
269 
TEST_F(ParserImplTest,Decoration_Interpolate_InvalidFirstValue)270 TEST_F(ParserImplTest, Decoration_Interpolate_InvalidFirstValue) {
271   auto p = parser("interpolate(other_thingy)");
272   auto deco = p->decoration();
273   EXPECT_FALSE(deco.matched);
274   EXPECT_TRUE(deco.errored);
275   EXPECT_EQ(deco.value, nullptr);
276   EXPECT_TRUE(p->has_error());
277   EXPECT_EQ(p->error(), "1:13: invalid interpolation type");
278 }
279 
TEST_F(ParserImplTest,Decoration_Interpolate_MissingSecondValue)280 TEST_F(ParserImplTest, Decoration_Interpolate_MissingSecondValue) {
281   auto p = parser("interpolate(perspective,)");
282   auto deco = p->decoration();
283   EXPECT_FALSE(deco.matched);
284   EXPECT_TRUE(deco.errored);
285   EXPECT_EQ(deco.value, nullptr);
286   EXPECT_TRUE(p->has_error());
287   EXPECT_EQ(p->error(), "1:25: invalid interpolation sampling");
288 }
289 
TEST_F(ParserImplTest,Decoration_Interpolate_InvalidSecondValue)290 TEST_F(ParserImplTest, Decoration_Interpolate_InvalidSecondValue) {
291   auto p = parser("interpolate(perspective, nope)");
292   auto deco = p->decoration();
293   EXPECT_FALSE(deco.matched);
294   EXPECT_TRUE(deco.errored);
295   EXPECT_EQ(deco.value, nullptr);
296   EXPECT_TRUE(p->has_error());
297   EXPECT_EQ(p->error(), "1:26: invalid interpolation sampling");
298 }
299 
TEST_F(ParserImplTest,Decoration_Binding)300 TEST_F(ParserImplTest, Decoration_Binding) {
301   auto p = parser("binding(4)");
302   auto deco = p->decoration();
303   EXPECT_TRUE(deco.matched);
304   EXPECT_FALSE(deco.errored);
305   ASSERT_NE(deco.value, nullptr);
306   auto* var_deco = deco.value->As<ast::Decoration>();
307   ASSERT_NE(var_deco, nullptr);
308   ASSERT_FALSE(p->has_error());
309   ASSERT_TRUE(var_deco->Is<ast::BindingDecoration>());
310 
311   auto* binding = var_deco->As<ast::BindingDecoration>();
312   EXPECT_EQ(binding->value, 4u);
313 }
314 
TEST_F(ParserImplTest,Decoration_Binding_MissingLeftParen)315 TEST_F(ParserImplTest, Decoration_Binding_MissingLeftParen) {
316   auto p = parser("binding 4)");
317   auto deco = p->decoration();
318   EXPECT_FALSE(deco.matched);
319   EXPECT_TRUE(deco.errored);
320   EXPECT_EQ(deco.value, nullptr);
321   EXPECT_TRUE(p->has_error());
322   EXPECT_EQ(p->error(), "1:9: expected '(' for binding decoration");
323 }
324 
TEST_F(ParserImplTest,Decoration_Binding_MissingRightParen)325 TEST_F(ParserImplTest, Decoration_Binding_MissingRightParen) {
326   auto p = parser("binding(4");
327   auto deco = p->decoration();
328   EXPECT_FALSE(deco.matched);
329   EXPECT_TRUE(deco.errored);
330   EXPECT_EQ(deco.value, nullptr);
331   EXPECT_TRUE(p->has_error());
332   EXPECT_EQ(p->error(), "1:10: expected ')' for binding decoration");
333 }
334 
TEST_F(ParserImplTest,Decoration_Binding_MissingValue)335 TEST_F(ParserImplTest, Decoration_Binding_MissingValue) {
336   auto p = parser("binding()");
337   auto deco = p->decoration();
338   EXPECT_FALSE(deco.matched);
339   EXPECT_TRUE(deco.errored);
340   EXPECT_EQ(deco.value, nullptr);
341   EXPECT_TRUE(p->has_error());
342   EXPECT_EQ(p->error(),
343             "1:9: expected signed integer literal for binding decoration");
344 }
345 
TEST_F(ParserImplTest,Decoration_Binding_MissingInvalid)346 TEST_F(ParserImplTest, Decoration_Binding_MissingInvalid) {
347   auto p = parser("binding(nan)");
348   auto deco = p->decoration();
349   EXPECT_FALSE(deco.matched);
350   EXPECT_TRUE(deco.errored);
351   EXPECT_EQ(deco.value, nullptr);
352   EXPECT_TRUE(p->has_error());
353   EXPECT_EQ(p->error(),
354             "1:9: expected signed integer literal for binding decoration");
355 }
356 
TEST_F(ParserImplTest,Decoration_group)357 TEST_F(ParserImplTest, Decoration_group) {
358   auto p = parser("group(4)");
359   auto deco = p->decoration();
360   EXPECT_TRUE(deco.matched);
361   EXPECT_FALSE(deco.errored);
362   ASSERT_NE(deco.value, nullptr);
363   auto* var_deco = deco.value->As<ast::Decoration>();
364   ASSERT_FALSE(p->has_error());
365   ASSERT_NE(var_deco, nullptr);
366   ASSERT_TRUE(var_deco->Is<ast::GroupDecoration>());
367 
368   auto* group = var_deco->As<ast::GroupDecoration>();
369   EXPECT_EQ(group->value, 4u);
370 }
371 
TEST_F(ParserImplTest,Decoration_Group_MissingLeftParen)372 TEST_F(ParserImplTest, Decoration_Group_MissingLeftParen) {
373   auto p = parser("group 2)");
374   auto deco = p->decoration();
375   EXPECT_FALSE(deco.matched);
376   EXPECT_TRUE(deco.errored);
377   EXPECT_EQ(deco.value, nullptr);
378   EXPECT_TRUE(p->has_error());
379   EXPECT_EQ(p->error(), "1:7: expected '(' for group decoration");
380 }
381 
TEST_F(ParserImplTest,Decoration_Group_MissingRightParen)382 TEST_F(ParserImplTest, Decoration_Group_MissingRightParen) {
383   auto p = parser("group(2");
384   auto deco = p->decoration();
385   EXPECT_FALSE(deco.matched);
386   EXPECT_TRUE(deco.errored);
387   EXPECT_EQ(deco.value, nullptr);
388   EXPECT_TRUE(p->has_error());
389   EXPECT_EQ(p->error(), "1:8: expected ')' for group decoration");
390 }
391 
TEST_F(ParserImplTest,Decoration_Group_MissingValue)392 TEST_F(ParserImplTest, Decoration_Group_MissingValue) {
393   auto p = parser("group()");
394   auto deco = p->decoration();
395   EXPECT_FALSE(deco.matched);
396   EXPECT_TRUE(deco.errored);
397   EXPECT_EQ(deco.value, nullptr);
398   EXPECT_TRUE(p->has_error());
399   EXPECT_EQ(p->error(),
400             "1:7: expected signed integer literal for group decoration");
401 }
402 
TEST_F(ParserImplTest,Decoration_Group_MissingInvalid)403 TEST_F(ParserImplTest, Decoration_Group_MissingInvalid) {
404   auto p = parser("group(nan)");
405   auto deco = p->decoration();
406   EXPECT_FALSE(deco.matched);
407   EXPECT_TRUE(deco.errored);
408   EXPECT_EQ(deco.value, nullptr);
409   EXPECT_TRUE(p->has_error());
410   EXPECT_EQ(p->error(),
411             "1:7: expected signed integer literal for group decoration");
412 }
413 
414 }  // namespace
415 }  // namespace wgsl
416 }  // namespace reader
417 }  // namespace tint
418