• 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,SingularExpression_Array_ConstantIndex)22 TEST_F(ParserImplTest, SingularExpression_Array_ConstantIndex) {
23   auto p = parser("a[1]");
24   auto e = p->singular_expression();
25   EXPECT_TRUE(e.matched);
26   EXPECT_FALSE(e.errored);
27   EXPECT_FALSE(p->has_error()) << p->error();
28   ASSERT_NE(e.value, nullptr);
29 
30   ASSERT_TRUE(e->Is<ast::IndexAccessorExpression>());
31   auto* idx = e->As<ast::IndexAccessorExpression>();
32 
33   ASSERT_TRUE(idx->object->Is<ast::IdentifierExpression>());
34   auto* ident = idx->object->As<ast::IdentifierExpression>();
35   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
36 
37   ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
38   EXPECT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 1);
39 }
40 
TEST_F(ParserImplTest,SingularExpression_Array_ExpressionIndex)41 TEST_F(ParserImplTest, SingularExpression_Array_ExpressionIndex) {
42   auto p = parser("a[1 + b / 4]");
43   auto e = p->singular_expression();
44   EXPECT_TRUE(e.matched);
45   EXPECT_FALSE(e.errored);
46   EXPECT_FALSE(p->has_error()) << p->error();
47   ASSERT_NE(e.value, nullptr);
48 
49   ASSERT_TRUE(e->Is<ast::IndexAccessorExpression>());
50   auto* idx = e->As<ast::IndexAccessorExpression>();
51 
52   ASSERT_TRUE(idx->object->Is<ast::IdentifierExpression>());
53   auto* ident = idx->object->As<ast::IdentifierExpression>();
54   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
55 
56   ASSERT_TRUE(idx->index->Is<ast::BinaryExpression>());
57 }
58 
TEST_F(ParserImplTest,SingularExpression_Array_MissingIndex)59 TEST_F(ParserImplTest, SingularExpression_Array_MissingIndex) {
60   auto p = parser("a[]");
61   auto e = p->singular_expression();
62   EXPECT_FALSE(e.matched);
63   EXPECT_TRUE(e.errored);
64   EXPECT_EQ(e.value, nullptr);
65   EXPECT_TRUE(p->has_error());
66   EXPECT_EQ(p->error(), "1:3: unable to parse expression inside []");
67 }
68 
TEST_F(ParserImplTest,SingularExpression_Array_MissingRightBrace)69 TEST_F(ParserImplTest, SingularExpression_Array_MissingRightBrace) {
70   auto p = parser("a[1");
71   auto e = p->singular_expression();
72   EXPECT_FALSE(e.matched);
73   EXPECT_TRUE(e.errored);
74   EXPECT_EQ(e.value, nullptr);
75   EXPECT_TRUE(p->has_error());
76   EXPECT_EQ(p->error(), "1:4: expected ']' for index accessor");
77 }
78 
TEST_F(ParserImplTest,SingularExpression_Array_InvalidIndex)79 TEST_F(ParserImplTest, SingularExpression_Array_InvalidIndex) {
80   auto p = parser("a[if(a() {})]");
81   auto e = p->singular_expression();
82   EXPECT_FALSE(e.matched);
83   EXPECT_TRUE(e.errored);
84   EXPECT_EQ(e.value, nullptr);
85   EXPECT_TRUE(p->has_error());
86   EXPECT_EQ(p->error(), "1:3: unable to parse expression inside []");
87 }
88 
TEST_F(ParserImplTest,SingularExpression_Call_Empty)89 TEST_F(ParserImplTest, SingularExpression_Call_Empty) {
90   auto p = parser("a()");
91   auto e = p->singular_expression();
92   EXPECT_TRUE(e.matched);
93   EXPECT_FALSE(e.errored);
94   EXPECT_FALSE(p->has_error()) << p->error();
95   ASSERT_NE(e.value, nullptr);
96 
97   ASSERT_TRUE(e->Is<ast::CallExpression>());
98   auto* c = e->As<ast::CallExpression>();
99 
100   EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("a"));
101 
102   EXPECT_EQ(c->args.size(), 0u);
103 }
104 
TEST_F(ParserImplTest,SingularExpression_Call_WithArgs)105 TEST_F(ParserImplTest, SingularExpression_Call_WithArgs) {
106   auto p = parser("test(1, b, 2 + 3 / b)");
107   auto e = p->singular_expression();
108   EXPECT_TRUE(e.matched);
109   EXPECT_FALSE(e.errored);
110   EXPECT_FALSE(p->has_error()) << p->error();
111   ASSERT_NE(e.value, nullptr);
112 
113   ASSERT_TRUE(e->Is<ast::CallExpression>());
114   auto* c = e->As<ast::CallExpression>();
115 
116   EXPECT_EQ(c->target.name->symbol, p->builder().Symbols().Get("test"));
117 
118   EXPECT_EQ(c->args.size(), 3u);
119   EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());
120   EXPECT_TRUE(c->args[1]->Is<ast::IdentifierExpression>());
121   EXPECT_TRUE(c->args[2]->Is<ast::BinaryExpression>());
122 }
123 
TEST_F(ParserImplTest,SingularExpression_Call_TrailingComma)124 TEST_F(ParserImplTest, SingularExpression_Call_TrailingComma) {
125   auto p = parser("a(b, )");
126   auto e = p->singular_expression();
127   EXPECT_TRUE(e.matched);
128   EXPECT_FALSE(e.errored);
129   ASSERT_NE(e.value, nullptr);
130 
131   ASSERT_TRUE(e->Is<ast::CallExpression>());
132   auto* c = e->As<ast::CallExpression>();
133   EXPECT_EQ(c->args.size(), 1u);
134 }
135 
TEST_F(ParserImplTest,SingularExpression_Call_InvalidArg)136 TEST_F(ParserImplTest, SingularExpression_Call_InvalidArg) {
137   auto p = parser("a(if(a) {})");
138   auto e = p->singular_expression();
139   EXPECT_FALSE(e.matched);
140   EXPECT_TRUE(e.errored);
141   EXPECT_EQ(e.value, nullptr);
142   EXPECT_TRUE(p->has_error());
143   EXPECT_EQ(p->error(), "1:3: expected ')' for function call");
144 }
145 
TEST_F(ParserImplTest,SingularExpression_Call_MissingRightParen)146 TEST_F(ParserImplTest, SingularExpression_Call_MissingRightParen) {
147   auto p = parser("a(");
148   auto e = p->singular_expression();
149   EXPECT_FALSE(e.matched);
150   EXPECT_TRUE(e.errored);
151   EXPECT_EQ(e.value, nullptr);
152   EXPECT_TRUE(p->has_error());
153   EXPECT_EQ(p->error(), "1:3: expected ')' for function call");
154 }
155 
TEST_F(ParserImplTest,SingularExpression_MemberAccessor)156 TEST_F(ParserImplTest, SingularExpression_MemberAccessor) {
157   auto p = parser("a.b");
158   auto e = p->singular_expression();
159   EXPECT_TRUE(e.matched);
160   EXPECT_FALSE(e.errored);
161   EXPECT_FALSE(p->has_error()) << p->error();
162   ASSERT_NE(e.value, nullptr);
163   ASSERT_TRUE(e->Is<ast::MemberAccessorExpression>());
164 
165   auto* m = e->As<ast::MemberAccessorExpression>();
166   ASSERT_TRUE(m->structure->Is<ast::IdentifierExpression>());
167   EXPECT_EQ(m->structure->As<ast::IdentifierExpression>()->symbol,
168             p->builder().Symbols().Get("a"));
169 
170   ASSERT_TRUE(m->member->Is<ast::IdentifierExpression>());
171   EXPECT_EQ(m->member->As<ast::IdentifierExpression>()->symbol,
172             p->builder().Symbols().Get("b"));
173 }
174 
TEST_F(ParserImplTest,SingularExpression_MemberAccesssor_InvalidIdent)175 TEST_F(ParserImplTest, SingularExpression_MemberAccesssor_InvalidIdent) {
176   auto p = parser("a.if");
177   auto e = p->singular_expression();
178   EXPECT_FALSE(e.matched);
179   EXPECT_TRUE(e.errored);
180   EXPECT_EQ(e.value, nullptr);
181   EXPECT_TRUE(p->has_error());
182   EXPECT_EQ(p->error(), "1:3: expected identifier for member accessor");
183 }
184 
TEST_F(ParserImplTest,SingularExpression_MemberAccessor_MissingIdent)185 TEST_F(ParserImplTest, SingularExpression_MemberAccessor_MissingIdent) {
186   auto p = parser("a.");
187   auto e = p->singular_expression();
188   EXPECT_FALSE(e.matched);
189   EXPECT_TRUE(e.errored);
190   EXPECT_EQ(e.value, nullptr);
191   EXPECT_TRUE(p->has_error());
192   EXPECT_EQ(p->error(), "1:3: expected identifier for member accessor");
193 }
194 
TEST_F(ParserImplTest,SingularExpression_NonMatch_returnLHS)195 TEST_F(ParserImplTest, SingularExpression_NonMatch_returnLHS) {
196   auto p = parser("a b");
197   auto e = p->singular_expression();
198   EXPECT_TRUE(e.matched);
199   EXPECT_FALSE(e.errored);
200   EXPECT_FALSE(p->has_error()) << p->error();
201   ASSERT_NE(e.value, nullptr);
202   ASSERT_TRUE(e->Is<ast::IdentifierExpression>());
203 }
204 
TEST_F(ParserImplTest,SingularExpression_Array_NestedIndexAccessor)205 TEST_F(ParserImplTest, SingularExpression_Array_NestedIndexAccessor) {
206   auto p = parser("a[b[c]]");
207   auto e = p->singular_expression();
208   EXPECT_TRUE(e.matched);
209   EXPECT_FALSE(e.errored);
210   EXPECT_FALSE(p->has_error()) << p->error();
211   ASSERT_NE(e.value, nullptr);
212 
213   const auto* outer_accessor = e->As<ast::IndexAccessorExpression>();
214   ASSERT_TRUE(outer_accessor);
215 
216   const auto* outer_object =
217       outer_accessor->object->As<ast::IdentifierExpression>();
218   ASSERT_TRUE(outer_object);
219   EXPECT_EQ(outer_object->symbol, p->builder().Symbols().Get("a"));
220 
221   const auto* inner_accessor =
222       outer_accessor->index->As<ast::IndexAccessorExpression>();
223   ASSERT_TRUE(inner_accessor);
224 
225   const auto* inner_object =
226       inner_accessor->object->As<ast::IdentifierExpression>();
227   ASSERT_TRUE(inner_object);
228   EXPECT_EQ(inner_object->symbol, p->builder().Symbols().Get("b"));
229 
230   const auto* index_expr =
231       inner_accessor->index->As<ast::IdentifierExpression>();
232   ASSERT_TRUE(index_expr);
233   EXPECT_EQ(index_expr->symbol, p->builder().Symbols().Get("c"));
234 }
235 
TEST_F(ParserImplTest,SingularExpression_PostfixPlusPlus)236 TEST_F(ParserImplTest, SingularExpression_PostfixPlusPlus) {
237   auto p = parser("a++");
238   auto e = p->singular_expression();
239   EXPECT_FALSE(e.matched);
240   EXPECT_TRUE(e.errored);
241   EXPECT_EQ(e.value, nullptr);
242   EXPECT_TRUE(p->has_error());
243   EXPECT_EQ(p->error(),
244             "1:2: postfix increment and decrement operators are reserved for a "
245             "future WGSL version");
246 }
247 
TEST_F(ParserImplTest,SingularExpression_PostfixMinusMinus)248 TEST_F(ParserImplTest, SingularExpression_PostfixMinusMinus) {
249   auto p = parser("a--");
250   auto e = p->singular_expression();
251   EXPECT_FALSE(e.matched);
252   EXPECT_TRUE(e.errored);
253   EXPECT_EQ(e.value, nullptr);
254   EXPECT_TRUE(p->has_error());
255   EXPECT_EQ(p->error(),
256             "1:2: postfix increment and decrement operators are reserved for a "
257             "future WGSL version");
258 }
259 
260 }  // namespace
261 }  // namespace wgsl
262 }  // namespace reader
263 }  // namespace tint
264