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