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