@@ -113,6 +113,113 @@ TEST_F(test_lex, lex_block_comments) {
113113 }
114114}
115115
116+ TEST_F (test_lex, lex_unopened_block_comment) {
117+ {
118+ error_collector v;
119+ padded_string input (u8" hello */" _sv);
120+ lexer l (&input, &v); // identifier
121+ EXPECT_EQ (l.peek ().type , token_type::identifier);
122+ l.skip (); // end of file
123+ EXPECT_EQ (l.peek ().type , token_type::end_of_file);
124+ EXPECT_THAT (v.errors ,
125+ ElementsAre (ERROR_TYPE_FIELD (
126+ error_unopened_block_comment, comment_close,
127+ offsets_matcher (&input, strlen (u8" hello " ), u8" */" ))));
128+ }
129+ {
130+ error_collector v;
131+ padded_string input (u8" *-----*/" _sv);
132+ lexer l (&input, &v);
133+
134+ while (l.peek ().type != token_type::end_of_file) {
135+ l.skip ();
136+ }
137+ EXPECT_EQ (l.peek ().type , token_type::end_of_file);
138+
139+ EXPECT_THAT (v.errors ,
140+ ElementsAre (ERROR_TYPE_FIELD (
141+ error_unopened_block_comment, comment_close,
142+ offsets_matcher (&input, strlen (u8" *-----" ), u8" */" ))));
143+ }
144+ {
145+ error_collector v;
146+ padded_string input (u8" *******/" _sv);
147+ lexer l (&input, &v);
148+ EXPECT_EQ (l.peek ().type , token_type::star_star);
149+ l.skip ();
150+ EXPECT_EQ (l.peek ().type , token_type::star_star);
151+ l.skip ();
152+ EXPECT_EQ (l.peek ().type , token_type::star_star);
153+ l.skip ();
154+ EXPECT_EQ (l.peek ().type , token_type::end_of_file);
155+
156+ EXPECT_THAT (v.errors ,
157+ ElementsAre (ERROR_TYPE_FIELD (
158+ error_unopened_block_comment, comment_close,
159+ offsets_matcher (&input, strlen (u8" ******" ), u8" */" ))));
160+ }
161+ {
162+ error_collector v;
163+ padded_string input (u8" */" _sv);
164+ lexer l (&input, &v);
165+ EXPECT_EQ (l.peek ().type , token_type::end_of_file);
166+
167+ EXPECT_THAT (v.errors , ElementsAre (ERROR_TYPE_FIELD (
168+ error_unopened_block_comment, comment_close,
169+ offsets_matcher (&input, 0 , u8" */" ))));
170+ }
171+ {
172+ error_collector v;
173+ padded_string input (u8" **/" _sv);
174+ lexer l (&input, &v);
175+ EXPECT_EQ (l.peek ().type , token_type::star);
176+ l.skip ();
177+ EXPECT_EQ (l.peek ().type , token_type::end_of_file);
178+ EXPECT_THAT (v.errors , ElementsAre (ERROR_TYPE_FIELD (
179+ error_unopened_block_comment, comment_close,
180+ offsets_matcher (&input, 1 , u8" */" ))));
181+ }
182+ }
183+
184+ TEST_F (test_lex, lex_regexp_literal_starting_with_star_slash) {
185+ {
186+ // '/*' is not an end of block comment because it precedes a regexp literal
187+ error_collector v;
188+ padded_string input (u8" */ hello/" _sv);
189+ lexer l (&input, &v);
190+ EXPECT_EQ (l.peek ().type , token_type::star);
191+ l.skip ();
192+ EXPECT_EQ (l.peek ().type , token_type::slash);
193+ l.reparse_as_regexp ();
194+ EXPECT_EQ (l.peek ().type , token_type::regexp);
195+ EXPECT_EQ (l.peek ().begin , &input[1 ]);
196+ EXPECT_EQ (l.peek ().end , &input[input.size ()]);
197+ l.skip ();
198+ EXPECT_EQ (l.peek ().type , token_type::end_of_file);
199+ EXPECT_THAT (v.errors , IsEmpty ());
200+ }
201+ }
202+
203+ TEST_F (test_lex, lex_regexp_literal_starting_with_star_star_slash) {
204+ {
205+ padded_string input (u8" 3 **/ banana/" _sv);
206+ error_collector v;
207+ lexer l (&input, &v);
208+ EXPECT_EQ (l.peek ().type , token_type::number);
209+ l.skip ();
210+ EXPECT_EQ (l.peek ().type , token_type::star_star);
211+ l.skip ();
212+ EXPECT_EQ (l.peek ().type , token_type::slash);
213+ l.reparse_as_regexp ();
214+ EXPECT_EQ (l.peek ().type , token_type::regexp);
215+ EXPECT_EQ (l.peek ().begin , &input[4 ]);
216+ EXPECT_EQ (l.peek ().end , &input[input.size ()]);
217+ l.skip ();
218+ EXPECT_EQ (l.peek ().type , token_type::end_of_file);
219+ EXPECT_THAT (v.errors , IsEmpty ());
220+ }
221+ }
222+
116223TEST_F (test_lex, lex_line_comments) {
117224 EXPECT_THAT (this ->lex_to_eof (u8" // hello" _sv), IsEmpty ());
118225 for (string8_view line_terminator : line_terminators) {
0 commit comments