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