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/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"
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 IgnoringDiagConsumer()),
40 SourceMgr(Diags
, FileMgr
),
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 MemoryBuffer
*Buf
= MemoryBuffer::getMemBuffer(Source
);
57 FileID File
= SourceMgr
.createFileIDForMemBuffer(Buf
);
58 SourceLocation Begin
= SourceMgr
.getLocForStartOfFile(File
);
60 Lexer
L(Allocator
, Traits
, Begin
, Source
, Source
+ strlen(Source
));
62 Sema
S(Allocator
, SourceMgr
, Diags
, Traits
, /*PP=*/ NULL
);
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
->getParamName() : "";
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
->getParamName() : "";
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
, Paragraph1
) {
631 const char *Sources
[] = {
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));
647 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " Aaa"));
648 ASSERT_TRUE(HasParagraphCommentAt(FC
, 1, " Bbb"));
652 TEST_F(CommentParserTest
, Paragraph2
) {
658 FullComment
*FC
= parseString(Source
);
659 ASSERT_TRUE(HasChildCount(FC
, 3));
661 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
663 BlockCommandComment
*BCC
;
664 ParagraphComment
*PC
;
665 ASSERT_TRUE(HasBlockCommandAt(FC
, Traits
, 1, BCC
, "brief", PC
));
667 ASSERT_TRUE(HasParagraphCommentAt(BCC
, 0, " Aaa"));
669 ASSERT_TRUE(HasParagraphCommentAt(FC
, 2, " Bbb"));
672 TEST_F(CommentParserTest
, Paragraph3
) {
673 const char *Source
= "// \\brief \\author";
675 FullComment
*FC
= parseString(Source
);
676 ASSERT_TRUE(HasChildCount(FC
, 3));
678 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
680 BlockCommandComment
*BCC
;
681 ParagraphComment
*PC
;
682 ASSERT_TRUE(HasBlockCommandAt(FC
, Traits
, 1, BCC
, "brief", PC
));
684 ASSERT_TRUE(HasParagraphCommentAt(BCC
, 0, " "));
687 BlockCommandComment
*BCC
;
688 ParagraphComment
*PC
;
689 ASSERT_TRUE(HasBlockCommandAt(FC
, Traits
, 2, BCC
, "author", PC
));
691 ASSERT_TRUE(GetChildAt(BCC
, 0, PC
));
692 ASSERT_TRUE(HasChildCount(PC
, 0));
696 TEST_F(CommentParserTest
, Paragraph4
) {
702 FullComment
*FC
= parseString(Source
);
703 ASSERT_TRUE(HasChildCount(FC
, 3));
705 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
707 BlockCommandComment
*BCC
;
708 ParagraphComment
*PC
;
709 ASSERT_TRUE(HasBlockCommandAt(FC
, Traits
, 1, BCC
, "brief", PC
));
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 "));
717 BlockCommandComment
*BCC
;
718 ParagraphComment
*PC
;
719 ASSERT_TRUE(HasBlockCommandAt(FC
, Traits
, 2, BCC
, "author", PC
));
721 ASSERT_TRUE(HasParagraphCommentAt(BCC
, 0, " Ccc"));
725 TEST_F(CommentParserTest
, ParamCommand1
) {
726 const char *Source
= "// \\param aaa";
728 FullComment
*FC
= parseString(Source
);
729 ASSERT_TRUE(HasChildCount(FC
, 2));
731 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
733 ParamCommandComment
*PCC
;
734 ParagraphComment
*PC
;
735 ASSERT_TRUE(HasParamCommandAt(FC
, Traits
, 1, PCC
, "param",
736 ParamCommandComment::In
,
737 /* IsDirectionExplicit = */ false,
739 ASSERT_TRUE(HasChildCount(PCC
, 1));
740 ASSERT_TRUE(HasChildCount(PC
, 0));
744 TEST_F(CommentParserTest
, ParamCommand2
) {
745 const char *Source
= "// \\param\\brief";
747 FullComment
*FC
= parseString(Source
);
748 ASSERT_TRUE(HasChildCount(FC
, 3));
750 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
752 ParamCommandComment
*PCC
;
753 ParagraphComment
*PC
;
754 ASSERT_TRUE(HasParamCommandAt(FC
, Traits
, 1, PCC
, "param",
755 ParamCommandComment::In
,
756 /* IsDirectionExplicit = */ false,
758 ASSERT_TRUE(HasChildCount(PCC
, 1));
759 ASSERT_TRUE(HasChildCount(PC
, 0));
762 BlockCommandComment
*BCC
;
763 ParagraphComment
*PC
;
764 ASSERT_TRUE(HasBlockCommandAt(FC
, Traits
, 2, BCC
, "brief", PC
));
765 ASSERT_TRUE(HasChildCount(PC
, 0));
769 TEST_F(CommentParserTest
, ParamCommand3
) {
770 const char *Sources
[] = {
771 "// \\param aaa Bbb\n",
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));
784 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
786 ParamCommandComment
*PCC
;
787 ParagraphComment
*PC
;
788 ASSERT_TRUE(HasParamCommandAt(FC
, Traits
, 1, PCC
, "param",
789 ParamCommandComment::In
,
790 /* IsDirectionExplicit = */ false,
792 ASSERT_TRUE(HasChildCount(PCC
, 1));
793 ASSERT_TRUE(HasParagraphCommentAt(PCC
, 0, " Bbb"));
798 TEST_F(CommentParserTest
, ParamCommand4
) {
799 const char *Sources
[] = {
800 "// \\param [in] aaa Bbb\n",
801 "// \\param[in] aaa Bbb\n",
806 "// \\param [in] aaa\n"
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));
814 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
816 ParamCommandComment
*PCC
;
817 ParagraphComment
*PC
;
818 ASSERT_TRUE(HasParamCommandAt(FC
, Traits
, 1, PCC
, "param",
819 ParamCommandComment::In
,
820 /* IsDirectionExplicit = */ true,
822 ASSERT_TRUE(HasChildCount(PCC
, 1));
823 ASSERT_TRUE(HasParagraphCommentAt(PCC
, 0, " Bbb"));
828 TEST_F(CommentParserTest
, ParamCommand5
) {
829 const char *Sources
[] = {
830 "// \\param [out] aaa Bbb\n",
831 "// \\param[out] aaa Bbb\n",
833 "// [out] aaa Bbb\n",
836 "// \\param [out] aaa\n"
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));
844 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
846 ParamCommandComment
*PCC
;
847 ParagraphComment
*PC
;
848 ASSERT_TRUE(HasParamCommandAt(FC
, Traits
, 1, PCC
, "param",
849 ParamCommandComment::Out
,
850 /* IsDirectionExplicit = */ true,
852 ASSERT_TRUE(HasChildCount(PCC
, 1));
853 ASSERT_TRUE(HasParagraphCommentAt(PCC
, 0, " Bbb"));
858 TEST_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",
865 "// \\param [in,out]\n"
867 "// \\param [in,out] aaa\n"
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));
875 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
877 ParamCommandComment
*PCC
;
878 ParagraphComment
*PC
;
879 ASSERT_TRUE(HasParamCommandAt(FC
, Traits
, 1, PCC
, "param",
880 ParamCommandComment::InOut
,
881 /* IsDirectionExplicit = */ true,
883 ASSERT_TRUE(HasChildCount(PCC
, 1));
884 ASSERT_TRUE(HasParagraphCommentAt(PCC
, 0, " Bbb"));
889 TEST_F(CommentParserTest
, ParamCommand7
) {
891 "// \\param aaa \\% Bbb \\$ ccc\n";
893 FullComment
*FC
= parseString(Source
);
894 ASSERT_TRUE(HasChildCount(FC
, 2));
896 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
898 ParamCommandComment
*PCC
;
899 ParagraphComment
*PC
;
900 ASSERT_TRUE(HasParamCommandAt(FC
, Traits
, 1, PCC
, "param",
901 ParamCommandComment::In
,
902 /* IsDirectionExplicit = */ false,
904 ASSERT_TRUE(HasChildCount(PCC
, 1));
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"));
915 TEST_F(CommentParserTest
, TParamCommand1
) {
916 const char *Sources
[] = {
917 "// \\tparam aaa Bbb\n",
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));
930 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
932 TParamCommandComment
*TPCC
;
933 ParagraphComment
*PC
;
934 ASSERT_TRUE(HasTParamCommandAt(FC
, Traits
, 1, TPCC
, "tparam",
936 ASSERT_TRUE(HasChildCount(TPCC
, 1));
937 ASSERT_TRUE(HasParagraphCommentAt(TPCC
, 0, " Bbb"));
942 TEST_F(CommentParserTest
, TParamCommand2
) {
943 const char *Source
= "// \\tparam\\brief";
945 FullComment
*FC
= parseString(Source
);
946 ASSERT_TRUE(HasChildCount(FC
, 3));
948 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
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));
957 BlockCommandComment
*BCC
;
958 ParagraphComment
*PC
;
959 ASSERT_TRUE(HasBlockCommandAt(FC
, Traits
, 2, BCC
, "brief", PC
));
960 ASSERT_TRUE(HasChildCount(PC
, 0));
965 TEST_F(CommentParserTest
, InlineCommand1
) {
966 const char *Source
= "// \\c";
968 FullComment
*FC
= parseString(Source
);
969 ASSERT_TRUE(HasChildCount(FC
, 1));
972 ParagraphComment
*PC
;
973 InlineCommandComment
*ICC
;
974 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
976 ASSERT_TRUE(HasChildCount(PC
, 2));
977 ASSERT_TRUE(HasTextAt(PC
, 0, " "));
978 ASSERT_TRUE(HasInlineCommandAt(PC
, Traits
, 1, ICC
, "c", NoArgs()));
982 TEST_F(CommentParserTest
, InlineCommand2
) {
983 const char *Source
= "// \\c ";
985 FullComment
*FC
= parseString(Source
);
986 ASSERT_TRUE(HasChildCount(FC
, 1));
989 ParagraphComment
*PC
;
990 InlineCommandComment
*ICC
;
991 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
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, " "));
1000 TEST_F(CommentParserTest
, InlineCommand3
) {
1001 const char *Source
= "// \\c aaa\n";
1003 FullComment
*FC
= parseString(Source
);
1004 ASSERT_TRUE(HasChildCount(FC
, 1));
1007 ParagraphComment
*PC
;
1008 InlineCommandComment
*ICC
;
1009 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
1011 ASSERT_TRUE(HasChildCount(PC
, 2));
1012 ASSERT_TRUE(HasTextAt(PC
, 0, " "));
1013 ASSERT_TRUE(HasInlineCommandAt(PC
, Traits
, 1, ICC
, "c", "aaa"));
1017 TEST_F(CommentParserTest
, InlineCommand4
) {
1018 const char *Source
= "// \\c aaa bbb";
1020 FullComment
*FC
= parseString(Source
);
1021 ASSERT_TRUE(HasChildCount(FC
, 1));
1024 ParagraphComment
*PC
;
1025 InlineCommandComment
*ICC
;
1026 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
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"));
1035 TEST_F(CommentParserTest
, InlineCommand5
) {
1036 const char *Source
= "// \\unknown aaa\n";
1038 FullComment
*FC
= parseString(Source
);
1039 ASSERT_TRUE(HasChildCount(FC
, 1));
1042 ParagraphComment
*PC
;
1043 InlineCommandComment
*ICC
;
1044 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
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"));
1053 TEST_F(CommentParserTest
, HTML1
) {
1054 const char *Sources
[] = {
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));
1065 ParagraphComment
*PC
;
1066 HTMLStartTagComment
*HST
;
1067 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
1069 ASSERT_TRUE(HasChildCount(PC
, 2));
1070 ASSERT_TRUE(HasTextAt(PC
, 0, " "));
1071 ASSERT_TRUE(HasHTMLStartTagAt(PC
, 1, HST
, "a", NoAttrs()));
1076 TEST_F(CommentParserTest
, HTML2
) {
1077 const char *Sources
[] = {
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));
1087 ParagraphComment
*PC
;
1088 HTMLStartTagComment
*HST
;
1089 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
1091 ASSERT_TRUE(HasChildCount(PC
, 2));
1092 ASSERT_TRUE(HasTextAt(PC
, 0, " "));
1093 ASSERT_TRUE(HasHTMLStartTagAt(PC
, 1, HST
, "br", SelfClosing()));
1098 TEST_F(CommentParserTest
, HTML3
) {
1099 const char *Sources
[] = {
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));
1111 ParagraphComment
*PC
;
1112 HTMLStartTagComment
*HST
;
1113 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
1115 ASSERT_TRUE(HasChildCount(PC
, 2));
1116 ASSERT_TRUE(HasTextAt(PC
, 0, " "));
1117 ASSERT_TRUE(HasHTMLStartTagAt(PC
, 1, HST
, "a", "href", ""));
1122 TEST_F(CommentParserTest
, HTML4
) {
1123 const char *Sources
[] = {
1124 "// <a href=\"bbb\"",
1125 "// <a href=\"bbb\">",
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));
1133 ParagraphComment
*PC
;
1134 HTMLStartTagComment
*HST
;
1135 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
1137 ASSERT_TRUE(HasChildCount(PC
, 2));
1138 ASSERT_TRUE(HasTextAt(PC
, 0, " "));
1139 ASSERT_TRUE(HasHTMLStartTagAt(PC
, 1, HST
, "a", "href", "bbb"));
1144 TEST_F(CommentParserTest
, HTML5
) {
1145 const char *Sources
[] = {
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));
1156 ParagraphComment
*PC
;
1157 HTMLEndTagComment
*HET
;
1158 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
1160 ASSERT_TRUE(HasChildCount(PC
, 2));
1161 ASSERT_TRUE(HasTextAt(PC
, 0, " "));
1162 ASSERT_TRUE(HasHTMLEndTagAt(PC
, 1, HET
, "a"));
1167 TEST_F(CommentParserTest
, HTML6
) {
1168 const char *Source
=
1174 FullComment
*FC
= parseString(Source
);
1175 ASSERT_TRUE(HasChildCount(FC
, 1));
1178 ParagraphComment
*PC
;
1179 HTMLStartTagComment
*HST
;
1180 HTMLEndTagComment
*HET
;
1181 ASSERT_TRUE(GetChildAt(FC
, 0, PC
));
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"));
1193 TEST_F(CommentParserTest
, VerbatimBlock1
) {
1194 const char *Source
= "// \\verbatim\\endverbatim\n";
1196 FullComment
*FC
= parseString(Source
);
1197 ASSERT_TRUE(HasChildCount(FC
, 2));
1199 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
1201 VerbatimBlockComment
*VCC
;
1202 ASSERT_TRUE(HasVerbatimBlockAt(FC
, Traits
, 1, VCC
,
1203 "verbatim", "endverbatim",
1208 TEST_F(CommentParserTest
, VerbatimBlock2
) {
1209 const char *Source
= "// \\verbatim Aaa \\endverbatim\n";
1211 FullComment
*FC
= parseString(Source
);
1212 ASSERT_TRUE(HasChildCount(FC
, 2));
1214 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
1216 VerbatimBlockComment
*VBC
;
1217 ASSERT_TRUE(HasVerbatimBlockAt(FC
, Traits
, 1, VBC
,
1218 "verbatim", "endverbatim",
1223 TEST_F(CommentParserTest
, VerbatimBlock3
) {
1224 const char *Source
= "// \\verbatim Aaa\n";
1226 FullComment
*FC
= parseString(Source
);
1227 ASSERT_TRUE(HasChildCount(FC
, 2));
1229 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
1231 VerbatimBlockComment
*VBC
;
1232 ASSERT_TRUE(HasVerbatimBlockAt(FC
, Traits
, 1, VBC
, "verbatim", "",
1237 TEST_F(CommentParserTest
, VerbatimBlock4
) {
1238 const char *Source
=
1240 "//\\endverbatim\n";
1242 FullComment
*FC
= parseString(Source
);
1243 ASSERT_TRUE(HasChildCount(FC
, 1));
1246 VerbatimBlockComment
*VBC
;
1247 ASSERT_TRUE(HasVerbatimBlockAt(FC
, Traits
, 0, VBC
,
1248 "verbatim", "endverbatim",
1253 TEST_F(CommentParserTest
, VerbatimBlock5
) {
1254 const char *Sources
[] = {
1257 "//\\endverbatim\n",
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));
1269 VerbatimBlockComment
*VBC
;
1270 ASSERT_TRUE(HasVerbatimBlockAt(FC
, Traits
, 0, VBC
,
1271 "verbatim", "endverbatim",
1277 TEST_F(CommentParserTest
, VerbatimBlock6
) {
1278 const char *Sources
[] = {
1281 "// \\endverbatim\n",
1285 " * \\endverbatim*/"
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));
1292 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
1294 VerbatimBlockComment
*VBC
;
1295 ASSERT_TRUE(HasVerbatimBlockAt(FC
, Traits
, 1, VBC
,
1296 "verbatim", "endverbatim",
1302 TEST_F(CommentParserTest
, VerbatimBlock7
) {
1303 const char *Sources
[] = {
1307 "// \\endverbatim\n",
1312 " * \\endverbatim*/"
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));
1319 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
1321 VerbatimBlockComment
*VBC
;
1322 ASSERT_TRUE(HasVerbatimBlockAt(FC
, Traits
, 1, VBC
,
1323 "verbatim", "endverbatim",
1324 Lines(), " Aaa", " Bbb"));
1329 TEST_F(CommentParserTest
, VerbatimBlock8
) {
1330 const char *Sources
[] = {
1335 "// \\endverbatim\n",
1341 " * \\endverbatim*/"
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));
1347 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
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));
1360 TEST_F(CommentParserTest
, VerbatimLine1
) {
1361 const char *Sources
[] = {
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));
1370 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
1372 VerbatimLineComment
*VLC
;
1373 ASSERT_TRUE(HasVerbatimLineAt(FC
, Traits
, 1, VLC
, "fn", ""));
1378 TEST_F(CommentParserTest
, VerbatimLine2
) {
1379 const char *Sources
[] = {
1380 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
1381 "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
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));
1388 ASSERT_TRUE(HasParagraphCommentAt(FC
, 0, " "));
1390 VerbatimLineComment
*VLC
;
1391 ASSERT_TRUE(HasVerbatimLineAt(FC
, Traits
, 1, VLC
, "fn",
1392 " void *foo(const char *zzz = \"\\$\");"));
1397 } // unnamed namespace
1399 } // end namespace comments
1400 } // end namespace clang