• 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 
22 const diag::Formatter::Style formatter_style{
23     /* print_file: */ true, /* print_severity: */ true,
24     /* print_line: */ true, /* print_newline_at_end: */ false};
25 
26 class ParserImplErrorResyncTest : public ParserImplTest {};
27 
28 #define EXPECT(SOURCE, EXPECTED)                                               \
29   do {                                                                         \
30     std::string source = SOURCE;                                               \
31     std::string expected = EXPECTED;                                           \
32     auto p = parser(source);                                                   \
33     EXPECT_EQ(false, p->Parse());                                              \
34     auto diagnostics = p->builder().Diagnostics();                             \
35     EXPECT_EQ(true, diagnostics.contains_errors());                            \
36     EXPECT_EQ(expected, diag::Formatter(formatter_style).format(diagnostics)); \
37   } while (false)
38 
TEST_F(ParserImplErrorResyncTest,BadFunctionDecls)39 TEST_F(ParserImplErrorResyncTest, BadFunctionDecls) {
40   EXPECT(R"(
41 fn .() -> . {}
42 fn x(.) {}
43 [[.,.]] fn -> {}
44 fn good() {}
45 )",
46          "test.wgsl:2:4 error: expected identifier for function declaration\n"
47          "fn .() -> . {}\n"
48          "   ^\n"
49          "\n"
50          "test.wgsl:2:11 error: unable to determine function return type\n"
51          "fn .() -> . {}\n"
52          "          ^\n"
53          "\n"
54          "test.wgsl:3:6 error: expected ')' for function declaration\n"
55          "fn x(.) {}\n"
56          "     ^\n"
57          "\n"
58          "test.wgsl:4:3 error: expected decoration\n"
59          "[[.,.]] fn -> {}\n"
60          "  ^\n"
61          "\n"
62          "test.wgsl:4:5 error: expected decoration\n"
63          "[[.,.]] fn -> {}\n"
64          "    ^\n"
65          "\n"
66          "test.wgsl:4:12 error: expected identifier for function declaration\n"
67          "[[.,.]] fn -> {}\n"
68          "           ^^\n");
69 }
70 
TEST_F(ParserImplErrorResyncTest,AssignmentStatement)71 TEST_F(ParserImplErrorResyncTest, AssignmentStatement) {
72   EXPECT(R"(
73 fn f() {
74   blah blah blah blah;
75   good = 1;
76   blah blah blah blah;
77   x = .;
78   good = 1;
79 }
80 )",
81          "test.wgsl:3:8 error: expected '=' for assignment\n"
82          "  blah blah blah blah;\n"
83          "       ^^^^\n"
84          "\n"
85          "test.wgsl:5:8 error: expected '=' for assignment\n"
86          "  blah blah blah blah;\n"
87          "       ^^^^\n"
88          "\n"
89          "test.wgsl:6:7 error: unable to parse right side of assignment\n"
90          "  x = .;\n"
91          "      ^\n");
92 }
93 
TEST_F(ParserImplErrorResyncTest,DiscardStatement)94 TEST_F(ParserImplErrorResyncTest, DiscardStatement) {
95   EXPECT(R"(
96 fn f() {
97   discard blah blah blah;
98   a = 1;
99   discard blah blah blah;
100 }
101 )",
102          "test.wgsl:3:11 error: expected ';' for discard statement\n"
103          "  discard blah blah blah;\n"
104          "          ^^^^\n"
105          "\n"
106          "test.wgsl:5:11 error: expected ';' for discard statement\n"
107          "  discard blah blah blah;\n"
108          "          ^^^^\n");
109 }
110 
TEST_F(ParserImplErrorResyncTest,StructMembers)111 TEST_F(ParserImplErrorResyncTest, StructMembers) {
112   EXPECT(R"(
113 struct S {
114     blah blah blah;
115     a : i32;
116     blah blah blah;
117     b : i32;
118     [[]] x : i32;
119     c : i32;
120 }
121 )",
122          "test.wgsl:3:10 error: expected ':' for struct member\n"
123          "    blah blah blah;\n"
124          "         ^^^^\n"
125          "\n"
126          "test.wgsl:5:10 error: expected ':' for struct member\n"
127          "    blah blah blah;\n"
128          "         ^^^^\n"
129          "\n"
130          "test.wgsl:7:7 error: empty decoration list\n"
131          "    [[]] x : i32;\n"
132          "      ^^\n");
133 }
134 
135 // Check that the forward scan in resynchronize() stop at nested sync points.
136 // In this test the inner resynchronize() is looking for a terminating ';', and
137 // the outer resynchronize() is looking for a terminating '}' for the function
138 // scope.
TEST_F(ParserImplErrorResyncTest,NestedSyncPoints)139 TEST_F(ParserImplErrorResyncTest, NestedSyncPoints) {
140   EXPECT(R"(
141 fn f() {
142   x = 1;
143   discard
144 }
145 struct S { blah };
146 )",
147          "test.wgsl:5:1 error: expected ';' for discard statement\n"
148          "}\n"
149          "^\n"
150          "\n"
151          "test.wgsl:6:17 error: expected ':' for struct member\n"
152          "struct S { blah };\n"
153          "                ^\n");
154 }
155 
TEST_F(ParserImplErrorResyncTest,BracketCounting)156 TEST_F(ParserImplErrorResyncTest, BracketCounting) {
157   EXPECT(R"(
158 [[woof[[[[]]]]]]
159 fn f(x(((())))) {
160   meow = {{{}}}
161 }
162 struct S { blah };
163 )",
164          "test.wgsl:2:3 error: expected decoration\n"
165          "[[woof[[[[]]]]]]\n"
166          "  ^^^^\n"
167          "\n"
168          "test.wgsl:3:7 error: expected ':' for parameter\n"
169          "fn f(x(((())))) {\n"
170          "      ^\n"
171          "\n"
172          "test.wgsl:4:10 error: unable to parse right side of assignment\n"
173          "  meow = {{{}}}\n"
174          "         ^\n"
175          "\n"
176          "test.wgsl:6:17 error: expected ':' for struct member\n"
177          "struct S { blah };\n"
178          "                ^\n");
179 }
180 
181 }  // namespace
182 }  // namespace wgsl
183 }  // namespace reader
184 }  // namespace tint
185