blob: dd92df421f22b143c74f7b5bbb101c24e59bc932 [file] [log] [blame]
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001//===- unittests/AST/CommentLexer.cpp ------ Comment lexer tests ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Basic/SourceManager.h"
11#include "clang/Basic/FileManager.h"
12#include "clang/Basic/Diagnostic.h"
13#include "clang/AST/CommentLexer.h"
14#include "llvm/ADT/STLExtras.h"
15#include <vector>
16
17#include "gtest/gtest.h"
18
19using namespace llvm;
20using namespace clang;
21
22namespace clang {
23namespace comments {
24
25namespace {
26class CommentLexerTest : public ::testing::Test {
27protected:
28 CommentLexerTest()
29 : FileMgr(FileMgrOpts),
30 DiagID(new DiagnosticIDs()),
31 Diags(DiagID, new IgnoringDiagConsumer()),
32 SourceMgr(Diags, FileMgr) {
33 }
34
35 FileSystemOptions FileMgrOpts;
36 FileManager FileMgr;
37 IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
38 DiagnosticsEngine Diags;
39 SourceManager SourceMgr;
40
41 void lexString(const char *Source, std::vector<Token> &Toks);
42};
43
44void CommentLexerTest::lexString(const char *Source,
45 std::vector<Token> &Toks) {
46 MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
47 FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
48 SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
49
50 comments::Lexer L(Begin, CommentOptions(),
51 Source, Source + strlen(Source));
52
53 while (1) {
54 Token Tok;
55 L.lex(Tok);
56 if (Tok.is(tok::eof))
57 break;
58 Toks.push_back(Tok);
59 }
60}
61
62} // unnamed namespace
63
64// Empty source range should be handled.
65TEST_F(CommentLexerTest, Basic1) {
66 const char *Source = "";
67 std::vector<Token> Toks;
68
69 lexString(Source, Toks);
70
71 ASSERT_EQ(0U, Toks.size());
72}
73
74// Empty comments should be handled.
75TEST_F(CommentLexerTest, Basic2) {
76 const char *Sources[] = {
77 "//", "///", "//!", "///<", "//!<"
78 };
79 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
80 std::vector<Token> Toks;
81
82 lexString(Sources[i], Toks);
83
84 ASSERT_EQ(1U, Toks.size());
85
86 ASSERT_EQ(tok::newline, Toks[0].getKind());
87 }
88}
89
90// Empty comments should be handled.
91TEST_F(CommentLexerTest, Basic3) {
92 const char *Sources[] = {
93 "/**/", "/***/", "/*!*/", "/**<*/", "/*!<*/"
94 };
95 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
96 std::vector<Token> Toks;
97
98 lexString(Sources[i], Toks);
99
100 ASSERT_EQ(2U, Toks.size());
101
102 ASSERT_EQ(tok::newline, Toks[0].getKind());
103 ASSERT_EQ(tok::newline, Toks[1].getKind());
104 }
105}
106
107// Single comment with plain text.
108TEST_F(CommentLexerTest, Basic4) {
109 const char *Sources[] = {
110 "// Meow", "/// Meow", "//! Meow",
111 "// Meow\n", "// Meow\r\n", "//! Meow\r",
112 };
113
114 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
115 std::vector<Token> Toks;
116
117 lexString(Sources[i], Toks);
118
119 ASSERT_EQ(2U, Toks.size());
120
121 ASSERT_EQ(tok::text, Toks[0].getKind());
122 ASSERT_EQ(StringRef(" Meow"), Toks[0].getText());
123
124 ASSERT_EQ(tok::newline, Toks[1].getKind());
125 }
126}
127
128// Single comment with plain text.
129TEST_F(CommentLexerTest, Basic5) {
130 const char *Sources[] = {
131 "/* Meow*/", "/** Meow*/", "/*! Meow*/"
132 };
133
134 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
135 std::vector<Token> Toks;
136
137 lexString(Sources[i], Toks);
138
139 ASSERT_EQ(3U, Toks.size());
140
141 ASSERT_EQ(tok::text, Toks[0].getKind());
142 ASSERT_EQ(StringRef(" Meow"), Toks[0].getText());
143
144 ASSERT_EQ(tok::newline, Toks[1].getKind());
145 ASSERT_EQ(tok::newline, Toks[2].getKind());
146 }
147}
148
149// Test newline escaping.
150TEST_F(CommentLexerTest, Basic6) {
151 const char *Sources[] = {
152 "// Aaa\\\n" " Bbb\\ \n" " Ccc?" "?/\n",
153 "// Aaa\\\r\n" " Bbb\\ \r\n" " Ccc?" "?/\r\n",
154 "// Aaa\\\r" " Bbb\\ \r" " Ccc?" "?/\r"
155 };
156
157 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
158 std::vector<Token> Toks;
159
160 lexString(Sources[i], Toks);
161
162 ASSERT_EQ(10U, Toks.size());
163
164 ASSERT_EQ(tok::text, Toks[0].getKind());
165 ASSERT_EQ(StringRef(" Aaa"), Toks[0].getText());
166 ASSERT_EQ(tok::text, Toks[1].getKind());
167 ASSERT_EQ(StringRef("\\"), Toks[1].getText());
168 ASSERT_EQ(tok::newline, Toks[2].getKind());
169
170 ASSERT_EQ(tok::text, Toks[3].getKind());
171 ASSERT_EQ(StringRef(" Bbb"), Toks[3].getText());
172 ASSERT_EQ(tok::text, Toks[4].getKind());
173 ASSERT_EQ(StringRef("\\"), Toks[4].getText());
174 ASSERT_EQ(tok::text, Toks[5].getKind());
175 ASSERT_EQ(StringRef(" "), Toks[5].getText());
176 ASSERT_EQ(tok::newline, Toks[6].getKind());
177
178 ASSERT_EQ(tok::text, Toks[7].getKind());
179 ASSERT_EQ(StringRef(" Ccc?" "?/"), Toks[7].getText());
180 ASSERT_EQ(tok::newline, Toks[8].getKind());
181
182 ASSERT_EQ(tok::newline, Toks[9].getKind());
183 }
184}
185
186// Check that we skip C-style aligned stars correctly.
187TEST_F(CommentLexerTest, Basic7) {
188 const char *Source =
189 "/* Aaa\n"
190 " * Bbb\r\n"
191 "\t* Ccc\n"
192 " ! Ddd\n"
193 " * Eee\n"
194 " ** Fff\n"
195 " */";
196 std::vector<Token> Toks;
197
198 lexString(Source, Toks);
199
200 ASSERT_EQ(15U, Toks.size());
201
202 ASSERT_EQ(tok::text, Toks[0].getKind());
203 ASSERT_EQ(StringRef(" Aaa"), Toks[0].getText());
204 ASSERT_EQ(tok::newline, Toks[1].getKind());
205
206 ASSERT_EQ(tok::text, Toks[2].getKind());
207 ASSERT_EQ(StringRef(" Bbb"), Toks[2].getText());
208 ASSERT_EQ(tok::newline, Toks[3].getKind());
209
210 ASSERT_EQ(tok::text, Toks[4].getKind());
211 ASSERT_EQ(StringRef(" Ccc"), Toks[4].getText());
212 ASSERT_EQ(tok::newline, Toks[5].getKind());
213
214 ASSERT_EQ(tok::text, Toks[6].getKind());
215 ASSERT_EQ(StringRef(" ! Ddd"), Toks[6].getText());
216 ASSERT_EQ(tok::newline, Toks[7].getKind());
217
218 ASSERT_EQ(tok::text, Toks[8].getKind());
219 ASSERT_EQ(StringRef(" Eee"), Toks[8].getText());
220 ASSERT_EQ(tok::newline, Toks[9].getKind());
221
222 ASSERT_EQ(tok::text, Toks[10].getKind());
223 ASSERT_EQ(StringRef("* Fff"), Toks[10].getText());
224 ASSERT_EQ(tok::newline, Toks[11].getKind());
225
226 ASSERT_EQ(tok::text, Toks[12].getKind());
227 ASSERT_EQ(StringRef(" "), Toks[12].getText());
228
229 ASSERT_EQ(tok::newline, Toks[13].getKind());
230 ASSERT_EQ(tok::newline, Toks[14].getKind());
231}
232
233// A command marker followed by comment end.
234TEST_F(CommentLexerTest, DoxygenCommand1) {
235 const char *Sources[] = { "//@", "///@", "//!@" };
236 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
237 std::vector<Token> Toks;
238
239 lexString(Sources[i], Toks);
240
241 ASSERT_EQ(2U, Toks.size());
242
243 ASSERT_EQ(tok::text, Toks[0].getKind());
244 ASSERT_EQ(StringRef("@"), Toks[0].getText());
245
246 ASSERT_EQ(tok::newline, Toks[1].getKind());
247 }
248}
249
250// A command marker followed by comment end.
251TEST_F(CommentLexerTest, DoxygenCommand2) {
252 const char *Sources[] = { "/*@*/", "/**@*/", "/*!@*/"};
253 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
254 std::vector<Token> Toks;
255
256 lexString(Sources[i], Toks);
257
258 ASSERT_EQ(3U, Toks.size());
259
260 ASSERT_EQ(tok::text, Toks[0].getKind());
261 ASSERT_EQ(StringRef("@"), Toks[0].getText());
262
263 ASSERT_EQ(tok::newline, Toks[1].getKind());
264 ASSERT_EQ(tok::newline, Toks[2].getKind());
265 }
266}
267
268// A command marker followed by comment end.
269TEST_F(CommentLexerTest, DoxygenCommand3) {
270 const char *Sources[] = { "/*\\*/", "/**\\*/" };
271 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
272 std::vector<Token> Toks;
273
274 lexString(Sources[i], Toks);
275
276 ASSERT_EQ(3U, Toks.size());
277
278 ASSERT_EQ(tok::text, Toks[0].getKind());
279 ASSERT_EQ(StringRef("\\"), Toks[0].getText());
280
281 ASSERT_EQ(tok::newline, Toks[1].getKind());
282 ASSERT_EQ(tok::newline, Toks[2].getKind());
283 }
284}
285
286// Doxygen escape sequences.
287TEST_F(CommentLexerTest, DoxygenCommand4) {
288 const char *Source =
289 "/// \\\\ \\@ \\& \\$ \\# \\< \\> \\% \\\" \\. \\::";
290 const char *Text[] = {
291 " ",
292 "\\", " ", "@", " ", "&", " ", "$", " ", "#", " ",
293 "<", " ", ">", " ", "%", " ", "\"", " ", ".", " ",
294 "::", ""
295 };
296
297 std::vector<Token> Toks;
298
299 lexString(Source, Toks);
300
301 ASSERT_EQ(array_lengthof(Text), Toks.size());
302
303 for (size_t i = 0, e = Toks.size(); i != e; i++) {
304 if(Toks[i].is(tok::text))
305 ASSERT_EQ(StringRef(Text[i]), Toks[i].getText())
306 << "index " << i;
307 }
308}
309
310TEST_F(CommentLexerTest, DoxygenCommand5) {
311 const char *Source = "/// \\brief Aaa.";
312 std::vector<Token> Toks;
313
314 lexString(Source, Toks);
315
316 ASSERT_EQ(4U, Toks.size());
317
318 ASSERT_EQ(tok::text, Toks[0].getKind());
319 ASSERT_EQ(StringRef(" "), Toks[0].getText());
320
321 ASSERT_EQ(tok::command, Toks[1].getKind());
322 ASSERT_EQ(StringRef("brief"), Toks[1].getCommandName());
323
324 ASSERT_EQ(tok::text, Toks[2].getKind());
325 ASSERT_EQ(StringRef(" Aaa."), Toks[2].getText());
326
327 ASSERT_EQ(tok::newline, Toks[3].getKind());
328}
329
330TEST_F(CommentLexerTest, DoxygenCommand6) {
331 const char *Source = "/// \\aaa\\bbb \\ccc\t\\ddd\n";
332 std::vector<Token> Toks;
333
334 lexString(Source, Toks);
335
336 ASSERT_EQ(8U, Toks.size());
337
338 ASSERT_EQ(tok::text, Toks[0].getKind());
339 ASSERT_EQ(StringRef(" "), Toks[0].getText());
340
341 ASSERT_EQ(tok::command, Toks[1].getKind());
342 ASSERT_EQ(StringRef("aaa"), Toks[1].getCommandName());
343
344 ASSERT_EQ(tok::command, Toks[2].getKind());
345 ASSERT_EQ(StringRef("bbb"), Toks[2].getCommandName());
346
347 ASSERT_EQ(tok::text, Toks[3].getKind());
348 ASSERT_EQ(StringRef(" "), Toks[3].getText());
349
350 ASSERT_EQ(tok::command, Toks[4].getKind());
351 ASSERT_EQ(StringRef("ccc"), Toks[4].getCommandName());
352
353 ASSERT_EQ(tok::text, Toks[5].getKind());
354 ASSERT_EQ(StringRef("\t"), Toks[5].getText());
355
356 ASSERT_EQ(tok::command, Toks[6].getKind());
357 ASSERT_EQ(StringRef("ddd"), Toks[6].getCommandName());
358
359 ASSERT_EQ(tok::newline, Toks[7].getKind());
360}
361
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000362TEST_F(CommentLexerTest, DoxygenCommand7) {
363 const char *Source = "// \\c\n";
364 std::vector<Token> Toks;
365
366 lexString(Source, Toks);
367
368 ASSERT_EQ(3U, Toks.size());
369
370 ASSERT_EQ(tok::text, Toks[0].getKind());
371 ASSERT_EQ(StringRef(" "), Toks[0].getText());
372
373 ASSERT_EQ(tok::command, Toks[1].getKind());
374 ASSERT_EQ(StringRef("c"), Toks[1].getCommandName());
375
376 ASSERT_EQ(tok::newline, Toks[2].getKind());
377}
378
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000379// Empty verbatim block.
380TEST_F(CommentLexerTest, VerbatimBlock1) {
381 const char *Sources[] = {
382 "/// \\verbatim\\endverbatim\n//",
383 "/** \\verbatim\\endverbatim*/"
384 };
385
386 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
387 std::vector<Token> Toks;
388
389 lexString(Sources[i], Toks);
390
391 ASSERT_EQ(5U, Toks.size());
392
393 ASSERT_EQ(tok::text, Toks[0].getKind());
394 ASSERT_EQ(StringRef(" "), Toks[0].getText());
395
396 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
397 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
398
399 ASSERT_EQ(tok::verbatim_block_end, Toks[2].getKind());
400 ASSERT_EQ(StringRef("endverbatim"), Toks[2].getVerbatimBlockName());
401
402 ASSERT_EQ(tok::newline, Toks[3].getKind());
403 ASSERT_EQ(tok::newline, Toks[4].getKind());
404 }
405}
406
407// Empty verbatim block without an end command.
408TEST_F(CommentLexerTest, VerbatimBlock2) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000409 const char *Source = "/// \\verbatim";
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000410
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000411 std::vector<Token> Toks;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000412
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000413 lexString(Source, Toks);
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000414
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000415 ASSERT_EQ(3U, Toks.size());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000416
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000417 ASSERT_EQ(tok::text, Toks[0].getKind());
418 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000419
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000420 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
421 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000422
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000423 ASSERT_EQ(tok::newline, Toks[2].getKind());
424}
425
426// Empty verbatim block without an end command.
427TEST_F(CommentLexerTest, VerbatimBlock3) {
428 const char *Source = "/** \\verbatim*/";
429
430 std::vector<Token> Toks;
431
432 lexString(Source, Toks);
433
434 ASSERT_EQ(4U, Toks.size());
435
436 ASSERT_EQ(tok::text, Toks[0].getKind());
437 ASSERT_EQ(StringRef(" "), Toks[0].getText());
438
439 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
440 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
441
442 ASSERT_EQ(tok::newline, Toks[2].getKind());
443 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000444}
445
446// Single-line verbatim block.
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000447TEST_F(CommentLexerTest, VerbatimBlock4) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000448 const char *Sources[] = {
449 "/// Meow \\verbatim aaa \\endverbatim\n//",
450 "/** Meow \\verbatim aaa \\endverbatim*/"
451 };
452
453 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
454 std::vector<Token> Toks;
455
456 lexString(Sources[i], Toks);
457
458 ASSERT_EQ(6U, Toks.size());
459
460 ASSERT_EQ(tok::text, Toks[0].getKind());
461 ASSERT_EQ(StringRef(" Meow "), Toks[0].getText());
462
463 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
464 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
465
466 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
467 ASSERT_EQ(StringRef(" aaa "), Toks[2].getVerbatimBlockText());
468
469 ASSERT_EQ(tok::verbatim_block_end, Toks[3].getKind());
470 ASSERT_EQ(StringRef("endverbatim"), Toks[3].getVerbatimBlockName());
471
472 ASSERT_EQ(tok::newline, Toks[4].getKind());
473 ASSERT_EQ(tok::newline, Toks[5].getKind());
474 }
475}
476
477// Single-line verbatim block without an end command.
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000478TEST_F(CommentLexerTest, VerbatimBlock5) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000479 const char *Sources[] = {
480 "/// Meow \\verbatim aaa \n//",
481 "/** Meow \\verbatim aaa */"
482 };
483
484 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
485 std::vector<Token> Toks;
486
487 lexString(Sources[i], Toks);
488
489 ASSERT_EQ(5U, Toks.size());
490
491 ASSERT_EQ(tok::text, Toks[0].getKind());
492 ASSERT_EQ(StringRef(" Meow "), Toks[0].getText());
493
494 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
495 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
496
497 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
498 ASSERT_EQ(StringRef(" aaa "), Toks[2].getVerbatimBlockText());
499
500 ASSERT_EQ(tok::newline, Toks[3].getKind());
501 ASSERT_EQ(tok::newline, Toks[4].getKind());
502 }
503}
504
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000505TEST_F(CommentLexerTest, VerbatimBlock6) {
506 const char *Source =
507 "// \\verbatim\n"
508 "// Aaa\n"
509 "//\n"
510 "// Bbb\n"
511 "// \\endverbatim\n";
512
513 std::vector<Token> Toks;
514
515 lexString(Source, Toks);
516
Dmitri Gribenko64da4e52012-07-18 23:01:58 +0000517 ASSERT_EQ(10U, Toks.size());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000518
519 ASSERT_EQ(tok::text, Toks[0].getKind());
520 ASSERT_EQ(StringRef(" "), Toks[0].getText());
521
522 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
523 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
524
525 ASSERT_EQ(tok::newline, Toks[2].getKind());
526
527 ASSERT_EQ(tok::verbatim_block_line, Toks[3].getKind());
528 ASSERT_EQ(StringRef(" Aaa"), Toks[3].getVerbatimBlockText());
529
530 ASSERT_EQ(tok::newline, Toks[4].getKind());
531
532 ASSERT_EQ(tok::newline, Toks[5].getKind());
533
534 ASSERT_EQ(tok::verbatim_block_line, Toks[6].getKind());
535 ASSERT_EQ(StringRef(" Bbb"), Toks[6].getVerbatimBlockText());
536
537 ASSERT_EQ(tok::newline, Toks[7].getKind());
538
Dmitri Gribenko64da4e52012-07-18 23:01:58 +0000539 ASSERT_EQ(tok::verbatim_block_end, Toks[8].getKind());
540 ASSERT_EQ(StringRef("endverbatim"), Toks[8].getVerbatimBlockName());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000541
Dmitri Gribenko64da4e52012-07-18 23:01:58 +0000542 ASSERT_EQ(tok::newline, Toks[9].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000543}
544
545TEST_F(CommentLexerTest, VerbatimBlock7) {
546 const char *Source =
547 "/* \\verbatim\n"
548 " * Aaa\n"
549 " *\n"
550 " * Bbb\n"
551 " * \\endverbatim\n"
552 " */";
553
554 std::vector<Token> Toks;
555
556 lexString(Source, Toks);
557
Dmitri Gribenko64da4e52012-07-18 23:01:58 +0000558 ASSERT_EQ(10U, Toks.size());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000559
560 ASSERT_EQ(tok::text, Toks[0].getKind());
561 ASSERT_EQ(StringRef(" "), Toks[0].getText());
562
563 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
564 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
565
566 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
567 ASSERT_EQ(StringRef(" Aaa"), Toks[2].getVerbatimBlockText());
568
569 ASSERT_EQ(tok::verbatim_block_line, Toks[3].getKind());
570 ASSERT_EQ(StringRef(""), Toks[3].getVerbatimBlockText());
571
572 ASSERT_EQ(tok::verbatim_block_line, Toks[4].getKind());
573 ASSERT_EQ(StringRef(" Bbb"), Toks[4].getVerbatimBlockText());
574
Dmitri Gribenko64da4e52012-07-18 23:01:58 +0000575 ASSERT_EQ(tok::verbatim_block_end, Toks[5].getKind());
576 ASSERT_EQ(StringRef("endverbatim"), Toks[5].getVerbatimBlockName());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000577
Dmitri Gribenko64da4e52012-07-18 23:01:58 +0000578 ASSERT_EQ(tok::newline, Toks[6].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000579
Dmitri Gribenko64da4e52012-07-18 23:01:58 +0000580 ASSERT_EQ(tok::text, Toks[7].getKind());
581 ASSERT_EQ(StringRef(" "), Toks[7].getText());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000582
Dmitri Gribenko64da4e52012-07-18 23:01:58 +0000583 ASSERT_EQ(tok::newline, Toks[8].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000584 ASSERT_EQ(tok::newline, Toks[9].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000585}
586
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000587// Complex test for verbatim blocks.
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000588TEST_F(CommentLexerTest, VerbatimBlock8) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000589 const char *Source =
590 "/* Meow \\verbatim aaa\\$\\@\n"
591 "bbb \\endverbati\r"
592 "ccc\r\n"
593 "ddd \\endverbatim Blah \\verbatim eee\n"
594 "\\endverbatim BlahBlah*/";
595 std::vector<Token> Toks;
596
597 lexString(Source, Toks);
598
599 ASSERT_EQ(14U, Toks.size());
600
601 ASSERT_EQ(tok::text, Toks[0].getKind());
602 ASSERT_EQ(StringRef(" Meow "), Toks[0].getText());
603
604 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
605 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
606
607 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000608 ASSERT_EQ(StringRef(" aaa\\$\\@"), Toks[2].getVerbatimBlockText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000609
610 ASSERT_EQ(tok::verbatim_block_line, Toks[3].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000611 ASSERT_EQ(StringRef("bbb \\endverbati"), Toks[3].getVerbatimBlockText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000612
613 ASSERT_EQ(tok::verbatim_block_line, Toks[4].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000614 ASSERT_EQ(StringRef("ccc"), Toks[4].getVerbatimBlockText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000615
616 ASSERT_EQ(tok::verbatim_block_line, Toks[5].getKind());
617 ASSERT_EQ(StringRef("ddd "), Toks[5].getVerbatimBlockText());
618
619 ASSERT_EQ(tok::verbatim_block_end, Toks[6].getKind());
620 ASSERT_EQ(StringRef("endverbatim"), Toks[6].getVerbatimBlockName());
621
622 ASSERT_EQ(tok::text, Toks[7].getKind());
623 ASSERT_EQ(StringRef(" Blah "), Toks[7].getText());
624
625 ASSERT_EQ(tok::verbatim_block_begin, Toks[8].getKind());
626 ASSERT_EQ(StringRef("verbatim"), Toks[8].getVerbatimBlockName());
627
628 ASSERT_EQ(tok::verbatim_block_line, Toks[9].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000629 ASSERT_EQ(StringRef(" eee"), Toks[9].getVerbatimBlockText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000630
631 ASSERT_EQ(tok::verbatim_block_end, Toks[10].getKind());
632 ASSERT_EQ(StringRef("endverbatim"), Toks[10].getVerbatimBlockName());
633
634 ASSERT_EQ(tok::text, Toks[11].getKind());
635 ASSERT_EQ(StringRef(" BlahBlah"), Toks[11].getText());
636
637 ASSERT_EQ(tok::newline, Toks[12].getKind());
638 ASSERT_EQ(tok::newline, Toks[13].getKind());
639}
640
641// LaTeX verbatim blocks.
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000642TEST_F(CommentLexerTest, VerbatimBlock9) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000643 const char *Source =
644 "/// \\f$ Aaa \\f$ \\f[ Bbb \\f] \\f{ Ccc \\f}";
645 std::vector<Token> Toks;
646
647 lexString(Source, Toks);
648
649 ASSERT_EQ(13U, Toks.size());
650
651 ASSERT_EQ(tok::text, Toks[0].getKind());
652 ASSERT_EQ(StringRef(" "), Toks[0].getText());
653
654 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
655 ASSERT_EQ(StringRef("f$"), Toks[1].getVerbatimBlockName());
656
657 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
658 ASSERT_EQ(StringRef(" Aaa "), Toks[2].getVerbatimBlockText());
659
660 ASSERT_EQ(tok::verbatim_block_end, Toks[3].getKind());
661 ASSERT_EQ(StringRef("f$"), Toks[3].getVerbatimBlockName());
662
663 ASSERT_EQ(tok::text, Toks[4].getKind());
664 ASSERT_EQ(StringRef(" "), Toks[4].getText());
665
666 ASSERT_EQ(tok::verbatim_block_begin, Toks[5].getKind());
667 ASSERT_EQ(StringRef("f["), Toks[5].getVerbatimBlockName());
668
669 ASSERT_EQ(tok::verbatim_block_line, Toks[6].getKind());
670 ASSERT_EQ(StringRef(" Bbb "), Toks[6].getVerbatimBlockText());
671
672 ASSERT_EQ(tok::verbatim_block_end, Toks[7].getKind());
673 ASSERT_EQ(StringRef("f]"), Toks[7].getVerbatimBlockName());
674
675 ASSERT_EQ(tok::text, Toks[8].getKind());
676 ASSERT_EQ(StringRef(" "), Toks[8].getText());
677
678 ASSERT_EQ(tok::verbatim_block_begin, Toks[9].getKind());
679 ASSERT_EQ(StringRef("f{"), Toks[9].getVerbatimBlockName());
680
681 ASSERT_EQ(tok::verbatim_block_line, Toks[10].getKind());
682 ASSERT_EQ(StringRef(" Ccc "), Toks[10].getVerbatimBlockText());
683
684 ASSERT_EQ(tok::verbatim_block_end, Toks[11].getKind());
685 ASSERT_EQ(StringRef("f}"), Toks[11].getVerbatimBlockName());
686
687 ASSERT_EQ(tok::newline, Toks[12].getKind());
688}
689
690// Empty verbatim line.
691TEST_F(CommentLexerTest, VerbatimLine1) {
692 const char *Sources[] = {
693 "/// \\fn\n//",
694 "/** \\fn*/"
695 };
696
697 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
698 std::vector<Token> Toks;
699
700 lexString(Sources[i], Toks);
701
702 ASSERT_EQ(4U, Toks.size());
703
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000704 ASSERT_EQ(tok::text, Toks[0].getKind());
705 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000706
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000707 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
708 ASSERT_EQ(StringRef("fn"), Toks[1].getVerbatimLineName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000709
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000710 ASSERT_EQ(tok::newline, Toks[2].getKind());
711 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000712 }
713}
714
715// Verbatim line with Doxygen escape sequences, which should not be expanded.
716TEST_F(CommentLexerTest, VerbatimLine2) {
717 const char *Sources[] = {
718 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
719 "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
720 };
721
722 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
723 std::vector<Token> Toks;
724
725 lexString(Sources[i], Toks);
726
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000727 ASSERT_EQ(5U, Toks.size());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000728
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000729 ASSERT_EQ(tok::text, Toks[0].getKind());
730 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000731
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000732 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
733 ASSERT_EQ(StringRef("fn"), Toks[1].getVerbatimLineName());
734
735 ASSERT_EQ(tok::verbatim_line_text, Toks[2].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000736 ASSERT_EQ(StringRef(" void *foo(const char *zzz = \"\\$\");"),
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000737 Toks[2].getVerbatimLineText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000738
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000739 ASSERT_EQ(tok::newline, Toks[3].getKind());
740 ASSERT_EQ(tok::newline, Toks[4].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000741 }
742}
743
744// Verbatim line should not eat anything from next source line.
745TEST_F(CommentLexerTest, VerbatimLine3) {
746 const char *Source =
747 "/** \\fn void *foo(const char *zzz = \"\\$\");\n"
748 " * Meow\n"
749 " */";
750
751 std::vector<Token> Toks;
752
753 lexString(Source, Toks);
754
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000755 ASSERT_EQ(9U, Toks.size());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000756
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000757 ASSERT_EQ(tok::text, Toks[0].getKind());
758 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000759
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000760 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
761 ASSERT_EQ(StringRef("fn"), Toks[1].getVerbatimLineName());
762
763 ASSERT_EQ(tok::verbatim_line_text, Toks[2].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000764 ASSERT_EQ(StringRef(" void *foo(const char *zzz = \"\\$\");"),
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000765 Toks[2].getVerbatimLineText());
766 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000767
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000768 ASSERT_EQ(tok::text, Toks[4].getKind());
769 ASSERT_EQ(StringRef(" Meow"), Toks[4].getText());
770 ASSERT_EQ(tok::newline, Toks[5].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000771
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000772 ASSERT_EQ(tok::text, Toks[6].getKind());
773 ASSERT_EQ(StringRef(" "), Toks[6].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000774
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000775 ASSERT_EQ(tok::newline, Toks[7].getKind());
776 ASSERT_EQ(tok::newline, Toks[8].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000777}
778
779TEST_F(CommentLexerTest, HTML1) {
780 const char *Source =
781 "// <";
782
783 std::vector<Token> Toks;
784
785 lexString(Source, Toks);
786
787 ASSERT_EQ(3U, Toks.size());
788
789 ASSERT_EQ(tok::text, Toks[0].getKind());
790 ASSERT_EQ(StringRef(" "), Toks[0].getText());
791
792 ASSERT_EQ(tok::text, Toks[1].getKind());
793 ASSERT_EQ(StringRef("<"), Toks[1].getText());
794
795 ASSERT_EQ(tok::newline, Toks[2].getKind());
796}
797
798TEST_F(CommentLexerTest, HTML2) {
Dmitri Gribenko5676d322012-06-27 23:28:29 +0000799 const char *Source =
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000800 "// a<2";
801
802 std::vector<Token> Toks;
803
804 lexString(Source, Toks);
805
806 ASSERT_EQ(4U, Toks.size());
807
808 ASSERT_EQ(tok::text, Toks[0].getKind());
809 ASSERT_EQ(StringRef(" a"), Toks[0].getText());
810
811 ASSERT_EQ(tok::text, Toks[1].getKind());
812 ASSERT_EQ(StringRef("<"), Toks[1].getText());
813
814 ASSERT_EQ(tok::text, Toks[2].getKind());
815 ASSERT_EQ(StringRef("2"), Toks[2].getText());
816
817 ASSERT_EQ(tok::newline, Toks[3].getKind());
818}
819
820TEST_F(CommentLexerTest, HTML3) {
821 const char *Source =
Dmitri Gribenko5676d322012-06-27 23:28:29 +0000822 "// < tag";
823
824 std::vector<Token> Toks;
825
826 lexString(Source, Toks);
827
828 ASSERT_EQ(4U, Toks.size());
829
830 ASSERT_EQ(tok::text, Toks[0].getKind());
831 ASSERT_EQ(StringRef(" "), Toks[0].getText());
832
833 ASSERT_EQ(tok::text, Toks[1].getKind());
834 ASSERT_EQ(StringRef("<"), Toks[1].getText());
835
836 ASSERT_EQ(tok::text, Toks[2].getKind());
837 ASSERT_EQ(StringRef(" tag"), Toks[2].getText());
838
839 ASSERT_EQ(tok::newline, Toks[3].getKind());
840}
841
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000842TEST_F(CommentLexerTest, HTML4) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000843 const char *Sources[] = {
844 "// <tag",
845 "// <tag "
846 };
847
848 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
849 std::vector<Token> Toks;
850
851 lexString(Sources[i], Toks);
852
853 ASSERT_EQ(3U, Toks.size());
854
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000855 ASSERT_EQ(tok::text, Toks[0].getKind());
856 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000857
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000858 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
859 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000860
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000861 ASSERT_EQ(tok::newline, Toks[2].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000862 }
863}
864
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000865TEST_F(CommentLexerTest, HTML5) {
866 const char *Source =
867 "// <tag 42";
868
869 std::vector<Token> Toks;
870
871 lexString(Source, Toks);
872
873 ASSERT_EQ(4U, Toks.size());
874
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000875 ASSERT_EQ(tok::text, Toks[0].getKind());
876 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000877
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000878 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
879 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000880
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000881 ASSERT_EQ(tok::text, Toks[2].getKind());
882 ASSERT_EQ(StringRef("42"), Toks[2].getText());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000883
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000884 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000885}
886
887TEST_F(CommentLexerTest, HTML6) {
888 const char *Source = "// <tag> Meow";
889
890 std::vector<Token> Toks;
891
892 lexString(Source, Toks);
893
894 ASSERT_EQ(5U, Toks.size());
895
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000896 ASSERT_EQ(tok::text, Toks[0].getKind());
897 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000898
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000899 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
900 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000901
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000902 ASSERT_EQ(tok::html_greater, Toks[2].getKind());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000903
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000904 ASSERT_EQ(tok::text, Toks[3].getKind());
905 ASSERT_EQ(StringRef(" Meow"), Toks[3].getText());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000906
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000907 ASSERT_EQ(tok::newline, Toks[4].getKind());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000908}
909
910TEST_F(CommentLexerTest, HTML7) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000911 const char *Source = "// <tag=";
912
913 std::vector<Token> Toks;
914
915 lexString(Source, Toks);
916
917 ASSERT_EQ(4U, Toks.size());
918
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000919 ASSERT_EQ(tok::text, Toks[0].getKind());
920 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000921
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000922 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
923 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000924
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000925 ASSERT_EQ(tok::text, Toks[2].getKind());
926 ASSERT_EQ(StringRef("="), Toks[2].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000927
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000928 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000929}
930
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000931TEST_F(CommentLexerTest, HTML8) {
932 const char *Source = "// <tag attr=> Meow";
933
934 std::vector<Token> Toks;
935
936 lexString(Source, Toks);
937
938 ASSERT_EQ(7U, Toks.size());
939
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000940 ASSERT_EQ(tok::text, Toks[0].getKind());
941 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000942
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000943 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
944 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000945
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000946 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
947 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000948
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000949 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000950
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000951 ASSERT_EQ(tok::html_greater, Toks[4].getKind());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000952
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000953 ASSERT_EQ(tok::text, Toks[5].getKind());
954 ASSERT_EQ(StringRef(" Meow"), Toks[5].getText());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000955
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000956 ASSERT_EQ(tok::newline, Toks[6].getKind());
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000957}
958
959TEST_F(CommentLexerTest, HTML9) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000960 const char *Sources[] = {
961 "// <tag attr",
962 "// <tag attr "
963 };
964
965 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
966 std::vector<Token> Toks;
967
968 lexString(Sources[i], Toks);
969
970 ASSERT_EQ(4U, Toks.size());
971
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000972 ASSERT_EQ(tok::text, Toks[0].getKind());
973 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000974
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000975 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
976 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000977
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000978 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
979 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000980
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000981 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000982 }
983}
984
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000985TEST_F(CommentLexerTest, HTML10) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000986 const char *Sources[] = {
987 "// <tag attr=",
988 "// <tag attr ="
989 };
990
991 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
992 std::vector<Token> Toks;
993
994 lexString(Sources[i], Toks);
995
996 ASSERT_EQ(5U, Toks.size());
997
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000998 ASSERT_EQ(tok::text, Toks[0].getKind());
999 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001000
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001001 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1002 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001003
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001004 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1005 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001006
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001007 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001008
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001009 ASSERT_EQ(tok::newline, Toks[4].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001010 }
1011}
1012
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001013TEST_F(CommentLexerTest, HTML11) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001014 const char *Sources[] = {
1015 "// <tag attr=\"",
1016 "// <tag attr = \"",
1017 "// <tag attr=\'",
1018 "// <tag attr = \'"
1019 };
1020
1021 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1022 std::vector<Token> Toks;
1023
1024 lexString(Sources[i], Toks);
1025
1026 ASSERT_EQ(6U, Toks.size());
1027
1028 ASSERT_EQ(tok::text, Toks[0].getKind());
1029 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1030
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001031 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1032 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001033
1034 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1035 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
1036
1037 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1038
1039 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1040 ASSERT_EQ(StringRef(""), Toks[4].getHTMLQuotedString());
1041
1042 ASSERT_EQ(tok::newline, Toks[5].getKind());
1043 }
1044}
1045
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001046TEST_F(CommentLexerTest, HTML12) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001047 const char *Source = "// <tag attr=@";
1048
1049 std::vector<Token> Toks;
1050
1051 lexString(Source, Toks);
1052
1053 ASSERT_EQ(6U, Toks.size());
1054
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001055 ASSERT_EQ(tok::text, Toks[0].getKind());
1056 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001057
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001058 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1059 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001060
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001061 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1062 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001063
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001064 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001065
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001066 ASSERT_EQ(tok::text, Toks[4].getKind());
1067 ASSERT_EQ(StringRef("@"), Toks[4].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001068
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001069 ASSERT_EQ(tok::newline, Toks[5].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001070}
1071
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001072TEST_F(CommentLexerTest, HTML13) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001073 const char *Sources[] = {
1074 "// <tag attr=\"val\\\"\\'val",
1075 "// <tag attr=\"val\\\"\\'val\"",
1076 "// <tag attr=\'val\\\"\\'val",
1077 "// <tag attr=\'val\\\"\\'val\'"
1078 };
1079
1080 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1081 std::vector<Token> Toks;
1082
1083 lexString(Sources[i], Toks);
1084
1085 ASSERT_EQ(6U, Toks.size());
1086
1087 ASSERT_EQ(tok::text, Toks[0].getKind());
1088 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1089
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001090 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1091 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001092
1093 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1094 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
1095
1096 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1097
1098 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1099 ASSERT_EQ(StringRef("val\\\"\\'val"), Toks[4].getHTMLQuotedString());
1100
1101 ASSERT_EQ(tok::newline, Toks[5].getKind());
1102 }
1103}
1104
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001105TEST_F(CommentLexerTest, HTML14) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001106 const char *Sources[] = {
1107 "// <tag attr=\"val\\\"\\'val\">",
1108 "// <tag attr=\'val\\\"\\'val\'>"
1109 };
1110
1111 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1112 std::vector<Token> Toks;
1113
1114 lexString(Sources[i], Toks);
1115
1116 ASSERT_EQ(7U, Toks.size());
1117
1118 ASSERT_EQ(tok::text, Toks[0].getKind());
1119 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1120
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001121 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1122 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001123
1124 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1125 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
1126
1127 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1128
1129 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1130 ASSERT_EQ(StringRef("val\\\"\\'val"), Toks[4].getHTMLQuotedString());
1131
1132 ASSERT_EQ(tok::html_greater, Toks[5].getKind());
1133
1134 ASSERT_EQ(tok::newline, Toks[6].getKind());
1135 }
1136}
1137
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001138TEST_F(CommentLexerTest, HTML15) {
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001139 const char *Sources[] = {
1140 "// <tag/>",
1141 "// <tag />"
1142 };
1143
1144 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1145 std::vector<Token> Toks;
1146
1147 lexString(Sources[i], Toks);
1148
1149 ASSERT_EQ(4U, Toks.size());
1150
1151 ASSERT_EQ(tok::text, Toks[0].getKind());
1152 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1153
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001154 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1155 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001156
1157 ASSERT_EQ(tok::html_slash_greater, Toks[2].getKind());
1158
1159 ASSERT_EQ(tok::newline, Toks[3].getKind());
1160 }
1161}
1162
1163TEST_F(CommentLexerTest, HTML16) {
1164 const char *Sources[] = {
1165 "// <tag/ Aaa",
1166 "// <tag / Aaa"
1167 };
1168
1169 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1170 std::vector<Token> Toks;
1171
1172 lexString(Sources[i], Toks);
1173
1174 ASSERT_EQ(5U, Toks.size());
1175
1176 ASSERT_EQ(tok::text, Toks[0].getKind());
1177 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1178
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001179 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1180 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001181
1182 ASSERT_EQ(tok::text, Toks[2].getKind());
1183 ASSERT_EQ(StringRef("/"), Toks[2].getText());
1184
1185 ASSERT_EQ(tok::text, Toks[3].getKind());
1186 ASSERT_EQ(StringRef(" Aaa"), Toks[3].getText());
1187
1188 ASSERT_EQ(tok::newline, Toks[4].getKind());
1189 }
1190}
1191
1192TEST_F(CommentLexerTest, HTML17) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001193 const char *Source = "// </";
1194
1195 std::vector<Token> Toks;
1196
1197 lexString(Source, Toks);
1198
1199 ASSERT_EQ(3U, Toks.size());
1200
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001201 ASSERT_EQ(tok::text, Toks[0].getKind());
1202 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001203
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001204 ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
1205 ASSERT_EQ(StringRef(""), Toks[1].getHTMLTagEndName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001206
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001207 ASSERT_EQ(tok::newline, Toks[2].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001208}
1209
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001210TEST_F(CommentLexerTest, HTML18) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001211 const char *Source = "// </@";
1212
1213 std::vector<Token> Toks;
1214
1215 lexString(Source, Toks);
1216
1217 ASSERT_EQ(4U, Toks.size());
1218
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001219 ASSERT_EQ(tok::text, Toks[0].getKind());
1220 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001221
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001222 ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
1223 ASSERT_EQ(StringRef(""), Toks[1].getHTMLTagEndName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001224
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001225 ASSERT_EQ(tok::text, Toks[2].getKind());
1226 ASSERT_EQ(StringRef("@"), Toks[2].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001227
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001228 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001229}
1230
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001231TEST_F(CommentLexerTest, HTML19) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001232 const char *Source = "// </tag";
1233
1234 std::vector<Token> Toks;
1235
1236 lexString(Source, Toks);
1237
1238 ASSERT_EQ(3U, Toks.size());
1239
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001240 ASSERT_EQ(tok::text, Toks[0].getKind());
1241 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001242
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001243 ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
1244 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagEndName());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001245
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001246 ASSERT_EQ(tok::newline, Toks[2].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001247}
1248
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001249TEST_F(CommentLexerTest, HTML20) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001250 const char *Sources[] = {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001251 "// </tag>",
1252 "// </ tag>",
1253 "// </ tag >"
1254 };
1255
1256 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1257 std::vector<Token> Toks;
1258
1259 lexString(Sources[i], Toks);
1260
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001261 ASSERT_EQ(4U, Toks.size());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001262
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001263 ASSERT_EQ(tok::text, Toks[0].getKind());
1264 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001265
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001266 ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
1267 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagEndName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001268
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001269 ASSERT_EQ(tok::html_greater, Toks[2].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001270
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001271 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001272 }
1273}
1274
1275TEST_F(CommentLexerTest, MultipleComments) {
1276 const char *Source =
1277 "// Aaa\n"
1278 "/// Bbb\n"
1279 "/* Ccc\n"
1280 " * Ddd*/\n"
1281 "/** Eee*/";
1282
1283 std::vector<Token> Toks;
1284
1285 lexString(Source, Toks);
1286
1287 ASSERT_EQ(12U, Toks.size());
1288
1289 ASSERT_EQ(tok::text, Toks[0].getKind());
1290 ASSERT_EQ(StringRef(" Aaa"), Toks[0].getText());
1291 ASSERT_EQ(tok::newline, Toks[1].getKind());
1292
1293 ASSERT_EQ(tok::text, Toks[2].getKind());
1294 ASSERT_EQ(StringRef(" Bbb"), Toks[2].getText());
1295 ASSERT_EQ(tok::newline, Toks[3].getKind());
1296
1297 ASSERT_EQ(tok::text, Toks[4].getKind());
1298 ASSERT_EQ(StringRef(" Ccc"), Toks[4].getText());
1299 ASSERT_EQ(tok::newline, Toks[5].getKind());
1300
1301 ASSERT_EQ(tok::text, Toks[6].getKind());
1302 ASSERT_EQ(StringRef(" Ddd"), Toks[6].getText());
1303 ASSERT_EQ(tok::newline, Toks[7].getKind());
1304 ASSERT_EQ(tok::newline, Toks[8].getKind());
1305
1306 ASSERT_EQ(tok::text, Toks[9].getKind());
1307 ASSERT_EQ(StringRef(" Eee"), Toks[9].getText());
1308
1309 ASSERT_EQ(tok::newline, Toks[10].getKind());
1310 ASSERT_EQ(tok::newline, Toks[11].getKind());
1311}
1312
1313} // end namespace comments
1314} // end namespace clang
1315