[RISCV] Add missing SiFive P400 scheduling model test for divisions. NFC
[llvm-project.git] / clang / unittests / AST / CommentParser.cpp
blobe0df182d430c36a3585ba87a588887c71473958c
1 //===- unittests/AST/CommentParser.cpp ------ Comment parser tests --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "clang/AST/CommentParser.h"
10 #include "clang/AST/Comment.h"
11 #include "clang/AST/CommentCommandTraits.h"
12 #include "clang/AST/CommentLexer.h"
13 #include "clang/AST/CommentSema.h"
14 #include "clang/Basic/CommentOptions.h"
15 #include "clang/Basic/Diagnostic.h"
16 #include "clang/Basic/DiagnosticOptions.h"
17 #include "clang/Basic/FileManager.h"
18 #include "clang/Basic/SourceManager.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/Support/Allocator.h"
21 #include "gtest/gtest.h"
23 using namespace llvm;
24 using namespace clang;
26 namespace clang {
27 namespace comments {
29 namespace {
31 const bool MY_DEBUG = true;
33 class CommentParserTest : public ::testing::Test {
34 protected:
35 CommentParserTest()
36 : FileMgr(FileMgrOpts),
37 DiagID(new DiagnosticIDs()),
38 Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
39 SourceMgr(Diags, FileMgr),
40 Traits(Allocator, CommentOptions()) {
43 FileSystemOptions FileMgrOpts;
44 FileManager FileMgr;
45 IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
46 DiagnosticsEngine Diags;
47 SourceManager SourceMgr;
48 llvm::BumpPtrAllocator Allocator;
49 CommandTraits Traits;
51 FullComment *parseString(const char *Source);
54 FullComment *CommentParserTest::parseString(const char *Source) {
55 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Source);
56 FileID File = SourceMgr.createFileID(std::move(Buf));
57 SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
59 Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source));
61 Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ nullptr);
62 Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
63 FullComment *FC = P.parseFullComment();
65 if (MY_DEBUG) {
66 llvm::errs() << "=== Source:\n" << Source << "\n=== AST:\n";
67 FC->dump();
70 Token Tok;
71 L.lex(Tok);
72 if (Tok.is(tok::eof))
73 return FC;
74 else
75 return nullptr;
78 ::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) {
79 if (!C)
80 return ::testing::AssertionFailure() << "Comment is NULL";
82 if (Count != C->child_count())
83 return ::testing::AssertionFailure()
84 << "Count = " << Count
85 << ", child_count = " << C->child_count();
87 return ::testing::AssertionSuccess();
90 template <typename T>
91 ::testing::AssertionResult GetChildAt(const Comment *C,
92 size_t Idx,
93 T *&Child) {
94 if (!C)
95 return ::testing::AssertionFailure() << "Comment is NULL";
97 if (Idx >= C->child_count())
98 return ::testing::AssertionFailure()
99 << "Idx out of range. Idx = " << Idx
100 << ", child_count = " << C->child_count();
102 Comment::child_iterator I = C->child_begin() + Idx;
103 Comment *CommentChild = *I;
104 if (!CommentChild)
105 return ::testing::AssertionFailure() << "Child is NULL";
107 Child = dyn_cast<T>(CommentChild);
108 if (!Child)
109 return ::testing::AssertionFailure()
110 << "Child is not of requested type, but a "
111 << CommentChild->getCommentKindName();
113 return ::testing::AssertionSuccess();
116 ::testing::AssertionResult HasTextAt(const Comment *C,
117 size_t Idx,
118 StringRef Text) {
119 TextComment *TC;
120 ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
121 if (!AR)
122 return AR;
124 StringRef ActualText = TC->getText();
125 if (ActualText != Text)
126 return ::testing::AssertionFailure()
127 << "TextComment has text \"" << ActualText.str() << "\", "
128 "expected \"" << Text.str() << "\"";
130 if (TC->hasTrailingNewline())
131 return ::testing::AssertionFailure()
132 << "TextComment has a trailing newline";
134 return ::testing::AssertionSuccess();
137 ::testing::AssertionResult HasTextWithNewlineAt(const Comment *C,
138 size_t Idx,
139 StringRef Text) {
140 TextComment *TC;
141 ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
142 if (!AR)
143 return AR;
145 StringRef ActualText = TC->getText();
146 if (ActualText != Text)
147 return ::testing::AssertionFailure()
148 << "TextComment has text \"" << ActualText.str() << "\", "
149 "expected \"" << Text.str() << "\"";
151 if (!TC->hasTrailingNewline())
152 return ::testing::AssertionFailure()
153 << "TextComment has no trailing newline";
155 return ::testing::AssertionSuccess();
158 ::testing::AssertionResult HasBlockCommandAt(const Comment *C,
159 const CommandTraits &Traits,
160 size_t Idx,
161 BlockCommandComment *&BCC,
162 StringRef Name,
163 ParagraphComment *&Paragraph) {
164 ::testing::AssertionResult AR = GetChildAt(C, Idx, BCC);
165 if (!AR)
166 return AR;
168 StringRef ActualName = BCC->getCommandName(Traits);
169 if (ActualName != Name)
170 return ::testing::AssertionFailure()
171 << "BlockCommandComment has name \"" << ActualName.str() << "\", "
172 "expected \"" << Name.str() << "\"";
174 Paragraph = BCC->getParagraph();
176 return ::testing::AssertionSuccess();
179 ::testing::AssertionResult
180 HasParamCommandAt(const Comment *C, const CommandTraits &Traits, size_t Idx,
181 ParamCommandComment *&PCC, StringRef CommandName,
182 ParamCommandPassDirection Direction, bool IsDirectionExplicit,
183 StringRef ParamName, ParagraphComment *&Paragraph) {
184 ::testing::AssertionResult AR = GetChildAt(C, Idx, PCC);
185 if (!AR)
186 return AR;
188 StringRef ActualCommandName = PCC->getCommandName(Traits);
189 if (ActualCommandName != CommandName)
190 return ::testing::AssertionFailure()
191 << "ParamCommandComment has name \"" << ActualCommandName.str() << "\", "
192 "expected \"" << CommandName.str() << "\"";
194 if (PCC->getDirection() != Direction)
195 return ::testing::AssertionFailure()
196 << "ParamCommandComment has direction "
197 << llvm::to_underlying(PCC->getDirection()) << ", expected "
198 << llvm::to_underlying(Direction);
200 if (PCC->isDirectionExplicit() != IsDirectionExplicit)
201 return ::testing::AssertionFailure()
202 << "ParamCommandComment has "
203 << (PCC->isDirectionExplicit() ? "explicit" : "implicit")
204 << " direction, "
205 "expected " << (IsDirectionExplicit ? "explicit" : "implicit");
207 if (!ParamName.empty() && !PCC->hasParamName())
208 return ::testing::AssertionFailure()
209 << "ParamCommandComment has no parameter name";
211 StringRef ActualParamName = PCC->hasParamName() ? PCC->getParamNameAsWritten() : "";
212 if (ActualParamName != ParamName)
213 return ::testing::AssertionFailure()
214 << "ParamCommandComment has parameter name \"" << ActualParamName.str()
215 << "\", "
216 "expected \"" << ParamName.str() << "\"";
218 Paragraph = PCC->getParagraph();
220 return ::testing::AssertionSuccess();
223 ::testing::AssertionResult HasTParamCommandAt(
224 const Comment *C,
225 const CommandTraits &Traits,
226 size_t Idx,
227 TParamCommandComment *&TPCC,
228 StringRef CommandName,
229 StringRef ParamName,
230 ParagraphComment *&Paragraph) {
231 ::testing::AssertionResult AR = GetChildAt(C, Idx, TPCC);
232 if (!AR)
233 return AR;
235 StringRef ActualCommandName = TPCC->getCommandName(Traits);
236 if (ActualCommandName != CommandName)
237 return ::testing::AssertionFailure()
238 << "TParamCommandComment has name \"" << ActualCommandName.str() << "\", "
239 "expected \"" << CommandName.str() << "\"";
241 if (!ParamName.empty() && !TPCC->hasParamName())
242 return ::testing::AssertionFailure()
243 << "TParamCommandComment has no parameter name";
245 StringRef ActualParamName = TPCC->hasParamName() ? TPCC->getParamNameAsWritten() : "";
246 if (ActualParamName != ParamName)
247 return ::testing::AssertionFailure()
248 << "TParamCommandComment has parameter name \"" << ActualParamName.str()
249 << "\", "
250 "expected \"" << ParamName.str() << "\"";
252 Paragraph = TPCC->getParagraph();
254 return ::testing::AssertionSuccess();
257 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
258 const CommandTraits &Traits,
259 size_t Idx,
260 InlineCommandComment *&ICC,
261 StringRef Name) {
262 ::testing::AssertionResult AR = GetChildAt(C, Idx, ICC);
263 if (!AR)
264 return AR;
266 StringRef ActualName = ICC->getCommandName(Traits);
267 if (ActualName != Name)
268 return ::testing::AssertionFailure()
269 << "InlineCommandComment has name \"" << ActualName.str() << "\", "
270 "expected \"" << Name.str() << "\"";
272 return ::testing::AssertionSuccess();
275 struct NoArgs {};
277 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
278 const CommandTraits &Traits,
279 size_t Idx,
280 InlineCommandComment *&ICC,
281 StringRef Name,
282 NoArgs) {
283 ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name);
284 if (!AR)
285 return AR;
287 if (ICC->getNumArgs() != 0)
288 return ::testing::AssertionFailure()
289 << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
290 "expected 0";
292 return ::testing::AssertionSuccess();
295 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
296 const CommandTraits &Traits,
297 size_t Idx,
298 InlineCommandComment *&ICC,
299 StringRef Name,
300 StringRef Arg) {
301 ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name);
302 if (!AR)
303 return AR;
305 if (ICC->getNumArgs() != 1)
306 return ::testing::AssertionFailure()
307 << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
308 "expected 1";
310 StringRef ActualArg = ICC->getArgText(0);
311 if (ActualArg != Arg)
312 return ::testing::AssertionFailure()
313 << "InlineCommandComment has argument \"" << ActualArg.str() << "\", "
314 "expected \"" << Arg.str() << "\"";
316 return ::testing::AssertionSuccess();
319 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
320 size_t Idx,
321 HTMLStartTagComment *&HST,
322 StringRef TagName) {
323 ::testing::AssertionResult AR = GetChildAt(C, Idx, HST);
324 if (!AR)
325 return AR;
327 StringRef ActualTagName = HST->getTagName();
328 if (ActualTagName != TagName)
329 return ::testing::AssertionFailure()
330 << "HTMLStartTagComment has name \"" << ActualTagName.str() << "\", "
331 "expected \"" << TagName.str() << "\"";
333 return ::testing::AssertionSuccess();
336 struct SelfClosing {};
338 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
339 size_t Idx,
340 HTMLStartTagComment *&HST,
341 StringRef TagName,
342 SelfClosing) {
343 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
344 if (!AR)
345 return AR;
347 if (!HST->isSelfClosing())
348 return ::testing::AssertionFailure()
349 << "HTMLStartTagComment is not self-closing";
351 return ::testing::AssertionSuccess();
355 struct NoAttrs {};
357 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
358 size_t Idx,
359 HTMLStartTagComment *&HST,
360 StringRef TagName,
361 NoAttrs) {
362 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
363 if (!AR)
364 return AR;
366 if (HST->isSelfClosing())
367 return ::testing::AssertionFailure()
368 << "HTMLStartTagComment is self-closing";
370 if (HST->getNumAttrs() != 0)
371 return ::testing::AssertionFailure()
372 << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
373 "expected 0";
375 return ::testing::AssertionSuccess();
378 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
379 size_t Idx,
380 HTMLStartTagComment *&HST,
381 StringRef TagName,
382 StringRef AttrName,
383 StringRef AttrValue) {
384 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
385 if (!AR)
386 return AR;
388 if (HST->isSelfClosing())
389 return ::testing::AssertionFailure()
390 << "HTMLStartTagComment is self-closing";
392 if (HST->getNumAttrs() != 1)
393 return ::testing::AssertionFailure()
394 << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
395 "expected 1";
397 StringRef ActualName = HST->getAttr(0).Name;
398 if (ActualName != AttrName)
399 return ::testing::AssertionFailure()
400 << "HTMLStartTagComment has attr \"" << ActualName.str() << "\", "
401 "expected \"" << AttrName.str() << "\"";
403 StringRef ActualValue = HST->getAttr(0).Value;
404 if (ActualValue != AttrValue)
405 return ::testing::AssertionFailure()
406 << "HTMLStartTagComment has attr value \"" << ActualValue.str() << "\", "
407 "expected \"" << AttrValue.str() << "\"";
409 return ::testing::AssertionSuccess();
412 ::testing::AssertionResult HasHTMLEndTagAt(const Comment *C,
413 size_t Idx,
414 HTMLEndTagComment *&HET,
415 StringRef TagName) {
416 ::testing::AssertionResult AR = GetChildAt(C, Idx, HET);
417 if (!AR)
418 return AR;
420 StringRef ActualTagName = HET->getTagName();
421 if (ActualTagName != TagName)
422 return ::testing::AssertionFailure()
423 << "HTMLEndTagComment has name \"" << ActualTagName.str() << "\", "
424 "expected \"" << TagName.str() << "\"";
426 return ::testing::AssertionSuccess();
429 ::testing::AssertionResult HasParagraphCommentAt(const Comment *C,
430 size_t Idx,
431 StringRef Text) {
432 ParagraphComment *PC;
435 ::testing::AssertionResult AR = GetChildAt(C, Idx, PC);
436 if (!AR)
437 return AR;
441 ::testing::AssertionResult AR = HasChildCount(PC, 1);
442 if (!AR)
443 return AR;
447 ::testing::AssertionResult AR = HasTextAt(PC, 0, Text);
448 if (!AR)
449 return AR;
452 return ::testing::AssertionSuccess();
455 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
456 const CommandTraits &Traits,
457 size_t Idx,
458 VerbatimBlockComment *&VBC,
459 StringRef Name,
460 StringRef CloseName) {
461 ::testing::AssertionResult AR = GetChildAt(C, Idx, VBC);
462 if (!AR)
463 return AR;
465 StringRef ActualName = VBC->getCommandName(Traits);
466 if (ActualName != Name)
467 return ::testing::AssertionFailure()
468 << "VerbatimBlockComment has name \"" << ActualName.str() << "\", "
469 "expected \"" << Name.str() << "\"";
471 StringRef ActualCloseName = VBC->getCloseName();
472 if (ActualCloseName != CloseName)
473 return ::testing::AssertionFailure()
474 << "VerbatimBlockComment has closing command name \""
475 << ActualCloseName.str() << "\", "
476 "expected \"" << CloseName.str() << "\"";
478 return ::testing::AssertionSuccess();
481 struct NoLines {};
482 struct Lines {};
484 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
485 const CommandTraits &Traits,
486 size_t Idx,
487 VerbatimBlockComment *&VBC,
488 StringRef Name,
489 StringRef CloseName,
490 NoLines) {
491 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
492 CloseName);
493 if (!AR)
494 return AR;
496 if (VBC->getNumLines() != 0)
497 return ::testing::AssertionFailure()
498 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
499 "expected 0";
501 return ::testing::AssertionSuccess();
504 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
505 const CommandTraits &Traits,
506 size_t Idx,
507 VerbatimBlockComment *&VBC,
508 StringRef Name,
509 StringRef CloseName,
510 Lines,
511 StringRef Line0) {
512 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
513 CloseName);
514 if (!AR)
515 return AR;
517 if (VBC->getNumLines() != 1)
518 return ::testing::AssertionFailure()
519 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
520 "expected 1";
522 StringRef ActualLine0 = VBC->getText(0);
523 if (ActualLine0 != Line0)
524 return ::testing::AssertionFailure()
525 << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", "
526 "expected \"" << Line0.str() << "\"";
528 return ::testing::AssertionSuccess();
531 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
532 const CommandTraits &Traits,
533 size_t Idx,
534 VerbatimBlockComment *&VBC,
535 StringRef Name,
536 StringRef CloseName,
537 Lines,
538 StringRef Line0,
539 StringRef Line1) {
540 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
541 CloseName);
542 if (!AR)
543 return AR;
545 if (VBC->getNumLines() != 2)
546 return ::testing::AssertionFailure()
547 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
548 "expected 2";
550 StringRef ActualLine0 = VBC->getText(0);
551 if (ActualLine0 != Line0)
552 return ::testing::AssertionFailure()
553 << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", "
554 "expected \"" << Line0.str() << "\"";
556 StringRef ActualLine1 = VBC->getText(1);
557 if (ActualLine1 != Line1)
558 return ::testing::AssertionFailure()
559 << "VerbatimBlockComment has lines[1] \"" << ActualLine1.str() << "\", "
560 "expected \"" << Line1.str() << "\"";
562 return ::testing::AssertionSuccess();
565 ::testing::AssertionResult HasVerbatimLineAt(const Comment *C,
566 const CommandTraits &Traits,
567 size_t Idx,
568 VerbatimLineComment *&VLC,
569 StringRef Name,
570 StringRef Text) {
571 ::testing::AssertionResult AR = GetChildAt(C, Idx, VLC);
572 if (!AR)
573 return AR;
575 StringRef ActualName = VLC->getCommandName(Traits);
576 if (ActualName != Name)
577 return ::testing::AssertionFailure()
578 << "VerbatimLineComment has name \"" << ActualName.str() << "\", "
579 "expected \"" << Name.str() << "\"";
581 StringRef ActualText = VLC->getText();
582 if (ActualText != Text)
583 return ::testing::AssertionFailure()
584 << "VerbatimLineComment has text \"" << ActualText.str() << "\", "
585 "expected \"" << Text.str() << "\"";
587 return ::testing::AssertionSuccess();
591 TEST_F(CommentParserTest, Basic1) {
592 const char *Source = "//";
594 FullComment *FC = parseString(Source);
595 ASSERT_TRUE(HasChildCount(FC, 0));
598 TEST_F(CommentParserTest, Basic2) {
599 const char *Source = "// Meow";
601 FullComment *FC = parseString(Source);
602 ASSERT_TRUE(HasChildCount(FC, 1));
604 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Meow"));
607 TEST_F(CommentParserTest, Basic3) {
608 const char *Source =
609 "// Aaa\n"
610 "// Bbb";
612 FullComment *FC = parseString(Source);
613 ASSERT_TRUE(HasChildCount(FC, 1));
616 ParagraphComment *PC;
617 ASSERT_TRUE(GetChildAt(FC, 0, PC));
619 ASSERT_TRUE(HasChildCount(PC, 2));
620 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
621 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb"));
625 TEST_F(CommentParserTest, ParagraphSplitting1) {
626 const char *Sources[] = {
627 ("// Aaa\n"
628 "//\n"
629 "// Bbb"),
631 ("// Aaa\n"
632 "// \n"
633 "// Bbb"),
635 ("// Aaa\n"
636 "//\t\n"
637 "// Bbb"),
639 ("// Aaa\n"
640 "//\n"
641 "//\n"
642 "// Bbb"),
644 ("/**\n"
645 " Aaa\n"
646 "\n"
647 " Bbb\n"
648 "*/"),
650 ("/**\n"
651 " Aaa\n"
652 " \n"
653 " Bbb\n"
654 "*/"),
656 ("/**\n"
657 " Aaa\n"
658 "\t \n"
659 " Bbb\n"
660 "*/"),
663 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
664 FullComment *FC = parseString(Sources[i]);
665 ASSERT_TRUE(HasChildCount(FC, 2));
667 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Aaa"));
668 ASSERT_TRUE(HasParagraphCommentAt(FC, 1, " Bbb"));
672 TEST_F(CommentParserTest, Paragraph1) {
673 const char *Source =
674 "// \\brief Aaa\n"
675 "//\n"
676 "// Bbb";
678 FullComment *FC = parseString(Source);
679 ASSERT_TRUE(HasChildCount(FC, 3));
681 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
683 BlockCommandComment *BCC;
684 ParagraphComment *PC;
685 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
687 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa"));
689 ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb"));
692 TEST_F(CommentParserTest, Paragraph2) {
693 const char *Source = "// \\brief \\author";
695 FullComment *FC = parseString(Source);
696 ASSERT_TRUE(HasChildCount(FC, 3));
698 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
700 BlockCommandComment *BCC;
701 ParagraphComment *PC;
702 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
704 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " "));
707 BlockCommandComment *BCC;
708 ParagraphComment *PC;
709 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC));
711 ASSERT_TRUE(GetChildAt(BCC, 0, PC));
712 ASSERT_TRUE(HasChildCount(PC, 0));
716 TEST_F(CommentParserTest, Paragraph3) {
717 const char *Source =
718 "// \\brief Aaa\n"
719 "// Bbb \\author\n"
720 "// Ccc";
722 FullComment *FC = parseString(Source);
723 ASSERT_TRUE(HasChildCount(FC, 3));
725 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
727 BlockCommandComment *BCC;
728 ParagraphComment *PC;
729 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
731 ASSERT_TRUE(GetChildAt(BCC, 0, PC));
732 ASSERT_TRUE(HasChildCount(PC, 2));
733 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
734 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb "));
737 BlockCommandComment *BCC;
738 ParagraphComment *PC;
739 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC));
741 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc"));
745 TEST_F(CommentParserTest, ParamCommand1) {
746 const char *Source = "// \\param aaa";
748 FullComment *FC = parseString(Source);
749 ASSERT_TRUE(HasChildCount(FC, 2));
751 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
753 ParamCommandComment *PCC;
754 ParagraphComment *PC;
755 ASSERT_TRUE(HasParamCommandAt(
756 FC, Traits, 1, PCC, "param", ParamCommandPassDirection::In,
757 /* IsDirectionExplicit = */ false, "aaa", PC));
758 ASSERT_TRUE(HasChildCount(PCC, 1));
759 ASSERT_TRUE(HasChildCount(PC, 0));
763 TEST_F(CommentParserTest, ParamCommand2) {
764 const char *Source = "// \\param\\brief";
766 FullComment *FC = parseString(Source);
767 ASSERT_TRUE(HasChildCount(FC, 3));
769 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
771 ParamCommandComment *PCC;
772 ParagraphComment *PC;
773 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
774 ParamCommandPassDirection::In,
775 /* IsDirectionExplicit = */ false, "", PC));
776 ASSERT_TRUE(HasChildCount(PCC, 1));
777 ASSERT_TRUE(HasChildCount(PC, 0));
780 BlockCommandComment *BCC;
781 ParagraphComment *PC;
782 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC));
783 ASSERT_TRUE(HasChildCount(PC, 0));
787 TEST_F(CommentParserTest, ParamCommand3) {
788 const char *Sources[] = {
789 "// \\param aaa Bbb\n",
790 ("// \\param\n"
791 "// aaa Bbb\n"),
792 ("// \\param \n"
793 "// aaa Bbb\n"),
794 ("// \\param aaa\n"
795 "// Bbb\n")
798 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
799 FullComment *FC = parseString(Sources[i]);
800 ASSERT_TRUE(HasChildCount(FC, 2));
802 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
804 ParamCommandComment *PCC;
805 ParagraphComment *PC;
806 ASSERT_TRUE(HasParamCommandAt(
807 FC, Traits, 1, PCC, "param", ParamCommandPassDirection::In,
808 /* IsDirectionExplicit = */ false, "aaa", PC));
809 ASSERT_TRUE(HasChildCount(PCC, 1));
810 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
815 TEST_F(CommentParserTest, ParamCommand4) {
816 const char *Sources[] = {
817 "// \\param [in] aaa Bbb\n",
818 "// \\param[in] aaa Bbb\n",
819 ("// \\param\n"
820 "// [in] aaa Bbb\n"),
821 ("// \\param [in]\n"
822 "// aaa Bbb\n"),
823 ("// \\param [in] aaa\n"
824 "// Bbb\n"),
827 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
828 FullComment *FC = parseString(Sources[i]);
829 ASSERT_TRUE(HasChildCount(FC, 2));
831 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
833 ParamCommandComment *PCC;
834 ParagraphComment *PC;
835 ASSERT_TRUE(HasParamCommandAt(
836 FC, Traits, 1, PCC, "param", ParamCommandPassDirection::In,
837 /* IsDirectionExplicit = */ true, "aaa", PC));
838 ASSERT_TRUE(HasChildCount(PCC, 1));
839 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
844 TEST_F(CommentParserTest, ParamCommand5) {
845 const char *Sources[] = {
846 "// \\param [out] aaa Bbb\n",
847 "// \\param[out] aaa Bbb\n",
848 ("// \\param\n"
849 "// [out] aaa Bbb\n"),
850 ("// \\param [out]\n"
851 "// aaa Bbb\n"),
852 ("// \\param [out] aaa\n"
853 "// Bbb\n"),
856 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
857 FullComment *FC = parseString(Sources[i]);
858 ASSERT_TRUE(HasChildCount(FC, 2));
860 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
862 ParamCommandComment *PCC;
863 ParagraphComment *PC;
864 ASSERT_TRUE(HasParamCommandAt(
865 FC, Traits, 1, PCC, "param", ParamCommandPassDirection::Out,
866 /* IsDirectionExplicit = */ true, "aaa", PC));
867 ASSERT_TRUE(HasChildCount(PCC, 1));
868 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
873 TEST_F(CommentParserTest, ParamCommand6) {
874 const char *Sources[] = {
875 "// \\param [in,out] aaa Bbb\n",
876 "// \\param[in,out] aaa Bbb\n",
877 "// \\param [in, out] aaa Bbb\n",
878 "// \\param [in,\n"
879 "// out] aaa Bbb\n",
880 "// \\param [in,out]\n"
881 "// aaa Bbb\n",
882 "// \\param [in,out] aaa\n"
883 "// Bbb\n"
886 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
887 FullComment *FC = parseString(Sources[i]);
888 ASSERT_TRUE(HasChildCount(FC, 2));
890 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
892 ParamCommandComment *PCC;
893 ParagraphComment *PC;
894 ASSERT_TRUE(HasParamCommandAt(
895 FC, Traits, 1, PCC, "param", ParamCommandPassDirection::InOut,
896 /* IsDirectionExplicit = */ true, "aaa", PC));
897 ASSERT_TRUE(HasChildCount(PCC, 1));
898 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
903 TEST_F(CommentParserTest, ParamCommand7) {
904 const char *Source =
905 "// \\param aaa \\% Bbb \\$ ccc\n";
907 FullComment *FC = parseString(Source);
908 ASSERT_TRUE(HasChildCount(FC, 2));
910 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
912 ParamCommandComment *PCC;
913 ParagraphComment *PC;
914 ASSERT_TRUE(HasParamCommandAt(
915 FC, Traits, 1, PCC, "param", ParamCommandPassDirection::In,
916 /* IsDirectionExplicit = */ false, "aaa", PC));
917 ASSERT_TRUE(HasChildCount(PCC, 1));
919 ASSERT_TRUE(HasChildCount(PC, 5));
920 ASSERT_TRUE(HasTextAt(PC, 0, " "));
921 ASSERT_TRUE(HasTextAt(PC, 1, "%"));
922 ASSERT_TRUE(HasTextAt(PC, 2, " Bbb "));
923 ASSERT_TRUE(HasTextAt(PC, 3, "$"));
924 ASSERT_TRUE(HasTextAt(PC, 4, " ccc"));
928 TEST_F(CommentParserTest, TParamCommand1) {
929 const char *Sources[] = {
930 "// \\tparam aaa Bbb\n",
931 "// \\tparam\n"
932 "// aaa Bbb\n",
933 "// \\tparam \n"
934 "// aaa Bbb\n",
935 "// \\tparam aaa\n"
936 "// Bbb\n"
939 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
940 FullComment *FC = parseString(Sources[i]);
941 ASSERT_TRUE(HasChildCount(FC, 2));
943 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
945 TParamCommandComment *TPCC;
946 ParagraphComment *PC;
947 ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam",
948 "aaa", PC));
949 ASSERT_TRUE(HasChildCount(TPCC, 1));
950 ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb"));
955 TEST_F(CommentParserTest, TParamCommand2) {
956 const char *Source = "// \\tparam\\brief";
958 FullComment *FC = parseString(Source);
959 ASSERT_TRUE(HasChildCount(FC, 3));
961 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
963 TParamCommandComment *TPCC;
964 ParagraphComment *PC;
965 ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", "", PC));
966 ASSERT_TRUE(HasChildCount(TPCC, 1));
967 ASSERT_TRUE(HasChildCount(PC, 0));
970 BlockCommandComment *BCC;
971 ParagraphComment *PC;
972 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC));
973 ASSERT_TRUE(HasChildCount(PC, 0));
978 TEST_F(CommentParserTest, InlineCommand1) {
979 const char *Source = "// \\c";
981 FullComment *FC = parseString(Source);
982 ASSERT_TRUE(HasChildCount(FC, 1));
985 ParagraphComment *PC;
986 InlineCommandComment *ICC;
987 ASSERT_TRUE(GetChildAt(FC, 0, PC));
989 ASSERT_TRUE(HasChildCount(PC, 2));
990 ASSERT_TRUE(HasTextAt(PC, 0, " "));
991 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs()));
995 TEST_F(CommentParserTest, InlineCommand2) {
996 const char *Source = "// \\c ";
998 FullComment *FC = parseString(Source);
999 ASSERT_TRUE(HasChildCount(FC, 1));
1002 ParagraphComment *PC;
1003 InlineCommandComment *ICC;
1004 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1006 ASSERT_TRUE(HasChildCount(PC, 3));
1007 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1008 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs()));
1009 ASSERT_TRUE(HasTextAt(PC, 2, " "));
1013 TEST_F(CommentParserTest, InlineCommand3) {
1014 const char *Source = "// \\c aaa\n";
1016 FullComment *FC = parseString(Source);
1017 ASSERT_TRUE(HasChildCount(FC, 1));
1020 ParagraphComment *PC;
1021 InlineCommandComment *ICC;
1022 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1024 ASSERT_TRUE(HasChildCount(PC, 2));
1025 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1026 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa"));
1030 TEST_F(CommentParserTest, InlineCommand4) {
1031 const char *Source = "// \\c aaa bbb";
1033 FullComment *FC = parseString(Source);
1034 ASSERT_TRUE(HasChildCount(FC, 1));
1037 ParagraphComment *PC;
1038 InlineCommandComment *ICC;
1039 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1041 ASSERT_TRUE(HasChildCount(PC, 3));
1042 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1043 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa"));
1044 ASSERT_TRUE(HasTextAt(PC, 2, " bbb"));
1048 TEST_F(CommentParserTest, InlineCommand5) {
1049 const char *Source = "// \\unknown aaa\n";
1051 FullComment *FC = parseString(Source);
1052 ASSERT_TRUE(HasChildCount(FC, 1));
1055 ParagraphComment *PC;
1056 InlineCommandComment *ICC;
1057 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1059 ASSERT_TRUE(HasChildCount(PC, 3));
1060 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1061 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "unknown", NoArgs()));
1062 ASSERT_TRUE(HasTextAt(PC, 2, " aaa"));
1066 TEST_F(CommentParserTest, HTML1) {
1067 const char *Sources[] = {
1068 "// <a",
1069 "// <a>",
1070 "// <a >"
1073 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1074 FullComment *FC = parseString(Sources[i]);
1075 ASSERT_TRUE(HasChildCount(FC, 1));
1078 ParagraphComment *PC;
1079 HTMLStartTagComment *HST;
1080 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1082 ASSERT_TRUE(HasChildCount(PC, 2));
1083 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1084 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs()));
1089 TEST_F(CommentParserTest, HTML2) {
1090 const char *Sources[] = {
1091 "// <br/>",
1092 "// <br />"
1095 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1096 FullComment *FC = parseString(Sources[i]);
1097 ASSERT_TRUE(HasChildCount(FC, 1));
1100 ParagraphComment *PC;
1101 HTMLStartTagComment *HST;
1102 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1104 ASSERT_TRUE(HasChildCount(PC, 2));
1105 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1106 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing()));
1111 TEST_F(CommentParserTest, HTML3) {
1112 const char *Sources[] = {
1113 "// <a href",
1114 "// <a href ",
1115 "// <a href>",
1116 "// <a href >",
1119 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1120 FullComment *FC = parseString(Sources[i]);
1121 ASSERT_TRUE(HasChildCount(FC, 1));
1124 ParagraphComment *PC;
1125 HTMLStartTagComment *HST;
1126 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1128 ASSERT_TRUE(HasChildCount(PC, 2));
1129 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1130 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", ""));
1135 TEST_F(CommentParserTest, HTML4) {
1136 const char *Sources[] = {
1137 "// <a href=\"bbb\"",
1138 "// <a href=\"bbb\">",
1141 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1142 FullComment *FC = parseString(Sources[i]);
1143 ASSERT_TRUE(HasChildCount(FC, 1));
1146 ParagraphComment *PC;
1147 HTMLStartTagComment *HST;
1148 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1150 ASSERT_TRUE(HasChildCount(PC, 2));
1151 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1152 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb"));
1157 TEST_F(CommentParserTest, HTML5) {
1158 const char *Sources[] = {
1159 "// </a",
1160 "// </a>",
1161 "// </a >"
1164 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1165 FullComment *FC = parseString(Sources[i]);
1166 ASSERT_TRUE(HasChildCount(FC, 1));
1169 ParagraphComment *PC;
1170 HTMLEndTagComment *HET;
1171 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1173 ASSERT_TRUE(HasChildCount(PC, 2));
1174 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1175 ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a"));
1180 TEST_F(CommentParserTest, HTML6) {
1181 const char *Source =
1182 "// <pre>\n"
1183 "// Aaa\n"
1184 "// Bbb\n"
1185 "// </pre>\n";
1187 FullComment *FC = parseString(Source);
1188 ASSERT_TRUE(HasChildCount(FC, 1));
1191 ParagraphComment *PC;
1192 HTMLStartTagComment *HST;
1193 HTMLEndTagComment *HET;
1194 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1196 ASSERT_TRUE(HasChildCount(PC, 6));
1197 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1198 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs()));
1199 ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa"));
1200 ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb"));
1201 ASSERT_TRUE(HasTextAt(PC, 4, " "));
1202 ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre"));
1206 TEST_F(CommentParserTest, VerbatimBlock1) {
1207 const char *Source = "// \\verbatim\\endverbatim\n";
1209 FullComment *FC = parseString(Source);
1210 ASSERT_TRUE(HasChildCount(FC, 2));
1212 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1214 VerbatimBlockComment *VCC;
1215 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VCC,
1216 "verbatim", "endverbatim",
1217 NoLines()));
1221 TEST_F(CommentParserTest, VerbatimBlock2) {
1222 const char *Source = "// \\verbatim Aaa \\endverbatim\n";
1224 FullComment *FC = parseString(Source);
1225 ASSERT_TRUE(HasChildCount(FC, 2));
1227 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1229 VerbatimBlockComment *VBC;
1230 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
1231 "verbatim", "endverbatim",
1232 Lines(), " Aaa "));
1236 TEST_F(CommentParserTest, VerbatimBlock3) {
1237 const char *Source = "// \\verbatim Aaa\n";
1239 FullComment *FC = parseString(Source);
1240 ASSERT_TRUE(HasChildCount(FC, 2));
1242 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1244 VerbatimBlockComment *VBC;
1245 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, "verbatim", "",
1246 Lines(), " Aaa"));
1250 TEST_F(CommentParserTest, VerbatimBlock4) {
1251 const char *Source =
1252 "//\\verbatim\n"
1253 "//\\endverbatim\n";
1255 FullComment *FC = parseString(Source);
1256 ASSERT_TRUE(HasChildCount(FC, 1));
1259 VerbatimBlockComment *VBC;
1260 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC,
1261 "verbatim", "endverbatim",
1262 NoLines()));
1266 TEST_F(CommentParserTest, VerbatimBlock5) {
1267 const char *Sources[] = {
1268 "//\\verbatim\n"
1269 "// Aaa\n"
1270 "//\\endverbatim\n",
1272 "/*\\verbatim\n"
1273 " * Aaa\n"
1274 " *\\endverbatim*/"
1277 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1278 FullComment *FC = parseString(Sources[i]);
1279 ASSERT_TRUE(HasChildCount(FC, 1));
1282 VerbatimBlockComment *VBC;
1283 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC,
1284 "verbatim", "endverbatim",
1285 Lines(), " Aaa"));
1290 TEST_F(CommentParserTest, VerbatimBlock6) {
1291 const char *Sources[] = {
1292 "// \\verbatim\n"
1293 "// Aaa\n"
1294 "// \\endverbatim\n",
1296 "/* \\verbatim\n"
1297 " * Aaa\n"
1298 " * \\endverbatim*/"
1301 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1302 FullComment *FC = parseString(Sources[i]);
1303 ASSERT_TRUE(HasChildCount(FC, 2));
1305 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1307 VerbatimBlockComment *VBC;
1308 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
1309 "verbatim", "endverbatim",
1310 Lines(), " Aaa"));
1315 TEST_F(CommentParserTest, VerbatimBlock7) {
1316 const char *Sources[] = {
1317 "// \\verbatim\n"
1318 "// Aaa\n"
1319 "// Bbb\n"
1320 "// \\endverbatim\n",
1322 "/* \\verbatim\n"
1323 " * Aaa\n"
1324 " * Bbb\n"
1325 " * \\endverbatim*/"
1328 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1329 FullComment *FC = parseString(Sources[i]);
1330 ASSERT_TRUE(HasChildCount(FC, 2));
1332 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1334 VerbatimBlockComment *VBC;
1335 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
1336 "verbatim", "endverbatim",
1337 Lines(), " Aaa", " Bbb"));
1342 TEST_F(CommentParserTest, VerbatimBlock8) {
1343 const char *Sources[] = {
1344 "// \\verbatim\n"
1345 "// Aaa\n"
1346 "//\n"
1347 "// Bbb\n"
1348 "// \\endverbatim\n",
1350 "/* \\verbatim\n"
1351 " * Aaa\n"
1352 " *\n"
1353 " * Bbb\n"
1354 " * \\endverbatim*/"
1356 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1357 FullComment *FC = parseString(Sources[i]);
1358 ASSERT_TRUE(HasChildCount(FC, 2));
1360 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1362 VerbatimBlockComment *VBC;
1363 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
1364 "verbatim", "endverbatim"));
1365 ASSERT_EQ(3U, VBC->getNumLines());
1366 ASSERT_EQ(" Aaa", VBC->getText(0));
1367 ASSERT_EQ("", VBC->getText(1));
1368 ASSERT_EQ(" Bbb", VBC->getText(2));
1373 TEST_F(CommentParserTest, VerbatimLine1) {
1374 const char *Sources[] = {
1375 "// \\fn",
1376 "// \\fn\n"
1379 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1380 FullComment *FC = parseString(Sources[i]);
1381 ASSERT_TRUE(HasChildCount(FC, 2));
1383 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1385 VerbatimLineComment *VLC;
1386 ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", ""));
1391 TEST_F(CommentParserTest, VerbatimLine2) {
1392 const char *Sources[] = {
1393 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
1394 "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
1397 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1398 FullComment *FC = parseString(Sources[i]);
1399 ASSERT_TRUE(HasChildCount(FC, 2));
1401 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1403 VerbatimLineComment *VLC;
1404 ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn",
1405 " void *foo(const char *zzz = \"\\$\");"));
1410 TEST_F(CommentParserTest, Deprecated) {
1411 const char *Sources[] = {
1412 "/** @deprecated*/",
1413 "/// @deprecated\n"
1416 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1417 FullComment *FC = parseString(Sources[i]);
1418 ASSERT_TRUE(HasChildCount(FC, 2));
1420 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1422 BlockCommandComment *BCC;
1423 ParagraphComment *PC;
1424 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "deprecated", PC));
1425 ASSERT_TRUE(HasChildCount(PC, 0));
1430 TEST_F(CommentParserTest, ThrowsCommandHasArg1) {
1431 const char *Sources[] = {
1432 "/// @throws int This function throws an integer",
1433 ("/// @throws\n"
1434 "/// int This function throws an integer"),
1435 ("/// @throws \n"
1436 "/// int This function throws an integer"),
1437 ("/// @throws\n"
1438 "/// int\n"
1439 "/// This function throws an integer"),
1440 ("/// @throws \n"
1441 "/// int \n"
1442 "/// This function throws an integer"),
1445 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1446 FullComment *FC = parseString(Sources[i]);
1447 ASSERT_TRUE(HasChildCount(FC, 2));
1449 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1451 BlockCommandComment *BCC;
1452 ParagraphComment *PC;
1453 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1454 ASSERT_TRUE(HasChildCount(PC, 1));
1455 ASSERT_TRUE(BCC->getNumArgs() == 1);
1456 ASSERT_TRUE(BCC->getArgText(0) == "int");
1461 TEST_F(CommentParserTest, ThrowsCommandHasArg2) {
1462 const char *Sources[] = {
1463 "/// @throws int** This function throws a double pointer to an integer",
1466 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1467 FullComment *FC = parseString(Sources[i]);
1468 ASSERT_TRUE(HasChildCount(FC, 2));
1470 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1472 BlockCommandComment *BCC;
1473 ParagraphComment *PC;
1474 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1475 ASSERT_TRUE(HasChildCount(PC, 1));
1476 ASSERT_TRUE(BCC->getNumArgs() == 1);
1477 ASSERT_TRUE(BCC->getArgText(0) == "int**");
1482 TEST_F(CommentParserTest, ThrowsCommandHasArg3) {
1483 const char *Sources[] = {
1484 "/// @throws Error<T> error of type Error<T>",
1487 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1488 FullComment *FC = parseString(Sources[i]);
1489 ASSERT_TRUE(HasChildCount(FC, 2));
1491 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1493 BlockCommandComment *BCC;
1494 ParagraphComment *PC;
1495 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1496 ASSERT_TRUE(HasChildCount(PC, 3)); // Extra children because <T> is parsed
1497 // as a series of TextComments
1498 ASSERT_TRUE(BCC->getNumArgs() == 1);
1499 ASSERT_TRUE(BCC->getArgText(0) == "Error<T>");
1504 TEST_F(CommentParserTest, ThrowsCommandHasArg4) {
1505 const char *Sources[] = {
1506 "/// @throws Error<Container<T>> nested templates",
1509 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1510 FullComment *FC = parseString(Sources[i]);
1511 ASSERT_TRUE(HasChildCount(FC, 2));
1513 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1515 BlockCommandComment *BCC;
1516 ParagraphComment *PC;
1517 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1518 ASSERT_TRUE(HasChildCount(PC, 1));
1519 ASSERT_TRUE(BCC->getNumArgs() == 1);
1520 ASSERT_TRUE(BCC->getArgText(0) == "Error<Container<T>>");
1525 TEST_F(CommentParserTest, ThrowsCommandHasArg5) {
1526 const char *Sources[] = {
1527 "/// @throws Error<Ts...> variadic templates",
1530 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1531 FullComment *FC = parseString(Sources[i]);
1532 ASSERT_TRUE(HasChildCount(FC, 2));
1534 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1536 BlockCommandComment *BCC;
1537 ParagraphComment *PC;
1538 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1539 ASSERT_TRUE(HasChildCount(PC, 1));
1540 ASSERT_TRUE(BCC->getNumArgs() == 1);
1541 ASSERT_TRUE(BCC->getArgText(0) == "Error<Ts...>");
1546 TEST_F(CommentParserTest, ThrowsCommandHasArg6) {
1547 const char *Sources[] = {
1548 "/// @throws Foo<(1 > 0)> typo1",
1551 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1552 FullComment *FC = parseString(Sources[i]);
1553 ASSERT_TRUE(HasChildCount(FC, 2));
1555 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1557 BlockCommandComment *BCC;
1558 ParagraphComment *PC;
1559 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1560 ASSERT_TRUE(HasChildCount(PC, 1));
1561 ASSERT_TRUE(BCC->getNumArgs() == 1);
1562 ASSERT_TRUE(BCC->getArgText(0) == "Foo<(1 >");
1567 // No matter the number of (unmatched) opening brackets, no type is parsed.
1568 TEST_F(CommentParserTest, ThrowsCommandHasArg7) {
1569 const char *Sources[] = {
1570 "/// @throws Foo<",
1571 "/// @throws Foo<<<",
1572 "/// @throws Foo<<<<<<<",
1573 "/// @throws Foo<\n",
1574 "/// @throws Foo<<<\n",
1575 "/// @throws Foo<<<<<<<\n",
1578 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1579 FullComment *FC = parseString(Sources[i]);
1580 ASSERT_TRUE(HasChildCount(FC, 2));
1582 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1584 BlockCommandComment *BCC;
1585 ParagraphComment *PC;
1586 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1587 ASSERT_TRUE(HasChildCount(PC, 0));
1588 ASSERT_TRUE(BCC->getNumArgs() == 0);
1593 // Types with a non-matching closing bracket are parsed as if they are a type
1594 TEST_F(CommentParserTest, ThrowsCommandHasArg8) {
1595 const char *Sources[] = {
1596 "/// @throws Foo>",
1597 "/// @throws Foo>\n",
1600 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1601 FullComment *FC = parseString(Sources[i]);
1602 ASSERT_TRUE(HasChildCount(FC, 2));
1604 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1606 BlockCommandComment *BCC;
1607 ParagraphComment *PC;
1608 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1609 ASSERT_TRUE(HasChildCount(PC, 0));
1610 ASSERT_TRUE(BCC->getNumArgs() == 1);
1611 ASSERT_TRUE(BCC->getArgText(0) == "Foo>");
1616 // Everying up until the end of the paragraph comment will be
1617 // eaten up if the template sequence is unterminated (i.e. number of
1618 // opening and closing brackets is not equal).
1619 TEST_F(CommentParserTest, ThrowsCommandHasArg9) {
1620 const char *Sources[] = {
1621 "/// @throws Foo<Bar<t>\n"
1622 "/// Aaa\n"
1623 "///\n"
1624 "/// Bbb\n"
1627 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1628 FullComment *FC = parseString(Sources[i]);
1629 ASSERT_TRUE(HasChildCount(FC, 3));
1631 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1633 BlockCommandComment *BCC;
1634 ParagraphComment *PC;
1635 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC));
1636 ASSERT_TRUE(HasChildCount(PC, 0));
1637 ASSERT_TRUE(BCC->getNumArgs() == 0);
1642 TEST_F(CommentParserTest, ParCommandHasArg1) {
1643 const char *Sources[] = {
1644 "/// @par Paragraph header:", "/// @par Paragraph header:\n",
1645 "/// @par Paragraph header:\r\n", "/// @par Paragraph header:\n\r",
1646 "/** @par Paragraph header:*/",
1649 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1650 FullComment *FC = parseString(Sources[i]);
1651 ASSERT_TRUE(HasChildCount(FC, 2));
1653 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1655 BlockCommandComment *BCC;
1656 ParagraphComment *PC;
1657 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC));
1658 ASSERT_TRUE(HasChildCount(PC, 0));
1659 ASSERT_TRUE(BCC->getNumArgs() == 1);
1660 ASSERT_TRUE(BCC->getArgText(0) == "Paragraph header:");
1665 TEST_F(CommentParserTest, ParCommandHasArg2) {
1666 const char *Sources[] = {
1667 "/// @par Paragraph header: ", "/// @par Paragraph header: \n",
1668 "/// @par Paragraph header: \r\n", "/// @par Paragraph header: \n\r",
1669 "/** @par Paragraph header: */",
1672 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1673 FullComment *FC = parseString(Sources[i]);
1674 ASSERT_TRUE(HasChildCount(FC, 2));
1676 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1678 BlockCommandComment *BCC;
1679 ParagraphComment *PC;
1680 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC));
1681 ASSERT_TRUE(HasChildCount(PC, 0));
1682 ASSERT_TRUE(BCC->getNumArgs() == 1);
1683 ASSERT_TRUE(BCC->getArgText(0) == "Paragraph header: ");
1688 TEST_F(CommentParserTest, ParCommandHasArg3) {
1689 const char *Sources[] = {
1690 ("/// @par Paragraph header:\n"
1691 "/// Paragraph body"),
1692 ("/// @par Paragraph header:\r\n"
1693 "/// Paragraph body"),
1694 ("/// @par Paragraph header:\n\r"
1695 "/// Paragraph body"),
1698 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1699 FullComment *FC = parseString(Sources[i]);
1700 ASSERT_TRUE(HasChildCount(FC, 2));
1702 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1704 BlockCommandComment *BCC;
1705 ParagraphComment *PC;
1706 TextComment *TC;
1707 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC));
1708 ASSERT_TRUE(HasChildCount(PC, 1));
1709 ASSERT_TRUE(BCC->getNumArgs() == 1);
1710 ASSERT_TRUE(BCC->getArgText(0) == "Paragraph header:");
1711 ASSERT_TRUE(GetChildAt(PC, 0, TC));
1712 ASSERT_TRUE(TC->getText() == " Paragraph body");
1717 TEST_F(CommentParserTest, ParCommandHasArg4) {
1718 const char *Sources[] = {
1719 ("/// @par Paragraph header:\n"
1720 "/// Paragraph body1\n"
1721 "/// Paragraph body2"),
1722 ("/// @par Paragraph header:\r\n"
1723 "/// Paragraph body1\n"
1724 "/// Paragraph body2"),
1725 ("/// @par Paragraph header:\n\r"
1726 "/// Paragraph body1\n"
1727 "/// Paragraph body2"),
1730 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1731 FullComment *FC = parseString(Sources[i]);
1732 ASSERT_TRUE(HasChildCount(FC, 2));
1734 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1736 BlockCommandComment *BCC;
1737 ParagraphComment *PC;
1738 TextComment *TC;
1739 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC));
1740 ASSERT_TRUE(HasChildCount(PC, 2));
1741 ASSERT_TRUE(BCC->getNumArgs() == 1);
1742 ASSERT_TRUE(BCC->getArgText(0) == "Paragraph header:");
1743 ASSERT_TRUE(GetChildAt(PC, 0, TC));
1744 ASSERT_TRUE(TC->getText() == " Paragraph body1");
1745 ASSERT_TRUE(GetChildAt(PC, 1, TC));
1746 ASSERT_TRUE(TC->getText() == " Paragraph body2");
1751 TEST_F(CommentParserTest, ParCommandHasArg5) {
1752 const char *Sources[] = {
1753 ("/// @par \n"
1754 "/// Paragraphs with no text before newline have no heading"),
1755 ("/// @par \r\n"
1756 "/// Paragraphs with no text before newline have no heading"),
1757 ("/// @par \n\r"
1758 "/// Paragraphs with no text before newline have no heading"),
1761 for (size_t i = 0, e = std::size(Sources); i != e; i++) {
1762 FullComment *FC = parseString(Sources[i]);
1763 ASSERT_TRUE(HasChildCount(FC, 2));
1765 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1767 BlockCommandComment *BCC;
1768 ParagraphComment *PC;
1769 TextComment *TC;
1770 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC));
1771 ASSERT_TRUE(HasChildCount(PC, 1));
1772 ASSERT_TRUE(BCC->getNumArgs() == 0);
1773 ASSERT_TRUE(GetChildAt(PC, 0, TC));
1774 ASSERT_TRUE(TC->getText() ==
1775 "Paragraphs with no text before newline have no heading");
1780 } // unnamed namespace
1782 } // end namespace comments
1783 } // end namespace clang