1 //===- unittests/AST/CommentParser.cpp ------ Comment parser 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/AST/CommentParser.h" 11 #include "clang/AST/Comment.h" 12 #include "clang/AST/CommentCommandTraits.h" 13 #include "clang/AST/CommentLexer.h" 14 #include "clang/AST/CommentSema.h" 15 #include "clang/Basic/CommentOptions.h" 16 #include "clang/Basic/Diagnostic.h" 17 #include "clang/Basic/DiagnosticOptions.h" 18 #include "clang/Basic/FileManager.h" 19 #include "clang/Basic/SourceManager.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/Support/Allocator.h" 22 #include "gtest/gtest.h" 23 #include <vector> 24 25 using namespace llvm; 26 using namespace clang; 27 28 namespace clang { 29 namespace comments { 30 31 namespace { 32 33 const bool DEBUG = true; 34 35 class CommentParserTest : public ::testing::Test { 36 protected: 37 CommentParserTest() 38 : FileMgr(FileMgrOpts), 39 DiagID(new DiagnosticIDs()), 40 Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()), 41 SourceMgr(Diags, FileMgr), 42 Traits(Allocator, CommentOptions()) { 43 } 44 45 FileSystemOptions FileMgrOpts; 46 FileManager FileMgr; 47 IntrusiveRefCntPtr<DiagnosticIDs> DiagID; 48 DiagnosticsEngine Diags; 49 SourceManager SourceMgr; 50 llvm::BumpPtrAllocator Allocator; 51 CommandTraits Traits; 52 53 FullComment *parseString(const char *Source); 54 }; 55 56 FullComment *CommentParserTest::parseString(const char *Source) { 57 MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source); 58 FileID File = SourceMgr.createFileIDForMemBuffer(Buf); 59 SourceLocation Begin = SourceMgr.getLocForStartOfFile(File); 60 61 Lexer L(Allocator, Traits, Begin, Source, Source + strlen(Source)); 62 63 Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ NULL); 64 Parser P(L, S, Allocator, SourceMgr, Diags, Traits); 65 FullComment *FC = P.parseFullComment(); 66 67 if (DEBUG) { 68 llvm::errs() << "=== Source:\n" << Source << "\n=== AST:\n"; 69 FC->dump(llvm::errs(), &Traits, &SourceMgr); 70 } 71 72 Token Tok; 73 L.lex(Tok); 74 if (Tok.is(tok::eof)) 75 return FC; 76 else 77 return NULL; 78 } 79 80 ::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) { 81 if (!C) 82 return ::testing::AssertionFailure() << "Comment is NULL"; 83 84 if (Count != C->child_count()) 85 return ::testing::AssertionFailure() 86 << "Count = " << Count 87 << ", child_count = " << C->child_count(); 88 89 return ::testing::AssertionSuccess(); 90 } 91 92 template <typename T> 93 ::testing::AssertionResult GetChildAt(const Comment *C, 94 size_t Idx, 95 T *&Child) { 96 if (!C) 97 return ::testing::AssertionFailure() << "Comment is NULL"; 98 99 if (Idx >= C->child_count()) 100 return ::testing::AssertionFailure() 101 << "Idx out of range. Idx = " << Idx 102 << ", child_count = " << C->child_count(); 103 104 Comment::child_iterator I = C->child_begin() + Idx; 105 Comment *CommentChild = *I; 106 if (!CommentChild) 107 return ::testing::AssertionFailure() << "Child is NULL"; 108 109 Child = dyn_cast<T>(CommentChild); 110 if (!Child) 111 return ::testing::AssertionFailure() 112 << "Child is not of requested type, but a " 113 << CommentChild->getCommentKindName(); 114 115 return ::testing::AssertionSuccess(); 116 } 117 118 ::testing::AssertionResult HasTextAt(const Comment *C, 119 size_t Idx, 120 StringRef Text) { 121 TextComment *TC; 122 ::testing::AssertionResult AR = GetChildAt(C, Idx, TC); 123 if (!AR) 124 return AR; 125 126 StringRef ActualText = TC->getText(); 127 if (ActualText != Text) 128 return ::testing::AssertionFailure() 129 << "TextComment has text \"" << ActualText.str() << "\", " 130 "expected \"" << Text.str() << "\""; 131 132 if (TC->hasTrailingNewline()) 133 return ::testing::AssertionFailure() 134 << "TextComment has a trailing newline"; 135 136 return ::testing::AssertionSuccess(); 137 } 138 139 ::testing::AssertionResult HasTextWithNewlineAt(const Comment *C, 140 size_t Idx, 141 StringRef Text) { 142 TextComment *TC; 143 ::testing::AssertionResult AR = GetChildAt(C, Idx, TC); 144 if (!AR) 145 return AR; 146 147 StringRef ActualText = TC->getText(); 148 if (ActualText != Text) 149 return ::testing::AssertionFailure() 150 << "TextComment has text \"" << ActualText.str() << "\", " 151 "expected \"" << Text.str() << "\""; 152 153 if (!TC->hasTrailingNewline()) 154 return ::testing::AssertionFailure() 155 << "TextComment has no trailing newline"; 156 157 return ::testing::AssertionSuccess(); 158 } 159 160 ::testing::AssertionResult HasBlockCommandAt(const Comment *C, 161 const CommandTraits &Traits, 162 size_t Idx, 163 BlockCommandComment *&BCC, 164 StringRef Name, 165 ParagraphComment *&Paragraph) { 166 ::testing::AssertionResult AR = GetChildAt(C, Idx, BCC); 167 if (!AR) 168 return AR; 169 170 StringRef ActualName = BCC->getCommandName(Traits); 171 if (ActualName != Name) 172 return ::testing::AssertionFailure() 173 << "BlockCommandComment has name \"" << ActualName.str() << "\", " 174 "expected \"" << Name.str() << "\""; 175 176 Paragraph = BCC->getParagraph(); 177 178 return ::testing::AssertionSuccess(); 179 } 180 181 ::testing::AssertionResult HasParamCommandAt( 182 const Comment *C, 183 const CommandTraits &Traits, 184 size_t Idx, 185 ParamCommandComment *&PCC, 186 StringRef CommandName, 187 ParamCommandComment::PassDirection Direction, 188 bool IsDirectionExplicit, 189 StringRef ParamName, 190 ParagraphComment *&Paragraph) { 191 ::testing::AssertionResult AR = GetChildAt(C, Idx, PCC); 192 if (!AR) 193 return AR; 194 195 StringRef ActualCommandName = PCC->getCommandName(Traits); 196 if (ActualCommandName != CommandName) 197 return ::testing::AssertionFailure() 198 << "ParamCommandComment has name \"" << ActualCommandName.str() << "\", " 199 "expected \"" << CommandName.str() << "\""; 200 201 if (PCC->getDirection() != Direction) 202 return ::testing::AssertionFailure() 203 << "ParamCommandComment has direction " << PCC->getDirection() << ", " 204 "expected " << Direction; 205 206 if (PCC->isDirectionExplicit() != IsDirectionExplicit) 207 return ::testing::AssertionFailure() 208 << "ParamCommandComment has " 209 << (PCC->isDirectionExplicit() ? "explicit" : "implicit") 210 << " direction, " 211 "expected " << (IsDirectionExplicit ? "explicit" : "implicit"); 212 213 if (!ParamName.empty() && !PCC->hasParamName()) 214 return ::testing::AssertionFailure() 215 << "ParamCommandComment has no parameter name"; 216 217 StringRef ActualParamName = PCC->hasParamName() ? PCC->getParamNameAsWritten() : ""; 218 if (ActualParamName != ParamName) 219 return ::testing::AssertionFailure() 220 << "ParamCommandComment has parameter name \"" << ActualParamName.str() 221 << "\", " 222 "expected \"" << ParamName.str() << "\""; 223 224 Paragraph = PCC->getParagraph(); 225 226 return ::testing::AssertionSuccess(); 227 } 228 229 ::testing::AssertionResult HasTParamCommandAt( 230 const Comment *C, 231 const CommandTraits &Traits, 232 size_t Idx, 233 TParamCommandComment *&TPCC, 234 StringRef CommandName, 235 StringRef ParamName, 236 ParagraphComment *&Paragraph) { 237 ::testing::AssertionResult AR = GetChildAt(C, Idx, TPCC); 238 if (!AR) 239 return AR; 240 241 StringRef ActualCommandName = TPCC->getCommandName(Traits); 242 if (ActualCommandName != CommandName) 243 return ::testing::AssertionFailure() 244 << "TParamCommandComment has name \"" << ActualCommandName.str() << "\", " 245 "expected \"" << CommandName.str() << "\""; 246 247 if (!ParamName.empty() && !TPCC->hasParamName()) 248 return ::testing::AssertionFailure() 249 << "TParamCommandComment has no parameter name"; 250 251 StringRef ActualParamName = TPCC->hasParamName() ? TPCC->getParamNameAsWritten() : ""; 252 if (ActualParamName != ParamName) 253 return ::testing::AssertionFailure() 254 << "TParamCommandComment has parameter name \"" << ActualParamName.str() 255 << "\", " 256 "expected \"" << ParamName.str() << "\""; 257 258 Paragraph = TPCC->getParagraph(); 259 260 return ::testing::AssertionSuccess(); 261 } 262 263 ::testing::AssertionResult HasInlineCommandAt(const Comment *C, 264 const CommandTraits &Traits, 265 size_t Idx, 266 InlineCommandComment *&ICC, 267 StringRef Name) { 268 ::testing::AssertionResult AR = GetChildAt(C, Idx, ICC); 269 if (!AR) 270 return AR; 271 272 StringRef ActualName = ICC->getCommandName(Traits); 273 if (ActualName != Name) 274 return ::testing::AssertionFailure() 275 << "InlineCommandComment has name \"" << ActualName.str() << "\", " 276 "expected \"" << Name.str() << "\""; 277 278 return ::testing::AssertionSuccess(); 279 } 280 281 struct NoArgs {}; 282 283 ::testing::AssertionResult HasInlineCommandAt(const Comment *C, 284 const CommandTraits &Traits, 285 size_t Idx, 286 InlineCommandComment *&ICC, 287 StringRef Name, 288 NoArgs) { 289 ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name); 290 if (!AR) 291 return AR; 292 293 if (ICC->getNumArgs() != 0) 294 return ::testing::AssertionFailure() 295 << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), " 296 "expected 0"; 297 298 return ::testing::AssertionSuccess(); 299 } 300 301 ::testing::AssertionResult HasInlineCommandAt(const Comment *C, 302 const CommandTraits &Traits, 303 size_t Idx, 304 InlineCommandComment *&ICC, 305 StringRef Name, 306 StringRef Arg) { 307 ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name); 308 if (!AR) 309 return AR; 310 311 if (ICC->getNumArgs() != 1) 312 return ::testing::AssertionFailure() 313 << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), " 314 "expected 1"; 315 316 StringRef ActualArg = ICC->getArgText(0); 317 if (ActualArg != Arg) 318 return ::testing::AssertionFailure() 319 << "InlineCommandComment has argument \"" << ActualArg.str() << "\", " 320 "expected \"" << Arg.str() << "\""; 321 322 return ::testing::AssertionSuccess(); 323 } 324 325 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C, 326 size_t Idx, 327 HTMLStartTagComment *&HST, 328 StringRef TagName) { 329 ::testing::AssertionResult AR = GetChildAt(C, Idx, HST); 330 if (!AR) 331 return AR; 332 333 StringRef ActualTagName = HST->getTagName(); 334 if (ActualTagName != TagName) 335 return ::testing::AssertionFailure() 336 << "HTMLStartTagComment has name \"" << ActualTagName.str() << "\", " 337 "expected \"" << TagName.str() << "\""; 338 339 return ::testing::AssertionSuccess(); 340 } 341 342 struct SelfClosing {}; 343 344 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C, 345 size_t Idx, 346 HTMLStartTagComment *&HST, 347 StringRef TagName, 348 SelfClosing) { 349 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName); 350 if (!AR) 351 return AR; 352 353 if (!HST->isSelfClosing()) 354 return ::testing::AssertionFailure() 355 << "HTMLStartTagComment is not self-closing"; 356 357 return ::testing::AssertionSuccess(); 358 } 359 360 361 struct NoAttrs {}; 362 363 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C, 364 size_t Idx, 365 HTMLStartTagComment *&HST, 366 StringRef TagName, 367 NoAttrs) { 368 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName); 369 if (!AR) 370 return AR; 371 372 if (HST->isSelfClosing()) 373 return ::testing::AssertionFailure() 374 << "HTMLStartTagComment is self-closing"; 375 376 if (HST->getNumAttrs() != 0) 377 return ::testing::AssertionFailure() 378 << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), " 379 "expected 0"; 380 381 return ::testing::AssertionSuccess(); 382 } 383 384 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C, 385 size_t Idx, 386 HTMLStartTagComment *&HST, 387 StringRef TagName, 388 StringRef AttrName, 389 StringRef AttrValue) { 390 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName); 391 if (!AR) 392 return AR; 393 394 if (HST->isSelfClosing()) 395 return ::testing::AssertionFailure() 396 << "HTMLStartTagComment is self-closing"; 397 398 if (HST->getNumAttrs() != 1) 399 return ::testing::AssertionFailure() 400 << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), " 401 "expected 1"; 402 403 StringRef ActualName = HST->getAttr(0).Name; 404 if (ActualName != AttrName) 405 return ::testing::AssertionFailure() 406 << "HTMLStartTagComment has attr \"" << ActualName.str() << "\", " 407 "expected \"" << AttrName.str() << "\""; 408 409 StringRef ActualValue = HST->getAttr(0).Value; 410 if (ActualValue != AttrValue) 411 return ::testing::AssertionFailure() 412 << "HTMLStartTagComment has attr value \"" << ActualValue.str() << "\", " 413 "expected \"" << AttrValue.str() << "\""; 414 415 return ::testing::AssertionSuccess(); 416 } 417 418 ::testing::AssertionResult HasHTMLEndTagAt(const Comment *C, 419 size_t Idx, 420 HTMLEndTagComment *&HET, 421 StringRef TagName) { 422 ::testing::AssertionResult AR = GetChildAt(C, Idx, HET); 423 if (!AR) 424 return AR; 425 426 StringRef ActualTagName = HET->getTagName(); 427 if (ActualTagName != TagName) 428 return ::testing::AssertionFailure() 429 << "HTMLEndTagComment has name \"" << ActualTagName.str() << "\", " 430 "expected \"" << TagName.str() << "\""; 431 432 return ::testing::AssertionSuccess(); 433 } 434 435 ::testing::AssertionResult HasParagraphCommentAt(const Comment *C, 436 size_t Idx, 437 StringRef Text) { 438 ParagraphComment *PC; 439 440 { 441 ::testing::AssertionResult AR = GetChildAt(C, Idx, PC); 442 if (!AR) 443 return AR; 444 } 445 446 { 447 ::testing::AssertionResult AR = HasChildCount(PC, 1); 448 if (!AR) 449 return AR; 450 } 451 452 { 453 ::testing::AssertionResult AR = HasTextAt(PC, 0, Text); 454 if (!AR) 455 return AR; 456 } 457 458 return ::testing::AssertionSuccess(); 459 } 460 461 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, 462 const CommandTraits &Traits, 463 size_t Idx, 464 VerbatimBlockComment *&VBC, 465 StringRef Name, 466 StringRef CloseName) { 467 ::testing::AssertionResult AR = GetChildAt(C, Idx, VBC); 468 if (!AR) 469 return AR; 470 471 StringRef ActualName = VBC->getCommandName(Traits); 472 if (ActualName != Name) 473 return ::testing::AssertionFailure() 474 << "VerbatimBlockComment has name \"" << ActualName.str() << "\", " 475 "expected \"" << Name.str() << "\""; 476 477 StringRef ActualCloseName = VBC->getCloseName(); 478 if (ActualCloseName != CloseName) 479 return ::testing::AssertionFailure() 480 << "VerbatimBlockComment has closing command name \"" 481 << ActualCloseName.str() << "\", " 482 "expected \"" << CloseName.str() << "\""; 483 484 return ::testing::AssertionSuccess(); 485 } 486 487 struct NoLines {}; 488 struct Lines {}; 489 490 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, 491 const CommandTraits &Traits, 492 size_t Idx, 493 VerbatimBlockComment *&VBC, 494 StringRef Name, 495 StringRef CloseName, 496 NoLines) { 497 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name, 498 CloseName); 499 if (!AR) 500 return AR; 501 502 if (VBC->getNumLines() != 0) 503 return ::testing::AssertionFailure() 504 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), " 505 "expected 0"; 506 507 return ::testing::AssertionSuccess(); 508 } 509 510 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, 511 const CommandTraits &Traits, 512 size_t Idx, 513 VerbatimBlockComment *&VBC, 514 StringRef Name, 515 StringRef CloseName, 516 Lines, 517 StringRef Line0) { 518 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name, 519 CloseName); 520 if (!AR) 521 return AR; 522 523 if (VBC->getNumLines() != 1) 524 return ::testing::AssertionFailure() 525 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), " 526 "expected 1"; 527 528 StringRef ActualLine0 = VBC->getText(0); 529 if (ActualLine0 != Line0) 530 return ::testing::AssertionFailure() 531 << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", " 532 "expected \"" << Line0.str() << "\""; 533 534 return ::testing::AssertionSuccess(); 535 } 536 537 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, 538 const CommandTraits &Traits, 539 size_t Idx, 540 VerbatimBlockComment *&VBC, 541 StringRef Name, 542 StringRef CloseName, 543 Lines, 544 StringRef Line0, 545 StringRef Line1) { 546 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name, 547 CloseName); 548 if (!AR) 549 return AR; 550 551 if (VBC->getNumLines() != 2) 552 return ::testing::AssertionFailure() 553 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), " 554 "expected 2"; 555 556 StringRef ActualLine0 = VBC->getText(0); 557 if (ActualLine0 != Line0) 558 return ::testing::AssertionFailure() 559 << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", " 560 "expected \"" << Line0.str() << "\""; 561 562 StringRef ActualLine1 = VBC->getText(1); 563 if (ActualLine1 != Line1) 564 return ::testing::AssertionFailure() 565 << "VerbatimBlockComment has lines[1] \"" << ActualLine1.str() << "\", " 566 "expected \"" << Line1.str() << "\""; 567 568 return ::testing::AssertionSuccess(); 569 } 570 571 ::testing::AssertionResult HasVerbatimLineAt(const Comment *C, 572 const CommandTraits &Traits, 573 size_t Idx, 574 VerbatimLineComment *&VLC, 575 StringRef Name, 576 StringRef Text) { 577 ::testing::AssertionResult AR = GetChildAt(C, Idx, VLC); 578 if (!AR) 579 return AR; 580 581 StringRef ActualName = VLC->getCommandName(Traits); 582 if (ActualName != Name) 583 return ::testing::AssertionFailure() 584 << "VerbatimLineComment has name \"" << ActualName.str() << "\", " 585 "expected \"" << Name.str() << "\""; 586 587 StringRef ActualText = VLC->getText(); 588 if (ActualText != Text) 589 return ::testing::AssertionFailure() 590 << "VerbatimLineComment has text \"" << ActualText.str() << "\", " 591 "expected \"" << Text.str() << "\""; 592 593 return ::testing::AssertionSuccess(); 594 } 595 596 597 TEST_F(CommentParserTest, Basic1) { 598 const char *Source = "//"; 599 600 FullComment *FC = parseString(Source); 601 ASSERT_TRUE(HasChildCount(FC, 0)); 602 } 603 604 TEST_F(CommentParserTest, Basic2) { 605 const char *Source = "// Meow"; 606 607 FullComment *FC = parseString(Source); 608 ASSERT_TRUE(HasChildCount(FC, 1)); 609 610 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Meow")); 611 } 612 613 TEST_F(CommentParserTest, Basic3) { 614 const char *Source = 615 "// Aaa\n" 616 "// Bbb"; 617 618 FullComment *FC = parseString(Source); 619 ASSERT_TRUE(HasChildCount(FC, 1)); 620 621 { 622 ParagraphComment *PC; 623 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 624 625 ASSERT_TRUE(HasChildCount(PC, 2)); 626 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa")); 627 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb")); 628 } 629 } 630 631 TEST_F(CommentParserTest, Paragraph1) { 632 const char *Sources[] = { 633 "// Aaa\n" 634 "//\n" 635 "// Bbb", 636 637 "// Aaa\n" 638 "//\n" 639 "//\n" 640 "// Bbb", 641 }; 642 643 644 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 645 FullComment *FC = parseString(Sources[i]); 646 ASSERT_TRUE(HasChildCount(FC, 2)); 647 648 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Aaa")); 649 ASSERT_TRUE(HasParagraphCommentAt(FC, 1, " Bbb")); 650 } 651 } 652 653 TEST_F(CommentParserTest, Paragraph2) { 654 const char *Source = 655 "// \\brief Aaa\n" 656 "//\n" 657 "// Bbb"; 658 659 FullComment *FC = parseString(Source); 660 ASSERT_TRUE(HasChildCount(FC, 3)); 661 662 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 663 { 664 BlockCommandComment *BCC; 665 ParagraphComment *PC; 666 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); 667 668 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa")); 669 } 670 ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb")); 671 } 672 673 TEST_F(CommentParserTest, Paragraph3) { 674 const char *Source = "// \\brief \\author"; 675 676 FullComment *FC = parseString(Source); 677 ASSERT_TRUE(HasChildCount(FC, 3)); 678 679 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 680 { 681 BlockCommandComment *BCC; 682 ParagraphComment *PC; 683 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); 684 685 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " ")); 686 } 687 { 688 BlockCommandComment *BCC; 689 ParagraphComment *PC; 690 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC)); 691 692 ASSERT_TRUE(GetChildAt(BCC, 0, PC)); 693 ASSERT_TRUE(HasChildCount(PC, 0)); 694 } 695 } 696 697 TEST_F(CommentParserTest, Paragraph4) { 698 const char *Source = 699 "// \\brief Aaa\n" 700 "// Bbb \\author\n" 701 "// Ccc"; 702 703 FullComment *FC = parseString(Source); 704 ASSERT_TRUE(HasChildCount(FC, 3)); 705 706 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 707 { 708 BlockCommandComment *BCC; 709 ParagraphComment *PC; 710 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); 711 712 ASSERT_TRUE(GetChildAt(BCC, 0, PC)); 713 ASSERT_TRUE(HasChildCount(PC, 2)); 714 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa")); 715 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb ")); 716 } 717 { 718 BlockCommandComment *BCC; 719 ParagraphComment *PC; 720 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC)); 721 722 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc")); 723 } 724 } 725 726 TEST_F(CommentParserTest, ParamCommand1) { 727 const char *Source = "// \\param aaa"; 728 729 FullComment *FC = parseString(Source); 730 ASSERT_TRUE(HasChildCount(FC, 2)); 731 732 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 733 { 734 ParamCommandComment *PCC; 735 ParagraphComment *PC; 736 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 737 ParamCommandComment::In, 738 /* IsDirectionExplicit = */ false, 739 "aaa", PC)); 740 ASSERT_TRUE(HasChildCount(PCC, 1)); 741 ASSERT_TRUE(HasChildCount(PC, 0)); 742 } 743 } 744 745 TEST_F(CommentParserTest, ParamCommand2) { 746 const char *Source = "// \\param\\brief"; 747 748 FullComment *FC = parseString(Source); 749 ASSERT_TRUE(HasChildCount(FC, 3)); 750 751 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 752 { 753 ParamCommandComment *PCC; 754 ParagraphComment *PC; 755 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 756 ParamCommandComment::In, 757 /* IsDirectionExplicit = */ false, 758 "", PC)); 759 ASSERT_TRUE(HasChildCount(PCC, 1)); 760 ASSERT_TRUE(HasChildCount(PC, 0)); 761 } 762 { 763 BlockCommandComment *BCC; 764 ParagraphComment *PC; 765 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC)); 766 ASSERT_TRUE(HasChildCount(PC, 0)); 767 } 768 } 769 770 TEST_F(CommentParserTest, ParamCommand3) { 771 const char *Sources[] = { 772 "// \\param aaa Bbb\n", 773 "// \\param\n" 774 "// aaa Bbb\n", 775 "// \\param \n" 776 "// aaa Bbb\n", 777 "// \\param aaa\n" 778 "// Bbb\n" 779 }; 780 781 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 782 FullComment *FC = parseString(Sources[i]); 783 ASSERT_TRUE(HasChildCount(FC, 2)); 784 785 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 786 { 787 ParamCommandComment *PCC; 788 ParagraphComment *PC; 789 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 790 ParamCommandComment::In, 791 /* IsDirectionExplicit = */ false, 792 "aaa", PC)); 793 ASSERT_TRUE(HasChildCount(PCC, 1)); 794 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); 795 } 796 } 797 } 798 799 TEST_F(CommentParserTest, ParamCommand4) { 800 const char *Sources[] = { 801 "// \\param [in] aaa Bbb\n", 802 "// \\param[in] aaa Bbb\n", 803 "// \\param\n" 804 "// [in] aaa Bbb\n", 805 "// \\param [in]\n" 806 "// aaa Bbb\n", 807 "// \\param [in] aaa\n" 808 "// Bbb\n", 809 }; 810 811 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 812 FullComment *FC = parseString(Sources[i]); 813 ASSERT_TRUE(HasChildCount(FC, 2)); 814 815 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 816 { 817 ParamCommandComment *PCC; 818 ParagraphComment *PC; 819 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 820 ParamCommandComment::In, 821 /* IsDirectionExplicit = */ true, 822 "aaa", PC)); 823 ASSERT_TRUE(HasChildCount(PCC, 1)); 824 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); 825 } 826 } 827 } 828 829 TEST_F(CommentParserTest, ParamCommand5) { 830 const char *Sources[] = { 831 "// \\param [out] aaa Bbb\n", 832 "// \\param[out] aaa Bbb\n", 833 "// \\param\n" 834 "// [out] aaa Bbb\n", 835 "// \\param [out]\n" 836 "// aaa Bbb\n", 837 "// \\param [out] aaa\n" 838 "// Bbb\n", 839 }; 840 841 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 842 FullComment *FC = parseString(Sources[i]); 843 ASSERT_TRUE(HasChildCount(FC, 2)); 844 845 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 846 { 847 ParamCommandComment *PCC; 848 ParagraphComment *PC; 849 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 850 ParamCommandComment::Out, 851 /* IsDirectionExplicit = */ true, 852 "aaa", PC)); 853 ASSERT_TRUE(HasChildCount(PCC, 1)); 854 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); 855 } 856 } 857 } 858 859 TEST_F(CommentParserTest, ParamCommand6) { 860 const char *Sources[] = { 861 "// \\param [in,out] aaa Bbb\n", 862 "// \\param[in,out] aaa Bbb\n", 863 "// \\param [in, out] aaa Bbb\n", 864 "// \\param [in,\n" 865 "// out] aaa Bbb\n", 866 "// \\param [in,out]\n" 867 "// aaa Bbb\n", 868 "// \\param [in,out] aaa\n" 869 "// Bbb\n" 870 }; 871 872 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 873 FullComment *FC = parseString(Sources[i]); 874 ASSERT_TRUE(HasChildCount(FC, 2)); 875 876 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 877 { 878 ParamCommandComment *PCC; 879 ParagraphComment *PC; 880 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 881 ParamCommandComment::InOut, 882 /* IsDirectionExplicit = */ true, 883 "aaa", PC)); 884 ASSERT_TRUE(HasChildCount(PCC, 1)); 885 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); 886 } 887 } 888 } 889 890 TEST_F(CommentParserTest, ParamCommand7) { 891 const char *Source = 892 "// \\param aaa \\% Bbb \\$ ccc\n"; 893 894 FullComment *FC = parseString(Source); 895 ASSERT_TRUE(HasChildCount(FC, 2)); 896 897 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 898 { 899 ParamCommandComment *PCC; 900 ParagraphComment *PC; 901 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 902 ParamCommandComment::In, 903 /* IsDirectionExplicit = */ false, 904 "aaa", PC)); 905 ASSERT_TRUE(HasChildCount(PCC, 1)); 906 907 ASSERT_TRUE(HasChildCount(PC, 5)); 908 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 909 ASSERT_TRUE(HasTextAt(PC, 1, "%")); 910 ASSERT_TRUE(HasTextAt(PC, 2, " Bbb ")); 911 ASSERT_TRUE(HasTextAt(PC, 3, "$")); 912 ASSERT_TRUE(HasTextAt(PC, 4, " ccc")); 913 } 914 } 915 916 TEST_F(CommentParserTest, TParamCommand1) { 917 const char *Sources[] = { 918 "// \\tparam aaa Bbb\n", 919 "// \\tparam\n" 920 "// aaa Bbb\n", 921 "// \\tparam \n" 922 "// aaa Bbb\n", 923 "// \\tparam aaa\n" 924 "// Bbb\n" 925 }; 926 927 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 928 FullComment *FC = parseString(Sources[i]); 929 ASSERT_TRUE(HasChildCount(FC, 2)); 930 931 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 932 { 933 TParamCommandComment *TPCC; 934 ParagraphComment *PC; 935 ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", 936 "aaa", PC)); 937 ASSERT_TRUE(HasChildCount(TPCC, 1)); 938 ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb")); 939 } 940 } 941 } 942 943 TEST_F(CommentParserTest, TParamCommand2) { 944 const char *Source = "// \\tparam\\brief"; 945 946 FullComment *FC = parseString(Source); 947 ASSERT_TRUE(HasChildCount(FC, 3)); 948 949 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 950 { 951 TParamCommandComment *TPCC; 952 ParagraphComment *PC; 953 ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", "", PC)); 954 ASSERT_TRUE(HasChildCount(TPCC, 1)); 955 ASSERT_TRUE(HasChildCount(PC, 0)); 956 } 957 { 958 BlockCommandComment *BCC; 959 ParagraphComment *PC; 960 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC)); 961 ASSERT_TRUE(HasChildCount(PC, 0)); 962 } 963 } 964 965 966 TEST_F(CommentParserTest, InlineCommand1) { 967 const char *Source = "// \\c"; 968 969 FullComment *FC = parseString(Source); 970 ASSERT_TRUE(HasChildCount(FC, 1)); 971 972 { 973 ParagraphComment *PC; 974 InlineCommandComment *ICC; 975 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 976 977 ASSERT_TRUE(HasChildCount(PC, 2)); 978 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 979 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs())); 980 } 981 } 982 983 TEST_F(CommentParserTest, InlineCommand2) { 984 const char *Source = "// \\c "; 985 986 FullComment *FC = parseString(Source); 987 ASSERT_TRUE(HasChildCount(FC, 1)); 988 989 { 990 ParagraphComment *PC; 991 InlineCommandComment *ICC; 992 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 993 994 ASSERT_TRUE(HasChildCount(PC, 3)); 995 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 996 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs())); 997 ASSERT_TRUE(HasTextAt(PC, 2, " ")); 998 } 999 } 1000 1001 TEST_F(CommentParserTest, InlineCommand3) { 1002 const char *Source = "// \\c aaa\n"; 1003 1004 FullComment *FC = parseString(Source); 1005 ASSERT_TRUE(HasChildCount(FC, 1)); 1006 1007 { 1008 ParagraphComment *PC; 1009 InlineCommandComment *ICC; 1010 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1011 1012 ASSERT_TRUE(HasChildCount(PC, 2)); 1013 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1014 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa")); 1015 } 1016 } 1017 1018 TEST_F(CommentParserTest, InlineCommand4) { 1019 const char *Source = "// \\c aaa bbb"; 1020 1021 FullComment *FC = parseString(Source); 1022 ASSERT_TRUE(HasChildCount(FC, 1)); 1023 1024 { 1025 ParagraphComment *PC; 1026 InlineCommandComment *ICC; 1027 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1028 1029 ASSERT_TRUE(HasChildCount(PC, 3)); 1030 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1031 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa")); 1032 ASSERT_TRUE(HasTextAt(PC, 2, " bbb")); 1033 } 1034 } 1035 1036 TEST_F(CommentParserTest, InlineCommand5) { 1037 const char *Source = "// \\unknown aaa\n"; 1038 1039 FullComment *FC = parseString(Source); 1040 ASSERT_TRUE(HasChildCount(FC, 1)); 1041 1042 { 1043 ParagraphComment *PC; 1044 InlineCommandComment *ICC; 1045 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1046 1047 ASSERT_TRUE(HasChildCount(PC, 3)); 1048 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1049 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "unknown", NoArgs())); 1050 ASSERT_TRUE(HasTextAt(PC, 2, " aaa")); 1051 } 1052 } 1053 1054 TEST_F(CommentParserTest, HTML1) { 1055 const char *Sources[] = { 1056 "// <a", 1057 "// <a>", 1058 "// <a >" 1059 }; 1060 1061 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1062 FullComment *FC = parseString(Sources[i]); 1063 ASSERT_TRUE(HasChildCount(FC, 1)); 1064 1065 { 1066 ParagraphComment *PC; 1067 HTMLStartTagComment *HST; 1068 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1069 1070 ASSERT_TRUE(HasChildCount(PC, 2)); 1071 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1072 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs())); 1073 } 1074 } 1075 } 1076 1077 TEST_F(CommentParserTest, HTML2) { 1078 const char *Sources[] = { 1079 "// <br/>", 1080 "// <br />" 1081 }; 1082 1083 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1084 FullComment *FC = parseString(Sources[i]); 1085 ASSERT_TRUE(HasChildCount(FC, 1)); 1086 1087 { 1088 ParagraphComment *PC; 1089 HTMLStartTagComment *HST; 1090 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1091 1092 ASSERT_TRUE(HasChildCount(PC, 2)); 1093 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1094 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing())); 1095 } 1096 } 1097 } 1098 1099 TEST_F(CommentParserTest, HTML3) { 1100 const char *Sources[] = { 1101 "// <a href", 1102 "// <a href ", 1103 "// <a href>", 1104 "// <a href >", 1105 }; 1106 1107 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1108 FullComment *FC = parseString(Sources[i]); 1109 ASSERT_TRUE(HasChildCount(FC, 1)); 1110 1111 { 1112 ParagraphComment *PC; 1113 HTMLStartTagComment *HST; 1114 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1115 1116 ASSERT_TRUE(HasChildCount(PC, 2)); 1117 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1118 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "")); 1119 } 1120 } 1121 } 1122 1123 TEST_F(CommentParserTest, HTML4) { 1124 const char *Sources[] = { 1125 "// <a href=\"bbb\"", 1126 "// <a href=\"bbb\">", 1127 }; 1128 1129 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1130 FullComment *FC = parseString(Sources[i]); 1131 ASSERT_TRUE(HasChildCount(FC, 1)); 1132 1133 { 1134 ParagraphComment *PC; 1135 HTMLStartTagComment *HST; 1136 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1137 1138 ASSERT_TRUE(HasChildCount(PC, 2)); 1139 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1140 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb")); 1141 } 1142 } 1143 } 1144 1145 TEST_F(CommentParserTest, HTML5) { 1146 const char *Sources[] = { 1147 "// </a", 1148 "// </a>", 1149 "// </a >" 1150 }; 1151 1152 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1153 FullComment *FC = parseString(Sources[i]); 1154 ASSERT_TRUE(HasChildCount(FC, 1)); 1155 1156 { 1157 ParagraphComment *PC; 1158 HTMLEndTagComment *HET; 1159 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1160 1161 ASSERT_TRUE(HasChildCount(PC, 2)); 1162 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1163 ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a")); 1164 } 1165 } 1166 } 1167 1168 TEST_F(CommentParserTest, HTML6) { 1169 const char *Source = 1170 "// <pre>\n" 1171 "// Aaa\n" 1172 "// Bbb\n" 1173 "// </pre>\n"; 1174 1175 FullComment *FC = parseString(Source); 1176 ASSERT_TRUE(HasChildCount(FC, 1)); 1177 1178 { 1179 ParagraphComment *PC; 1180 HTMLStartTagComment *HST; 1181 HTMLEndTagComment *HET; 1182 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1183 1184 ASSERT_TRUE(HasChildCount(PC, 6)); 1185 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1186 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs())); 1187 ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa")); 1188 ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb")); 1189 ASSERT_TRUE(HasTextAt(PC, 4, " ")); 1190 ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre")); 1191 } 1192 } 1193 1194 TEST_F(CommentParserTest, VerbatimBlock1) { 1195 const char *Source = "// \\verbatim\\endverbatim\n"; 1196 1197 FullComment *FC = parseString(Source); 1198 ASSERT_TRUE(HasChildCount(FC, 2)); 1199 1200 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1201 { 1202 VerbatimBlockComment *VCC; 1203 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VCC, 1204 "verbatim", "endverbatim", 1205 NoLines())); 1206 } 1207 } 1208 1209 TEST_F(CommentParserTest, VerbatimBlock2) { 1210 const char *Source = "// \\verbatim Aaa \\endverbatim\n"; 1211 1212 FullComment *FC = parseString(Source); 1213 ASSERT_TRUE(HasChildCount(FC, 2)); 1214 1215 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1216 { 1217 VerbatimBlockComment *VBC; 1218 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, 1219 "verbatim", "endverbatim", 1220 Lines(), " Aaa ")); 1221 } 1222 } 1223 1224 TEST_F(CommentParserTest, VerbatimBlock3) { 1225 const char *Source = "// \\verbatim Aaa\n"; 1226 1227 FullComment *FC = parseString(Source); 1228 ASSERT_TRUE(HasChildCount(FC, 2)); 1229 1230 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1231 { 1232 VerbatimBlockComment *VBC; 1233 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, "verbatim", "", 1234 Lines(), " Aaa")); 1235 } 1236 } 1237 1238 TEST_F(CommentParserTest, VerbatimBlock4) { 1239 const char *Source = 1240 "//\\verbatim\n" 1241 "//\\endverbatim\n"; 1242 1243 FullComment *FC = parseString(Source); 1244 ASSERT_TRUE(HasChildCount(FC, 1)); 1245 1246 { 1247 VerbatimBlockComment *VBC; 1248 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC, 1249 "verbatim", "endverbatim", 1250 NoLines())); 1251 } 1252 } 1253 1254 TEST_F(CommentParserTest, VerbatimBlock5) { 1255 const char *Sources[] = { 1256 "//\\verbatim\n" 1257 "// Aaa\n" 1258 "//\\endverbatim\n", 1259 1260 "/*\\verbatim\n" 1261 " * Aaa\n" 1262 " *\\endverbatim*/" 1263 }; 1264 1265 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1266 FullComment *FC = parseString(Sources[i]); 1267 ASSERT_TRUE(HasChildCount(FC, 1)); 1268 1269 { 1270 VerbatimBlockComment *VBC; 1271 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC, 1272 "verbatim", "endverbatim", 1273 Lines(), " Aaa")); 1274 } 1275 } 1276 } 1277 1278 TEST_F(CommentParserTest, VerbatimBlock6) { 1279 const char *Sources[] = { 1280 "// \\verbatim\n" 1281 "// Aaa\n" 1282 "// \\endverbatim\n", 1283 1284 "/* \\verbatim\n" 1285 " * Aaa\n" 1286 " * \\endverbatim*/" 1287 }; 1288 1289 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1290 FullComment *FC = parseString(Sources[i]); 1291 ASSERT_TRUE(HasChildCount(FC, 2)); 1292 1293 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1294 { 1295 VerbatimBlockComment *VBC; 1296 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, 1297 "verbatim", "endverbatim", 1298 Lines(), " Aaa")); 1299 } 1300 } 1301 } 1302 1303 TEST_F(CommentParserTest, VerbatimBlock7) { 1304 const char *Sources[] = { 1305 "// \\verbatim\n" 1306 "// Aaa\n" 1307 "// Bbb\n" 1308 "// \\endverbatim\n", 1309 1310 "/* \\verbatim\n" 1311 " * Aaa\n" 1312 " * Bbb\n" 1313 " * \\endverbatim*/" 1314 }; 1315 1316 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1317 FullComment *FC = parseString(Sources[i]); 1318 ASSERT_TRUE(HasChildCount(FC, 2)); 1319 1320 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1321 { 1322 VerbatimBlockComment *VBC; 1323 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, 1324 "verbatim", "endverbatim", 1325 Lines(), " Aaa", " Bbb")); 1326 } 1327 } 1328 } 1329 1330 TEST_F(CommentParserTest, VerbatimBlock8) { 1331 const char *Sources[] = { 1332 "// \\verbatim\n" 1333 "// Aaa\n" 1334 "//\n" 1335 "// Bbb\n" 1336 "// \\endverbatim\n", 1337 1338 "/* \\verbatim\n" 1339 " * Aaa\n" 1340 " *\n" 1341 " * Bbb\n" 1342 " * \\endverbatim*/" 1343 }; 1344 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1345 FullComment *FC = parseString(Sources[i]); 1346 ASSERT_TRUE(HasChildCount(FC, 2)); 1347 1348 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1349 { 1350 VerbatimBlockComment *VBC; 1351 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, 1352 "verbatim", "endverbatim")); 1353 ASSERT_EQ(3U, VBC->getNumLines()); 1354 ASSERT_EQ(" Aaa", VBC->getText(0)); 1355 ASSERT_EQ("", VBC->getText(1)); 1356 ASSERT_EQ(" Bbb", VBC->getText(2)); 1357 } 1358 } 1359 } 1360 1361 TEST_F(CommentParserTest, VerbatimLine1) { 1362 const char *Sources[] = { 1363 "// \\fn", 1364 "// \\fn\n" 1365 }; 1366 1367 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1368 FullComment *FC = parseString(Sources[i]); 1369 ASSERT_TRUE(HasChildCount(FC, 2)); 1370 1371 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1372 { 1373 VerbatimLineComment *VLC; 1374 ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", "")); 1375 } 1376 } 1377 } 1378 1379 TEST_F(CommentParserTest, VerbatimLine2) { 1380 const char *Sources[] = { 1381 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//", 1382 "/** \\fn void *foo(const char *zzz = \"\\$\");*/" 1383 }; 1384 1385 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1386 FullComment *FC = parseString(Sources[i]); 1387 ASSERT_TRUE(HasChildCount(FC, 2)); 1388 1389 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1390 { 1391 VerbatimLineComment *VLC; 1392 ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", 1393 " void *foo(const char *zzz = \"\\$\");")); 1394 } 1395 } 1396 } 1397 1398 } // unnamed namespace 1399 1400 } // end namespace comments 1401 } // end namespace clang 1402 1403