[clang-tidy][modernize-use-starts-ends-with] Fix operator rewriting false negative...
[llvm-project.git] / clang-tools-extra / unittests / clang-doc / YAMLGeneratorTest.cpp
blob9b1d87dfa013566d1d2038eb6529b3244c8db056
1 //===-- clang-doc/YAMLGeneratorTest.cpp
2 //------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #include "ClangDocTest.h"
11 #include "Generators.h"
12 #include "Representation.h"
13 #include "gtest/gtest.h"
15 namespace clang {
16 namespace doc {
18 std::unique_ptr<Generator> getYAMLGenerator() {
19 auto G = doc::findGeneratorByName("yaml");
20 if (!G)
21 return nullptr;
22 return std::move(G.get());
25 TEST(YAMLGeneratorTest, emitNamespaceYAML) {
26 NamespaceInfo I;
27 I.Name = "Namespace";
28 I.Path = "path/to/A";
29 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
31 I.Children.Namespaces.emplace_back(
32 EmptySID, "ChildNamespace", InfoType::IT_namespace,
33 "path::to::A::Namespace::ChildNamespace", "path/to/A/Namespace");
34 I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
35 "path::to::A::Namespace::ChildStruct",
36 "path/to/A/Namespace");
37 I.Children.Functions.emplace_back();
38 I.Children.Functions.back().Name = "OneFunction";
39 I.Children.Functions.back().Access = AccessSpecifier::AS_none;
40 I.Children.Enums.emplace_back();
41 I.Children.Enums.back().Name = "OneEnum";
43 auto G = getYAMLGenerator();
44 assert(G);
45 std::string Buffer;
46 llvm::raw_string_ostream Actual(Buffer);
47 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
48 assert(!Err);
49 std::string Expected =
50 R"raw(---
51 USR: '0000000000000000000000000000000000000000'
52 Name: 'Namespace'
53 Path: 'path/to/A'
54 Namespace:
55 - Type: Namespace
56 Name: 'A'
57 QualName: 'A'
58 ChildNamespaces:
59 - Type: Namespace
60 Name: 'ChildNamespace'
61 QualName: 'path::to::A::Namespace::ChildNamespace'
62 Path: 'path/to/A/Namespace'
63 ChildRecords:
64 - Type: Record
65 Name: 'ChildStruct'
66 QualName: 'path::to::A::Namespace::ChildStruct'
67 Path: 'path/to/A/Namespace'
68 ChildFunctions:
69 - USR: '0000000000000000000000000000000000000000'
70 Name: 'OneFunction'
71 ReturnType: {}
72 ChildEnums:
73 - USR: '0000000000000000000000000000000000000000'
74 Name: 'OneEnum'
75 ...
76 )raw";
77 EXPECT_EQ(Expected, Actual.str());
80 TEST(YAMLGeneratorTest, emitRecordYAML) {
81 RecordInfo I;
82 I.Name = "r";
83 I.Path = "path/to/A";
84 I.IsTypeDef = true;
85 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
87 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
88 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
90 I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
92 // Member documentation.
93 CommentInfo TopComment;
94 TopComment.Kind = "FullComment";
95 TopComment.Children.emplace_back(std::make_unique<CommentInfo>());
96 CommentInfo *Brief = TopComment.Children.back().get();
97 Brief->Kind = "ParagraphComment";
98 Brief->Children.emplace_back(std::make_unique<CommentInfo>());
99 Brief->Children.back()->Kind = "TextComment";
100 Brief->Children.back()->Name = "ParagraphComment";
101 Brief->Children.back()->Text = "Value of the thing.";
102 I.Members.back().Description.push_back(std::move(TopComment));
104 I.TagType = TagTypeKind::Class;
105 I.Bases.emplace_back(EmptySID, "F", "path/to/F", true,
106 AccessSpecifier::AS_public, true);
107 I.Bases.back().Children.Functions.emplace_back();
108 I.Bases.back().Children.Functions.back().Name = "InheritedFunctionOne";
109 I.Bases.back().Members.emplace_back(TypeInfo("int"), "N",
110 AccessSpecifier::AS_private);
111 // F is in the global namespace
112 I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record, "");
113 I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record,
114 "path::to::G::G", "path/to/G");
116 I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
117 "path::to::A::r::ChildStruct", "path/to/A/r");
118 I.Children.Functions.emplace_back();
119 I.Children.Functions.back().Name = "OneFunction";
120 I.Children.Enums.emplace_back();
121 I.Children.Enums.back().Name = "OneEnum";
123 auto G = getYAMLGenerator();
124 assert(G);
125 std::string Buffer;
126 llvm::raw_string_ostream Actual(Buffer);
127 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
128 assert(!Err);
129 std::string Expected =
130 R"raw(---
131 USR: '0000000000000000000000000000000000000000'
132 Name: 'r'
133 Path: 'path/to/A'
134 Namespace:
135 - Type: Namespace
136 Name: 'A'
137 QualName: 'A'
138 DefLocation:
139 LineNumber: 10
140 Filename: 'test.cpp'
141 Location:
142 - LineNumber: 12
143 Filename: 'test.cpp'
144 TagType: Class
145 IsTypeDef: true
146 Members:
147 - Type:
148 Name: 'int'
149 QualName: 'int'
150 Name: 'X'
151 Access: Private
152 Description:
153 - Kind: 'FullComment'
154 Children:
155 - Kind: 'ParagraphComment'
156 Children:
157 - Kind: 'TextComment'
158 Text: 'Value of the thing.'
159 Name: 'ParagraphComment'
160 Bases:
161 - USR: '0000000000000000000000000000000000000000'
162 Name: 'F'
163 Path: 'path/to/F'
164 TagType: Struct
165 Members:
166 - Type:
167 Name: 'int'
168 QualName: 'int'
169 Name: 'N'
170 Access: Private
171 ChildFunctions:
172 - USR: '0000000000000000000000000000000000000000'
173 Name: 'InheritedFunctionOne'
174 ReturnType: {}
175 Access: Public
176 IsVirtual: true
177 Access: Public
178 IsParent: true
179 Parents:
180 - Type: Record
181 Name: 'F'
182 VirtualParents:
183 - Type: Record
184 Name: 'G'
185 QualName: 'path::to::G::G'
186 Path: 'path/to/G'
187 ChildRecords:
188 - Type: Record
189 Name: 'ChildStruct'
190 QualName: 'path::to::A::r::ChildStruct'
191 Path: 'path/to/A/r'
192 ChildFunctions:
193 - USR: '0000000000000000000000000000000000000000'
194 Name: 'OneFunction'
195 ReturnType: {}
196 Access: Public
197 ChildEnums:
198 - USR: '0000000000000000000000000000000000000000'
199 Name: 'OneEnum'
201 )raw";
202 EXPECT_EQ(Expected, Actual.str());
205 TEST(YAMLGeneratorTest, emitFunctionYAML) {
206 FunctionInfo I;
207 I.Name = "f";
208 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
210 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
211 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
213 I.Access = AccessSpecifier::AS_none;
215 I.ReturnType = TypeInfo(Reference(EmptySID, "void", InfoType::IT_default));
216 I.Params.emplace_back(TypeInfo("int"), "P");
217 I.Params.emplace_back(TypeInfo("double"), "D");
218 I.Params.back().DefaultValue = "2.0 * M_PI";
219 I.IsMethod = true;
220 I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
222 auto G = getYAMLGenerator();
223 assert(G);
224 std::string Buffer;
225 llvm::raw_string_ostream Actual(Buffer);
226 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
227 assert(!Err);
228 std::string Expected =
229 R"raw(---
230 USR: '0000000000000000000000000000000000000000'
231 Name: 'f'
232 Namespace:
233 - Type: Namespace
234 Name: 'A'
235 QualName: 'A'
236 DefLocation:
237 LineNumber: 10
238 Filename: 'test.cpp'
239 Location:
240 - LineNumber: 12
241 Filename: 'test.cpp'
242 IsMethod: true
243 Parent:
244 Type: Record
245 Name: 'Parent'
246 QualName: 'Parent'
247 Params:
248 - Type:
249 Name: 'int'
250 QualName: 'int'
251 Name: 'P'
252 - Type:
253 Name: 'double'
254 QualName: 'double'
255 Name: 'D'
256 DefaultValue: '2.0 * M_PI'
257 ReturnType:
258 Type:
259 Name: 'void'
260 QualName: 'void'
262 )raw";
263 EXPECT_EQ(Expected, Actual.str());
266 // Tests the equivalent of:
267 // namespace A {
268 // enum e { X };
269 // }
270 TEST(YAMLGeneratorTest, emitSimpleEnumYAML) {
271 EnumInfo I;
272 I.Name = "e";
273 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
275 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
276 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
278 I.Members.emplace_back("X");
279 I.Scoped = false;
281 auto G = getYAMLGenerator();
282 assert(G);
283 std::string Buffer;
284 llvm::raw_string_ostream Actual(Buffer);
285 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
286 assert(!Err);
287 std::string Expected =
288 R"raw(---
289 USR: '0000000000000000000000000000000000000000'
290 Name: 'e'
291 Namespace:
292 - Type: Namespace
293 Name: 'A'
294 QualName: 'A'
295 DefLocation:
296 LineNumber: 10
297 Filename: 'test.cpp'
298 Location:
299 - LineNumber: 12
300 Filename: 'test.cpp'
301 Members:
302 - Name: 'X'
303 Value: '0'
305 )raw";
306 EXPECT_EQ(Expected, Actual.str());
309 // Tests the equivalent of:
310 // enum class e : short { X = FOO_BAR + 2 };
311 TEST(YAMLGeneratorTest, enumTypedScopedEnumYAML) {
312 EnumInfo I;
313 I.Name = "e";
315 I.Members.emplace_back("X", "-9876", "FOO_BAR + 2");
316 I.Scoped = true;
317 I.BaseType = TypeInfo("short");
319 auto G = getYAMLGenerator();
320 assert(G);
321 std::string Buffer;
322 llvm::raw_string_ostream Actual(Buffer);
323 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
324 assert(!Err);
325 std::string Expected =
326 R"raw(---
327 USR: '0000000000000000000000000000000000000000'
328 Name: 'e'
329 Scoped: true
330 BaseType:
331 Type:
332 Name: 'short'
333 QualName: 'short'
334 Members:
335 - Name: 'X'
336 Value: '-9876'
337 Expr: 'FOO_BAR + 2'
339 )raw";
340 EXPECT_EQ(Expected, Actual.str());
343 TEST(YAMLGeneratorTest, enumTypedefYAML) {
344 TypedefInfo I;
345 I.Name = "MyUsing";
346 I.Underlying = TypeInfo("int");
347 I.IsUsing = true;
349 auto G = getYAMLGenerator();
350 assert(G);
351 std::string Buffer;
352 llvm::raw_string_ostream Actual(Buffer);
353 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
354 assert(!Err);
355 std::string Expected =
356 R"raw(---
357 USR: '0000000000000000000000000000000000000000'
358 Name: 'MyUsing'
359 Underlying:
360 Name: 'int'
361 QualName: 'int'
362 IsUsing: true
364 )raw";
365 EXPECT_EQ(Expected, Actual.str());
368 TEST(YAMLGeneratorTest, emitCommentYAML) {
369 FunctionInfo I;
370 I.Name = "f";
371 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
372 I.ReturnType = TypeInfo("void");
373 I.Params.emplace_back(TypeInfo("int"), "I");
374 I.Params.emplace_back(TypeInfo("int"), "J");
375 I.Access = AccessSpecifier::AS_none;
377 CommentInfo Top;
378 Top.Kind = "FullComment";
380 Top.Children.emplace_back(std::make_unique<CommentInfo>());
381 CommentInfo *BlankLine = Top.Children.back().get();
382 BlankLine->Kind = "ParagraphComment";
383 BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
384 BlankLine->Children.back()->Kind = "TextComment";
386 Top.Children.emplace_back(std::make_unique<CommentInfo>());
387 CommentInfo *Brief = Top.Children.back().get();
388 Brief->Kind = "ParagraphComment";
389 Brief->Children.emplace_back(std::make_unique<CommentInfo>());
390 Brief->Children.back()->Kind = "TextComment";
391 Brief->Children.back()->Name = "ParagraphComment";
392 Brief->Children.back()->Text = " Brief description.";
394 Top.Children.emplace_back(std::make_unique<CommentInfo>());
395 CommentInfo *Extended = Top.Children.back().get();
396 Extended->Kind = "ParagraphComment";
397 Extended->Children.emplace_back(std::make_unique<CommentInfo>());
398 Extended->Children.back()->Kind = "TextComment";
399 Extended->Children.back()->Text = " Extended description that";
400 Extended->Children.emplace_back(std::make_unique<CommentInfo>());
401 Extended->Children.back()->Kind = "TextComment";
402 Extended->Children.back()->Text = " continues onto the next line.";
404 Top.Children.emplace_back(std::make_unique<CommentInfo>());
405 CommentInfo *HTML = Top.Children.back().get();
406 HTML->Kind = "ParagraphComment";
407 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
408 HTML->Children.back()->Kind = "TextComment";
409 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
410 HTML->Children.back()->Kind = "HTMLStartTagComment";
411 HTML->Children.back()->Name = "ul";
412 HTML->Children.back()->AttrKeys.emplace_back("class");
413 HTML->Children.back()->AttrValues.emplace_back("test");
414 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
415 HTML->Children.back()->Kind = "HTMLStartTagComment";
416 HTML->Children.back()->Name = "li";
417 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
418 HTML->Children.back()->Kind = "TextComment";
419 HTML->Children.back()->Text = " Testing.";
420 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
421 HTML->Children.back()->Kind = "HTMLEndTagComment";
422 HTML->Children.back()->Name = "ul";
423 HTML->Children.back()->SelfClosing = true;
425 Top.Children.emplace_back(std::make_unique<CommentInfo>());
426 CommentInfo *Verbatim = Top.Children.back().get();
427 Verbatim->Kind = "VerbatimBlockComment";
428 Verbatim->Name = "verbatim";
429 Verbatim->CloseName = "endverbatim";
430 Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
431 Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
432 Verbatim->Children.back()->Text = " The description continues.";
434 Top.Children.emplace_back(std::make_unique<CommentInfo>());
435 CommentInfo *ParamOut = Top.Children.back().get();
436 ParamOut->Kind = "ParamCommandComment";
437 ParamOut->Direction = "[out]";
438 ParamOut->ParamName = "I";
439 ParamOut->Explicit = true;
440 ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
441 ParamOut->Children.back()->Kind = "ParagraphComment";
442 ParamOut->Children.back()->Children.emplace_back(
443 std::make_unique<CommentInfo>());
444 ParamOut->Children.back()->Children.back()->Kind = "TextComment";
445 ParamOut->Children.back()->Children.emplace_back(
446 std::make_unique<CommentInfo>());
447 ParamOut->Children.back()->Children.back()->Kind = "TextComment";
448 ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
450 Top.Children.emplace_back(std::make_unique<CommentInfo>());
451 CommentInfo *ParamIn = Top.Children.back().get();
452 ParamIn->Kind = "ParamCommandComment";
453 ParamIn->Direction = "[in]";
454 ParamIn->ParamName = "J";
455 ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
456 ParamIn->Children.back()->Kind = "ParagraphComment";
457 ParamIn->Children.back()->Children.emplace_back(
458 std::make_unique<CommentInfo>());
459 ParamIn->Children.back()->Children.back()->Kind = "TextComment";
460 ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
461 ParamIn->Children.back()->Children.emplace_back(
462 std::make_unique<CommentInfo>());
463 ParamIn->Children.back()->Children.back()->Kind = "TextComment";
465 Top.Children.emplace_back(std::make_unique<CommentInfo>());
466 CommentInfo *Return = Top.Children.back().get();
467 Return->Kind = "BlockCommandComment";
468 Return->Name = "return";
469 Return->Explicit = true;
470 Return->Children.emplace_back(std::make_unique<CommentInfo>());
471 Return->Children.back()->Kind = "ParagraphComment";
472 Return->Children.back()->Children.emplace_back(
473 std::make_unique<CommentInfo>());
474 Return->Children.back()->Children.back()->Kind = "TextComment";
475 Return->Children.back()->Children.back()->Text = "void";
477 I.Description.emplace_back(std::move(Top));
479 auto G = getYAMLGenerator();
480 assert(G);
481 std::string Buffer;
482 llvm::raw_string_ostream Actual(Buffer);
483 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
484 assert(!Err);
485 std::string Expected =
486 R"raw(---
487 USR: '0000000000000000000000000000000000000000'
488 Name: 'f'
489 Description:
490 - Kind: 'FullComment'
491 Children:
492 - Kind: 'ParagraphComment'
493 Children:
494 - Kind: 'TextComment'
495 - Kind: 'ParagraphComment'
496 Children:
497 - Kind: 'TextComment'
498 Text: ' Brief description.'
499 Name: 'ParagraphComment'
500 - Kind: 'ParagraphComment'
501 Children:
502 - Kind: 'TextComment'
503 Text: ' Extended description that'
504 - Kind: 'TextComment'
505 Text: ' continues onto the next line.'
506 - Kind: 'ParagraphComment'
507 Children:
508 - Kind: 'TextComment'
509 - Kind: 'HTMLStartTagComment'
510 Name: 'ul'
511 AttrKeys:
512 - 'class'
513 AttrValues:
514 - 'test'
515 - Kind: 'HTMLStartTagComment'
516 Name: 'li'
517 - Kind: 'TextComment'
518 Text: ' Testing.'
519 - Kind: 'HTMLEndTagComment'
520 Name: 'ul'
521 SelfClosing: true
522 - Kind: 'VerbatimBlockComment'
523 Name: 'verbatim'
524 CloseName: 'endverbatim'
525 Children:
526 - Kind: 'VerbatimBlockLineComment'
527 Text: ' The description continues.'
528 - Kind: 'ParamCommandComment'
529 Direction: '[out]'
530 ParamName: 'I'
531 Explicit: true
532 Children:
533 - Kind: 'ParagraphComment'
534 Children:
535 - Kind: 'TextComment'
536 - Kind: 'TextComment'
537 Text: ' is a parameter.'
538 - Kind: 'ParamCommandComment'
539 Direction: '[in]'
540 ParamName: 'J'
541 Children:
542 - Kind: 'ParagraphComment'
543 Children:
544 - Kind: 'TextComment'
545 Text: ' is a parameter.'
546 - Kind: 'TextComment'
547 - Kind: 'BlockCommandComment'
548 Name: 'return'
549 Explicit: true
550 Children:
551 - Kind: 'ParagraphComment'
552 Children:
553 - Kind: 'TextComment'
554 Text: 'void'
555 DefLocation:
556 LineNumber: 10
557 Filename: 'test.cpp'
558 Params:
559 - Type:
560 Name: 'int'
561 QualName: 'int'
562 Name: 'I'
563 - Type:
564 Name: 'int'
565 QualName: 'int'
566 Name: 'J'
567 ReturnType:
568 Type:
569 Name: 'void'
570 QualName: 'void'
572 )raw";
574 EXPECT_EQ(Expected, Actual.str());
577 } // namespace doc
578 } // namespace clang