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,Empty)22 TEST_F(ParserImplTest, Empty) {
23 auto p = parser("");
24 ASSERT_TRUE(p->Parse()) << p->error();
25 }
26
TEST_F(ParserImplTest,Parses)27 TEST_F(ParserImplTest, Parses) {
28 auto p = parser(R"(
29 [[stage(fragment)]]
30 fn main() -> [[location(0)]] vec4<f32> {
31 return vec4<f32>(.4, .2, .3, 1);
32 }
33 )");
34 ASSERT_TRUE(p->Parse()) << p->error();
35
36 Program program = p->program();
37 ASSERT_EQ(1u, program.AST().Functions().size());
38 }
39
TEST_F(ParserImplTest,HandlesError)40 TEST_F(ParserImplTest, HandlesError) {
41 auto p = parser(R"(
42 fn main() -> { // missing return type
43 return;
44 })");
45
46 ASSERT_FALSE(p->Parse());
47 ASSERT_TRUE(p->has_error());
48 EXPECT_EQ(p->error(), "2:15: unable to determine function return type");
49 }
50
TEST_F(ParserImplTest,HandlesUnexpectedToken)51 TEST_F(ParserImplTest, HandlesUnexpectedToken) {
52 auto p = parser(R"(
53 fn main() {
54 }
55 foobar
56 )");
57
58 ASSERT_FALSE(p->Parse());
59 ASSERT_TRUE(p->has_error());
60 EXPECT_EQ(p->error(), "4:1: unexpected token");
61 }
62
TEST_F(ParserImplTest,HandlesBadToken_InMiddle)63 TEST_F(ParserImplTest, HandlesBadToken_InMiddle) {
64 auto p = parser(R"(
65 fn main() {
66 let f = 0x1p500000000000; // Exponent too big for hex float
67 return;
68 })");
69
70 ASSERT_FALSE(p->Parse());
71 ASSERT_TRUE(p->has_error());
72 EXPECT_EQ(p->error(), "3:11: exponent is too large for hex float");
73 }
74
TEST_F(ParserImplTest,HandlesBadToken_AtModuleScope)75 TEST_F(ParserImplTest, HandlesBadToken_AtModuleScope) {
76 auto p = parser(R"(
77 fn main() {
78 return;
79 }
80 0x1p5000000000000
81 )");
82
83 ASSERT_FALSE(p->Parse());
84 ASSERT_TRUE(p->has_error());
85 EXPECT_EQ(p->error(), "5:1: exponent is too large for hex float");
86 }
87
TEST_F(ParserImplTest,Comments_TerminatedBlockComment)88 TEST_F(ParserImplTest, Comments_TerminatedBlockComment) {
89 auto p = parser(R"(
90 /**
91 * Here is my shader.
92 *
93 * /* I can nest /**/ comments. */
94 * // I can nest line comments too.
95 **/
96 [[stage(fragment)]] // This is the stage
97 fn main(/*
98 no
99 parameters
100 */) -> [[location(0)]] vec4<f32> {
101 return/*block_comments_delimit_tokens*/vec4<f32>(.4, .2, .3, 1);
102 }/* block comments are OK at EOF...*/)");
103
104 ASSERT_TRUE(p->Parse()) << p->error();
105 ASSERT_EQ(1u, p->program().AST().Functions().size());
106 }
107
TEST_F(ParserImplTest,Comments_UnterminatedBlockComment)108 TEST_F(ParserImplTest, Comments_UnterminatedBlockComment) {
109 auto p = parser(R"(
110 [[stage(fragment)]]
111 fn main() -> [[location(0)]] vec4<f32> {
112 return vec4<f32>(.4, .2, .3, 1);
113 } /* unterminated block comments are invalid ...)");
114
115 ASSERT_FALSE(p->Parse());
116 ASSERT_TRUE(p->has_error());
117 EXPECT_EQ(p->error(), "5:3: unterminated block comment") << p->error();
118 }
119
120 } // namespace
121 } // namespace wgsl
122 } // namespace reader
123 } // namespace tint
124