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