blob: e1089cc5dce3b6b075dd3c183cd4b84ea9f8bd31 [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
517 ASSERT_EQ(11U, Toks.size());
518
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
539 ASSERT_EQ(tok::verbatim_block_line, Toks[8].getKind());
540 ASSERT_EQ(StringRef(" "), Toks[8].getVerbatimBlockText());
541
542 ASSERT_EQ(tok::verbatim_block_end, Toks[9].getKind());
543 ASSERT_EQ(StringRef("endverbatim"), Toks[9].getVerbatimBlockName());
544
545 ASSERT_EQ(tok::newline, Toks[10].getKind());
546}
547
548TEST_F(CommentLexerTest, VerbatimBlock7) {
549 const char *Source =
550 "/* \\verbatim\n"
551 " * Aaa\n"
552 " *\n"
553 " * Bbb\n"
554 " * \\endverbatim\n"
555 " */";
556
557 std::vector<Token> Toks;
558
559 lexString(Source, Toks);
560
561 ASSERT_EQ(11U, Toks.size());
562
563 ASSERT_EQ(tok::text, Toks[0].getKind());
564 ASSERT_EQ(StringRef(" "), Toks[0].getText());
565
566 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
567 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
568
569 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
570 ASSERT_EQ(StringRef(" Aaa"), Toks[2].getVerbatimBlockText());
571
572 ASSERT_EQ(tok::verbatim_block_line, Toks[3].getKind());
573 ASSERT_EQ(StringRef(""), Toks[3].getVerbatimBlockText());
574
575 ASSERT_EQ(tok::verbatim_block_line, Toks[4].getKind());
576 ASSERT_EQ(StringRef(" Bbb"), Toks[4].getVerbatimBlockText());
577
578 ASSERT_EQ(tok::verbatim_block_line, Toks[5].getKind());
579 ASSERT_EQ(StringRef(" "), Toks[5].getVerbatimBlockText());
580
581 ASSERT_EQ(tok::verbatim_block_end, Toks[6].getKind());
582 ASSERT_EQ(StringRef("endverbatim"), Toks[6].getVerbatimBlockName());
583
584 ASSERT_EQ(tok::newline, Toks[7].getKind());
585
586 ASSERT_EQ(tok::text, Toks[8].getKind());
587 ASSERT_EQ(StringRef(" "), Toks[8].getText());
588
589 ASSERT_EQ(tok::newline, Toks[9].getKind());
590 ASSERT_EQ(tok::newline, Toks[10].getKind());
591}
592
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000593// Complex test for verbatim blocks.
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000594TEST_F(CommentLexerTest, VerbatimBlock8) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000595 const char *Source =
596 "/* Meow \\verbatim aaa\\$\\@\n"
597 "bbb \\endverbati\r"
598 "ccc\r\n"
599 "ddd \\endverbatim Blah \\verbatim eee\n"
600 "\\endverbatim BlahBlah*/";
601 std::vector<Token> Toks;
602
603 lexString(Source, Toks);
604
605 ASSERT_EQ(14U, Toks.size());
606
607 ASSERT_EQ(tok::text, Toks[0].getKind());
608 ASSERT_EQ(StringRef(" Meow "), Toks[0].getText());
609
610 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
611 ASSERT_EQ(StringRef("verbatim"), Toks[1].getVerbatimBlockName());
612
613 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000614 ASSERT_EQ(StringRef(" aaa\\$\\@"), Toks[2].getVerbatimBlockText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000615
616 ASSERT_EQ(tok::verbatim_block_line, Toks[3].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000617 ASSERT_EQ(StringRef("bbb \\endverbati"), Toks[3].getVerbatimBlockText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000618
619 ASSERT_EQ(tok::verbatim_block_line, Toks[4].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000620 ASSERT_EQ(StringRef("ccc"), Toks[4].getVerbatimBlockText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000621
622 ASSERT_EQ(tok::verbatim_block_line, Toks[5].getKind());
623 ASSERT_EQ(StringRef("ddd "), Toks[5].getVerbatimBlockText());
624
625 ASSERT_EQ(tok::verbatim_block_end, Toks[6].getKind());
626 ASSERT_EQ(StringRef("endverbatim"), Toks[6].getVerbatimBlockName());
627
628 ASSERT_EQ(tok::text, Toks[7].getKind());
629 ASSERT_EQ(StringRef(" Blah "), Toks[7].getText());
630
631 ASSERT_EQ(tok::verbatim_block_begin, Toks[8].getKind());
632 ASSERT_EQ(StringRef("verbatim"), Toks[8].getVerbatimBlockName());
633
634 ASSERT_EQ(tok::verbatim_block_line, Toks[9].getKind());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000635 ASSERT_EQ(StringRef(" eee"), Toks[9].getVerbatimBlockText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000636
637 ASSERT_EQ(tok::verbatim_block_end, Toks[10].getKind());
638 ASSERT_EQ(StringRef("endverbatim"), Toks[10].getVerbatimBlockName());
639
640 ASSERT_EQ(tok::text, Toks[11].getKind());
641 ASSERT_EQ(StringRef(" BlahBlah"), Toks[11].getText());
642
643 ASSERT_EQ(tok::newline, Toks[12].getKind());
644 ASSERT_EQ(tok::newline, Toks[13].getKind());
645}
646
647// LaTeX verbatim blocks.
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000648TEST_F(CommentLexerTest, VerbatimBlock9) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000649 const char *Source =
650 "/// \\f$ Aaa \\f$ \\f[ Bbb \\f] \\f{ Ccc \\f}";
651 std::vector<Token> Toks;
652
653 lexString(Source, Toks);
654
655 ASSERT_EQ(13U, Toks.size());
656
657 ASSERT_EQ(tok::text, Toks[0].getKind());
658 ASSERT_EQ(StringRef(" "), Toks[0].getText());
659
660 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
661 ASSERT_EQ(StringRef("f$"), Toks[1].getVerbatimBlockName());
662
663 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
664 ASSERT_EQ(StringRef(" Aaa "), Toks[2].getVerbatimBlockText());
665
666 ASSERT_EQ(tok::verbatim_block_end, Toks[3].getKind());
667 ASSERT_EQ(StringRef("f$"), Toks[3].getVerbatimBlockName());
668
669 ASSERT_EQ(tok::text, Toks[4].getKind());
670 ASSERT_EQ(StringRef(" "), Toks[4].getText());
671
672 ASSERT_EQ(tok::verbatim_block_begin, Toks[5].getKind());
673 ASSERT_EQ(StringRef("f["), Toks[5].getVerbatimBlockName());
674
675 ASSERT_EQ(tok::verbatim_block_line, Toks[6].getKind());
676 ASSERT_EQ(StringRef(" Bbb "), Toks[6].getVerbatimBlockText());
677
678 ASSERT_EQ(tok::verbatim_block_end, Toks[7].getKind());
679 ASSERT_EQ(StringRef("f]"), Toks[7].getVerbatimBlockName());
680
681 ASSERT_EQ(tok::text, Toks[8].getKind());
682 ASSERT_EQ(StringRef(" "), Toks[8].getText());
683
684 ASSERT_EQ(tok::verbatim_block_begin, Toks[9].getKind());
685 ASSERT_EQ(StringRef("f{"), Toks[9].getVerbatimBlockName());
686
687 ASSERT_EQ(tok::verbatim_block_line, Toks[10].getKind());
688 ASSERT_EQ(StringRef(" Ccc "), Toks[10].getVerbatimBlockText());
689
690 ASSERT_EQ(tok::verbatim_block_end, Toks[11].getKind());
691 ASSERT_EQ(StringRef("f}"), Toks[11].getVerbatimBlockName());
692
693 ASSERT_EQ(tok::newline, Toks[12].getKind());
694}
695
696// Empty verbatim line.
697TEST_F(CommentLexerTest, VerbatimLine1) {
698 const char *Sources[] = {
699 "/// \\fn\n//",
700 "/** \\fn*/"
701 };
702
703 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
704 std::vector<Token> Toks;
705
706 lexString(Sources[i], Toks);
707
708 ASSERT_EQ(4U, Toks.size());
709
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000710 ASSERT_EQ(tok::text, Toks[0].getKind());
711 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000712
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000713 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
714 ASSERT_EQ(StringRef("fn"), Toks[1].getVerbatimLineName());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000715
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000716 ASSERT_EQ(tok::newline, Toks[2].getKind());
717 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000718 }
719}
720
721// Verbatim line with Doxygen escape sequences, which should not be expanded.
722TEST_F(CommentLexerTest, VerbatimLine2) {
723 const char *Sources[] = {
724 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
725 "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
726 };
727
728 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
729 std::vector<Token> Toks;
730
731 lexString(Sources[i], Toks);
732
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000733 ASSERT_EQ(5U, Toks.size());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000734
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000735 ASSERT_EQ(tok::text, Toks[0].getKind());
736 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000737
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000738 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
739 ASSERT_EQ(StringRef("fn"), Toks[1].getVerbatimLineName());
740
741 ASSERT_EQ(tok::verbatim_line_text, Toks[2].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000742 ASSERT_EQ(StringRef(" void *foo(const char *zzz = \"\\$\");"),
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000743 Toks[2].getVerbatimLineText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000744
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000745 ASSERT_EQ(tok::newline, Toks[3].getKind());
746 ASSERT_EQ(tok::newline, Toks[4].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000747 }
748}
749
750// Verbatim line should not eat anything from next source line.
751TEST_F(CommentLexerTest, VerbatimLine3) {
752 const char *Source =
753 "/** \\fn void *foo(const char *zzz = \"\\$\");\n"
754 " * Meow\n"
755 " */";
756
757 std::vector<Token> Toks;
758
759 lexString(Source, Toks);
760
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000761 ASSERT_EQ(9U, Toks.size());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000762
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000763 ASSERT_EQ(tok::text, Toks[0].getKind());
764 ASSERT_EQ(StringRef(" "), Toks[0].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000765
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000766 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
767 ASSERT_EQ(StringRef("fn"), Toks[1].getVerbatimLineName());
768
769 ASSERT_EQ(tok::verbatim_line_text, Toks[2].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000770 ASSERT_EQ(StringRef(" void *foo(const char *zzz = \"\\$\");"),
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000771 Toks[2].getVerbatimLineText());
772 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000773
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000774 ASSERT_EQ(tok::text, Toks[4].getKind());
775 ASSERT_EQ(StringRef(" Meow"), Toks[4].getText());
776 ASSERT_EQ(tok::newline, Toks[5].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000777
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000778 ASSERT_EQ(tok::text, Toks[6].getKind());
779 ASSERT_EQ(StringRef(" "), Toks[6].getText());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000780
Dmitri Gribenko962668d2012-06-27 16:53:58 +0000781 ASSERT_EQ(tok::newline, Toks[7].getKind());
782 ASSERT_EQ(tok::newline, Toks[8].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000783}
784
785TEST_F(CommentLexerTest, HTML1) {
786 const char *Source =
787 "// <";
788
789 std::vector<Token> Toks;
790
791 lexString(Source, Toks);
792
793 ASSERT_EQ(3U, Toks.size());
794
795 ASSERT_EQ(tok::text, Toks[0].getKind());
796 ASSERT_EQ(StringRef(" "), Toks[0].getText());
797
798 ASSERT_EQ(tok::text, Toks[1].getKind());
799 ASSERT_EQ(StringRef("<"), Toks[1].getText());
800
801 ASSERT_EQ(tok::newline, Toks[2].getKind());
802}
803
804TEST_F(CommentLexerTest, HTML2) {
Dmitri Gribenko5676d322012-06-27 23:28:29 +0000805 const char *Source =
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000806 "// a<2";
807
808 std::vector<Token> Toks;
809
810 lexString(Source, Toks);
811
812 ASSERT_EQ(4U, Toks.size());
813
814 ASSERT_EQ(tok::text, Toks[0].getKind());
815 ASSERT_EQ(StringRef(" a"), Toks[0].getText());
816
817 ASSERT_EQ(tok::text, Toks[1].getKind());
818 ASSERT_EQ(StringRef("<"), Toks[1].getText());
819
820 ASSERT_EQ(tok::text, Toks[2].getKind());
821 ASSERT_EQ(StringRef("2"), Toks[2].getText());
822
823 ASSERT_EQ(tok::newline, Toks[3].getKind());
824}
825
826TEST_F(CommentLexerTest, HTML3) {
827 const char *Source =
Dmitri Gribenko5676d322012-06-27 23:28:29 +0000828 "// < tag";
829
830 std::vector<Token> Toks;
831
832 lexString(Source, Toks);
833
834 ASSERT_EQ(4U, Toks.size());
835
836 ASSERT_EQ(tok::text, Toks[0].getKind());
837 ASSERT_EQ(StringRef(" "), Toks[0].getText());
838
839 ASSERT_EQ(tok::text, Toks[1].getKind());
840 ASSERT_EQ(StringRef("<"), Toks[1].getText());
841
842 ASSERT_EQ(tok::text, Toks[2].getKind());
843 ASSERT_EQ(StringRef(" tag"), Toks[2].getText());
844
845 ASSERT_EQ(tok::newline, Toks[3].getKind());
846}
847
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000848TEST_F(CommentLexerTest, HTML4) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000849 const char *Sources[] = {
850 "// <tag",
851 "// <tag "
852 };
853
854 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
855 std::vector<Token> Toks;
856
857 lexString(Sources[i], Toks);
858
859 ASSERT_EQ(3U, Toks.size());
860
861 ASSERT_EQ(tok::text, Toks[0].getKind());
862 ASSERT_EQ(StringRef(" "), Toks[0].getText());
863
864 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
865 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
866
867 ASSERT_EQ(tok::newline, Toks[2].getKind());
868 }
869}
870
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000871TEST_F(CommentLexerTest, HTML5) {
872 const char *Source =
873 "// <tag 42";
874
875 std::vector<Token> Toks;
876
877 lexString(Source, Toks);
878
879 ASSERT_EQ(4U, Toks.size());
880
881 ASSERT_EQ(tok::text, Toks[0].getKind());
882 ASSERT_EQ(StringRef(" "), Toks[0].getText());
883
884 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
885 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
886
887 ASSERT_EQ(tok::text, Toks[2].getKind());
888 ASSERT_EQ(StringRef("42"), Toks[2].getText());
889
890 ASSERT_EQ(tok::newline, Toks[3].getKind());
891}
892
893TEST_F(CommentLexerTest, HTML6) {
894 const char *Source = "// <tag> Meow";
895
896 std::vector<Token> Toks;
897
898 lexString(Source, Toks);
899
900 ASSERT_EQ(5U, Toks.size());
901
902 ASSERT_EQ(tok::text, Toks[0].getKind());
903 ASSERT_EQ(StringRef(" "), Toks[0].getText());
904
905 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
906 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
907
908 ASSERT_EQ(tok::html_greater, Toks[2].getKind());
909
910 ASSERT_EQ(tok::text, Toks[3].getKind());
911 ASSERT_EQ(StringRef(" Meow"), Toks[3].getText());
912
913 ASSERT_EQ(tok::newline, Toks[4].getKind());
914}
915
916TEST_F(CommentLexerTest, HTML7) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000917 const char *Source = "// <tag=";
918
919 std::vector<Token> Toks;
920
921 lexString(Source, Toks);
922
923 ASSERT_EQ(4U, Toks.size());
924
925 ASSERT_EQ(tok::text, Toks[0].getKind());
926 ASSERT_EQ(StringRef(" "), Toks[0].getText());
927
928 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
929 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
930
931 ASSERT_EQ(tok::text, Toks[2].getKind());
932 ASSERT_EQ(StringRef("="), Toks[2].getText());
933
934 ASSERT_EQ(tok::newline, Toks[3].getKind());
935}
936
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000937TEST_F(CommentLexerTest, HTML8) {
938 const char *Source = "// <tag attr=> Meow";
939
940 std::vector<Token> Toks;
941
942 lexString(Source, Toks);
943
944 ASSERT_EQ(7U, Toks.size());
945
946 ASSERT_EQ(tok::text, Toks[0].getKind());
947 ASSERT_EQ(StringRef(" "), Toks[0].getText());
948
949 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
950 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
951
952 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
953 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
954
955 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
956
957 ASSERT_EQ(tok::html_greater, Toks[4].getKind());
958
959 ASSERT_EQ(tok::text, Toks[5].getKind());
960 ASSERT_EQ(StringRef(" Meow"), Toks[5].getText());
961
962 ASSERT_EQ(tok::newline, Toks[6].getKind());
963}
964
965TEST_F(CommentLexerTest, HTML9) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000966 const char *Sources[] = {
967 "// <tag attr",
968 "// <tag attr "
969 };
970
971 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
972 std::vector<Token> Toks;
973
974 lexString(Sources[i], Toks);
975
976 ASSERT_EQ(4U, Toks.size());
977
978 ASSERT_EQ(tok::text, Toks[0].getKind());
979 ASSERT_EQ(StringRef(" "), Toks[0].getText());
980
981 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
982 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
983
984 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
985 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
986
987 ASSERT_EQ(tok::newline, Toks[3].getKind());
988 }
989}
990
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +0000991TEST_F(CommentLexerTest, HTML10) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000992 const char *Sources[] = {
993 "// <tag attr=",
994 "// <tag attr ="
995 };
996
997 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
998 std::vector<Token> Toks;
999
1000 lexString(Sources[i], Toks);
1001
1002 ASSERT_EQ(5U, Toks.size());
1003
1004 ASSERT_EQ(tok::text, Toks[0].getKind());
1005 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1006
1007 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
1008 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
1009
1010 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1011 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
1012
1013 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1014
1015 ASSERT_EQ(tok::newline, Toks[4].getKind());
1016 }
1017}
1018
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001019TEST_F(CommentLexerTest, HTML11) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001020 const char *Sources[] = {
1021 "// <tag attr=\"",
1022 "// <tag attr = \"",
1023 "// <tag attr=\'",
1024 "// <tag attr = \'"
1025 };
1026
1027 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1028 std::vector<Token> Toks;
1029
1030 lexString(Sources[i], Toks);
1031
1032 ASSERT_EQ(6U, Toks.size());
1033
1034 ASSERT_EQ(tok::text, Toks[0].getKind());
1035 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1036
1037 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
1038 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
1039
1040 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1041 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
1042
1043 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1044
1045 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1046 ASSERT_EQ(StringRef(""), Toks[4].getHTMLQuotedString());
1047
1048 ASSERT_EQ(tok::newline, Toks[5].getKind());
1049 }
1050}
1051
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001052TEST_F(CommentLexerTest, HTML12) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001053 const char *Source = "// <tag attr=@";
1054
1055 std::vector<Token> Toks;
1056
1057 lexString(Source, Toks);
1058
1059 ASSERT_EQ(6U, Toks.size());
1060
1061 ASSERT_EQ(tok::text, Toks[0].getKind());
1062 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1063
1064 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
1065 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
1066
1067 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1068 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
1069
1070 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1071
1072 ASSERT_EQ(tok::text, Toks[4].getKind());
1073 ASSERT_EQ(StringRef("@"), Toks[4].getText());
1074
1075 ASSERT_EQ(tok::newline, Toks[5].getKind());
1076}
1077
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001078TEST_F(CommentLexerTest, HTML13) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001079 const char *Sources[] = {
1080 "// <tag attr=\"val\\\"\\'val",
1081 "// <tag attr=\"val\\\"\\'val\"",
1082 "// <tag attr=\'val\\\"\\'val",
1083 "// <tag attr=\'val\\\"\\'val\'"
1084 };
1085
1086 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1087 std::vector<Token> Toks;
1088
1089 lexString(Sources[i], Toks);
1090
1091 ASSERT_EQ(6U, Toks.size());
1092
1093 ASSERT_EQ(tok::text, Toks[0].getKind());
1094 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1095
1096 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
1097 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
1098
1099 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1100 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
1101
1102 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1103
1104 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1105 ASSERT_EQ(StringRef("val\\\"\\'val"), Toks[4].getHTMLQuotedString());
1106
1107 ASSERT_EQ(tok::newline, Toks[5].getKind());
1108 }
1109}
1110
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001111TEST_F(CommentLexerTest, HTML14) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001112 const char *Sources[] = {
1113 "// <tag attr=\"val\\\"\\'val\">",
1114 "// <tag attr=\'val\\\"\\'val\'>"
1115 };
1116
1117 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1118 std::vector<Token> Toks;
1119
1120 lexString(Sources[i], Toks);
1121
1122 ASSERT_EQ(7U, Toks.size());
1123
1124 ASSERT_EQ(tok::text, Toks[0].getKind());
1125 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1126
1127 ASSERT_EQ(tok::html_tag_open, Toks[1].getKind());
1128 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagOpenName());
1129
1130 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1131 ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
1132
1133 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1134
1135 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1136 ASSERT_EQ(StringRef("val\\\"\\'val"), Toks[4].getHTMLQuotedString());
1137
1138 ASSERT_EQ(tok::html_greater, Toks[5].getKind());
1139
1140 ASSERT_EQ(tok::newline, Toks[6].getKind());
1141 }
1142}
1143
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001144TEST_F(CommentLexerTest, HTML15) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001145 const char *Source = "// </";
1146
1147 std::vector<Token> Toks;
1148
1149 lexString(Source, Toks);
1150
1151 ASSERT_EQ(3U, Toks.size());
1152
1153 ASSERT_EQ(tok::text, Toks[0].getKind());
1154 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1155
1156 ASSERT_EQ(tok::html_tag_close, Toks[1].getKind());
1157 ASSERT_EQ(StringRef(""), Toks[1].getHTMLTagCloseName());
1158
1159 ASSERT_EQ(tok::newline, Toks[2].getKind());
1160}
1161
1162
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001163TEST_F(CommentLexerTest, HTML16) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001164 const char *Source = "// </@";
1165
1166 std::vector<Token> Toks;
1167
1168 lexString(Source, Toks);
1169
1170 ASSERT_EQ(4U, Toks.size());
1171
1172 ASSERT_EQ(tok::text, Toks[0].getKind());
1173 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1174
1175 ASSERT_EQ(tok::html_tag_close, Toks[1].getKind());
1176 ASSERT_EQ(StringRef(""), Toks[1].getHTMLTagCloseName());
1177
1178 ASSERT_EQ(tok::text, Toks[2].getKind());
1179 ASSERT_EQ(StringRef("@"), Toks[2].getText());
1180
1181 ASSERT_EQ(tok::newline, Toks[3].getKind());
1182}
1183
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001184TEST_F(CommentLexerTest, HTML17) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001185 const char *Source = "// </tag";
1186
1187 std::vector<Token> Toks;
1188
1189 lexString(Source, Toks);
1190
1191 ASSERT_EQ(3U, Toks.size());
1192
1193 ASSERT_EQ(tok::text, Toks[0].getKind());
1194 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1195
1196 ASSERT_EQ(tok::html_tag_close, Toks[1].getKind());
1197 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagCloseName());
1198
1199 ASSERT_EQ(tok::newline, Toks[2].getKind());
1200}
1201
Dmitri Gribenkoa99ec102012-07-09 21:32:40 +00001202TEST_F(CommentLexerTest, HTML18) {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001203 const char *Sources[] = {
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001204 "// </tag>",
1205 "// </ tag>",
1206 "// </ tag >"
1207 };
1208
1209 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1210 std::vector<Token> Toks;
1211
1212 lexString(Sources[i], Toks);
1213
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001214 ASSERT_EQ(4U, Toks.size());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001215
1216 ASSERT_EQ(tok::text, Toks[0].getKind());
1217 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1218
1219 ASSERT_EQ(tok::html_tag_close, Toks[1].getKind());
1220 ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagCloseName());
1221
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001222 ASSERT_EQ(tok::html_greater, Toks[2].getKind());
1223
1224 ASSERT_EQ(tok::newline, Toks[3].getKind());
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001225 }
1226}
1227
1228TEST_F(CommentLexerTest, MultipleComments) {
1229 const char *Source =
1230 "// Aaa\n"
1231 "/// Bbb\n"
1232 "/* Ccc\n"
1233 " * Ddd*/\n"
1234 "/** Eee*/";
1235
1236 std::vector<Token> Toks;
1237
1238 lexString(Source, Toks);
1239
1240 ASSERT_EQ(12U, Toks.size());
1241
1242 ASSERT_EQ(tok::text, Toks[0].getKind());
1243 ASSERT_EQ(StringRef(" Aaa"), Toks[0].getText());
1244 ASSERT_EQ(tok::newline, Toks[1].getKind());
1245
1246 ASSERT_EQ(tok::text, Toks[2].getKind());
1247 ASSERT_EQ(StringRef(" Bbb"), Toks[2].getText());
1248 ASSERT_EQ(tok::newline, Toks[3].getKind());
1249
1250 ASSERT_EQ(tok::text, Toks[4].getKind());
1251 ASSERT_EQ(StringRef(" Ccc"), Toks[4].getText());
1252 ASSERT_EQ(tok::newline, Toks[5].getKind());
1253
1254 ASSERT_EQ(tok::text, Toks[6].getKind());
1255 ASSERT_EQ(StringRef(" Ddd"), Toks[6].getText());
1256 ASSERT_EQ(tok::newline, Toks[7].getKind());
1257 ASSERT_EQ(tok::newline, Toks[8].getKind());
1258
1259 ASSERT_EQ(tok::text, Toks[9].getKind());
1260 ASSERT_EQ(StringRef(" Eee"), Toks[9].getText());
1261
1262 ASSERT_EQ(tok::newline, Toks[10].getKind());
1263 ASSERT_EQ(tok::newline, Toks[11].getKind());
1264}
1265
1266} // end namespace comments
1267} // end namespace clang
1268