1 //===- unittests/AST/CommentParser.cpp ------ Comment parser tests --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/AST/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"
25 using namespace clang;
32 const bool DEBUG = true;
34 class CommentParserTest : public ::testing::Test {
37 : FileMgr(FileMgrOpts),
38 DiagID(new DiagnosticIDs()),
39 Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
40 SourceMgr(Diags, FileMgr),
41 Traits(Allocator, CommentOptions()) {
44 FileSystemOptions FileMgrOpts;
46 IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
47 DiagnosticsEngine Diags;
48 SourceManager SourceMgr;
49 llvm::BumpPtrAllocator Allocator;
52 FullComment *parseString(const char *Source);
55 FullComment *CommentParserTest::parseString(const char *Source) {
56 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Source);
57 FileID File = SourceMgr.createFileID(std::move(Buf));
58 SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
60 Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source));
62 Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ nullptr);
63 Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
64 FullComment *FC = P.parseFullComment();
67 llvm::errs() << "=== Source:\n" << Source << "\n=== AST:\n";
68 FC->dump(llvm::errs(), &Traits, &SourceMgr);
79 ::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) {
81 return ::testing::AssertionFailure() << "Comment is NULL";
83 if (Count != C->child_count())
84 return ::testing::AssertionFailure()
85 << "Count = " << Count
86 << ", child_count = " << C->child_count();
88 return ::testing::AssertionSuccess();
92 ::testing::AssertionResult GetChildAt(const Comment *C,
96 return ::testing::AssertionFailure() << "Comment is NULL";
98 if (Idx >= C->child_count())
99 return ::testing::AssertionFailure()
100 << "Idx out of range. Idx = " << Idx
101 << ", child_count = " << C->child_count();
103 Comment::child_iterator I = C->child_begin() + Idx;
104 Comment *CommentChild = *I;
106 return ::testing::AssertionFailure() << "Child is NULL";
108 Child = dyn_cast<T>(CommentChild);
110 return ::testing::AssertionFailure()
111 << "Child is not of requested type, but a "
112 << CommentChild->getCommentKindName();
114 return ::testing::AssertionSuccess();
117 ::testing::AssertionResult HasTextAt(const Comment *C,
121 ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
125 StringRef ActualText = TC->getText();
126 if (ActualText != Text)
127 return ::testing::AssertionFailure()
128 << "TextComment has text \"" << ActualText.str() << "\", "
129 "expected \"" << Text.str() << "\"";
131 if (TC->hasTrailingNewline())
132 return ::testing::AssertionFailure()
133 << "TextComment has a trailing newline";
135 return ::testing::AssertionSuccess();
138 ::testing::AssertionResult HasTextWithNewlineAt(const Comment *C,
142 ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
146 StringRef ActualText = TC->getText();
147 if (ActualText != Text)
148 return ::testing::AssertionFailure()
149 << "TextComment has text \"" << ActualText.str() << "\", "
150 "expected \"" << Text.str() << "\"";
152 if (!TC->hasTrailingNewline())
153 return ::testing::AssertionFailure()
154 << "TextComment has no trailing newline";
156 return ::testing::AssertionSuccess();
159 ::testing::AssertionResult HasBlockCommandAt(const Comment *C,
160 const CommandTraits &Traits,
162 BlockCommandComment *&BCC,
164 ParagraphComment *&Paragraph) {
165 ::testing::AssertionResult AR = GetChildAt(C, Idx, BCC);
169 StringRef ActualName = BCC->getCommandName(Traits);
170 if (ActualName != Name)
171 return ::testing::AssertionFailure()
172 << "BlockCommandComment has name \"" << ActualName.str() << "\", "
173 "expected \"" << Name.str() << "\"";
175 Paragraph = BCC->getParagraph();
177 return ::testing::AssertionSuccess();
180 ::testing::AssertionResult HasParamCommandAt(
182 const CommandTraits &Traits,
184 ParamCommandComment *&PCC,
185 StringRef CommandName,
186 ParamCommandComment::PassDirection Direction,
187 bool IsDirectionExplicit,
189 ParagraphComment *&Paragraph) {
190 ::testing::AssertionResult AR = GetChildAt(C, Idx, PCC);
194 StringRef ActualCommandName = PCC->getCommandName(Traits);
195 if (ActualCommandName != CommandName)
196 return ::testing::AssertionFailure()
197 << "ParamCommandComment has name \"" << ActualCommandName.str() << "\", "
198 "expected \"" << CommandName.str() << "\"";
200 if (PCC->getDirection() != Direction)
201 return ::testing::AssertionFailure()
202 << "ParamCommandComment has direction " << PCC->getDirection() << ", "
203 "expected " << Direction;
205 if (PCC->isDirectionExplicit() != IsDirectionExplicit)
206 return ::testing::AssertionFailure()
207 << "ParamCommandComment has "
208 << (PCC->isDirectionExplicit() ? "explicit" : "implicit")
210 "expected " << (IsDirectionExplicit ? "explicit" : "implicit");
212 if (!ParamName.empty() && !PCC->hasParamName())
213 return ::testing::AssertionFailure()
214 << "ParamCommandComment has no parameter name";
216 StringRef ActualParamName = PCC->hasParamName() ? PCC->getParamNameAsWritten() : "";
217 if (ActualParamName != ParamName)
218 return ::testing::AssertionFailure()
219 << "ParamCommandComment has parameter name \"" << ActualParamName.str()
221 "expected \"" << ParamName.str() << "\"";
223 Paragraph = PCC->getParagraph();
225 return ::testing::AssertionSuccess();
228 ::testing::AssertionResult HasTParamCommandAt(
230 const CommandTraits &Traits,
232 TParamCommandComment *&TPCC,
233 StringRef CommandName,
235 ParagraphComment *&Paragraph) {
236 ::testing::AssertionResult AR = GetChildAt(C, Idx, TPCC);
240 StringRef ActualCommandName = TPCC->getCommandName(Traits);
241 if (ActualCommandName != CommandName)
242 return ::testing::AssertionFailure()
243 << "TParamCommandComment has name \"" << ActualCommandName.str() << "\", "
244 "expected \"" << CommandName.str() << "\"";
246 if (!ParamName.empty() && !TPCC->hasParamName())
247 return ::testing::AssertionFailure()
248 << "TParamCommandComment has no parameter name";
250 StringRef ActualParamName = TPCC->hasParamName() ? TPCC->getParamNameAsWritten() : "";
251 if (ActualParamName != ParamName)
252 return ::testing::AssertionFailure()
253 << "TParamCommandComment has parameter name \"" << ActualParamName.str()
255 "expected \"" << ParamName.str() << "\"";
257 Paragraph = TPCC->getParagraph();
259 return ::testing::AssertionSuccess();
262 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
263 const CommandTraits &Traits,
265 InlineCommandComment *&ICC,
267 ::testing::AssertionResult AR = GetChildAt(C, Idx, ICC);
271 StringRef ActualName = ICC->getCommandName(Traits);
272 if (ActualName != Name)
273 return ::testing::AssertionFailure()
274 << "InlineCommandComment has name \"" << ActualName.str() << "\", "
275 "expected \"" << Name.str() << "\"";
277 return ::testing::AssertionSuccess();
282 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
283 const CommandTraits &Traits,
285 InlineCommandComment *&ICC,
288 ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name);
292 if (ICC->getNumArgs() != 0)
293 return ::testing::AssertionFailure()
294 << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
297 return ::testing::AssertionSuccess();
300 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
301 const CommandTraits &Traits,
303 InlineCommandComment *&ICC,
306 ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name);
310 if (ICC->getNumArgs() != 1)
311 return ::testing::AssertionFailure()
312 << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
315 StringRef ActualArg = ICC->getArgText(0);
316 if (ActualArg != Arg)
317 return ::testing::AssertionFailure()
318 << "InlineCommandComment has argument \"" << ActualArg.str() << "\", "
319 "expected \"" << Arg.str() << "\"";
321 return ::testing::AssertionSuccess();
324 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
326 HTMLStartTagComment *&HST,
328 ::testing::AssertionResult AR = GetChildAt(C, Idx, HST);
332 StringRef ActualTagName = HST->getTagName();
333 if (ActualTagName != TagName)
334 return ::testing::AssertionFailure()
335 << "HTMLStartTagComment has name \"" << ActualTagName.str() << "\", "
336 "expected \"" << TagName.str() << "\"";
338 return ::testing::AssertionSuccess();
341 struct SelfClosing {};
343 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
345 HTMLStartTagComment *&HST,
348 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
352 if (!HST->isSelfClosing())
353 return ::testing::AssertionFailure()
354 << "HTMLStartTagComment is not self-closing";
356 return ::testing::AssertionSuccess();
362 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
364 HTMLStartTagComment *&HST,
367 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
371 if (HST->isSelfClosing())
372 return ::testing::AssertionFailure()
373 << "HTMLStartTagComment is self-closing";
375 if (HST->getNumAttrs() != 0)
376 return ::testing::AssertionFailure()
377 << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
380 return ::testing::AssertionSuccess();
383 ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
385 HTMLStartTagComment *&HST,
388 StringRef AttrValue) {
389 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
393 if (HST->isSelfClosing())
394 return ::testing::AssertionFailure()
395 << "HTMLStartTagComment is self-closing";
397 if (HST->getNumAttrs() != 1)
398 return ::testing::AssertionFailure()
399 << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
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() << "\"";
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() << "\"";
414 return ::testing::AssertionSuccess();
417 ::testing::AssertionResult HasHTMLEndTagAt(const Comment *C,
419 HTMLEndTagComment *&HET,
421 ::testing::AssertionResult AR = GetChildAt(C, Idx, HET);
425 StringRef ActualTagName = HET->getTagName();
426 if (ActualTagName != TagName)
427 return ::testing::AssertionFailure()
428 << "HTMLEndTagComment has name \"" << ActualTagName.str() << "\", "
429 "expected \"" << TagName.str() << "\"";
431 return ::testing::AssertionSuccess();
434 ::testing::AssertionResult HasParagraphCommentAt(const Comment *C,
437 ParagraphComment *PC;
440 ::testing::AssertionResult AR = GetChildAt(C, Idx, PC);
446 ::testing::AssertionResult AR = HasChildCount(PC, 1);
452 ::testing::AssertionResult AR = HasTextAt(PC, 0, Text);
457 return ::testing::AssertionSuccess();
460 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
461 const CommandTraits &Traits,
463 VerbatimBlockComment *&VBC,
465 StringRef CloseName) {
466 ::testing::AssertionResult AR = GetChildAt(C, Idx, VBC);
470 StringRef ActualName = VBC->getCommandName(Traits);
471 if (ActualName != Name)
472 return ::testing::AssertionFailure()
473 << "VerbatimBlockComment has name \"" << ActualName.str() << "\", "
474 "expected \"" << Name.str() << "\"";
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() << "\"";
483 return ::testing::AssertionSuccess();
489 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
490 const CommandTraits &Traits,
492 VerbatimBlockComment *&VBC,
496 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
501 if (VBC->getNumLines() != 0)
502 return ::testing::AssertionFailure()
503 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
506 return ::testing::AssertionSuccess();
509 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
510 const CommandTraits &Traits,
512 VerbatimBlockComment *&VBC,
517 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
522 if (VBC->getNumLines() != 1)
523 return ::testing::AssertionFailure()
524 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
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() << "\"";
533 return ::testing::AssertionSuccess();
536 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
537 const CommandTraits &Traits,
539 VerbatimBlockComment *&VBC,
545 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
550 if (VBC->getNumLines() != 2)
551 return ::testing::AssertionFailure()
552 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
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() << "\"";
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() << "\"";
567 return ::testing::AssertionSuccess();
570 ::testing::AssertionResult HasVerbatimLineAt(const Comment *C,
571 const CommandTraits &Traits,
573 VerbatimLineComment *&VLC,
576 ::testing::AssertionResult AR = GetChildAt(C, Idx, VLC);
580 StringRef ActualName = VLC->getCommandName(Traits);
581 if (ActualName != Name)
582 return ::testing::AssertionFailure()
583 << "VerbatimLineComment has name \"" << ActualName.str() << "\", "
584 "expected \"" << Name.str() << "\"";
586 StringRef ActualText = VLC->getText();
587 if (ActualText != Text)
588 return ::testing::AssertionFailure()
589 << "VerbatimLineComment has text \"" << ActualText.str() << "\", "
590 "expected \"" << Text.str() << "\"";
592 return ::testing::AssertionSuccess();
596 TEST_F(CommentParserTest, Basic1) {
597 const char *Source = "//";
599 FullComment *FC = parseString(Source);
600 ASSERT_TRUE(HasChildCount(FC, 0));
603 TEST_F(CommentParserTest, Basic2) {
604 const char *Source = "// Meow";
606 FullComment *FC = parseString(Source);
607 ASSERT_TRUE(HasChildCount(FC, 1));
609 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Meow"));
612 TEST_F(CommentParserTest, Basic3) {
617 FullComment *FC = parseString(Source);
618 ASSERT_TRUE(HasChildCount(FC, 1));
621 ParagraphComment *PC;
622 ASSERT_TRUE(GetChildAt(FC, 0, PC));
624 ASSERT_TRUE(HasChildCount(PC, 2));
625 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
626 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb"));
630 TEST_F(CommentParserTest, ParagraphSplitting1) {
631 const char *Sources[] = {
668 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
669 FullComment *FC = parseString(Sources[i]);
670 ASSERT_TRUE(HasChildCount(FC, 2));
672 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Aaa"));
673 ASSERT_TRUE(HasParagraphCommentAt(FC, 1, " Bbb"));
677 TEST_F(CommentParserTest, Paragraph1) {
683 FullComment *FC = parseString(Source);
684 ASSERT_TRUE(HasChildCount(FC, 3));
686 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
688 BlockCommandComment *BCC;
689 ParagraphComment *PC;
690 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
692 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa"));
694 ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb"));
697 TEST_F(CommentParserTest, Paragraph2) {
698 const char *Source = "// \\brief \\author";
700 FullComment *FC = parseString(Source);
701 ASSERT_TRUE(HasChildCount(FC, 3));
703 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
705 BlockCommandComment *BCC;
706 ParagraphComment *PC;
707 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
709 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " "));
712 BlockCommandComment *BCC;
713 ParagraphComment *PC;
714 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC));
716 ASSERT_TRUE(GetChildAt(BCC, 0, PC));
717 ASSERT_TRUE(HasChildCount(PC, 0));
721 TEST_F(CommentParserTest, Paragraph3) {
727 FullComment *FC = parseString(Source);
728 ASSERT_TRUE(HasChildCount(FC, 3));
730 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
732 BlockCommandComment *BCC;
733 ParagraphComment *PC;
734 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
736 ASSERT_TRUE(GetChildAt(BCC, 0, PC));
737 ASSERT_TRUE(HasChildCount(PC, 2));
738 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
739 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb "));
742 BlockCommandComment *BCC;
743 ParagraphComment *PC;
744 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC));
746 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc"));
750 TEST_F(CommentParserTest, ParamCommand1) {
751 const char *Source = "// \\param aaa";
753 FullComment *FC = parseString(Source);
754 ASSERT_TRUE(HasChildCount(FC, 2));
756 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
758 ParamCommandComment *PCC;
759 ParagraphComment *PC;
760 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
761 ParamCommandComment::In,
762 /* IsDirectionExplicit = */ false,
764 ASSERT_TRUE(HasChildCount(PCC, 1));
765 ASSERT_TRUE(HasChildCount(PC, 0));
769 TEST_F(CommentParserTest, ParamCommand2) {
770 const char *Source = "// \\param\\brief";
772 FullComment *FC = parseString(Source);
773 ASSERT_TRUE(HasChildCount(FC, 3));
775 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
777 ParamCommandComment *PCC;
778 ParagraphComment *PC;
779 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
780 ParamCommandComment::In,
781 /* IsDirectionExplicit = */ false,
783 ASSERT_TRUE(HasChildCount(PCC, 1));
784 ASSERT_TRUE(HasChildCount(PC, 0));
787 BlockCommandComment *BCC;
788 ParagraphComment *PC;
789 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC));
790 ASSERT_TRUE(HasChildCount(PC, 0));
794 TEST_F(CommentParserTest, ParamCommand3) {
795 const char *Sources[] = {
796 "// \\param aaa Bbb\n",
805 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
806 FullComment *FC = parseString(Sources[i]);
807 ASSERT_TRUE(HasChildCount(FC, 2));
809 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
811 ParamCommandComment *PCC;
812 ParagraphComment *PC;
813 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
814 ParamCommandComment::In,
815 /* IsDirectionExplicit = */ false,
817 ASSERT_TRUE(HasChildCount(PCC, 1));
818 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
823 TEST_F(CommentParserTest, ParamCommand4) {
824 const char *Sources[] = {
825 "// \\param [in] aaa Bbb\n",
826 "// \\param[in] aaa Bbb\n",
831 "// \\param [in] aaa\n"
835 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
836 FullComment *FC = parseString(Sources[i]);
837 ASSERT_TRUE(HasChildCount(FC, 2));
839 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
841 ParamCommandComment *PCC;
842 ParagraphComment *PC;
843 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
844 ParamCommandComment::In,
845 /* IsDirectionExplicit = */ true,
847 ASSERT_TRUE(HasChildCount(PCC, 1));
848 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
853 TEST_F(CommentParserTest, ParamCommand5) {
854 const char *Sources[] = {
855 "// \\param [out] aaa Bbb\n",
856 "// \\param[out] aaa Bbb\n",
858 "// [out] aaa Bbb\n",
861 "// \\param [out] aaa\n"
865 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
866 FullComment *FC = parseString(Sources[i]);
867 ASSERT_TRUE(HasChildCount(FC, 2));
869 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
871 ParamCommandComment *PCC;
872 ParagraphComment *PC;
873 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
874 ParamCommandComment::Out,
875 /* IsDirectionExplicit = */ true,
877 ASSERT_TRUE(HasChildCount(PCC, 1));
878 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
883 TEST_F(CommentParserTest, ParamCommand6) {
884 const char *Sources[] = {
885 "// \\param [in,out] aaa Bbb\n",
886 "// \\param[in,out] aaa Bbb\n",
887 "// \\param [in, out] aaa Bbb\n",
890 "// \\param [in,out]\n"
892 "// \\param [in,out] aaa\n"
896 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
897 FullComment *FC = parseString(Sources[i]);
898 ASSERT_TRUE(HasChildCount(FC, 2));
900 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
902 ParamCommandComment *PCC;
903 ParagraphComment *PC;
904 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
905 ParamCommandComment::InOut,
906 /* IsDirectionExplicit = */ true,
908 ASSERT_TRUE(HasChildCount(PCC, 1));
909 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
914 TEST_F(CommentParserTest, ParamCommand7) {
916 "// \\param aaa \\% Bbb \\$ ccc\n";
918 FullComment *FC = parseString(Source);
919 ASSERT_TRUE(HasChildCount(FC, 2));
921 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
923 ParamCommandComment *PCC;
924 ParagraphComment *PC;
925 ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
926 ParamCommandComment::In,
927 /* IsDirectionExplicit = */ false,
929 ASSERT_TRUE(HasChildCount(PCC, 1));
931 ASSERT_TRUE(HasChildCount(PC, 5));
932 ASSERT_TRUE(HasTextAt(PC, 0, " "));
933 ASSERT_TRUE(HasTextAt(PC, 1, "%"));
934 ASSERT_TRUE(HasTextAt(PC, 2, " Bbb "));
935 ASSERT_TRUE(HasTextAt(PC, 3, "$"));
936 ASSERT_TRUE(HasTextAt(PC, 4, " ccc"));
940 TEST_F(CommentParserTest, TParamCommand1) {
941 const char *Sources[] = {
942 "// \\tparam aaa Bbb\n",
951 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
952 FullComment *FC = parseString(Sources[i]);
953 ASSERT_TRUE(HasChildCount(FC, 2));
955 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
957 TParamCommandComment *TPCC;
958 ParagraphComment *PC;
959 ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam",
961 ASSERT_TRUE(HasChildCount(TPCC, 1));
962 ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb"));
967 TEST_F(CommentParserTest, TParamCommand2) {
968 const char *Source = "// \\tparam\\brief";
970 FullComment *FC = parseString(Source);
971 ASSERT_TRUE(HasChildCount(FC, 3));
973 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
975 TParamCommandComment *TPCC;
976 ParagraphComment *PC;
977 ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", "", PC));
978 ASSERT_TRUE(HasChildCount(TPCC, 1));
979 ASSERT_TRUE(HasChildCount(PC, 0));
982 BlockCommandComment *BCC;
983 ParagraphComment *PC;
984 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC));
985 ASSERT_TRUE(HasChildCount(PC, 0));
990 TEST_F(CommentParserTest, InlineCommand1) {
991 const char *Source = "// \\c";
993 FullComment *FC = parseString(Source);
994 ASSERT_TRUE(HasChildCount(FC, 1));
997 ParagraphComment *PC;
998 InlineCommandComment *ICC;
999 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1001 ASSERT_TRUE(HasChildCount(PC, 2));
1002 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1003 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs()));
1007 TEST_F(CommentParserTest, InlineCommand2) {
1008 const char *Source = "// \\c ";
1010 FullComment *FC = parseString(Source);
1011 ASSERT_TRUE(HasChildCount(FC, 1));
1014 ParagraphComment *PC;
1015 InlineCommandComment *ICC;
1016 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1018 ASSERT_TRUE(HasChildCount(PC, 3));
1019 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1020 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs()));
1021 ASSERT_TRUE(HasTextAt(PC, 2, " "));
1025 TEST_F(CommentParserTest, InlineCommand3) {
1026 const char *Source = "// \\c aaa\n";
1028 FullComment *FC = parseString(Source);
1029 ASSERT_TRUE(HasChildCount(FC, 1));
1032 ParagraphComment *PC;
1033 InlineCommandComment *ICC;
1034 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1036 ASSERT_TRUE(HasChildCount(PC, 2));
1037 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1038 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa"));
1042 TEST_F(CommentParserTest, InlineCommand4) {
1043 const char *Source = "// \\c aaa bbb";
1045 FullComment *FC = parseString(Source);
1046 ASSERT_TRUE(HasChildCount(FC, 1));
1049 ParagraphComment *PC;
1050 InlineCommandComment *ICC;
1051 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1053 ASSERT_TRUE(HasChildCount(PC, 3));
1054 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1055 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa"));
1056 ASSERT_TRUE(HasTextAt(PC, 2, " bbb"));
1060 TEST_F(CommentParserTest, InlineCommand5) {
1061 const char *Source = "// \\unknown aaa\n";
1063 FullComment *FC = parseString(Source);
1064 ASSERT_TRUE(HasChildCount(FC, 1));
1067 ParagraphComment *PC;
1068 InlineCommandComment *ICC;
1069 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1071 ASSERT_TRUE(HasChildCount(PC, 3));
1072 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1073 ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "unknown", NoArgs()));
1074 ASSERT_TRUE(HasTextAt(PC, 2, " aaa"));
1078 TEST_F(CommentParserTest, HTML1) {
1079 const char *Sources[] = {
1085 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1086 FullComment *FC = parseString(Sources[i]);
1087 ASSERT_TRUE(HasChildCount(FC, 1));
1090 ParagraphComment *PC;
1091 HTMLStartTagComment *HST;
1092 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1094 ASSERT_TRUE(HasChildCount(PC, 2));
1095 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1096 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs()));
1101 TEST_F(CommentParserTest, HTML2) {
1102 const char *Sources[] = {
1107 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1108 FullComment *FC = parseString(Sources[i]);
1109 ASSERT_TRUE(HasChildCount(FC, 1));
1112 ParagraphComment *PC;
1113 HTMLStartTagComment *HST;
1114 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1116 ASSERT_TRUE(HasChildCount(PC, 2));
1117 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1118 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing()));
1123 TEST_F(CommentParserTest, HTML3) {
1124 const char *Sources[] = {
1131 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1132 FullComment *FC = parseString(Sources[i]);
1133 ASSERT_TRUE(HasChildCount(FC, 1));
1136 ParagraphComment *PC;
1137 HTMLStartTagComment *HST;
1138 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1140 ASSERT_TRUE(HasChildCount(PC, 2));
1141 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1142 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", ""));
1147 TEST_F(CommentParserTest, HTML4) {
1148 const char *Sources[] = {
1149 "// <a href=\"bbb\"",
1150 "// <a href=\"bbb\">",
1153 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1154 FullComment *FC = parseString(Sources[i]);
1155 ASSERT_TRUE(HasChildCount(FC, 1));
1158 ParagraphComment *PC;
1159 HTMLStartTagComment *HST;
1160 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1162 ASSERT_TRUE(HasChildCount(PC, 2));
1163 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1164 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb"));
1169 TEST_F(CommentParserTest, HTML5) {
1170 const char *Sources[] = {
1176 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1177 FullComment *FC = parseString(Sources[i]);
1178 ASSERT_TRUE(HasChildCount(FC, 1));
1181 ParagraphComment *PC;
1182 HTMLEndTagComment *HET;
1183 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1185 ASSERT_TRUE(HasChildCount(PC, 2));
1186 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1187 ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a"));
1192 TEST_F(CommentParserTest, HTML6) {
1193 const char *Source =
1199 FullComment *FC = parseString(Source);
1200 ASSERT_TRUE(HasChildCount(FC, 1));
1203 ParagraphComment *PC;
1204 HTMLStartTagComment *HST;
1205 HTMLEndTagComment *HET;
1206 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1208 ASSERT_TRUE(HasChildCount(PC, 6));
1209 ASSERT_TRUE(HasTextAt(PC, 0, " "));
1210 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs()));
1211 ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa"));
1212 ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb"));
1213 ASSERT_TRUE(HasTextAt(PC, 4, " "));
1214 ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre"));
1218 TEST_F(CommentParserTest, VerbatimBlock1) {
1219 const char *Source = "// \\verbatim\\endverbatim\n";
1221 FullComment *FC = parseString(Source);
1222 ASSERT_TRUE(HasChildCount(FC, 2));
1224 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1226 VerbatimBlockComment *VCC;
1227 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VCC,
1228 "verbatim", "endverbatim",
1233 TEST_F(CommentParserTest, VerbatimBlock2) {
1234 const char *Source = "// \\verbatim Aaa \\endverbatim\n";
1236 FullComment *FC = parseString(Source);
1237 ASSERT_TRUE(HasChildCount(FC, 2));
1239 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1241 VerbatimBlockComment *VBC;
1242 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
1243 "verbatim", "endverbatim",
1248 TEST_F(CommentParserTest, VerbatimBlock3) {
1249 const char *Source = "// \\verbatim Aaa\n";
1251 FullComment *FC = parseString(Source);
1252 ASSERT_TRUE(HasChildCount(FC, 2));
1254 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1256 VerbatimBlockComment *VBC;
1257 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, "verbatim", "",
1262 TEST_F(CommentParserTest, VerbatimBlock4) {
1263 const char *Source =
1265 "//\\endverbatim\n";
1267 FullComment *FC = parseString(Source);
1268 ASSERT_TRUE(HasChildCount(FC, 1));
1271 VerbatimBlockComment *VBC;
1272 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC,
1273 "verbatim", "endverbatim",
1278 TEST_F(CommentParserTest, VerbatimBlock5) {
1279 const char *Sources[] = {
1282 "//\\endverbatim\n",
1289 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1290 FullComment *FC = parseString(Sources[i]);
1291 ASSERT_TRUE(HasChildCount(FC, 1));
1294 VerbatimBlockComment *VBC;
1295 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC,
1296 "verbatim", "endverbatim",
1302 TEST_F(CommentParserTest, VerbatimBlock6) {
1303 const char *Sources[] = {
1306 "// \\endverbatim\n",
1310 " * \\endverbatim*/"
1313 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1314 FullComment *FC = parseString(Sources[i]);
1315 ASSERT_TRUE(HasChildCount(FC, 2));
1317 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1319 VerbatimBlockComment *VBC;
1320 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
1321 "verbatim", "endverbatim",
1327 TEST_F(CommentParserTest, VerbatimBlock7) {
1328 const char *Sources[] = {
1332 "// \\endverbatim\n",
1337 " * \\endverbatim*/"
1340 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1341 FullComment *FC = parseString(Sources[i]);
1342 ASSERT_TRUE(HasChildCount(FC, 2));
1344 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1346 VerbatimBlockComment *VBC;
1347 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
1348 "verbatim", "endverbatim",
1349 Lines(), " Aaa", " Bbb"));
1354 TEST_F(CommentParserTest, VerbatimBlock8) {
1355 const char *Sources[] = {
1360 "// \\endverbatim\n",
1366 " * \\endverbatim*/"
1368 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1369 FullComment *FC = parseString(Sources[i]);
1370 ASSERT_TRUE(HasChildCount(FC, 2));
1372 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1374 VerbatimBlockComment *VBC;
1375 ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
1376 "verbatim", "endverbatim"));
1377 ASSERT_EQ(3U, VBC->getNumLines());
1378 ASSERT_EQ(" Aaa", VBC->getText(0));
1379 ASSERT_EQ("", VBC->getText(1));
1380 ASSERT_EQ(" Bbb", VBC->getText(2));
1385 TEST_F(CommentParserTest, VerbatimLine1) {
1386 const char *Sources[] = {
1391 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1392 FullComment *FC = parseString(Sources[i]);
1393 ASSERT_TRUE(HasChildCount(FC, 2));
1395 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1397 VerbatimLineComment *VLC;
1398 ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", ""));
1403 TEST_F(CommentParserTest, VerbatimLine2) {
1404 const char *Sources[] = {
1405 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
1406 "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
1409 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1410 FullComment *FC = parseString(Sources[i]);
1411 ASSERT_TRUE(HasChildCount(FC, 2));
1413 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1415 VerbatimLineComment *VLC;
1416 ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn",
1417 " void *foo(const char *zzz = \"\\$\");"));
1422 TEST_F(CommentParserTest, Deprecated) {
1423 const char *Sources[] = {
1424 "/** @deprecated*/",
1428 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1429 FullComment *FC = parseString(Sources[i]);
1430 ASSERT_TRUE(HasChildCount(FC, 2));
1432 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1434 BlockCommandComment *BCC;
1435 ParagraphComment *PC;
1436 ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "deprecated", PC));
1437 ASSERT_TRUE(HasChildCount(PC, 0));
1442 } // unnamed namespace
1444 } // end namespace comments
1445 } // end namespace clang