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