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 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Source); 58 FileID File = SourceMgr.createFileID(std::move(Buf)); 59 SourceLocation Begin = SourceMgr.getLocForStartOfFile(File); 60 61 Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source)); 62 63 Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ nullptr); 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 nullptr; 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, ParagraphSplitting1) { 632 const char *Sources[] = { 633 "// Aaa\n" 634 "//\n" 635 "// Bbb", 636 637 "// Aaa\n" 638 "// \n" 639 "// Bbb", 640 641 "// Aaa\n" 642 "//\t\n" 643 "// Bbb", 644 645 "// Aaa\n" 646 "//\n" 647 "//\n" 648 "// Bbb", 649 650 "/**\n" 651 " Aaa\n" 652 "\n" 653 " Bbb\n" 654 "*/", 655 656 "/**\n" 657 " Aaa\n" 658 " \n" 659 " Bbb\n" 660 "*/", 661 662 "/**\n" 663 " Aaa\n" 664 "\t \n" 665 " Bbb\n" 666 "*/", 667 }; 668 669 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 670 FullComment *FC = parseString(Sources[i]); 671 ASSERT_TRUE(HasChildCount(FC, 2)); 672 673 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Aaa")); 674 ASSERT_TRUE(HasParagraphCommentAt(FC, 1, " Bbb")); 675 } 676 } 677 678 TEST_F(CommentParserTest, Paragraph1) { 679 const char *Source = 680 "// \\brief Aaa\n" 681 "//\n" 682 "// Bbb"; 683 684 FullComment *FC = parseString(Source); 685 ASSERT_TRUE(HasChildCount(FC, 3)); 686 687 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 688 { 689 BlockCommandComment *BCC; 690 ParagraphComment *PC; 691 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); 692 693 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa")); 694 } 695 ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb")); 696 } 697 698 TEST_F(CommentParserTest, Paragraph2) { 699 const char *Source = "// \\brief \\author"; 700 701 FullComment *FC = parseString(Source); 702 ASSERT_TRUE(HasChildCount(FC, 3)); 703 704 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 705 { 706 BlockCommandComment *BCC; 707 ParagraphComment *PC; 708 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); 709 710 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " ")); 711 } 712 { 713 BlockCommandComment *BCC; 714 ParagraphComment *PC; 715 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC)); 716 717 ASSERT_TRUE(GetChildAt(BCC, 0, PC)); 718 ASSERT_TRUE(HasChildCount(PC, 0)); 719 } 720 } 721 722 TEST_F(CommentParserTest, Paragraph3) { 723 const char *Source = 724 "// \\brief Aaa\n" 725 "// Bbb \\author\n" 726 "// Ccc"; 727 728 FullComment *FC = parseString(Source); 729 ASSERT_TRUE(HasChildCount(FC, 3)); 730 731 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 732 { 733 BlockCommandComment *BCC; 734 ParagraphComment *PC; 735 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); 736 737 ASSERT_TRUE(GetChildAt(BCC, 0, PC)); 738 ASSERT_TRUE(HasChildCount(PC, 2)); 739 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa")); 740 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb ")); 741 } 742 { 743 BlockCommandComment *BCC; 744 ParagraphComment *PC; 745 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC)); 746 747 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc")); 748 } 749 } 750 751 TEST_F(CommentParserTest, ParamCommand1) { 752 const char *Source = "// \\param aaa"; 753 754 FullComment *FC = parseString(Source); 755 ASSERT_TRUE(HasChildCount(FC, 2)); 756 757 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 758 { 759 ParamCommandComment *PCC; 760 ParagraphComment *PC; 761 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 762 ParamCommandComment::In, 763 /* IsDirectionExplicit = */ false, 764 "aaa", PC)); 765 ASSERT_TRUE(HasChildCount(PCC, 1)); 766 ASSERT_TRUE(HasChildCount(PC, 0)); 767 } 768 } 769 770 TEST_F(CommentParserTest, ParamCommand2) { 771 const char *Source = "// \\param\\brief"; 772 773 FullComment *FC = parseString(Source); 774 ASSERT_TRUE(HasChildCount(FC, 3)); 775 776 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 777 { 778 ParamCommandComment *PCC; 779 ParagraphComment *PC; 780 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 781 ParamCommandComment::In, 782 /* IsDirectionExplicit = */ false, 783 "", PC)); 784 ASSERT_TRUE(HasChildCount(PCC, 1)); 785 ASSERT_TRUE(HasChildCount(PC, 0)); 786 } 787 { 788 BlockCommandComment *BCC; 789 ParagraphComment *PC; 790 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC)); 791 ASSERT_TRUE(HasChildCount(PC, 0)); 792 } 793 } 794 795 TEST_F(CommentParserTest, ParamCommand3) { 796 const char *Sources[] = { 797 "// \\param aaa Bbb\n", 798 "// \\param\n" 799 "// aaa Bbb\n", 800 "// \\param \n" 801 "// aaa Bbb\n", 802 "// \\param aaa\n" 803 "// Bbb\n" 804 }; 805 806 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 807 FullComment *FC = parseString(Sources[i]); 808 ASSERT_TRUE(HasChildCount(FC, 2)); 809 810 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 811 { 812 ParamCommandComment *PCC; 813 ParagraphComment *PC; 814 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 815 ParamCommandComment::In, 816 /* IsDirectionExplicit = */ false, 817 "aaa", PC)); 818 ASSERT_TRUE(HasChildCount(PCC, 1)); 819 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); 820 } 821 } 822 } 823 824 TEST_F(CommentParserTest, ParamCommand4) { 825 const char *Sources[] = { 826 "// \\param [in] aaa Bbb\n", 827 "// \\param[in] aaa Bbb\n", 828 "// \\param\n" 829 "// [in] aaa Bbb\n", 830 "// \\param [in]\n" 831 "// aaa Bbb\n", 832 "// \\param [in] aaa\n" 833 "// Bbb\n", 834 }; 835 836 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 837 FullComment *FC = parseString(Sources[i]); 838 ASSERT_TRUE(HasChildCount(FC, 2)); 839 840 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 841 { 842 ParamCommandComment *PCC; 843 ParagraphComment *PC; 844 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 845 ParamCommandComment::In, 846 /* IsDirectionExplicit = */ true, 847 "aaa", PC)); 848 ASSERT_TRUE(HasChildCount(PCC, 1)); 849 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); 850 } 851 } 852 } 853 854 TEST_F(CommentParserTest, ParamCommand5) { 855 const char *Sources[] = { 856 "// \\param [out] aaa Bbb\n", 857 "// \\param[out] aaa Bbb\n", 858 "// \\param\n" 859 "// [out] aaa Bbb\n", 860 "// \\param [out]\n" 861 "// aaa Bbb\n", 862 "// \\param [out] aaa\n" 863 "// Bbb\n", 864 }; 865 866 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 867 FullComment *FC = parseString(Sources[i]); 868 ASSERT_TRUE(HasChildCount(FC, 2)); 869 870 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 871 { 872 ParamCommandComment *PCC; 873 ParagraphComment *PC; 874 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 875 ParamCommandComment::Out, 876 /* IsDirectionExplicit = */ true, 877 "aaa", PC)); 878 ASSERT_TRUE(HasChildCount(PCC, 1)); 879 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); 880 } 881 } 882 } 883 884 TEST_F(CommentParserTest, ParamCommand6) { 885 const char *Sources[] = { 886 "// \\param [in,out] aaa Bbb\n", 887 "// \\param[in,out] aaa Bbb\n", 888 "// \\param [in, out] aaa Bbb\n", 889 "// \\param [in,\n" 890 "// out] aaa Bbb\n", 891 "// \\param [in,out]\n" 892 "// aaa Bbb\n", 893 "// \\param [in,out] aaa\n" 894 "// Bbb\n" 895 }; 896 897 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 898 FullComment *FC = parseString(Sources[i]); 899 ASSERT_TRUE(HasChildCount(FC, 2)); 900 901 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 902 { 903 ParamCommandComment *PCC; 904 ParagraphComment *PC; 905 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 906 ParamCommandComment::InOut, 907 /* IsDirectionExplicit = */ true, 908 "aaa", PC)); 909 ASSERT_TRUE(HasChildCount(PCC, 1)); 910 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); 911 } 912 } 913 } 914 915 TEST_F(CommentParserTest, ParamCommand7) { 916 const char *Source = 917 "// \\param aaa \\% Bbb \\$ ccc\n"; 918 919 FullComment *FC = parseString(Source); 920 ASSERT_TRUE(HasChildCount(FC, 2)); 921 922 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 923 { 924 ParamCommandComment *PCC; 925 ParagraphComment *PC; 926 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", 927 ParamCommandComment::In, 928 /* IsDirectionExplicit = */ false, 929 "aaa", PC)); 930 ASSERT_TRUE(HasChildCount(PCC, 1)); 931 932 ASSERT_TRUE(HasChildCount(PC, 5)); 933 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 934 ASSERT_TRUE(HasTextAt(PC, 1, "%")); 935 ASSERT_TRUE(HasTextAt(PC, 2, " Bbb ")); 936 ASSERT_TRUE(HasTextAt(PC, 3, "$")); 937 ASSERT_TRUE(HasTextAt(PC, 4, " ccc")); 938 } 939 } 940 941 TEST_F(CommentParserTest, TParamCommand1) { 942 const char *Sources[] = { 943 "// \\tparam aaa Bbb\n", 944 "// \\tparam\n" 945 "// aaa Bbb\n", 946 "// \\tparam \n" 947 "// aaa Bbb\n", 948 "// \\tparam aaa\n" 949 "// Bbb\n" 950 }; 951 952 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 953 FullComment *FC = parseString(Sources[i]); 954 ASSERT_TRUE(HasChildCount(FC, 2)); 955 956 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 957 { 958 TParamCommandComment *TPCC; 959 ParagraphComment *PC; 960 ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", 961 "aaa", PC)); 962 ASSERT_TRUE(HasChildCount(TPCC, 1)); 963 ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb")); 964 } 965 } 966 } 967 968 TEST_F(CommentParserTest, TParamCommand2) { 969 const char *Source = "// \\tparam\\brief"; 970 971 FullComment *FC = parseString(Source); 972 ASSERT_TRUE(HasChildCount(FC, 3)); 973 974 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 975 { 976 TParamCommandComment *TPCC; 977 ParagraphComment *PC; 978 ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", "", PC)); 979 ASSERT_TRUE(HasChildCount(TPCC, 1)); 980 ASSERT_TRUE(HasChildCount(PC, 0)); 981 } 982 { 983 BlockCommandComment *BCC; 984 ParagraphComment *PC; 985 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC)); 986 ASSERT_TRUE(HasChildCount(PC, 0)); 987 } 988 } 989 990 991 TEST_F(CommentParserTest, InlineCommand1) { 992 const char *Source = "// \\c"; 993 994 FullComment *FC = parseString(Source); 995 ASSERT_TRUE(HasChildCount(FC, 1)); 996 997 { 998 ParagraphComment *PC; 999 InlineCommandComment *ICC; 1000 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1001 1002 ASSERT_TRUE(HasChildCount(PC, 2)); 1003 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1004 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs())); 1005 } 1006 } 1007 1008 TEST_F(CommentParserTest, InlineCommand2) { 1009 const char *Source = "// \\c "; 1010 1011 FullComment *FC = parseString(Source); 1012 ASSERT_TRUE(HasChildCount(FC, 1)); 1013 1014 { 1015 ParagraphComment *PC; 1016 InlineCommandComment *ICC; 1017 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1018 1019 ASSERT_TRUE(HasChildCount(PC, 3)); 1020 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1021 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs())); 1022 ASSERT_TRUE(HasTextAt(PC, 2, " ")); 1023 } 1024 } 1025 1026 TEST_F(CommentParserTest, InlineCommand3) { 1027 const char *Source = "// \\c aaa\n"; 1028 1029 FullComment *FC = parseString(Source); 1030 ASSERT_TRUE(HasChildCount(FC, 1)); 1031 1032 { 1033 ParagraphComment *PC; 1034 InlineCommandComment *ICC; 1035 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1036 1037 ASSERT_TRUE(HasChildCount(PC, 2)); 1038 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1039 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa")); 1040 } 1041 } 1042 1043 TEST_F(CommentParserTest, InlineCommand4) { 1044 const char *Source = "// \\c aaa bbb"; 1045 1046 FullComment *FC = parseString(Source); 1047 ASSERT_TRUE(HasChildCount(FC, 1)); 1048 1049 { 1050 ParagraphComment *PC; 1051 InlineCommandComment *ICC; 1052 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1053 1054 ASSERT_TRUE(HasChildCount(PC, 3)); 1055 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1056 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa")); 1057 ASSERT_TRUE(HasTextAt(PC, 2, " bbb")); 1058 } 1059 } 1060 1061 TEST_F(CommentParserTest, InlineCommand5) { 1062 const char *Source = "// \\unknown aaa\n"; 1063 1064 FullComment *FC = parseString(Source); 1065 ASSERT_TRUE(HasChildCount(FC, 1)); 1066 1067 { 1068 ParagraphComment *PC; 1069 InlineCommandComment *ICC; 1070 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1071 1072 ASSERT_TRUE(HasChildCount(PC, 3)); 1073 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1074 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "unknown", NoArgs())); 1075 ASSERT_TRUE(HasTextAt(PC, 2, " aaa")); 1076 } 1077 } 1078 1079 TEST_F(CommentParserTest, HTML1) { 1080 const char *Sources[] = { 1081 "// <a", 1082 "// <a>", 1083 "// <a >" 1084 }; 1085 1086 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1087 FullComment *FC = parseString(Sources[i]); 1088 ASSERT_TRUE(HasChildCount(FC, 1)); 1089 1090 { 1091 ParagraphComment *PC; 1092 HTMLStartTagComment *HST; 1093 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1094 1095 ASSERT_TRUE(HasChildCount(PC, 2)); 1096 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1097 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs())); 1098 } 1099 } 1100 } 1101 1102 TEST_F(CommentParserTest, HTML2) { 1103 const char *Sources[] = { 1104 "// <br/>", 1105 "// <br />" 1106 }; 1107 1108 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1109 FullComment *FC = parseString(Sources[i]); 1110 ASSERT_TRUE(HasChildCount(FC, 1)); 1111 1112 { 1113 ParagraphComment *PC; 1114 HTMLStartTagComment *HST; 1115 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1116 1117 ASSERT_TRUE(HasChildCount(PC, 2)); 1118 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1119 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing())); 1120 } 1121 } 1122 } 1123 1124 TEST_F(CommentParserTest, HTML3) { 1125 const char *Sources[] = { 1126 "// <a href", 1127 "// <a href ", 1128 "// <a href>", 1129 "// <a href >", 1130 }; 1131 1132 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1133 FullComment *FC = parseString(Sources[i]); 1134 ASSERT_TRUE(HasChildCount(FC, 1)); 1135 1136 { 1137 ParagraphComment *PC; 1138 HTMLStartTagComment *HST; 1139 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1140 1141 ASSERT_TRUE(HasChildCount(PC, 2)); 1142 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1143 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "")); 1144 } 1145 } 1146 } 1147 1148 TEST_F(CommentParserTest, HTML4) { 1149 const char *Sources[] = { 1150 "// <a href=\"bbb\"", 1151 "// <a href=\"bbb\">", 1152 }; 1153 1154 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1155 FullComment *FC = parseString(Sources[i]); 1156 ASSERT_TRUE(HasChildCount(FC, 1)); 1157 1158 { 1159 ParagraphComment *PC; 1160 HTMLStartTagComment *HST; 1161 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1162 1163 ASSERT_TRUE(HasChildCount(PC, 2)); 1164 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1165 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb")); 1166 } 1167 } 1168 } 1169 1170 TEST_F(CommentParserTest, HTML5) { 1171 const char *Sources[] = { 1172 "// </a", 1173 "// </a>", 1174 "// </a >" 1175 }; 1176 1177 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1178 FullComment *FC = parseString(Sources[i]); 1179 ASSERT_TRUE(HasChildCount(FC, 1)); 1180 1181 { 1182 ParagraphComment *PC; 1183 HTMLEndTagComment *HET; 1184 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1185 1186 ASSERT_TRUE(HasChildCount(PC, 2)); 1187 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1188 ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a")); 1189 } 1190 } 1191 } 1192 1193 TEST_F(CommentParserTest, HTML6) { 1194 const char *Source = 1195 "// <pre>\n" 1196 "// Aaa\n" 1197 "// Bbb\n" 1198 "// </pre>\n"; 1199 1200 FullComment *FC = parseString(Source); 1201 ASSERT_TRUE(HasChildCount(FC, 1)); 1202 1203 { 1204 ParagraphComment *PC; 1205 HTMLStartTagComment *HST; 1206 HTMLEndTagComment *HET; 1207 ASSERT_TRUE(GetChildAt(FC, 0, PC)); 1208 1209 ASSERT_TRUE(HasChildCount(PC, 6)); 1210 ASSERT_TRUE(HasTextAt(PC, 0, " ")); 1211 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs())); 1212 ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa")); 1213 ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb")); 1214 ASSERT_TRUE(HasTextAt(PC, 4, " ")); 1215 ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre")); 1216 } 1217 } 1218 1219 TEST_F(CommentParserTest, VerbatimBlock1) { 1220 const char *Source = "// \\verbatim\\endverbatim\n"; 1221 1222 FullComment *FC = parseString(Source); 1223 ASSERT_TRUE(HasChildCount(FC, 2)); 1224 1225 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1226 { 1227 VerbatimBlockComment *VCC; 1228 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VCC, 1229 "verbatim", "endverbatim", 1230 NoLines())); 1231 } 1232 } 1233 1234 TEST_F(CommentParserTest, VerbatimBlock2) { 1235 const char *Source = "// \\verbatim Aaa \\endverbatim\n"; 1236 1237 FullComment *FC = parseString(Source); 1238 ASSERT_TRUE(HasChildCount(FC, 2)); 1239 1240 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1241 { 1242 VerbatimBlockComment *VBC; 1243 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, 1244 "verbatim", "endverbatim", 1245 Lines(), " Aaa ")); 1246 } 1247 } 1248 1249 TEST_F(CommentParserTest, VerbatimBlock3) { 1250 const char *Source = "// \\verbatim Aaa\n"; 1251 1252 FullComment *FC = parseString(Source); 1253 ASSERT_TRUE(HasChildCount(FC, 2)); 1254 1255 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1256 { 1257 VerbatimBlockComment *VBC; 1258 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, "verbatim", "", 1259 Lines(), " Aaa")); 1260 } 1261 } 1262 1263 TEST_F(CommentParserTest, VerbatimBlock4) { 1264 const char *Source = 1265 "//\\verbatim\n" 1266 "//\\endverbatim\n"; 1267 1268 FullComment *FC = parseString(Source); 1269 ASSERT_TRUE(HasChildCount(FC, 1)); 1270 1271 { 1272 VerbatimBlockComment *VBC; 1273 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC, 1274 "verbatim", "endverbatim", 1275 NoLines())); 1276 } 1277 } 1278 1279 TEST_F(CommentParserTest, VerbatimBlock5) { 1280 const char *Sources[] = { 1281 "//\\verbatim\n" 1282 "// Aaa\n" 1283 "//\\endverbatim\n", 1284 1285 "/*\\verbatim\n" 1286 " * Aaa\n" 1287 " *\\endverbatim*/" 1288 }; 1289 1290 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1291 FullComment *FC = parseString(Sources[i]); 1292 ASSERT_TRUE(HasChildCount(FC, 1)); 1293 1294 { 1295 VerbatimBlockComment *VBC; 1296 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC, 1297 "verbatim", "endverbatim", 1298 Lines(), " Aaa")); 1299 } 1300 } 1301 } 1302 1303 TEST_F(CommentParserTest, VerbatimBlock6) { 1304 const char *Sources[] = { 1305 "// \\verbatim\n" 1306 "// Aaa\n" 1307 "// \\endverbatim\n", 1308 1309 "/* \\verbatim\n" 1310 " * Aaa\n" 1311 " * \\endverbatim*/" 1312 }; 1313 1314 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1315 FullComment *FC = parseString(Sources[i]); 1316 ASSERT_TRUE(HasChildCount(FC, 2)); 1317 1318 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1319 { 1320 VerbatimBlockComment *VBC; 1321 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, 1322 "verbatim", "endverbatim", 1323 Lines(), " Aaa")); 1324 } 1325 } 1326 } 1327 1328 TEST_F(CommentParserTest, VerbatimBlock7) { 1329 const char *Sources[] = { 1330 "// \\verbatim\n" 1331 "// Aaa\n" 1332 "// Bbb\n" 1333 "// \\endverbatim\n", 1334 1335 "/* \\verbatim\n" 1336 " * Aaa\n" 1337 " * Bbb\n" 1338 " * \\endverbatim*/" 1339 }; 1340 1341 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1342 FullComment *FC = parseString(Sources[i]); 1343 ASSERT_TRUE(HasChildCount(FC, 2)); 1344 1345 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1346 { 1347 VerbatimBlockComment *VBC; 1348 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, 1349 "verbatim", "endverbatim", 1350 Lines(), " Aaa", " Bbb")); 1351 } 1352 } 1353 } 1354 1355 TEST_F(CommentParserTest, VerbatimBlock8) { 1356 const char *Sources[] = { 1357 "// \\verbatim\n" 1358 "// Aaa\n" 1359 "//\n" 1360 "// Bbb\n" 1361 "// \\endverbatim\n", 1362 1363 "/* \\verbatim\n" 1364 " * Aaa\n" 1365 " *\n" 1366 " * Bbb\n" 1367 " * \\endverbatim*/" 1368 }; 1369 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1370 FullComment *FC = parseString(Sources[i]); 1371 ASSERT_TRUE(HasChildCount(FC, 2)); 1372 1373 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1374 { 1375 VerbatimBlockComment *VBC; 1376 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, 1377 "verbatim", "endverbatim")); 1378 ASSERT_EQ(3U, VBC->getNumLines()); 1379 ASSERT_EQ(" Aaa", VBC->getText(0)); 1380 ASSERT_EQ("", VBC->getText(1)); 1381 ASSERT_EQ(" Bbb", VBC->getText(2)); 1382 } 1383 } 1384 } 1385 1386 TEST_F(CommentParserTest, VerbatimLine1) { 1387 const char *Sources[] = { 1388 "// \\fn", 1389 "// \\fn\n" 1390 }; 1391 1392 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1393 FullComment *FC = parseString(Sources[i]); 1394 ASSERT_TRUE(HasChildCount(FC, 2)); 1395 1396 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1397 { 1398 VerbatimLineComment *VLC; 1399 ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", "")); 1400 } 1401 } 1402 } 1403 1404 TEST_F(CommentParserTest, VerbatimLine2) { 1405 const char *Sources[] = { 1406 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//", 1407 "/** \\fn void *foo(const char *zzz = \"\\$\");*/" 1408 }; 1409 1410 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1411 FullComment *FC = parseString(Sources[i]); 1412 ASSERT_TRUE(HasChildCount(FC, 2)); 1413 1414 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1415 { 1416 VerbatimLineComment *VLC; 1417 ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", 1418 " void *foo(const char *zzz = \"\\$\");")); 1419 } 1420 } 1421 } 1422 1423 TEST_F(CommentParserTest, Deprecated) { 1424 const char *Sources[] = { 1425 "/** @deprecated*/", 1426 "/// @deprecated\n" 1427 }; 1428 1429 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) { 1430 FullComment *FC = parseString(Sources[i]); 1431 ASSERT_TRUE(HasChildCount(FC, 2)); 1432 1433 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); 1434 { 1435 BlockCommandComment *BCC; 1436 ParagraphComment *PC; 1437 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "deprecated", PC)); 1438 ASSERT_TRUE(HasChildCount(PC, 0)); 1439 } 1440 } 1441 } 1442 1443 } // unnamed namespace 1444 1445 } // end namespace comments 1446 } // end namespace clang 1447 1448