1 //===- unittests/AST/CommentLexer.cpp ------ Comment lexer tests ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/AST/CommentLexer.h"
11 #include "clang/AST/CommentCommandTraits.h"
12 #include "clang/Basic/CommentOptions.h"
13 #include "clang/Basic/Diagnostic.h"
14 #include "clang/Basic/DiagnosticOptions.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Basic/SourceManager.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "gtest/gtest.h"
22 using namespace clang;
28 class CommentLexerTest : public ::testing::Test {
31 : FileMgr(FileMgrOpts),
32 DiagID(new DiagnosticIDs()),
33 Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
34 SourceMgr(Diags, FileMgr),
35 Traits(Allocator, CommentOptions()) {
38 FileSystemOptions FileMgrOpts;
40 IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
41 DiagnosticsEngine Diags;
42 SourceManager SourceMgr;
43 llvm::BumpPtrAllocator Allocator;
46 void lexString(const char *Source, std::vector<Token> &Toks);
48 StringRef getCommandName(const Token &Tok) {
49 return Traits.getCommandInfo(Tok.getCommandID())->Name;
52 StringRef getVerbatimBlockName(const Token &Tok) {
53 return Traits.getCommandInfo(Tok.getVerbatimBlockID())->Name;
56 StringRef getVerbatimLineName(const Token &Tok) {
57 return Traits.getCommandInfo(Tok.getVerbatimLineID())->Name;
61 void CommentLexerTest::lexString(const char *Source,
62 std::vector<Token> &Toks) {
63 MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
64 FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
65 SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
67 Lexer L(Allocator, Traits, Begin, Source, Source + strlen(Source));
78 } // unnamed namespace
80 // Empty source range should be handled.
81 TEST_F(CommentLexerTest, Basic1) {
82 const char *Source = "";
83 std::vector<Token> Toks;
85 lexString(Source, Toks);
87 ASSERT_EQ(0U, Toks.size());
90 // Empty comments should be handled.
91 TEST_F(CommentLexerTest, Basic2) {
92 const char *Sources[] = {
93 "//", "///", "//!", "///<", "//!<"
95 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
96 std::vector<Token> Toks;
98 lexString(Sources[i], Toks);
100 ASSERT_EQ(1U, Toks.size());
102 ASSERT_EQ(tok::newline, Toks[0].getKind());
106 // Empty comments should be handled.
107 TEST_F(CommentLexerTest, Basic3) {
108 const char *Sources[] = {
109 "/**/", "/***/", "/*!*/", "/**<*/", "/*!<*/"
111 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
112 std::vector<Token> Toks;
114 lexString(Sources[i], Toks);
116 ASSERT_EQ(2U, Toks.size());
118 ASSERT_EQ(tok::newline, Toks[0].getKind());
119 ASSERT_EQ(tok::newline, Toks[1].getKind());
123 // Single comment with plain text.
124 TEST_F(CommentLexerTest, Basic4) {
125 const char *Sources[] = {
126 "// Meow", "/// Meow", "//! Meow",
127 "// Meow\n", "// Meow\r\n", "//! Meow\r",
130 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
131 std::vector<Token> Toks;
133 lexString(Sources[i], Toks);
135 ASSERT_EQ(2U, Toks.size());
137 ASSERT_EQ(tok::text, Toks[0].getKind());
138 ASSERT_EQ(StringRef(" Meow"), Toks[0].getText());
140 ASSERT_EQ(tok::newline, Toks[1].getKind());
144 // Single comment with plain text.
145 TEST_F(CommentLexerTest, Basic5) {
146 const char *Sources[] = {
147 "/* Meow*/", "/** Meow*/", "/*! Meow*/"
150 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
151 std::vector<Token> Toks;
153 lexString(Sources[i], Toks);
155 ASSERT_EQ(3U, Toks.size());
157 ASSERT_EQ(tok::text, Toks[0].getKind());
158 ASSERT_EQ(StringRef(" Meow"), Toks[0].getText());
160 ASSERT_EQ(tok::newline, Toks[1].getKind());
161 ASSERT_EQ(tok::newline, Toks[2].getKind());
165 // Test newline escaping.
166 TEST_F(CommentLexerTest, Basic6) {
167 const char *Sources[] = {
168 "// Aaa\\\n" " Bbb\\ \n" " Ccc?" "?/\n",
169 "// Aaa\\\r\n" " Bbb\\ \r\n" " Ccc?" "?/\r\n",
170 "// Aaa\\\r" " Bbb\\ \r" " Ccc?" "?/\r"
173 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
174 std::vector<Token> Toks;
176 lexString(Sources[i], Toks);
178 ASSERT_EQ(10U, Toks.size());
180 ASSERT_EQ(tok::text, Toks[0].getKind());
181 ASSERT_EQ(StringRef(" Aaa"), Toks[0].getText());
182 ASSERT_EQ(tok::text, Toks[1].getKind());
183 ASSERT_EQ(StringRef("\\"), Toks[1].getText());
184 ASSERT_EQ(tok::newline, Toks[2].getKind());
186 ASSERT_EQ(tok::text, Toks[3].getKind());
187 ASSERT_EQ(StringRef(" Bbb"), Toks[3].getText());
188 ASSERT_EQ(tok::text, Toks[4].getKind());
189 ASSERT_EQ(StringRef("\\"), Toks[4].getText());
190 ASSERT_EQ(tok::text, Toks[5].getKind());
191 ASSERT_EQ(StringRef(" "), Toks[5].getText());
192 ASSERT_EQ(tok::newline, Toks[6].getKind());
194 ASSERT_EQ(tok::text, Toks[7].getKind());
195 ASSERT_EQ(StringRef(" Ccc?" "?/"), Toks[7].getText());
196 ASSERT_EQ(tok::newline, Toks[8].getKind());
198 ASSERT_EQ(tok::newline, Toks[9].getKind());
202 // Check that we skip C-style aligned stars correctly.
203 TEST_F(CommentLexerTest, Basic7) {
212 std::vector<Token> Toks;
214 lexString(Source, Toks);
216 ASSERT_EQ(15U, Toks.size());
218 ASSERT_EQ(tok::text, Toks[0].getKind());
219 ASSERT_EQ(StringRef(" Aaa"), Toks[0].getText());
220 ASSERT_EQ(tok::newline, Toks[1].getKind());
222 ASSERT_EQ(tok::text, Toks[2].getKind());
223 ASSERT_EQ(StringRef(" Bbb"), Toks[2].getText());
224 ASSERT_EQ(tok::newline, Toks[3].getKind());
226 ASSERT_EQ(tok::text, Toks[4].getKind());
227 ASSERT_EQ(StringRef(" Ccc"), Toks[4].getText());
228 ASSERT_EQ(tok::newline, Toks[5].getKind());
230 ASSERT_EQ(tok::text, Toks[6].getKind());
231 ASSERT_EQ(StringRef(" ! Ddd"), Toks[6].getText());
232 ASSERT_EQ(tok::newline, Toks[7].getKind());
234 ASSERT_EQ(tok::text, Toks[8].getKind());
235 ASSERT_EQ(StringRef(" Eee"), Toks[8].getText());
236 ASSERT_EQ(tok::newline, Toks[9].getKind());
238 ASSERT_EQ(tok::text, Toks[10].getKind());
239 ASSERT_EQ(StringRef("* Fff"), Toks[10].getText());
240 ASSERT_EQ(tok::newline, Toks[11].getKind());
242 ASSERT_EQ(tok::text, Toks[12].getKind());
243 ASSERT_EQ(StringRef(" "), Toks[12].getText());
245 ASSERT_EQ(tok::newline, Toks[13].getKind());
246 ASSERT_EQ(tok::newline, Toks[14].getKind());
249 // A command marker followed by comment end.
250 TEST_F(CommentLexerTest, DoxygenCommand1) {
251 const char *Sources[] = { "//@", "///@", "//!@" };
252 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
253 std::vector<Token> Toks;
255 lexString(Sources[i], Toks);
257 ASSERT_EQ(2U, Toks.size());
259 ASSERT_EQ(tok::text, Toks[0].getKind());
260 ASSERT_EQ(StringRef("@"), Toks[0].getText());
262 ASSERT_EQ(tok::newline, Toks[1].getKind());
266 // A command marker followed by comment end.
267 TEST_F(CommentLexerTest, DoxygenCommand2) {
268 const char *Sources[] = { "/*@*/", "/**@*/", "/*!@*/"};
269 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
270 std::vector<Token> Toks;
272 lexString(Sources[i], Toks);
274 ASSERT_EQ(3U, Toks.size());
276 ASSERT_EQ(tok::text, Toks[0].getKind());
277 ASSERT_EQ(StringRef("@"), Toks[0].getText());
279 ASSERT_EQ(tok::newline, Toks[1].getKind());
280 ASSERT_EQ(tok::newline, Toks[2].getKind());
284 // A command marker followed by comment end.
285 TEST_F(CommentLexerTest, DoxygenCommand3) {
286 const char *Sources[] = { "/*\\*/", "/**\\*/" };
287 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
288 std::vector<Token> Toks;
290 lexString(Sources[i], Toks);
292 ASSERT_EQ(3U, Toks.size());
294 ASSERT_EQ(tok::text, Toks[0].getKind());
295 ASSERT_EQ(StringRef("\\"), Toks[0].getText());
297 ASSERT_EQ(tok::newline, Toks[1].getKind());
298 ASSERT_EQ(tok::newline, Toks[2].getKind());
302 // Doxygen escape sequences.
303 TEST_F(CommentLexerTest, DoxygenCommand4) {
304 const char *Sources[] = {
305 "/// \\\\ \\@ \\& \\$ \\# \\< \\> \\% \\\" \\. \\::",
306 "/// @\\ @@ @& @$ @# @< @> @% @\" @. @::"
308 const char *Text[] = {
310 "\\", " ", "@", " ", "&", " ", "$", " ", "#", " ",
311 "<", " ", ">", " ", "%", " ", "\"", " ", ".", " ",
315 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
316 std::vector<Token> Toks;
318 lexString(Sources[i], Toks);
320 ASSERT_EQ(array_lengthof(Text), Toks.size());
322 for (size_t j = 0, e = Toks.size(); j != e; j++) {
323 if(Toks[j].is(tok::text))
324 ASSERT_EQ(StringRef(Text[j]), Toks[j].getText())
330 // A command marker followed by a non-letter that is not a part of an escape
332 TEST_F(CommentLexerTest, DoxygenCommand5) {
333 const char *Source = "/// \\^ \\0";
334 std::vector<Token> Toks;
336 lexString(Source, Toks);
338 ASSERT_EQ(6U, Toks.size());
340 ASSERT_EQ(tok::text, Toks[0].getKind());
341 ASSERT_EQ(StringRef(" "), Toks[0].getText());
343 ASSERT_EQ(tok::text, Toks[1].getKind());
344 ASSERT_EQ(StringRef("\\"), Toks[1].getText());
346 ASSERT_EQ(tok::text, Toks[2].getKind());
347 ASSERT_EQ(StringRef("^ "), Toks[2].getText());
349 ASSERT_EQ(tok::text, Toks[3].getKind());
350 ASSERT_EQ(StringRef("\\"), Toks[3].getText());
352 ASSERT_EQ(tok::text, Toks[4].getKind());
353 ASSERT_EQ(StringRef("0"), Toks[4].getText());
355 ASSERT_EQ(tok::newline, Toks[5].getKind());
358 TEST_F(CommentLexerTest, DoxygenCommand6) {
359 const char *Source = "/// \\brief Aaa.";
360 std::vector<Token> Toks;
362 lexString(Source, Toks);
364 ASSERT_EQ(4U, Toks.size());
366 ASSERT_EQ(tok::text, Toks[0].getKind());
367 ASSERT_EQ(StringRef(" "), Toks[0].getText());
369 ASSERT_EQ(tok::backslash_command, Toks[1].getKind());
370 ASSERT_EQ(StringRef("brief"), getCommandName(Toks[1]));
372 ASSERT_EQ(tok::text, Toks[2].getKind());
373 ASSERT_EQ(StringRef(" Aaa."), Toks[2].getText());
375 ASSERT_EQ(tok::newline, Toks[3].getKind());
378 TEST_F(CommentLexerTest, DoxygenCommand7) {
379 const char *Source = "/// \\em\\em \\em\t\\em\n";
380 std::vector<Token> Toks;
382 lexString(Source, Toks);
384 ASSERT_EQ(8U, Toks.size());
386 ASSERT_EQ(tok::text, Toks[0].getKind());
387 ASSERT_EQ(StringRef(" "), Toks[0].getText());
389 ASSERT_EQ(tok::backslash_command, Toks[1].getKind());
390 ASSERT_EQ(StringRef("em"), getCommandName(Toks[1]));
392 ASSERT_EQ(tok::backslash_command, Toks[2].getKind());
393 ASSERT_EQ(StringRef("em"), getCommandName(Toks[2]));
395 ASSERT_EQ(tok::text, Toks[3].getKind());
396 ASSERT_EQ(StringRef(" "), Toks[3].getText());
398 ASSERT_EQ(tok::backslash_command, Toks[4].getKind());
399 ASSERT_EQ(StringRef("em"), getCommandName(Toks[4]));
401 ASSERT_EQ(tok::text, Toks[5].getKind());
402 ASSERT_EQ(StringRef("\t"), Toks[5].getText());
404 ASSERT_EQ(tok::backslash_command, Toks[6].getKind());
405 ASSERT_EQ(StringRef("em"), getCommandName(Toks[6]));
407 ASSERT_EQ(tok::newline, Toks[7].getKind());
410 TEST_F(CommentLexerTest, DoxygenCommand8) {
411 const char *Source = "/// @em@em @em\t@em\n";
412 std::vector<Token> Toks;
414 lexString(Source, Toks);
416 ASSERT_EQ(8U, Toks.size());
418 ASSERT_EQ(tok::text, Toks[0].getKind());
419 ASSERT_EQ(StringRef(" "), Toks[0].getText());
421 ASSERT_EQ(tok::at_command, Toks[1].getKind());
422 ASSERT_EQ(StringRef("em"), getCommandName(Toks[1]));
424 ASSERT_EQ(tok::at_command, Toks[2].getKind());
425 ASSERT_EQ(StringRef("em"), getCommandName(Toks[2]));
427 ASSERT_EQ(tok::text, Toks[3].getKind());
428 ASSERT_EQ(StringRef(" "), Toks[3].getText());
430 ASSERT_EQ(tok::at_command, Toks[4].getKind());
431 ASSERT_EQ(StringRef("em"), getCommandName(Toks[4]));
433 ASSERT_EQ(tok::text, Toks[5].getKind());
434 ASSERT_EQ(StringRef("\t"), Toks[5].getText());
436 ASSERT_EQ(tok::at_command, Toks[6].getKind());
437 ASSERT_EQ(StringRef("em"), getCommandName(Toks[6]));
439 ASSERT_EQ(tok::newline, Toks[7].getKind());
442 TEST_F(CommentLexerTest, DoxygenCommand9) {
443 const char *Source = "/// \\aaa\\bbb \\ccc\t\\ddd\n";
444 std::vector<Token> Toks;
446 lexString(Source, Toks);
448 ASSERT_EQ(8U, Toks.size());
450 ASSERT_EQ(tok::text, Toks[0].getKind());
451 ASSERT_EQ(StringRef(" "), Toks[0].getText());
453 ASSERT_EQ(tok::unknown_command, Toks[1].getKind());
454 ASSERT_EQ(StringRef("aaa"), Toks[1].getUnknownCommandName());
456 ASSERT_EQ(tok::unknown_command, Toks[2].getKind());
457 ASSERT_EQ(StringRef("bbb"), Toks[2].getUnknownCommandName());
459 ASSERT_EQ(tok::text, Toks[3].getKind());
460 ASSERT_EQ(StringRef(" "), Toks[3].getText());
462 ASSERT_EQ(tok::unknown_command, Toks[4].getKind());
463 ASSERT_EQ(StringRef("ccc"), Toks[4].getUnknownCommandName());
465 ASSERT_EQ(tok::text, Toks[5].getKind());
466 ASSERT_EQ(StringRef("\t"), Toks[5].getText());
468 ASSERT_EQ(tok::unknown_command, Toks[6].getKind());
469 ASSERT_EQ(StringRef("ddd"), Toks[6].getUnknownCommandName());
471 ASSERT_EQ(tok::newline, Toks[7].getKind());
474 TEST_F(CommentLexerTest, DoxygenCommand10) {
475 const char *Source = "// \\c\n";
476 std::vector<Token> Toks;
478 lexString(Source, Toks);
480 ASSERT_EQ(3U, Toks.size());
482 ASSERT_EQ(tok::text, Toks[0].getKind());
483 ASSERT_EQ(StringRef(" "), Toks[0].getText());
485 ASSERT_EQ(tok::backslash_command, Toks[1].getKind());
486 ASSERT_EQ(StringRef("c"), getCommandName(Toks[1]));
488 ASSERT_EQ(tok::newline, Toks[2].getKind());
491 TEST_F(CommentLexerTest, RegisterCustomBlockCommand) {
493 "/// \\NewBlockCommand Aaa.\n"
494 "/// @NewBlockCommand Aaa.\n";
496 Traits.registerBlockCommand(StringRef("NewBlockCommand"));
498 std::vector<Token> Toks;
500 lexString(Source, Toks);
502 ASSERT_EQ(8U, Toks.size());
504 ASSERT_EQ(tok::text, Toks[0].getKind());
505 ASSERT_EQ(StringRef(" "), Toks[0].getText());
507 ASSERT_EQ(tok::backslash_command, Toks[1].getKind());
508 ASSERT_EQ(StringRef("NewBlockCommand"), getCommandName(Toks[1]));
510 ASSERT_EQ(tok::text, Toks[2].getKind());
511 ASSERT_EQ(StringRef(" Aaa."), Toks[2].getText());
513 ASSERT_EQ(tok::newline, Toks[3].getKind());
515 ASSERT_EQ(tok::text, Toks[4].getKind());
516 ASSERT_EQ(StringRef(" "), Toks[4].getText());
518 ASSERT_EQ(tok::at_command, Toks[5].getKind());
519 ASSERT_EQ(StringRef("NewBlockCommand"), getCommandName(Toks[5]));
521 ASSERT_EQ(tok::text, Toks[6].getKind());
522 ASSERT_EQ(StringRef(" Aaa."), Toks[6].getText());
524 ASSERT_EQ(tok::newline, Toks[7].getKind());
527 TEST_F(CommentLexerTest, RegisterMultipleBlockCommands) {
531 "/// \\Blech quux=corge\n";
533 Traits.registerBlockCommand(StringRef("Foo"));
534 Traits.registerBlockCommand(StringRef("Bar"));
535 Traits.registerBlockCommand(StringRef("Blech"));
537 std::vector<Token> Toks;
539 lexString(Source, Toks);
541 ASSERT_EQ(11U, Toks.size());
543 ASSERT_EQ(tok::text, Toks[0].getKind());
544 ASSERT_EQ(StringRef(" "), Toks[0].getText());
546 ASSERT_EQ(tok::backslash_command, Toks[1].getKind());
547 ASSERT_EQ(StringRef("Foo"), getCommandName(Toks[1]));
549 ASSERT_EQ(tok::newline, Toks[2].getKind());
551 ASSERT_EQ(tok::text, Toks[3].getKind());
552 ASSERT_EQ(StringRef(" "), Toks[3].getText());
554 ASSERT_EQ(tok::backslash_command, Toks[4].getKind());
555 ASSERT_EQ(StringRef("Bar"), getCommandName(Toks[4]));
557 ASSERT_EQ(tok::text, Toks[5].getKind());
558 ASSERT_EQ(StringRef(" Baz"), Toks[5].getText());
560 ASSERT_EQ(tok::newline, Toks[6].getKind());
562 ASSERT_EQ(tok::text, Toks[7].getKind());
563 ASSERT_EQ(StringRef(" "), Toks[7].getText());
565 ASSERT_EQ(tok::backslash_command, Toks[8].getKind());
566 ASSERT_EQ(StringRef("Blech"), getCommandName(Toks[8]));
568 ASSERT_EQ(tok::text, Toks[9].getKind());
569 ASSERT_EQ(StringRef(" quux=corge"), Toks[9].getText());
571 ASSERT_EQ(tok::newline, Toks[10].getKind());
574 // Empty verbatim block.
575 TEST_F(CommentLexerTest, VerbatimBlock1) {
576 const char *Sources[] = {
577 "/// \\verbatim\\endverbatim\n//",
578 "/** \\verbatim\\endverbatim*/"
581 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
582 std::vector<Token> Toks;
584 lexString(Sources[i], Toks);
586 ASSERT_EQ(5U, Toks.size());
588 ASSERT_EQ(tok::text, Toks[0].getKind());
589 ASSERT_EQ(StringRef(" "), Toks[0].getText());
591 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
592 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[1]));
594 ASSERT_EQ(tok::verbatim_block_end, Toks[2].getKind());
595 ASSERT_EQ(StringRef("endverbatim"), getVerbatimBlockName(Toks[2]));
597 ASSERT_EQ(tok::newline, Toks[3].getKind());
598 ASSERT_EQ(tok::newline, Toks[4].getKind());
602 // Empty verbatim block without an end command.
603 TEST_F(CommentLexerTest, VerbatimBlock2) {
604 const char *Source = "/// \\verbatim";
606 std::vector<Token> Toks;
608 lexString(Source, Toks);
610 ASSERT_EQ(3U, Toks.size());
612 ASSERT_EQ(tok::text, Toks[0].getKind());
613 ASSERT_EQ(StringRef(" "), Toks[0].getText());
615 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
616 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[1]));
618 ASSERT_EQ(tok::newline, Toks[2].getKind());
621 // Empty verbatim block without an end command.
622 TEST_F(CommentLexerTest, VerbatimBlock3) {
623 const char *Source = "/** \\verbatim*/";
625 std::vector<Token> Toks;
627 lexString(Source, Toks);
629 ASSERT_EQ(4U, Toks.size());
631 ASSERT_EQ(tok::text, Toks[0].getKind());
632 ASSERT_EQ(StringRef(" "), Toks[0].getText());
634 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
635 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[1]));
637 ASSERT_EQ(tok::newline, Toks[2].getKind());
638 ASSERT_EQ(tok::newline, Toks[3].getKind());
641 // Single-line verbatim block.
642 TEST_F(CommentLexerTest, VerbatimBlock4) {
643 const char *Sources[] = {
644 "/// Meow \\verbatim aaa \\endverbatim\n//",
645 "/** Meow \\verbatim aaa \\endverbatim*/"
648 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
649 std::vector<Token> Toks;
651 lexString(Sources[i], Toks);
653 ASSERT_EQ(6U, Toks.size());
655 ASSERT_EQ(tok::text, Toks[0].getKind());
656 ASSERT_EQ(StringRef(" Meow "), Toks[0].getText());
658 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
659 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[1]));
661 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
662 ASSERT_EQ(StringRef(" aaa "), Toks[2].getVerbatimBlockText());
664 ASSERT_EQ(tok::verbatim_block_end, Toks[3].getKind());
665 ASSERT_EQ(StringRef("endverbatim"), getVerbatimBlockName(Toks[3]));
667 ASSERT_EQ(tok::newline, Toks[4].getKind());
668 ASSERT_EQ(tok::newline, Toks[5].getKind());
672 // Single-line verbatim block without an end command.
673 TEST_F(CommentLexerTest, VerbatimBlock5) {
674 const char *Sources[] = {
675 "/// Meow \\verbatim aaa \n//",
676 "/** Meow \\verbatim aaa */"
679 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
680 std::vector<Token> Toks;
682 lexString(Sources[i], Toks);
684 ASSERT_EQ(5U, Toks.size());
686 ASSERT_EQ(tok::text, Toks[0].getKind());
687 ASSERT_EQ(StringRef(" Meow "), Toks[0].getText());
689 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
690 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[1]));
692 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
693 ASSERT_EQ(StringRef(" aaa "), Toks[2].getVerbatimBlockText());
695 ASSERT_EQ(tok::newline, Toks[3].getKind());
696 ASSERT_EQ(tok::newline, Toks[4].getKind());
700 TEST_F(CommentLexerTest, VerbatimBlock6) {
706 "// \\endverbatim\n";
708 std::vector<Token> Toks;
710 lexString(Source, Toks);
712 ASSERT_EQ(10U, Toks.size());
714 ASSERT_EQ(tok::text, Toks[0].getKind());
715 ASSERT_EQ(StringRef(" "), Toks[0].getText());
717 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
718 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[1]));
720 ASSERT_EQ(tok::newline, Toks[2].getKind());
722 ASSERT_EQ(tok::verbatim_block_line, Toks[3].getKind());
723 ASSERT_EQ(StringRef(" Aaa"), Toks[3].getVerbatimBlockText());
725 ASSERT_EQ(tok::newline, Toks[4].getKind());
727 ASSERT_EQ(tok::newline, Toks[5].getKind());
729 ASSERT_EQ(tok::verbatim_block_line, Toks[6].getKind());
730 ASSERT_EQ(StringRef(" Bbb"), Toks[6].getVerbatimBlockText());
732 ASSERT_EQ(tok::newline, Toks[7].getKind());
734 ASSERT_EQ(tok::verbatim_block_end, Toks[8].getKind());
735 ASSERT_EQ(StringRef("endverbatim"), getVerbatimBlockName(Toks[8]));
737 ASSERT_EQ(tok::newline, Toks[9].getKind());
740 TEST_F(CommentLexerTest, VerbatimBlock7) {
749 std::vector<Token> Toks;
751 lexString(Source, Toks);
753 ASSERT_EQ(10U, Toks.size());
755 ASSERT_EQ(tok::text, Toks[0].getKind());
756 ASSERT_EQ(StringRef(" "), Toks[0].getText());
758 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
759 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[1]));
761 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
762 ASSERT_EQ(StringRef(" Aaa"), Toks[2].getVerbatimBlockText());
764 ASSERT_EQ(tok::verbatim_block_line, Toks[3].getKind());
765 ASSERT_EQ(StringRef(""), Toks[3].getVerbatimBlockText());
767 ASSERT_EQ(tok::verbatim_block_line, Toks[4].getKind());
768 ASSERT_EQ(StringRef(" Bbb"), Toks[4].getVerbatimBlockText());
770 ASSERT_EQ(tok::verbatim_block_end, Toks[5].getKind());
771 ASSERT_EQ(StringRef("endverbatim"), getVerbatimBlockName(Toks[5]));
773 ASSERT_EQ(tok::newline, Toks[6].getKind());
775 ASSERT_EQ(tok::text, Toks[7].getKind());
776 ASSERT_EQ(StringRef(" "), Toks[7].getText());
778 ASSERT_EQ(tok::newline, Toks[8].getKind());
779 ASSERT_EQ(tok::newline, Toks[9].getKind());
782 // Complex test for verbatim blocks.
783 TEST_F(CommentLexerTest, VerbatimBlock8) {
785 "/* Meow \\verbatim aaa\\$\\@\n"
788 "ddd \\endverbatim Blah \\verbatim eee\n"
789 "\\endverbatim BlahBlah*/";
790 std::vector<Token> Toks;
792 lexString(Source, Toks);
794 ASSERT_EQ(14U, Toks.size());
796 ASSERT_EQ(tok::text, Toks[0].getKind());
797 ASSERT_EQ(StringRef(" Meow "), Toks[0].getText());
799 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
800 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[1]));
802 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
803 ASSERT_EQ(StringRef(" aaa\\$\\@"), Toks[2].getVerbatimBlockText());
805 ASSERT_EQ(tok::verbatim_block_line, Toks[3].getKind());
806 ASSERT_EQ(StringRef("bbb \\endverbati"), Toks[3].getVerbatimBlockText());
808 ASSERT_EQ(tok::verbatim_block_line, Toks[4].getKind());
809 ASSERT_EQ(StringRef("ccc"), Toks[4].getVerbatimBlockText());
811 ASSERT_EQ(tok::verbatim_block_line, Toks[5].getKind());
812 ASSERT_EQ(StringRef("ddd "), Toks[5].getVerbatimBlockText());
814 ASSERT_EQ(tok::verbatim_block_end, Toks[6].getKind());
815 ASSERT_EQ(StringRef("endverbatim"), getVerbatimBlockName(Toks[6]));
817 ASSERT_EQ(tok::text, Toks[7].getKind());
818 ASSERT_EQ(StringRef(" Blah "), Toks[7].getText());
820 ASSERT_EQ(tok::verbatim_block_begin, Toks[8].getKind());
821 ASSERT_EQ(StringRef("verbatim"), getVerbatimBlockName(Toks[8]));
823 ASSERT_EQ(tok::verbatim_block_line, Toks[9].getKind());
824 ASSERT_EQ(StringRef(" eee"), Toks[9].getVerbatimBlockText());
826 ASSERT_EQ(tok::verbatim_block_end, Toks[10].getKind());
827 ASSERT_EQ(StringRef("endverbatim"), getVerbatimBlockName(Toks[10]));
829 ASSERT_EQ(tok::text, Toks[11].getKind());
830 ASSERT_EQ(StringRef(" BlahBlah"), Toks[11].getText());
832 ASSERT_EQ(tok::newline, Toks[12].getKind());
833 ASSERT_EQ(tok::newline, Toks[13].getKind());
836 // LaTeX verbatim blocks.
837 TEST_F(CommentLexerTest, VerbatimBlock9) {
839 "/// \\f$ Aaa \\f$ \\f[ Bbb \\f] \\f{ Ccc \\f}";
840 std::vector<Token> Toks;
842 lexString(Source, Toks);
844 ASSERT_EQ(13U, Toks.size());
846 ASSERT_EQ(tok::text, Toks[0].getKind());
847 ASSERT_EQ(StringRef(" "), Toks[0].getText());
849 ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
850 ASSERT_EQ(StringRef("f$"), getVerbatimBlockName(Toks[1]));
852 ASSERT_EQ(tok::verbatim_block_line, Toks[2].getKind());
853 ASSERT_EQ(StringRef(" Aaa "), Toks[2].getVerbatimBlockText());
855 ASSERT_EQ(tok::verbatim_block_end, Toks[3].getKind());
856 ASSERT_EQ(StringRef("f$"), getVerbatimBlockName(Toks[3]));
858 ASSERT_EQ(tok::text, Toks[4].getKind());
859 ASSERT_EQ(StringRef(" "), Toks[4].getText());
861 ASSERT_EQ(tok::verbatim_block_begin, Toks[5].getKind());
862 ASSERT_EQ(StringRef("f["), getVerbatimBlockName(Toks[5]));
864 ASSERT_EQ(tok::verbatim_block_line, Toks[6].getKind());
865 ASSERT_EQ(StringRef(" Bbb "), Toks[6].getVerbatimBlockText());
867 ASSERT_EQ(tok::verbatim_block_end, Toks[7].getKind());
868 ASSERT_EQ(StringRef("f]"), getVerbatimBlockName(Toks[7]));
870 ASSERT_EQ(tok::text, Toks[8].getKind());
871 ASSERT_EQ(StringRef(" "), Toks[8].getText());
873 ASSERT_EQ(tok::verbatim_block_begin, Toks[9].getKind());
874 ASSERT_EQ(StringRef("f{"), getVerbatimBlockName(Toks[9]));
876 ASSERT_EQ(tok::verbatim_block_line, Toks[10].getKind());
877 ASSERT_EQ(StringRef(" Ccc "), Toks[10].getVerbatimBlockText());
879 ASSERT_EQ(tok::verbatim_block_end, Toks[11].getKind());
880 ASSERT_EQ(StringRef("f}"), getVerbatimBlockName(Toks[11]));
882 ASSERT_EQ(tok::newline, Toks[12].getKind());
885 // Empty verbatim line.
886 TEST_F(CommentLexerTest, VerbatimLine1) {
887 const char *Sources[] = {
892 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
893 std::vector<Token> Toks;
895 lexString(Sources[i], Toks);
897 ASSERT_EQ(4U, Toks.size());
899 ASSERT_EQ(tok::text, Toks[0].getKind());
900 ASSERT_EQ(StringRef(" "), Toks[0].getText());
902 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
903 ASSERT_EQ(StringRef("fn"), getVerbatimLineName(Toks[1]));
905 ASSERT_EQ(tok::newline, Toks[2].getKind());
906 ASSERT_EQ(tok::newline, Toks[3].getKind());
910 // Verbatim line with Doxygen escape sequences, which should not be expanded.
911 TEST_F(CommentLexerTest, VerbatimLine2) {
912 const char *Sources[] = {
913 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
914 "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
917 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
918 std::vector<Token> Toks;
920 lexString(Sources[i], Toks);
922 ASSERT_EQ(5U, Toks.size());
924 ASSERT_EQ(tok::text, Toks[0].getKind());
925 ASSERT_EQ(StringRef(" "), Toks[0].getText());
927 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
928 ASSERT_EQ(StringRef("fn"), getVerbatimLineName(Toks[1]));
930 ASSERT_EQ(tok::verbatim_line_text, Toks[2].getKind());
931 ASSERT_EQ(StringRef(" void *foo(const char *zzz = \"\\$\");"),
932 Toks[2].getVerbatimLineText());
934 ASSERT_EQ(tok::newline, Toks[3].getKind());
935 ASSERT_EQ(tok::newline, Toks[4].getKind());
939 // Verbatim line should not eat anything from next source line.
940 TEST_F(CommentLexerTest, VerbatimLine3) {
942 "/** \\fn void *foo(const char *zzz = \"\\$\");\n"
946 std::vector<Token> Toks;
948 lexString(Source, Toks);
950 ASSERT_EQ(9U, Toks.size());
952 ASSERT_EQ(tok::text, Toks[0].getKind());
953 ASSERT_EQ(StringRef(" "), Toks[0].getText());
955 ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
956 ASSERT_EQ(StringRef("fn"), getVerbatimLineName(Toks[1]));
958 ASSERT_EQ(tok::verbatim_line_text, Toks[2].getKind());
959 ASSERT_EQ(StringRef(" void *foo(const char *zzz = \"\\$\");"),
960 Toks[2].getVerbatimLineText());
961 ASSERT_EQ(tok::newline, Toks[3].getKind());
963 ASSERT_EQ(tok::text, Toks[4].getKind());
964 ASSERT_EQ(StringRef(" Meow"), Toks[4].getText());
965 ASSERT_EQ(tok::newline, Toks[5].getKind());
967 ASSERT_EQ(tok::text, Toks[6].getKind());
968 ASSERT_EQ(StringRef(" "), Toks[6].getText());
970 ASSERT_EQ(tok::newline, Toks[7].getKind());
971 ASSERT_EQ(tok::newline, Toks[8].getKind());
974 TEST_F(CommentLexerTest, HTML1) {
978 std::vector<Token> Toks;
980 lexString(Source, Toks);
982 ASSERT_EQ(3U, Toks.size());
984 ASSERT_EQ(tok::text, Toks[0].getKind());
985 ASSERT_EQ(StringRef(" "), Toks[0].getText());
987 ASSERT_EQ(tok::text, Toks[1].getKind());
988 ASSERT_EQ(StringRef("<"), Toks[1].getText());
990 ASSERT_EQ(tok::newline, Toks[2].getKind());
993 TEST_F(CommentLexerTest, HTML2) {
997 std::vector<Token> Toks;
999 lexString(Source, Toks);
1001 ASSERT_EQ(4U, Toks.size());
1003 ASSERT_EQ(tok::text, Toks[0].getKind());
1004 ASSERT_EQ(StringRef(" a"), Toks[0].getText());
1006 ASSERT_EQ(tok::text, Toks[1].getKind());
1007 ASSERT_EQ(StringRef("<"), Toks[1].getText());
1009 ASSERT_EQ(tok::text, Toks[2].getKind());
1010 ASSERT_EQ(StringRef("2"), Toks[2].getText());
1012 ASSERT_EQ(tok::newline, Toks[3].getKind());
1015 TEST_F(CommentLexerTest, HTML3) {
1016 const char *Source =
1019 std::vector<Token> Toks;
1021 lexString(Source, Toks);
1023 ASSERT_EQ(4U, Toks.size());
1025 ASSERT_EQ(tok::text, Toks[0].getKind());
1026 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1028 ASSERT_EQ(tok::text, Toks[1].getKind());
1029 ASSERT_EQ(StringRef("<"), Toks[1].getText());
1031 ASSERT_EQ(tok::text, Toks[2].getKind());
1032 ASSERT_EQ(StringRef(" img"), Toks[2].getText());
1034 ASSERT_EQ(tok::newline, Toks[3].getKind());
1037 TEST_F(CommentLexerTest, HTML4) {
1038 const char *Sources[] = {
1043 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1044 std::vector<Token> Toks;
1046 lexString(Sources[i], Toks);
1048 ASSERT_EQ(3U, Toks.size());
1050 ASSERT_EQ(tok::text, Toks[0].getKind());
1051 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1053 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1054 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1056 ASSERT_EQ(tok::newline, Toks[2].getKind());
1060 TEST_F(CommentLexerTest, HTML5) {
1061 const char *Source =
1064 std::vector<Token> Toks;
1066 lexString(Source, Toks);
1068 ASSERT_EQ(4U, Toks.size());
1070 ASSERT_EQ(tok::text, Toks[0].getKind());
1071 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1073 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1074 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1076 ASSERT_EQ(tok::text, Toks[2].getKind());
1077 ASSERT_EQ(StringRef("42"), Toks[2].getText());
1079 ASSERT_EQ(tok::newline, Toks[3].getKind());
1082 TEST_F(CommentLexerTest, HTML6) {
1083 const char *Source = "// <img> Meow";
1085 std::vector<Token> Toks;
1087 lexString(Source, Toks);
1089 ASSERT_EQ(5U, Toks.size());
1091 ASSERT_EQ(tok::text, Toks[0].getKind());
1092 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1094 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1095 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1097 ASSERT_EQ(tok::html_greater, Toks[2].getKind());
1099 ASSERT_EQ(tok::text, Toks[3].getKind());
1100 ASSERT_EQ(StringRef(" Meow"), Toks[3].getText());
1102 ASSERT_EQ(tok::newline, Toks[4].getKind());
1105 TEST_F(CommentLexerTest, HTML7) {
1106 const char *Source = "// <img=";
1108 std::vector<Token> Toks;
1110 lexString(Source, Toks);
1112 ASSERT_EQ(4U, Toks.size());
1114 ASSERT_EQ(tok::text, Toks[0].getKind());
1115 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1117 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1118 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1120 ASSERT_EQ(tok::text, Toks[2].getKind());
1121 ASSERT_EQ(StringRef("="), Toks[2].getText());
1123 ASSERT_EQ(tok::newline, Toks[3].getKind());
1126 TEST_F(CommentLexerTest, HTML8) {
1127 const char *Source = "// <img src=> Meow";
1129 std::vector<Token> Toks;
1131 lexString(Source, Toks);
1133 ASSERT_EQ(7U, Toks.size());
1135 ASSERT_EQ(tok::text, Toks[0].getKind());
1136 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1138 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1139 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1141 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1142 ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
1144 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1146 ASSERT_EQ(tok::html_greater, Toks[4].getKind());
1148 ASSERT_EQ(tok::text, Toks[5].getKind());
1149 ASSERT_EQ(StringRef(" Meow"), Toks[5].getText());
1151 ASSERT_EQ(tok::newline, Toks[6].getKind());
1154 TEST_F(CommentLexerTest, HTML9) {
1155 const char *Sources[] = {
1160 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1161 std::vector<Token> Toks;
1163 lexString(Sources[i], Toks);
1165 ASSERT_EQ(4U, Toks.size());
1167 ASSERT_EQ(tok::text, Toks[0].getKind());
1168 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1170 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1171 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1173 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1174 ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
1176 ASSERT_EQ(tok::newline, Toks[3].getKind());
1180 TEST_F(CommentLexerTest, HTML10) {
1181 const char *Sources[] = {
1186 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1187 std::vector<Token> Toks;
1189 lexString(Sources[i], Toks);
1191 ASSERT_EQ(5U, Toks.size());
1193 ASSERT_EQ(tok::text, Toks[0].getKind());
1194 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1196 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1197 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1199 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1200 ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
1202 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1204 ASSERT_EQ(tok::newline, Toks[4].getKind());
1208 TEST_F(CommentLexerTest, HTML11) {
1209 const char *Sources[] = {
1216 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1217 std::vector<Token> Toks;
1219 lexString(Sources[i], Toks);
1221 ASSERT_EQ(6U, Toks.size());
1223 ASSERT_EQ(tok::text, Toks[0].getKind());
1224 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1226 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1227 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1229 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1230 ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
1232 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1234 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1235 ASSERT_EQ(StringRef(""), Toks[4].getHTMLQuotedString());
1237 ASSERT_EQ(tok::newline, Toks[5].getKind());
1241 TEST_F(CommentLexerTest, HTML12) {
1242 const char *Source = "// <img src=@";
1244 std::vector<Token> Toks;
1246 lexString(Source, Toks);
1248 ASSERT_EQ(6U, Toks.size());
1250 ASSERT_EQ(tok::text, Toks[0].getKind());
1251 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1253 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1254 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1256 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1257 ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
1259 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1261 ASSERT_EQ(tok::text, Toks[4].getKind());
1262 ASSERT_EQ(StringRef("@"), Toks[4].getText());
1264 ASSERT_EQ(tok::newline, Toks[5].getKind());
1267 TEST_F(CommentLexerTest, HTML13) {
1268 const char *Sources[] = {
1269 "// <img src=\"val\\\"\\'val",
1270 "// <img src=\"val\\\"\\'val\"",
1271 "// <img src=\'val\\\"\\'val",
1272 "// <img src=\'val\\\"\\'val\'"
1275 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1276 std::vector<Token> Toks;
1278 lexString(Sources[i], Toks);
1280 ASSERT_EQ(6U, Toks.size());
1282 ASSERT_EQ(tok::text, Toks[0].getKind());
1283 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1285 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1286 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1288 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1289 ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
1291 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1293 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1294 ASSERT_EQ(StringRef("val\\\"\\'val"), Toks[4].getHTMLQuotedString());
1296 ASSERT_EQ(tok::newline, Toks[5].getKind());
1300 TEST_F(CommentLexerTest, HTML14) {
1301 const char *Sources[] = {
1302 "// <img src=\"val\\\"\\'val\">",
1303 "// <img src=\'val\\\"\\'val\'>"
1306 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1307 std::vector<Token> Toks;
1309 lexString(Sources[i], Toks);
1311 ASSERT_EQ(7U, Toks.size());
1313 ASSERT_EQ(tok::text, Toks[0].getKind());
1314 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1316 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1317 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1319 ASSERT_EQ(tok::html_ident, Toks[2].getKind());
1320 ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
1322 ASSERT_EQ(tok::html_equals, Toks[3].getKind());
1324 ASSERT_EQ(tok::html_quoted_string, Toks[4].getKind());
1325 ASSERT_EQ(StringRef("val\\\"\\'val"), Toks[4].getHTMLQuotedString());
1327 ASSERT_EQ(tok::html_greater, Toks[5].getKind());
1329 ASSERT_EQ(tok::newline, Toks[6].getKind());
1333 TEST_F(CommentLexerTest, HTML15) {
1334 const char *Sources[] = {
1339 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1340 std::vector<Token> Toks;
1342 lexString(Sources[i], Toks);
1344 ASSERT_EQ(4U, Toks.size());
1346 ASSERT_EQ(tok::text, Toks[0].getKind());
1347 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1349 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1350 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1352 ASSERT_EQ(tok::html_slash_greater, Toks[2].getKind());
1354 ASSERT_EQ(tok::newline, Toks[3].getKind());
1358 TEST_F(CommentLexerTest, HTML16) {
1359 const char *Sources[] = {
1364 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1365 std::vector<Token> Toks;
1367 lexString(Sources[i], Toks);
1369 ASSERT_EQ(5U, Toks.size());
1371 ASSERT_EQ(tok::text, Toks[0].getKind());
1372 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1374 ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
1375 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
1377 ASSERT_EQ(tok::text, Toks[2].getKind());
1378 ASSERT_EQ(StringRef("/"), Toks[2].getText());
1380 ASSERT_EQ(tok::text, Toks[3].getKind());
1381 ASSERT_EQ(StringRef(" Aaa"), Toks[3].getText());
1383 ASSERT_EQ(tok::newline, Toks[4].getKind());
1387 TEST_F(CommentLexerTest, HTML17) {
1388 const char *Source = "// </";
1390 std::vector<Token> Toks;
1392 lexString(Source, Toks);
1394 ASSERT_EQ(3U, Toks.size());
1396 ASSERT_EQ(tok::text, Toks[0].getKind());
1397 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1399 ASSERT_EQ(tok::text, Toks[1].getKind());
1400 ASSERT_EQ(StringRef("</"), Toks[1].getText());
1402 ASSERT_EQ(tok::newline, Toks[2].getKind());
1405 TEST_F(CommentLexerTest, HTML18) {
1406 const char *Source = "// </@";
1408 std::vector<Token> Toks;
1410 lexString(Source, Toks);
1412 ASSERT_EQ(4U, Toks.size());
1414 ASSERT_EQ(tok::text, Toks[0].getKind());
1415 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1417 ASSERT_EQ(tok::text, Toks[1].getKind());
1418 ASSERT_EQ(StringRef("</"), Toks[1].getText());
1420 ASSERT_EQ(tok::text, Toks[2].getKind());
1421 ASSERT_EQ(StringRef("@"), Toks[2].getText());
1423 ASSERT_EQ(tok::newline, Toks[3].getKind());
1426 TEST_F(CommentLexerTest, HTML19) {
1427 const char *Source = "// </img";
1429 std::vector<Token> Toks;
1431 lexString(Source, Toks);
1433 ASSERT_EQ(3U, Toks.size());
1435 ASSERT_EQ(tok::text, Toks[0].getKind());
1436 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1438 ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
1439 ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagEndName());
1441 ASSERT_EQ(tok::newline, Toks[2].getKind());
1444 TEST_F(CommentLexerTest, NotAKnownHTMLTag1) {
1445 const char *Source = "// <tag>";
1447 std::vector<Token> Toks;
1449 lexString(Source, Toks);
1451 ASSERT_EQ(4U, Toks.size());
1453 ASSERT_EQ(tok::text, Toks[0].getKind());
1454 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1456 ASSERT_EQ(tok::text, Toks[1].getKind());
1457 ASSERT_EQ(StringRef("<tag"), Toks[1].getText());
1459 ASSERT_EQ(tok::text, Toks[2].getKind());
1460 ASSERT_EQ(StringRef(">"), Toks[2].getText());
1462 ASSERT_EQ(tok::newline, Toks[3].getKind());
1465 TEST_F(CommentLexerTest, NotAKnownHTMLTag2) {
1466 const char *Source = "// </tag>";
1468 std::vector<Token> Toks;
1470 lexString(Source, Toks);
1472 ASSERT_EQ(4U, Toks.size());
1474 ASSERT_EQ(tok::text, Toks[0].getKind());
1475 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1477 ASSERT_EQ(tok::text, Toks[1].getKind());
1478 ASSERT_EQ(StringRef("</tag"), Toks[1].getText());
1480 ASSERT_EQ(tok::text, Toks[2].getKind());
1481 ASSERT_EQ(StringRef(">"), Toks[2].getText());
1483 ASSERT_EQ(tok::newline, Toks[3].getKind());
1486 TEST_F(CommentLexerTest, HTMLCharacterReferences1) {
1487 const char *Source = "// &";
1489 std::vector<Token> Toks;
1491 lexString(Source, Toks);
1493 ASSERT_EQ(3U, Toks.size());
1495 ASSERT_EQ(tok::text, Toks[0].getKind());
1496 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1498 ASSERT_EQ(tok::text, Toks[1].getKind());
1499 ASSERT_EQ(StringRef("&"), Toks[1].getText());
1501 ASSERT_EQ(tok::newline, Toks[2].getKind());
1504 TEST_F(CommentLexerTest, HTMLCharacterReferences2) {
1505 const char *Source = "// &!";
1507 std::vector<Token> Toks;
1509 lexString(Source, Toks);
1511 ASSERT_EQ(4U, Toks.size());
1513 ASSERT_EQ(tok::text, Toks[0].getKind());
1514 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1516 ASSERT_EQ(tok::text, Toks[1].getKind());
1517 ASSERT_EQ(StringRef("&"), Toks[1].getText());
1519 ASSERT_EQ(tok::text, Toks[2].getKind());
1520 ASSERT_EQ(StringRef("!"), Toks[2].getText());
1522 ASSERT_EQ(tok::newline, Toks[3].getKind());
1525 TEST_F(CommentLexerTest, HTMLCharacterReferences3) {
1526 const char *Source = "// &";
1528 std::vector<Token> Toks;
1530 lexString(Source, Toks);
1532 ASSERT_EQ(3U, Toks.size());
1534 ASSERT_EQ(tok::text, Toks[0].getKind());
1535 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1537 ASSERT_EQ(tok::text, Toks[1].getKind());
1538 ASSERT_EQ(StringRef("&"), Toks[1].getText());
1540 ASSERT_EQ(tok::newline, Toks[2].getKind());
1543 TEST_F(CommentLexerTest, HTMLCharacterReferences4) {
1544 const char *Source = "// &!";
1546 std::vector<Token> Toks;
1548 lexString(Source, Toks);
1550 ASSERT_EQ(4U, Toks.size());
1552 ASSERT_EQ(tok::text, Toks[0].getKind());
1553 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1555 ASSERT_EQ(tok::text, Toks[1].getKind());
1556 ASSERT_EQ(StringRef("&"), Toks[1].getText());
1558 ASSERT_EQ(tok::text, Toks[2].getKind());
1559 ASSERT_EQ(StringRef("!"), Toks[2].getText());
1561 ASSERT_EQ(tok::newline, Toks[3].getKind());
1564 TEST_F(CommentLexerTest, HTMLCharacterReferences5) {
1565 const char *Source = "// &#";
1567 std::vector<Token> Toks;
1569 lexString(Source, Toks);
1571 ASSERT_EQ(3U, Toks.size());
1573 ASSERT_EQ(tok::text, Toks[0].getKind());
1574 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1576 ASSERT_EQ(tok::text, Toks[1].getKind());
1577 ASSERT_EQ(StringRef("&#"), Toks[1].getText());
1579 ASSERT_EQ(tok::newline, Toks[2].getKind());
1582 TEST_F(CommentLexerTest, HTMLCharacterReferences6) {
1583 const char *Source = "// &#a";
1585 std::vector<Token> Toks;
1587 lexString(Source, Toks);
1589 ASSERT_EQ(4U, Toks.size());
1591 ASSERT_EQ(tok::text, Toks[0].getKind());
1592 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1594 ASSERT_EQ(tok::text, Toks[1].getKind());
1595 ASSERT_EQ(StringRef("&#"), Toks[1].getText());
1597 ASSERT_EQ(tok::text, Toks[2].getKind());
1598 ASSERT_EQ(StringRef("a"), Toks[2].getText());
1600 ASSERT_EQ(tok::newline, Toks[3].getKind());
1603 TEST_F(CommentLexerTest, HTMLCharacterReferences7) {
1604 const char *Source = "// *";
1606 std::vector<Token> Toks;
1608 lexString(Source, Toks);
1610 ASSERT_EQ(3U, Toks.size());
1612 ASSERT_EQ(tok::text, Toks[0].getKind());
1613 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1615 ASSERT_EQ(tok::text, Toks[1].getKind());
1616 ASSERT_EQ(StringRef("*"), Toks[1].getText());
1618 ASSERT_EQ(tok::newline, Toks[2].getKind());
1621 TEST_F(CommentLexerTest, HTMLCharacterReferences8) {
1622 const char *Source = "// *a";
1624 std::vector<Token> Toks;
1626 lexString(Source, Toks);
1628 ASSERT_EQ(4U, Toks.size());
1630 ASSERT_EQ(tok::text, Toks[0].getKind());
1631 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1633 ASSERT_EQ(tok::text, Toks[1].getKind());
1634 ASSERT_EQ(StringRef("*"), Toks[1].getText());
1636 ASSERT_EQ(tok::text, Toks[2].getKind());
1637 ASSERT_EQ(StringRef("a"), Toks[2].getText());
1639 ASSERT_EQ(tok::newline, Toks[3].getKind());
1642 TEST_F(CommentLexerTest, HTMLCharacterReferences9) {
1643 const char *Source = "// &#x";
1645 std::vector<Token> Toks;
1647 lexString(Source, Toks);
1649 ASSERT_EQ(3U, Toks.size());
1651 ASSERT_EQ(tok::text, Toks[0].getKind());
1652 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1654 ASSERT_EQ(tok::text, Toks[1].getKind());
1655 ASSERT_EQ(StringRef("&#x"), Toks[1].getText());
1657 ASSERT_EQ(tok::newline, Toks[2].getKind());
1660 TEST_F(CommentLexerTest, HTMLCharacterReferences10) {
1661 const char *Source = "// &#xz";
1663 std::vector<Token> Toks;
1665 lexString(Source, Toks);
1667 ASSERT_EQ(4U, Toks.size());
1669 ASSERT_EQ(tok::text, Toks[0].getKind());
1670 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1672 ASSERT_EQ(tok::text, Toks[1].getKind());
1673 ASSERT_EQ(StringRef("&#x"), Toks[1].getText());
1675 ASSERT_EQ(tok::text, Toks[2].getKind());
1676 ASSERT_EQ(StringRef("z"), Toks[2].getText());
1678 ASSERT_EQ(tok::newline, Toks[3].getKind());
1681 TEST_F(CommentLexerTest, HTMLCharacterReferences11) {
1682 const char *Source = "// «";
1684 std::vector<Token> Toks;
1686 lexString(Source, Toks);
1688 ASSERT_EQ(3U, Toks.size());
1690 ASSERT_EQ(tok::text, Toks[0].getKind());
1691 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1693 ASSERT_EQ(tok::text, Toks[1].getKind());
1694 ASSERT_EQ(StringRef("«"), Toks[1].getText());
1696 ASSERT_EQ(tok::newline, Toks[2].getKind());
1699 TEST_F(CommentLexerTest, HTMLCharacterReferences12) {
1700 const char *Source = "// «z";
1702 std::vector<Token> Toks;
1704 lexString(Source, Toks);
1706 ASSERT_EQ(4U, Toks.size());
1708 ASSERT_EQ(tok::text, Toks[0].getKind());
1709 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1711 ASSERT_EQ(tok::text, Toks[1].getKind());
1712 ASSERT_EQ(StringRef("«"), Toks[1].getText());
1714 ASSERT_EQ(tok::text, Toks[2].getKind());
1715 ASSERT_EQ(StringRef("z"), Toks[2].getText());
1717 ASSERT_EQ(tok::newline, Toks[3].getKind());
1720 TEST_F(CommentLexerTest, HTMLCharacterReferences13) {
1721 const char *Source = "// &";
1723 std::vector<Token> Toks;
1725 lexString(Source, Toks);
1727 ASSERT_EQ(3U, Toks.size());
1729 ASSERT_EQ(tok::text, Toks[0].getKind());
1730 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1732 ASSERT_EQ(tok::text, Toks[1].getKind());
1733 ASSERT_EQ(StringRef("&"), Toks[1].getText());
1735 ASSERT_EQ(tok::newline, Toks[2].getKind());
1738 TEST_F(CommentLexerTest, HTMLCharacterReferences14) {
1739 const char *Source = "// &<";
1741 std::vector<Token> Toks;
1743 lexString(Source, Toks);
1745 ASSERT_EQ(4U, Toks.size());
1747 ASSERT_EQ(tok::text, Toks[0].getKind());
1748 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1750 ASSERT_EQ(tok::text, Toks[1].getKind());
1751 ASSERT_EQ(StringRef("&"), Toks[1].getText());
1753 ASSERT_EQ(tok::text, Toks[2].getKind());
1754 ASSERT_EQ(StringRef("<"), Toks[2].getText());
1756 ASSERT_EQ(tok::newline, Toks[3].getKind());
1759 TEST_F(CommentLexerTest, HTMLCharacterReferences15) {
1760 const char *Source = "// & meow";
1762 std::vector<Token> Toks;
1764 lexString(Source, Toks);
1766 ASSERT_EQ(4U, Toks.size());
1768 ASSERT_EQ(tok::text, Toks[0].getKind());
1769 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1771 ASSERT_EQ(tok::text, Toks[1].getKind());
1772 ASSERT_EQ(StringRef("&"), Toks[1].getText());
1774 ASSERT_EQ(tok::text, Toks[2].getKind());
1775 ASSERT_EQ(StringRef(" meow"), Toks[2].getText());
1777 ASSERT_EQ(tok::newline, Toks[3].getKind());
1780 TEST_F(CommentLexerTest, HTMLCharacterReferences16) {
1781 const char *Sources[] = {
1788 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1789 std::vector<Token> Toks;
1791 lexString(Sources[i], Toks);
1793 ASSERT_EQ(3U, Toks.size());
1795 ASSERT_EQ(tok::text, Toks[0].getKind());
1796 ASSERT_EQ(StringRef(" "), Toks[0].getText());
1798 ASSERT_EQ(tok::text, Toks[1].getKind());
1799 ASSERT_EQ(StringRef("="), Toks[1].getText());
1801 ASSERT_EQ(tok::newline, Toks[2].getKind());
1805 TEST_F(CommentLexerTest, MultipleComments) {
1806 const char *Source =
1813 std::vector<Token> Toks;
1815 lexString(Source, Toks);
1817 ASSERT_EQ(12U, Toks.size());
1819 ASSERT_EQ(tok::text, Toks[0].getKind());
1820 ASSERT_EQ(StringRef(" Aaa"), Toks[0].getText());
1821 ASSERT_EQ(tok::newline, Toks[1].getKind());
1823 ASSERT_EQ(tok::text, Toks[2].getKind());
1824 ASSERT_EQ(StringRef(" Bbb"), Toks[2].getText());
1825 ASSERT_EQ(tok::newline, Toks[3].getKind());
1827 ASSERT_EQ(tok::text, Toks[4].getKind());
1828 ASSERT_EQ(StringRef(" Ccc"), Toks[4].getText());
1829 ASSERT_EQ(tok::newline, Toks[5].getKind());
1831 ASSERT_EQ(tok::text, Toks[6].getKind());
1832 ASSERT_EQ(StringRef(" Ddd"), Toks[6].getText());
1833 ASSERT_EQ(tok::newline, Toks[7].getKind());
1834 ASSERT_EQ(tok::newline, Toks[8].getKind());
1836 ASSERT_EQ(tok::text, Toks[9].getKind());
1837 ASSERT_EQ(StringRef(" Eee"), Toks[9].getText());
1839 ASSERT_EQ(tok::newline, Toks[10].getKind());
1840 ASSERT_EQ(tok::newline, Toks[11].getKind());
1843 } // end namespace comments
1844 } // end namespace clang