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,GlobalVariableDecl_WithoutConstructor)22 TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
23 auto p = parser("var<private> a : f32");
24 auto decos = p->decoration_list();
25 EXPECT_FALSE(decos.errored);
26 EXPECT_FALSE(decos.matched);
27 auto e = p->global_variable_decl(decos.value);
28 ASSERT_FALSE(p->has_error()) << p->error();
29 EXPECT_TRUE(e.matched);
30 EXPECT_FALSE(e.errored);
31 ASSERT_NE(e.value, nullptr);
32
33 EXPECT_EQ(e->symbol, p->builder().Symbols().Get("a"));
34 EXPECT_TRUE(e->type->Is<ast::F32>());
35 EXPECT_EQ(e->declared_storage_class, ast::StorageClass::kPrivate);
36
37 EXPECT_EQ(e->source.range.begin.line, 1u);
38 EXPECT_EQ(e->source.range.begin.column, 14u);
39 EXPECT_EQ(e->source.range.end.line, 1u);
40 EXPECT_EQ(e->source.range.end.column, 15u);
41
42 ASSERT_EQ(e->constructor, nullptr);
43 }
44
TEST_F(ParserImplTest,GlobalVariableDecl_WithConstructor)45 TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
46 auto p = parser("var<private> a : f32 = 1.");
47 auto decos = p->decoration_list();
48 EXPECT_FALSE(decos.errored);
49 EXPECT_FALSE(decos.matched);
50 auto e = p->global_variable_decl(decos.value);
51 ASSERT_FALSE(p->has_error()) << p->error();
52 EXPECT_TRUE(e.matched);
53 EXPECT_FALSE(e.errored);
54 ASSERT_NE(e.value, nullptr);
55
56 EXPECT_EQ(e->symbol, p->builder().Symbols().Get("a"));
57 EXPECT_TRUE(e->type->Is<ast::F32>());
58 EXPECT_EQ(e->declared_storage_class, ast::StorageClass::kPrivate);
59
60 EXPECT_EQ(e->source.range.begin.line, 1u);
61 EXPECT_EQ(e->source.range.begin.column, 14u);
62 EXPECT_EQ(e->source.range.end.line, 1u);
63 EXPECT_EQ(e->source.range.end.column, 15u);
64
65 ASSERT_NE(e->constructor, nullptr);
66 ASSERT_TRUE(e->constructor->Is<ast::FloatLiteralExpression>());
67 }
68
TEST_F(ParserImplTest,GlobalVariableDecl_WithDecoration)69 TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
70 auto p = parser("[[binding(2), group(1)]] var<uniform> a : f32");
71 auto decos = p->decoration_list();
72 EXPECT_FALSE(decos.errored);
73 EXPECT_TRUE(decos.matched);
74 auto e = p->global_variable_decl(decos.value);
75 ASSERT_FALSE(p->has_error()) << p->error();
76 EXPECT_TRUE(e.matched);
77 EXPECT_FALSE(e.errored);
78 ASSERT_NE(e.value, nullptr);
79
80 EXPECT_EQ(e->symbol, p->builder().Symbols().Get("a"));
81 ASSERT_NE(e->type, nullptr);
82 EXPECT_TRUE(e->type->Is<ast::F32>());
83 EXPECT_EQ(e->declared_storage_class, ast::StorageClass::kUniform);
84
85 EXPECT_EQ(e->source.range.begin.line, 1u);
86 EXPECT_EQ(e->source.range.begin.column, 39u);
87 EXPECT_EQ(e->source.range.end.line, 1u);
88 EXPECT_EQ(e->source.range.end.column, 40u);
89
90 ASSERT_EQ(e->constructor, nullptr);
91
92 auto& decorations = e->decorations;
93 ASSERT_EQ(decorations.size(), 2u);
94 ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
95 ASSERT_TRUE(decorations[1]->Is<ast::GroupDecoration>());
96 }
97
TEST_F(ParserImplTest,GlobalVariableDecl_WithDecoration_MulitpleGroups)98 TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
99 auto p = parser("[[binding(2)]] [[group(1)]] var<uniform> a : f32");
100 auto decos = p->decoration_list();
101 EXPECT_FALSE(decos.errored);
102 EXPECT_TRUE(decos.matched);
103
104 auto e = p->global_variable_decl(decos.value);
105 ASSERT_FALSE(p->has_error()) << p->error();
106 EXPECT_TRUE(e.matched);
107 EXPECT_FALSE(e.errored);
108 ASSERT_NE(e.value, nullptr);
109
110 EXPECT_EQ(e->symbol, p->builder().Symbols().Get("a"));
111 ASSERT_NE(e->type, nullptr);
112 EXPECT_TRUE(e->type->Is<ast::F32>());
113 EXPECT_EQ(e->declared_storage_class, ast::StorageClass::kUniform);
114
115 EXPECT_EQ(e->source.range.begin.line, 1u);
116 EXPECT_EQ(e->source.range.begin.column, 42u);
117 EXPECT_EQ(e->source.range.end.line, 1u);
118 EXPECT_EQ(e->source.range.end.column, 43u);
119
120 ASSERT_EQ(e->constructor, nullptr);
121
122 auto& decorations = e->decorations;
123 ASSERT_EQ(decorations.size(), 2u);
124 ASSERT_TRUE(decorations[0]->Is<ast::BindingDecoration>());
125 ASSERT_TRUE(decorations[1]->Is<ast::GroupDecoration>());
126 }
127
TEST_F(ParserImplTest,GlobalVariableDecl_InvalidDecoration)128 TEST_F(ParserImplTest, GlobalVariableDecl_InvalidDecoration) {
129 auto p = parser("[[binding()]] var<uniform> a : f32");
130 auto decos = p->decoration_list();
131 EXPECT_TRUE(decos.errored);
132 EXPECT_FALSE(decos.matched);
133
134 auto e = p->global_variable_decl(decos.value);
135 EXPECT_FALSE(e.errored);
136 EXPECT_TRUE(e.matched);
137 EXPECT_NE(e.value, nullptr);
138
139 EXPECT_TRUE(p->has_error());
140 EXPECT_EQ(p->error(),
141 "1:11: expected signed integer literal for binding decoration");
142 }
143
TEST_F(ParserImplTest,GlobalVariableDecl_InvalidConstExpr)144 TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
145 auto p = parser("var<private> a : f32 = if (a) {}");
146 auto decos = p->decoration_list();
147 EXPECT_FALSE(decos.errored);
148 EXPECT_FALSE(decos.matched);
149 auto e = p->global_variable_decl(decos.value);
150 EXPECT_TRUE(p->has_error());
151 EXPECT_TRUE(e.errored);
152 EXPECT_FALSE(e.matched);
153 EXPECT_EQ(e.value, nullptr);
154 EXPECT_EQ(p->error(), "1:24: invalid type for const_expr");
155 }
156
TEST_F(ParserImplTest,GlobalVariableDecl_InvalidVariableDecl)157 TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
158 auto p = parser("var<invalid> a : f32;");
159 auto decos = p->decoration_list();
160 EXPECT_FALSE(decos.errored);
161 EXPECT_FALSE(decos.matched);
162 auto e = p->global_variable_decl(decos.value);
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:5: invalid storage class for variable declaration");
168 }
169
170 } // namespace
171 } // namespace wgsl
172 } // namespace reader
173 } // namespace tint
174