clang-tools 22.0.0git
JSONGenerator.cpp
Go to the documentation of this file.
1#include "Generators.h"
2#include "clang/Basic/Specifiers.h"
3#include "llvm/Support/JSON.h"
4
5using namespace llvm;
6using namespace llvm::json;
7
8namespace clang {
9namespace doc {
10
11class JSONGenerator : public Generator {
12public:
13 static const char *Format;
14
15 Error generateDocumentation(StringRef RootDir,
16 llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
17 const ClangDocContext &CDCtx,
18 std::string DirName) override;
19 Error createResources(ClangDocContext &CDCtx) override;
20 Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
21 const ClangDocContext &CDCtx) override;
22};
23
24const char *JSONGenerator::Format = "json";
25
26static void serializeInfo(const ConstraintInfo &I, Object &Obj);
27static void serializeInfo(const RecordInfo &I, Object &Obj,
28 const std::optional<StringRef> &RepositoryUrl);
29
30static void serializeReference(const Reference &Ref, Object &ReferenceObj);
31
32template <typename Container, typename SerializationFunc>
33static void serializeArray(const Container &Records, Object &Obj,
34 const std::string &Key,
35 SerializationFunc SerializeInfo);
36
37// Convenience lambda to pass to serializeArray.
38// If a serializeInfo needs a RepositoryUrl, create a local lambda that captures
39// the optional.
40static auto SerializeInfoLambda = [](const auto &Info, Object &Object) {
41 serializeInfo(Info, Object);
42};
43static auto SerializeReferenceLambda = [](const auto &Ref, Object &Object) {
44 serializeReference(Ref, Object);
45};
46
47static std::string infoTypeToString(InfoType IT) {
48 switch (IT) {
50 return "default";
52 return "namespace";
54 return "record";
56 return "function";
58 return "enum";
60 return "typedef";
62 return "concept";
64 return "variable";
66 return "friend";
67 }
68 llvm_unreachable("Unknown InfoType encountered.");
69}
70
71static json::Object
73 const std::optional<StringRef> RepositoryUrl) {
74 Object LocationObj = Object();
75 LocationObj["LineNumber"] = Loc.StartLineNumber;
76 LocationObj["Filename"] = Loc.Filename;
77
78 if (!Loc.IsFileInRootDir || !RepositoryUrl)
79 return LocationObj;
80 SmallString<128> FileURL(*RepositoryUrl);
81 sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename);
82 FileURL += "#" + std::to_string(Loc.StartLineNumber);
83 LocationObj["FileURL"] = FileURL;
84 return LocationObj;
85}
86
87static void insertComment(Object &Description, json::Value &Comment,
88 StringRef Key) {
89 auto DescriptionIt = Description.find(Key);
90
91 if (DescriptionIt == Description.end()) {
92 auto CommentsArray = json::Array();
93 CommentsArray.push_back(Comment);
94 Description[Key] = std::move(CommentsArray);
95 Description["Has" + Key.str()] = true;
96 } else {
97 DescriptionIt->getSecond().getAsArray()->push_back(Comment);
98 }
99}
100
101static json::Value extractTextComments(Object *ParagraphComment) {
102 if (!ParagraphComment)
103 return json::Object();
104 return *ParagraphComment->get("Children");
105}
106
107static json::Value extractVerbatimComments(json::Array VerbatimLines) {
108 json::Value TextArray = json::Array();
109 auto &TextArrayRef = *TextArray.getAsArray();
110 for (auto &Line : VerbatimLines)
111 TextArrayRef.push_back(*Line.getAsObject()
112 ->get("VerbatimBlockLineComment")
113 ->getAsObject()
114 ->get("Text"));
115
116 return TextArray;
117}
118
119static Object serializeComment(const CommentInfo &I, Object &Description) {
120 // taken from PR #142273
121 Object Obj = Object();
122
123 json::Value ChildVal = Object();
124 Object &Child = *ChildVal.getAsObject();
125
126 json::Value ChildArr = Array();
127 auto &CARef = *ChildArr.getAsArray();
128 CARef.reserve(I.Children.size());
129 for (const auto &C : I.Children)
130 CARef.emplace_back(serializeComment(*C, Description));
131
132 switch (I.Kind) {
134 Obj.insert({commentKindToString(I.Kind), I.Text});
135 return Obj;
136 }
137
139 auto TextCommentsArray = extractTextComments(CARef.front().getAsObject());
140 if (I.Name == "brief")
141 insertComment(Description, TextCommentsArray, "BriefComments");
142 else if (I.Name == "return")
143 insertComment(Description, TextCommentsArray, "ReturnComments");
144 else if (I.Name == "throws" || I.Name == "throw") {
145 json::Value ThrowsVal = Object();
146 auto &ThrowsObj = *ThrowsVal.getAsObject();
147 ThrowsObj["Exception"] = I.Args.front();
148 ThrowsObj["Children"] = TextCommentsArray;
149 insertComment(Description, ThrowsVal, "ThrowsComments");
150 }
151 return Obj;
152 }
153
155 json::Value ArgsArr = Array();
156 auto &ARef = *ArgsArr.getAsArray();
157 ARef.reserve(I.Args.size());
158 for (const auto &Arg : I.Args)
159 ARef.emplace_back(Arg);
160 Child.insert({"Command", I.Name});
161 Child.insert({"Args", ArgsArr});
162 Child.insert({"Children", ChildArr});
163 Obj.insert({commentKindToString(I.Kind), ChildVal});
164 return Obj;
165 }
166
169 Child.insert({"ParamName", I.ParamName});
170 Child.insert({"Direction", I.Direction});
171 Child.insert({"Explicit", I.Explicit});
172 auto TextCommentsArray = extractTextComments(CARef.front().getAsObject());
173 Child.insert({"Children", TextCommentsArray});
175 insertComment(Description, ChildVal, "ParamComments");
176 return Obj;
177 }
178
180 if (I.CloseName == "endcode") {
181 // We don't support \code language specification
182 auto TextCommentsArray = extractVerbatimComments(CARef);
183 insertComment(Description, TextCommentsArray, "CodeComments");
184 } else if (I.CloseName == "endverbatim")
185 insertComment(Description, ChildVal, "VerbatimComments");
186 return Obj;
187 }
188
191 Child.insert({"Text", I.Text});
192 Child.insert({"Children", ChildArr});
193 Obj.insert({commentKindToString(I.Kind), ChildVal});
194 return Obj;
195 }
196
198 json::Value AttrKeysArray = json::Array();
199 json::Value AttrValuesArray = json::Array();
200 auto &KeyArr = *AttrKeysArray.getAsArray();
201 auto &ValArr = *AttrValuesArray.getAsArray();
202 KeyArr.reserve(I.AttrKeys.size());
203 ValArr.reserve(I.AttrValues.size());
204 for (const auto &K : I.AttrKeys)
205 KeyArr.emplace_back(K);
206 for (const auto &V : I.AttrValues)
207 ValArr.emplace_back(V);
208 Child.insert({"Name", I.Name});
209 Child.insert({"SelfClosing", I.SelfClosing});
210 Child.insert({"AttrKeys", AttrKeysArray});
211 Child.insert({"AttrValues", AttrValuesArray});
212 Child.insert({"Children", ChildArr});
213 Obj.insert({commentKindToString(I.Kind), ChildVal});
214 return Obj;
215 }
216
218 Child.insert({"Name", I.Name});
219 Child.insert({"Children", ChildArr});
220 Obj.insert({commentKindToString(I.Kind), ChildVal});
221 return Obj;
222 }
223
226 Child.insert({"Children", ChildArr});
227 Child["ParagraphComment"] = true;
228 return Child;
229 }
230
232 Obj.insert({commentKindToString(I.Kind), I.Text});
233 return Obj;
234 }
235 }
236 llvm_unreachable("Unknown comment kind encountered.");
237}
238
239static void
240serializeCommonAttributes(const Info &I, json::Object &Obj,
241 const std::optional<StringRef> RepositoryUrl) {
242 Obj["Name"] = I.Name;
243 Obj["USR"] = toHex(toStringRef(I.USR));
244 Obj["InfoType"] = infoTypeToString(I.IT);
245 if (!I.DocumentationFileName.empty())
246 Obj["DocumentationFileName"] = I.DocumentationFileName;
247
248 if (!I.Path.empty())
249 Obj["Path"] = I.Path;
250
251 if (!I.Namespace.empty()) {
252 Obj["Namespace"] = json::Array();
253 for (const auto &NS : I.Namespace)
254 Obj["Namespace"].getAsArray()->push_back(NS.Name);
255 }
256
257 if (!I.Description.empty()) {
258 Object Description = Object();
259 // Skip straight to the FullComment's children
260 auto &Comments = I.Description.at(0).Children;
261 for (const auto &CommentInfo : Comments) {
262 json::Value Comment = serializeComment(*CommentInfo, Description);
263 // if a ParagraphComment is returned, then it is a top-level comment that
264 // needs to be inserted manually.
265 if (auto *ParagraphComment = Comment.getAsObject();
266 ParagraphComment->get("ParagraphComment")) {
267 auto TextCommentsArray = extractTextComments(ParagraphComment);
268 insertComment(Description, TextCommentsArray, "ParagraphComments");
269 }
270 }
271 Obj["Description"] = std::move(Description);
272 }
273
274 // Namespaces aren't SymbolInfos, so they dont have a DefLoc
275 if (I.IT != InfoType::IT_namespace) {
276 const auto *Symbol = static_cast<const SymbolInfo *>(&I);
277 if (Symbol->DefLoc)
278 Obj["Location"] =
279 serializeLocation(Symbol->DefLoc.value(), RepositoryUrl);
280 }
281}
282
283static void serializeReference(const Reference &Ref, Object &ReferenceObj) {
284 ReferenceObj["Path"] = Ref.Path;
285 ReferenceObj["Name"] = Ref.Name;
286 ReferenceObj["QualName"] = Ref.QualName;
287 ReferenceObj["USR"] = toHex(toStringRef(Ref.USR));
288 if (!Ref.DocumentationFileName.empty())
289 ReferenceObj["DocumentationFileName"] = Ref.DocumentationFileName;
290}
291
292// Although namespaces and records both have ScopeChildren, they serialize them
293// differently. Only enums, records, and typedefs are handled here.
294static void
295serializeCommonChildren(const ScopeChildren &Children, json::Object &Obj,
296 const std::optional<StringRef> RepositoryUrl) {
297 static auto SerializeInfo = [RepositoryUrl](const auto &Info,
298 Object &Object) {
300 };
301
302 if (!Children.Enums.empty()) {
303 serializeArray(Children.Enums, Obj, "Enums", SerializeInfo);
304 Obj["HasEnums"] = true;
305 }
306
307 if (!Children.Typedefs.empty())
308 serializeArray(Children.Typedefs, Obj, "Typedefs", SerializeInfo);
309
310 if (!Children.Records.empty()) {
311 serializeArray(Children.Records, Obj, "Records", SerializeReferenceLambda);
312 Obj["HasRecords"] = true;
313 }
314}
315
316template <typename Container, typename SerializationFunc>
317static void serializeArray(const Container &Records, Object &Obj,
318 const std::string &Key,
319 SerializationFunc SerializeInfo) {
320 json::Value RecordsArray = Array();
321 auto &RecordsArrayRef = *RecordsArray.getAsArray();
322 RecordsArrayRef.reserve(Records.size());
323 for (size_t Index = 0; Index < Records.size(); ++Index) {
324 json::Value ItemVal = Object();
325 auto &ItemObj = *ItemVal.getAsObject();
326 SerializeInfo(Records[Index], ItemObj);
327 if (Index == Records.size() - 1)
328 ItemObj["End"] = true;
329 RecordsArrayRef.push_back(ItemVal);
330 }
331 Obj[Key] = RecordsArray;
332}
333
334static void serializeInfo(const ConstraintInfo &I, Object &Obj) {
336 Obj["Expression"] = I.ConstraintExpr;
337}
338
339static void serializeInfo(const ArrayRef<TemplateParamInfo> &Params,
340 Object &Obj) {
341 json::Value ParamsArray = Array();
342 auto &ParamsArrayRef = *ParamsArray.getAsArray();
343 ParamsArrayRef.reserve(Params.size());
344 for (const auto &Param : Params)
345 ParamsArrayRef.push_back(Param.Contents);
346 Obj["Parameters"] = ParamsArray;
347}
348
349static void serializeInfo(const TemplateInfo &Template, Object &Obj) {
350 json::Value TemplateVal = Object();
351 auto &TemplateObj = *TemplateVal.getAsObject();
352
353 if (Template.Specialization) {
354 json::Value TemplateSpecializationVal = Object();
355 auto &TemplateSpecializationObj = *TemplateSpecializationVal.getAsObject();
356 TemplateSpecializationObj["SpecializationOf"] =
357 toHex(toStringRef(Template.Specialization->SpecializationOf));
358 if (!Template.Specialization->Params.empty())
359 serializeInfo(Template.Specialization->Params, TemplateSpecializationObj);
360 TemplateObj["Specialization"] = TemplateSpecializationVal;
361 }
362
363 if (!Template.Params.empty())
364 serializeInfo(Template.Params, TemplateObj);
365
366 if (!Template.Constraints.empty())
367 serializeArray(Template.Constraints, TemplateObj, "Constraints",
369
370 Obj["Template"] = TemplateVal;
371}
372
373static void serializeInfo(const ConceptInfo &I, Object &Obj,
374 const std::optional<StringRef> &RepositoryUrl) {
376 Obj["IsType"] = I.IsType;
377 Obj["ConstraintExpression"] = I.ConstraintExpression;
378 serializeInfo(I.Template, Obj);
379}
380
381static void serializeInfo(const TypeInfo &I, Object &Obj) {
382 Obj["Name"] = I.Type.Name;
383 Obj["QualName"] = I.Type.QualName;
384 Obj["USR"] = toHex(toStringRef(I.Type.USR));
385 Obj["IsTemplate"] = I.IsTemplate;
386 Obj["IsBuiltIn"] = I.IsBuiltIn;
387}
388
389static void serializeInfo(const FieldTypeInfo &I, Object &Obj) {
390 Obj["Name"] = I.Name;
391 Obj["Type"] = I.Type.Name;
392}
393
394static void serializeInfo(const FunctionInfo &F, json::Object &Obj,
395 const std::optional<StringRef> RepositoryURL) {
396 serializeCommonAttributes(F, Obj, RepositoryURL);
397 Obj["IsStatic"] = F.IsStatic;
398
399 auto ReturnTypeObj = Object();
400 serializeInfo(F.ReturnType, ReturnTypeObj);
401 Obj["ReturnType"] = std::move(ReturnTypeObj);
402
403 if (!F.Params.empty())
404 serializeArray(F.Params, Obj, "Params", SerializeInfoLambda);
405
406 if (F.Template)
407 serializeInfo(F.Template.value(), Obj);
408}
409
410static void serializeInfo(const EnumValueInfo &I, Object &Obj) {
411 Obj["Name"] = I.Name;
412 if (!I.ValueExpr.empty())
413 Obj["ValueExpr"] = I.ValueExpr;
414 else
415 Obj["Value"] = I.Value;
416}
417
418static void serializeInfo(const EnumInfo &I, json::Object &Obj,
419 const std::optional<StringRef> &RepositoryUrl) {
421 Obj["Scoped"] = I.Scoped;
422
423 if (I.BaseType) {
424 json::Value BaseTypeVal = Object();
425 auto &BaseTypeObj = *BaseTypeVal.getAsObject();
426 BaseTypeObj["Name"] = I.BaseType->Type.Name;
427 BaseTypeObj["QualName"] = I.BaseType->Type.QualName;
428 BaseTypeObj["USR"] = toHex(toStringRef(I.BaseType->Type.USR));
429 Obj["BaseType"] = BaseTypeVal;
430 }
431
432 if (!I.Members.empty())
433 serializeArray(I.Members, Obj, "Members", SerializeInfoLambda);
434}
435
436static void serializeInfo(const TypedefInfo &I, json::Object &Obj,
437 const std::optional<StringRef> &RepositoryUrl) {
439 Obj["TypeDeclaration"] = I.TypeDeclaration;
440 Obj["IsUsing"] = I.IsUsing;
441 json::Value TypeVal = Object();
442 auto &TypeObj = *TypeVal.getAsObject();
443 serializeInfo(I.Underlying, TypeObj);
444 Obj["Underlying"] = TypeVal;
445}
446
447static void serializeInfo(const BaseRecordInfo &I, Object &Obj,
448 const std::optional<StringRef> &RepositoryUrl) {
449 serializeInfo(static_cast<const RecordInfo &>(I), Obj, RepositoryUrl);
450 Obj["IsVirtual"] = I.IsVirtual;
451 Obj["Access"] = getAccessSpelling(I.Access);
452 Obj["IsParent"] = I.IsParent;
453}
454
455static void serializeInfo(const FriendInfo &I, Object &Obj) {
456 auto FriendRef = Object();
457 serializeReference(I.Ref, FriendRef);
458 Obj["Reference"] = std::move(FriendRef);
459 Obj["IsClass"] = I.IsClass;
460 if (I.Template)
461 serializeInfo(I.Template.value(), Obj);
462 if (I.Params)
463 serializeArray(I.Params.value(), Obj, "Params", SerializeInfoLambda);
464 if (I.ReturnType) {
465 auto ReturnTypeObj = Object();
466 serializeInfo(I.ReturnType.value(), ReturnTypeObj);
467 Obj["ReturnType"] = std::move(ReturnTypeObj);
468 }
469}
470
471static void insertArray(Object &Obj, json::Value &Array, StringRef Key) {
472 Obj[Key] = Array;
473 Obj["Has" + Key.str()] = true;
474}
475
476static void serializeInfo(const RecordInfo &I, json::Object &Obj,
477 const std::optional<StringRef> &RepositoryUrl) {
479 Obj["TagType"] = getTagType(I.TagType);
480 Obj["IsTypedef"] = I.IsTypeDef;
481 Obj["MangledName"] = I.MangledName;
482
483 if (!I.Children.Functions.empty()) {
484 json::Value PubFunctionsArray = Array();
485 json::Array &PubFunctionsArrayRef = *PubFunctionsArray.getAsArray();
486 json::Value ProtFunctionsArray = Array();
487 json::Array &ProtFunctionsArrayRef = *ProtFunctionsArray.getAsArray();
488
489 for (const auto &Function : I.Children.Functions) {
490 json::Value FunctionVal = Object();
491 auto &FunctionObj = *FunctionVal.getAsObject();
492 serializeInfo(Function, FunctionObj, RepositoryUrl);
493 AccessSpecifier Access = Function.Access;
494 if (Access == AccessSpecifier::AS_public)
495 PubFunctionsArrayRef.push_back(FunctionVal);
496 else if (Access == AccessSpecifier::AS_protected)
497 ProtFunctionsArrayRef.push_back(FunctionVal);
498 }
499
500 if (!PubFunctionsArrayRef.empty())
501 insertArray(Obj, PubFunctionsArray, "PublicFunctions");
502 if (!ProtFunctionsArrayRef.empty())
503 Obj["ProtectedFunctions"] = ProtFunctionsArray;
504 }
505
506 if (!I.Members.empty()) {
507 json::Value PublicMembersArray = Array();
508 json::Array &PubMembersArrayRef = *PublicMembersArray.getAsArray();
509 json::Value ProtectedMembersArray = Array();
510 json::Array &ProtMembersArrayRef = *ProtectedMembersArray.getAsArray();
511
512 for (const MemberTypeInfo &Member : I.Members) {
513 json::Value MemberVal = Object();
514 auto &MemberObj = *MemberVal.getAsObject();
515 MemberObj["Name"] = Member.Name;
516 MemberObj["Type"] = Member.Type.Name;
517
518 if (Member.Access == AccessSpecifier::AS_public)
519 PubMembersArrayRef.push_back(MemberVal);
520 else if (Member.Access == AccessSpecifier::AS_protected)
521 ProtMembersArrayRef.push_back(MemberVal);
522 }
523
524 if (!PubMembersArrayRef.empty())
525 insertArray(Obj, PublicMembersArray, "PublicMembers");
526 if (!ProtMembersArrayRef.empty())
527 Obj["ProtectedMembers"] = ProtectedMembersArray;
528 }
529
530 if (!I.Bases.empty())
532 I.Bases, Obj, "Bases",
533 [&RepositoryUrl](const BaseRecordInfo &Base, Object &BaseObj) {
534 serializeInfo(Base, BaseObj, RepositoryUrl);
535 });
536
537 if (!I.Parents.empty())
539
540 if (!I.VirtualParents.empty())
541 serializeArray(I.VirtualParents, Obj, "VirtualParents",
543
544 if (I.Template)
545 serializeInfo(I.Template.value(), Obj);
546
547 if (!I.Friends.empty())
548 serializeArray(I.Friends, Obj, "Friends", SerializeInfoLambda);
549
551}
552
553static void serializeInfo(const VarInfo &I, json::Object &Obj,
554 const std::optional<StringRef> RepositoryUrl) {
556 Obj["IsStatic"] = I.IsStatic;
557 auto TypeObj = Object();
558 serializeInfo(I.Type, TypeObj);
559 Obj["Type"] = std::move(TypeObj);
560}
561
562static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
563 const std::optional<StringRef> RepositoryUrl) {
565
566 if (!I.Children.Namespaces.empty())
567 serializeArray(I.Children.Namespaces, Obj, "Namespaces",
569
570 static auto SerializeInfo = [RepositoryUrl](const auto &Info,
571 Object &Object) {
573 };
574
575 if (!I.Children.Functions.empty())
576 serializeArray(I.Children.Functions, Obj, "Functions", SerializeInfo);
577
578 if (!I.Children.Concepts.empty())
579 serializeArray(I.Children.Concepts, Obj, "Concepts", SerializeInfo);
580
581 if (!I.Children.Variables.empty())
582 serializeArray(I.Children.Variables, Obj, "Variables", SerializeInfo);
583
585}
586
587static SmallString<16> determineFileName(Info *I, SmallString<128> &Path) {
588 SmallString<16> FileName;
589 if (I->IT == InfoType::IT_record) {
590 auto *RecordSymbolInfo = static_cast<SymbolInfo *>(I);
591 FileName = RecordSymbolInfo->MangledName;
592 } else if (I->IT == InfoType::IT_namespace) {
593 FileName = "index";
594 } else
595 FileName = I->Name;
596 sys::path::append(Path, FileName + ".json");
597 return FileName;
598}
599
601 StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
602 const ClangDocContext &CDCtx, std::string DirName) {
603 StringSet<> CreatedDirs;
604 StringMap<std::vector<doc::Info *>> FileToInfos;
605 for (const auto &Group : Infos) {
606 Info *Info = Group.getValue().get();
607
608 SmallString<128> Path;
609 auto RootDirStr = RootDir.str() + "/json";
610 StringRef JSONDir = StringRef(RootDirStr);
611 sys::path::native(JSONDir, Path);
612 sys::path::append(Path, Info->getRelativeFilePath(""));
613 if (!CreatedDirs.contains(Path)) {
614 if (std::error_code Err = sys::fs::create_directories(Path);
615 Err != std::error_code())
616 return createFileError(Twine(Path), Err);
617 CreatedDirs.insert(Path);
618 }
619
620 SmallString<16> FileName = determineFileName(Info, Path);
621 if (FileToInfos.contains(Path))
622 continue;
623 FileToInfos[Path].push_back(Info);
624 Info->DocumentationFileName = FileName;
625 }
626
627 for (const auto &Group : FileToInfos) {
628 std::error_code FileErr;
629 raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_Text);
630 if (FileErr)
631 return createFileError("cannot open file " + Group.getKey(), FileErr);
632
633 for (const auto &Info : Group.getValue())
634 if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx))
635 return Err;
636 }
637
638 return Error::success();
639}
640
641Error JSONGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
642 const ClangDocContext &CDCtx) {
643 json::Object Obj = Object();
644
645 switch (I->IT) {
647 serializeInfo(*static_cast<NamespaceInfo *>(I), Obj, CDCtx.RepositoryUrl);
648 break;
650 serializeInfo(*static_cast<RecordInfo *>(I), Obj, CDCtx.RepositoryUrl);
651 break;
658 break;
660 return createStringError(inconvertibleErrorCode(), "unexpected info type");
661 }
662 OS << llvm::formatv("{0:2}", llvm::json::Value(std::move(Obj)));
663 return Error::success();
664}
665
667 return Error::success();
668}
669
670static GeneratorRegistry::Add<JSONGenerator> JSON(JSONGenerator::Format,
671 "Generator for JSON output.");
673} // namespace doc
674} // namespace clang
static llvm::cl::opt< std::string > RepositoryUrl("repository", llvm::cl::desc(R"( URL of repository that hosts code. Used for links to definition locations.)"), llvm::cl::cat(ClangDocCategory))
static const char * Format
Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, const ClangDocContext &CDCtx) override
Error createResources(ClangDocContext &CDCtx) override
Error generateDocumentation(StringRef RootDir, llvm::StringMap< std::unique_ptr< doc::Info > > Infos, const ClangDocContext &CDCtx, std::string DirName) override
static std::string infoTypeToString(InfoType IT)
static json::Value extractTextComments(Object *ParagraphComment)
static Object serializeComment(const CommentInfo &I, Object &Description)
std::string getTagType(TagTypeKind AS)
static void insertComment(Object &Description, json::Value &Comment, StringRef Key)
static void serializeArray(const Container &Records, Object &Obj, const std::string &Key, SerializationFunc SerializeInfo)
volatile int JSONGeneratorAnchorSource
static auto SerializeReferenceLambda
static void serializeReference(const Reference &Ref, Object &ReferenceObj)
static void serializeInfo(const ConstraintInfo &I, Object &Obj)
static void serializeCommonAttributes(const Info &I, json::Object &Obj, const std::optional< StringRef > RepositoryUrl)
static GeneratorRegistry::Add< JSONGenerator > JSON(JSONGenerator::Format, "Generator for JSON output.")
static void serializeCommonChildren(const ScopeChildren &Children, json::Object &Obj, const std::optional< StringRef > RepositoryUrl)
static auto SerializeInfoLambda
static SmallString< 16 > determineFileName(Info *I, SmallString< 128 > &Path)
static json::Value extractVerbatimComments(json::Array VerbatimLines)
static json::Object serializeLocation(const Location &Loc, const std::optional< StringRef > RepositoryUrl)
llvm::StringRef commentKindToString(CommentKind Kind)
static void insertArray(Object &Obj, json::Value &Array, StringRef Key)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Some operations such as code completion produce a set of candidates.
Definition Generators.h:146
std::optional< std::string > RepositoryUrl
SmallString< 8 > Direction
std::vector< std::unique_ptr< CommentInfo > > Children
llvm::SmallVector< SmallString< 16 >, 4 > AttrValues
SmallString< 16 > CloseName
SmallString< 16 > Name
SmallString< 64 > Text
llvm::SmallVector< SmallString< 16 >, 4 > AttrKeys
llvm::SmallVector< SmallString< 16 >, 4 > Args
SmallString< 16 > ParamName
SmallString< 16 > ConstraintExpression
SmallString< 16 > ConstraintExpr
llvm::SmallVector< EnumValueInfo, 4 > Members
std::optional< TypeInfo > BaseType
SmallString< 16 > ValueExpr
std::optional< TypeInfo > ReturnType
std::optional< SmallVector< FieldTypeInfo, 4 > > Params
std::optional< TemplateInfo > Template
llvm::SmallVector< FieldTypeInfo, 4 > Params
std::optional< TemplateInfo > Template
A base struct for Infos.
SmallString< 16 > DocumentationFileName
SmallString< 16 > Name
std::vector< CommentInfo > Description
llvm::SmallString< 128 > Path
llvm::SmallString< 64 > getRelativeFilePath(const StringRef &CurrentPath) const
Returns the file path for this Info relative to CurrentPath.
llvm::SmallVector< Reference, 4 > Namespace
SmallString< 32 > Filename
llvm::SmallVector< MemberTypeInfo, 4 > Members
std::optional< TemplateInfo > Template
std::vector< FriendInfo > Friends
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
std::vector< BaseRecordInfo > Bases
SmallString< 16 > QualName
llvm::SmallString< 128 > Path
SmallString< 16 > DocumentationFileName
SmallString< 16 > Name
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< VarInfo > Variables
std::vector< ConceptInfo > Concepts
SmallString< 16 > MangledName
SmallString< 16 > TypeDeclaration