2#include "clang/Basic/Specifiers.h"
3#include "llvm/Support/JSON.h"
6using namespace llvm::json;
11template <
typename Container,
typename SerializationFunc>
13 const Container &Records, Object &Obj,
const StringRef Key,
14 SerializationFunc SerializeInfo,
const StringRef EndKey =
"End",
15 function_ref<
void(Object &)> UpdateJson = [](Object &Obj) {});
24 json::Object serializeLocation(
const Location &Loc);
25 void serializeCommonAttributes(
const Info &I, json::Object &Obj);
26 void serializeCommonChildren(
28 std::optional<ReferenceFunc> MDReferenceLambda = std::nullopt);
30 void serializeInfo(
const TemplateInfo &Template, Object &Obj);
31 void serializeInfo(
const ConceptInfo &I, Object &Obj);
32 void serializeInfo(
const TypeInfo &I, Object &Obj);
34 void serializeInfo(
const FunctionInfo &F, json::Object &Obj);
36 void serializeInfo(
const EnumInfo &I, json::Object &Obj);
37 void serializeInfo(
const TypedefInfo &I, json::Object &Obj);
39 void serializeInfo(
const FriendInfo &I, Object &Obj);
40 void serializeInfo(
const RecordInfo &I, json::Object &Obj);
41 void serializeInfo(
const VarInfo &I, json::Object &Obj);
42 void serializeInfo(
const NamespaceInfo &I, json::Object &Obj);
43 SmallString<16> determineFileName(
Info *I, SmallString<128> &Path);
44 Error serializeIndex(StringRef RootDir);
45 void generateContext(
const Info &I, Object &Obj);
46 void serializeReference(
const Reference &Ref, Object &ReferenceObj);
48 void serializeMDReference(
const Reference &Ref, Object &ReferenceObj,
52 auto serializeInfoLambda() {
53 return [
this](
const auto &
Info, Object &Object) {
54 serializeInfo(
Info, Object);
57 auto serializeReferenceLambda() {
58 return [
this](
const auto &Ref, Object &Object) {
59 serializeReference(Ref, Object);
71 std::string DirName)
override;
107 llvm_unreachable(
"Unknown InfoType encountered.");
110json::Object JSONGenerator::serializeLocation(
const Location &Loc) {
111 Object LocationObj = Object();
112 LocationObj[
"LineNumber"] = Loc.StartLineNumber;
113 LocationObj[
"Filename"] = Loc.Filename;
118 sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename);
120 std::string LinePrefix;
126 FileURL += LinePrefix + std::to_string(Loc.StartLineNumber);
127 LocationObj[
"FileURL"] = FileURL;
139 if (
auto *Obj = Comment.getAsObject()) {
140 if (
auto *Children = Obj->getArray(
"Children");
141 Children && Children->empty())
145 else if (
auto *Array = Comment.getAsArray(); Array && Array->empty()) {
149 auto DescriptionIt = Description.find(Key);
151 if (DescriptionIt == Description.end()) {
152 auto CommentsArray = json::Array();
153 CommentsArray.push_back(Comment);
154 Description[Key] = std::move(CommentsArray);
155 Description[
"Has" + Key.str()] =
true;
157 DescriptionIt->getSecond().getAsArray()->push_back(Comment);
165 if (!ParagraphComment)
166 return json::Value(
nullptr);
167 json::Value *Children = ParagraphComment->get(
"Children");
169 return json::Value(
nullptr);
170 auto ChildrenArray = *Children->getAsArray();
171 auto ChildrenIt = ChildrenArray.begin();
172 while (ChildrenIt != ChildrenArray.end()) {
173 auto *ChildObj = ChildrenIt->getAsObject();
174 assert(ChildObj &&
"Invalid JSON object in Comment");
175 auto TextComment = ChildObj->getString(
"TextComment");
176 if (!TextComment || TextComment->empty()) {
177 ChildrenIt = ChildrenArray.erase(ChildrenIt);
182 return ChildrenArray;
186 json::Value TextArray = json::Array();
187 auto &TextArrayRef = *TextArray.getAsArray();
188 for (
auto &Line : VerbatimLines)
189 TextArrayRef.push_back(*Line.getAsObject()
190 ->get(
"VerbatimBlockLineComment")
199 Object Obj = Object();
201 json::Value ChildVal = Object();
202 Object &Child = *ChildVal.getAsObject();
204 json::Value ChildArr = Array();
205 auto &CARef = *ChildArr.getAsArray();
219 if (I.
Name ==
"brief")
220 insertComment(Description, TextCommentsArray,
"BriefComments");
221 else if (I.
Name ==
"return")
222 insertComment(Description, TextCommentsArray,
"ReturnComments");
223 else if (I.
Name ==
"throws" || I.
Name ==
"throw") {
224 json::Value ThrowsVal = Object();
225 auto &ThrowsObj = *ThrowsVal.getAsObject();
226 ThrowsObj[
"Exception"] = I.
Args.front();
227 ThrowsObj[
"Children"] = TextCommentsArray;
234 json::Value ArgsArr = Array();
235 auto &ARef = *ArgsArr.getAsArray();
236 ARef.reserve(I.
Args.size());
237 for (
const auto &Arg : I.
Args)
238 ARef.emplace_back(Arg);
239 Child.insert({
"Command", I.
Name});
240 Child.insert({
"Args", ArgsArr});
241 Child.insert({
"Children", ChildArr});
248 Child.insert({
"ParamName", I.
ParamName});
249 Child.insert({
"Direction", I.
Direction});
250 Child.insert({
"Explicit", I.
Explicit});
252 Child.insert({
"Children", TextCommentsArray});
264 insertComment(Description, TextCommentsArray,
"CodeComments");
272 Child.insert({
"Text", I.
Text});
273 Child.insert({
"Children", ChildArr});
279 json::Value AttrKeysArray = json::Array();
280 json::Value AttrValuesArray = json::Array();
281 auto &KeyArr = *AttrKeysArray.getAsArray();
282 auto &ValArr = *AttrValuesArray.getAsArray();
286 KeyArr.emplace_back(K);
288 ValArr.emplace_back(V);
289 Child.insert({
"Name", I.
Name});
291 Child.insert({
"AttrKeys", AttrKeysArray});
292 Child.insert({
"AttrValues", AttrValuesArray});
293 Child.insert({
"Children", ChildArr});
299 Child.insert({
"Name", I.
Name});
300 Child.insert({
"Children", ChildArr});
307 Child.insert({
"Children", ChildArr});
308 Child[
"ParagraphComment"] =
true;
317 llvm_unreachable(
"Unknown comment kind encountered.");
321void JSONGenerator::generateContext(
const Info &I, Object &Obj) {
322 json::Value ContextArray = json::Array();
323 auto &ContextArrayRef = *ContextArray.getAsArray();
324 ContextArrayRef.reserve(I.Contexts.size());
326 std::string CurrentRelativePath;
327 bool PreviousRecord =
false;
328 for (
const auto &Current : I.Contexts) {
329 json::Value ContextVal = Object();
330 Object &Context = *ContextVal.getAsObject();
331 serializeReference(Current, Context);
334 if (Current.DocumentationFileName ==
"index") {
337 PreviousRecord =
false;
338 Context[
"RelativePath"] =
"./";
342 PreviousRecord =
true;
343 CurrentRelativePath +=
"../";
344 Context[
"RelativePath"] = CurrentRelativePath;
346 ContextArrayRef.push_back(ContextVal);
350 if (PreviousRecord && (Current.DocumentationFileName ==
"index")) {
353 PreviousRecord =
false;
354 }
else if (Current.DocumentationFileName !=
"index") {
357 PreviousRecord =
true;
358 CurrentRelativePath +=
"../";
361 PreviousRecord =
false;
362 CurrentRelativePath +=
"../";
365 if (Current.QualName ==
"GlobalNamespace" && Current.RelativePath !=
"./")
366 Context[
"DocumentationFileName"] =
367 SmallString<16>(
"GlobalNamespace/index");
369 Context[
"RelativePath"] = CurrentRelativePath;
370 ContextArrayRef.insert(ContextArrayRef.begin(), ContextVal);
373 ContextArrayRef.back().getAsObject()->insert({
"End",
true});
374 Obj[
"Contexts"] = ContextArray;
375 Obj[
"HasContexts"] =
true;
378void JSONGenerator::serializeCommonAttributes(
const Info &I,
382 Obj[
"USR"] = toHex(toStringRef(I.USR));
387 insertNonEmpty(
"DocumentationFileName", I.DocumentationFileName, Obj);
390 if (!I.Namespace.empty()) {
391 Obj[
"Namespace"] = json::Array();
392 for (
const auto &NS : I.Namespace)
393 Obj[
"Namespace"].getAsArray()->push_back(NS.Name);
396 if (!I.Description.empty()) {
399 auto &Comments = I.Description.at(0).Children;
400 for (
const auto &CommentInfo : Comments) {
404 if (
auto *ParagraphComment = Comment.getAsObject();
405 ParagraphComment->get(
"ParagraphComment")) {
407 if (TextCommentsArray.kind() == json::Value::Null ||
408 TextCommentsArray.getAsArray()->empty())
410 insertComment(Description, TextCommentsArray,
"ParagraphComments");
413 Obj[
"Description"] = std::move(Description);
418 const auto *Symbol =
static_cast<const SymbolInfo *
>(&I);
420 Obj[
"Location"] = serializeLocation(Symbol->DefLoc.value());
423 if (!I.Contexts.empty())
424 generateContext(I, Obj);
427void JSONGenerator::serializeReference(
const Reference &Ref,
428 Object &ReferenceObj) {
430 ReferenceObj[
"Name"] = Ref.Name;
431 ReferenceObj[
"QualName"] = Ref.QualName;
432 ReferenceObj[
"USR"] = toHex(toStringRef(Ref.USR));
433 if (!Ref.DocumentationFileName.empty()) {
434 ReferenceObj[
"DocumentationFileName"] = Ref.DocumentationFileName;
438 if (Ref.Path !=
"GlobalNamespace" && !Ref.Path.empty())
439 ReferenceObj[
"PathStem"] = sys::path::stem(Ref.Path);
443void JSONGenerator::serializeMDReference(
const Reference &Ref,
444 Object &ReferenceObj,
445 StringRef BasePath) {
446 serializeReference(Ref, ReferenceObj);
447 SmallString<64>
Path = Ref.getRelativeFilePath(BasePath);
448 sys::path::native(Path, sys::path::Style::posix);
449 sys::path::append(Path, sys::path::Style::posix,
450 Ref.getFileBaseName() +
".md");
451 ReferenceObj[
"BasePath"] =
Path;
458void JSONGenerator::serializeCommonChildren(
460 std::optional<ReferenceFunc> MDReferenceLambda) {
463 Obj[
"HasEnums"] =
true;
468 Obj[
"HasTypedefs"] =
true;
473 ? MDReferenceLambda.value()
474 : serializeReferenceLambda();
476 Obj[
"HasRecords"] =
true;
480template <
typename Container,
typename SerializationFunc>
482 SerializationFunc SerializeInfo, StringRef EndKey,
483 function_ref<
void(Object &)> UpdateJson) {
484 json::Value RecordsArray = Array();
485 auto &RecordsArrayRef = *RecordsArray.getAsArray();
486 RecordsArrayRef.reserve(Records.size());
488 json::Value ItemVal = Object();
489 auto &ItemObj = *ItemVal.getAsObject();
490 SerializeInfo(Records[
Index], ItemObj);
491 if (
Index == Records.size() - 1)
492 ItemObj[EndKey] =
true;
493 RecordsArrayRef.push_back(ItemVal);
495 Obj[Key] = RecordsArray;
499void JSONGenerator::serializeInfo(
const ConstraintInfo &I, Object &Obj) {
500 serializeReference(I.ConceptRef, Obj);
501 Obj[
"Expression"] = I.ConstraintExpr;
504void JSONGenerator::serializeInfo(
const TemplateInfo &Template, Object &Obj) {
505 json::Value TemplateVal = Object();
506 auto &TemplateObj = *TemplateVal.getAsObject();
507 auto SerializeTemplateParam = [](
const TemplateParamInfo &Param,
509 JsonObj[
"Param"] = Param.Contents;
512 if (Template.Specialization) {
513 json::Value TemplateSpecializationVal =
Object();
514 auto &TemplateSpecializationObj = *TemplateSpecializationVal.getAsObject();
515 TemplateSpecializationObj[
"SpecializationOf"] =
516 toHex(toStringRef(Template.Specialization->SpecializationOf));
517 if (!Template.Specialization->Params.empty()) {
518 bool VerticalDisplay =
520 serializeArray(Template.Specialization->Params, TemplateSpecializationObj,
521 "Parameters", SerializeTemplateParam,
"End",
522 [VerticalDisplay](Object &JsonObj) {
523 JsonObj[
"VerticalDisplay"] = VerticalDisplay;
526 TemplateObj[
"Specialization"] = TemplateSpecializationVal;
529 if (!Template.Params.empty()) {
532 SerializeTemplateParam,
"End",
533 [VerticalDisplay](Object &JsonObj) {
534 JsonObj[
"VerticalDisplay"] = VerticalDisplay;
538 if (!Template.Constraints.empty())
540 serializeInfoLambda());
542 Obj[
"Template"] = TemplateVal;
545void JSONGenerator::serializeInfo(
const ConceptInfo &I, Object &Obj) {
546 serializeCommonAttributes(I, Obj);
547 Obj[
"IsType"] = I.IsType;
548 Obj[
"ConstraintExpression"] = I.ConstraintExpression;
549 serializeInfo(I.Template, Obj);
552void JSONGenerator::serializeInfo(
const TypeInfo &I, Object &Obj) {
553 Obj[
"Name"] = I.Type.Name;
554 Obj[
"QualName"] = I.Type.QualName;
555 Obj[
"USR"] = toHex(toStringRef(I.Type.USR));
556 Obj[
"IsTemplate"] = I.IsTemplate;
557 Obj[
"IsBuiltIn"] = I.IsBuiltIn;
560void JSONGenerator::serializeInfo(
const FieldTypeInfo &I, Object &Obj) {
561 Obj[
"Name"] = I.Name;
563 json::Value ReferenceVal =
Object();
564 Object &ReferenceObj = *ReferenceVal.getAsObject();
565 serializeReference(I.Type, ReferenceObj);
566 Obj[
"Type"] = ReferenceVal;
569void JSONGenerator::serializeInfo(
const FunctionInfo &F, json::Object &Obj) {
570 serializeCommonAttributes(F, Obj);
571 Obj[
"IsStatic"] = F.IsStatic;
573 auto ReturnTypeObj =
Object();
574 serializeInfo(F.ReturnType, ReturnTypeObj);
575 Obj[
"ReturnType"] = std::move(ReturnTypeObj);
577 if (!F.Params.empty()) {
579 serializeArray(F.Params, Obj,
"Params", serializeInfoLambda(),
"ParamEnd",
580 [VerticalDisplay](Object &JsonObj) {
581 JsonObj[
"VerticalDisplay"] = VerticalDisplay;
586 serializeInfo(F.Template.value(), Obj);
589void JSONGenerator::serializeInfo(
const EnumValueInfo &I, Object &Obj) {
590 Obj[
"Name"] = I.Name;
591 if (!I.ValueExpr.empty())
592 Obj[
"ValueExpr"] = I.ValueExpr;
594 Obj[
"Value"] = I.Value;
597void JSONGenerator::serializeInfo(
const EnumInfo &I, json::Object &Obj) {
598 serializeCommonAttributes(I, Obj);
599 Obj[
"Scoped"] = I.Scoped;
602 json::Value BaseTypeVal =
Object();
603 auto &BaseTypeObj = *BaseTypeVal.getAsObject();
604 BaseTypeObj[
"Name"] = I.BaseType->Type.Name;
605 BaseTypeObj[
"QualName"] = I.BaseType->Type.QualName;
606 BaseTypeObj[
"USR"] = toHex(toStringRef(I.BaseType->Type.USR));
607 Obj[
"BaseType"] = BaseTypeVal;
610 if (!I.Members.empty())
614void JSONGenerator::serializeInfo(
const TypedefInfo &I, json::Object &Obj) {
615 serializeCommonAttributes(I, Obj);
616 Obj[
"TypeDeclaration"] = I.TypeDeclaration;
617 Obj[
"IsUsing"] = I.IsUsing;
618 json::Value TypeVal =
Object();
619 auto &TypeObj = *TypeVal.getAsObject();
620 serializeInfo(I.Underlying, TypeObj);
621 Obj[
"Underlying"] = TypeVal;
623 serializeInfo(I.Template.value(), Obj);
626void JSONGenerator::serializeInfo(
const BaseRecordInfo &I, Object &Obj) {
627 serializeInfo(
static_cast<const RecordInfo &
>(I), Obj);
628 Obj[
"IsVirtual"] = I.IsVirtual;
629 Obj[
"Access"] = getAccessSpelling(I.Access);
630 Obj[
"IsParent"] = I.IsParent;
633void JSONGenerator::serializeInfo(
const FriendInfo &I, Object &Obj) {
634 auto FriendRef =
Object();
635 serializeReference(I.Ref, FriendRef);
636 Obj[
"Reference"] = std::move(FriendRef);
637 Obj[
"IsClass"] = I.IsClass;
639 serializeInfo(I.Template.value(), Obj);
641 serializeArray(I.Params.value(), Obj,
"Params", serializeInfoLambda());
643 auto ReturnTypeObj =
Object();
644 serializeInfo(I.ReturnType.value(), ReturnTypeObj);
645 Obj[
"ReturnType"] = std::move(ReturnTypeObj);
647 serializeCommonAttributes(I, Obj);
650static void insertArray(Object &Obj, json::Value &Array, StringRef Key) {
652 Obj[
"Has" + Key.str()] =
true;
655void JSONGenerator::serializeInfo(
const RecordInfo &I, json::Object &Obj) {
656 serializeCommonAttributes(I, Obj);
658 Obj[
"IsTypedef"] = I.IsTypeDef;
659 Obj[
"MangledName"] = I.MangledName;
661 if (!I.Children.Functions.empty()) {
662 json::Value PubFunctionsArray = Array();
663 json::Array &PubFunctionsArrayRef = *PubFunctionsArray.getAsArray();
664 json::Value ProtFunctionsArray = Array();
665 json::Array &ProtFunctionsArrayRef = *ProtFunctionsArray.getAsArray();
667 for (
const auto &Function : I.Children.Functions) {
668 json::Value FunctionVal = Object();
669 auto &FunctionObj = *FunctionVal.getAsObject();
670 serializeInfo(Function, FunctionObj);
671 AccessSpecifier Access = Function.Access;
672 if (Access == AccessSpecifier::AS_public)
673 PubFunctionsArrayRef.push_back(FunctionVal);
674 else if (Access == AccessSpecifier::AS_protected)
675 ProtFunctionsArrayRef.push_back(FunctionVal);
678 if (!PubFunctionsArrayRef.empty())
679 insertArray(Obj, PubFunctionsArray,
"PublicMethods");
680 if (!ProtFunctionsArrayRef.empty())
681 insertArray(Obj, ProtFunctionsArray,
"ProtectedMethods");
684 if (!I.Members.empty()) {
685 Obj[
"HasMembers"] =
true;
686 json::Value PublicMembersArray =
Array();
687 json::Array &PubMembersArrayRef = *PublicMembersArray.getAsArray();
688 json::Value ProtectedMembersArray =
Array();
689 json::Array &ProtMembersArrayRef = *ProtectedMembersArray.getAsArray();
690 json::Value PrivateMembersArray =
Array();
691 json::Array &PrivateMembersArrayRef = *PrivateMembersArray.getAsArray();
693 for (
const MemberTypeInfo &Member : I.Members) {
694 json::Value MemberVal =
Object();
695 auto &MemberObj = *MemberVal.getAsObject();
696 MemberObj[
"Name"] = Member.Name;
697 MemberObj[
"Type"] = Member.Type.Name;
698 MemberObj[
"IsStatic"] = Member.IsStatic;
700 if (Member.Access == AccessSpecifier::AS_public)
701 PubMembersArrayRef.push_back(MemberVal);
702 else if (Member.Access == AccessSpecifier::AS_protected)
703 ProtMembersArrayRef.push_back(MemberVal);
704 else if (Member.Access == AccessSpecifier::AS_private)
705 PrivateMembersArrayRef.push_back(MemberVal);
708 if (!PubMembersArrayRef.empty())
709 insertArray(Obj, PublicMembersArray,
"PublicMembers");
710 if (!ProtMembersArrayRef.empty())
711 insertArray(Obj, ProtectedMembersArray,
"ProtectedMembers");
712 if (!PrivateMembersArrayRef.empty())
713 insertArray(Obj, PrivateMembersArray,
"PrivateMembers");
716 if (!I.Bases.empty())
719 if (!I.Parents.empty()) {
720 serializeArray(I.Parents, Obj,
"Parents", serializeReferenceLambda());
721 Obj[
"HasParents"] =
true;
724 if (!I.VirtualParents.empty()) {
726 serializeReferenceLambda());
727 Obj[
"HasVirtualParents"] =
true;
731 serializeInfo(I.Template.value(), Obj);
733 if (!I.Friends.empty()) {
735 Obj[
"HasFriends"] =
true;
738 serializeCommonChildren(I.Children, Obj);
741void JSONGenerator::serializeInfo(
const VarInfo &I, json::Object &Obj) {
742 serializeCommonAttributes(I, Obj);
743 Obj[
"IsStatic"] = I.IsStatic;
745 serializeInfo(I.Type, TypeObj);
746 Obj[
"Type"] = std::move(TypeObj);
749void JSONGenerator::serializeInfo(
const NamespaceInfo &I, json::Object &Obj) {
750 serializeCommonAttributes(I, Obj);
752 Obj[
"Name"] =
"Global Namespace";
754 if (!I.Children.Namespaces.empty()) {
756 serializeReferenceLambda());
757 Obj[
"HasNamespaces"] =
true;
760 if (!I.Children.Functions.empty()) {
762 serializeInfoLambda());
763 Obj[
"HasFunctions"] =
true;
766 if (!I.Children.Concepts.empty()) {
767 serializeArray(I.Children.Concepts, Obj,
"Concepts", serializeInfoLambda());
768 Obj[
"HasConcepts"] =
true;
771 if (!I.Children.Variables.empty()) {
773 serializeInfoLambda());
774 Obj[
"HasVariables"] =
true;
779 SmallString<64> BasePath = I.getRelativeFilePath(
"");
783 SerializeReferenceFunc = [
this, BasePath](
const Reference &Ref,
785 serializeMDReference(Ref, Object, BasePath);
787 serializeCommonChildren(I.Children, Obj, SerializeReferenceFunc);
789 SerializeReferenceFunc = serializeReferenceLambda();
790 serializeCommonChildren(I.Children, Obj);
793 if (!I.Children.Namespaces.empty()) {
795 SerializeReferenceFunc);
796 Obj[
"HasNamespaces"] =
true;
800SmallString<16> JSONGenerator::determineFileName(
Info *I,
801 SmallString<128> &Path) {
802 SmallString<16> FileName;
804 auto *RecordSymbolInfo =
static_cast<SymbolInfo *
>(I);
805 FileName = RecordSymbolInfo->MangledName;
810 sys::path::append(Path, FileName +
".json");
819 Processed.reserve(CDCtxIndex.
Children.size());
823 sys::path::native(NewPath, sys::path::Style::posix);
824 sys::path::append(NewPath, sys::path::Style::posix,
826 NewIdx.
Path = NewPath;
827 Processed.push_back(NewIdx);
834Error JSONGenerator::serializeAllFiles(
const ClangDocContext &CDCtx,
836 json::Value ObjVal = Object();
837 Object &Obj = *ObjVal.getAsObject();
839 serializeArray(IndexCopy, Obj,
"Index", serializeReferenceLambda());
840 SmallString<128> Path;
841 sys::path::append(Path, RootDir,
"json",
"all_files.json");
842 std::error_code FileErr;
843 raw_fd_ostream RootOS(Path, FileErr, sys::fs::OF_Text);
845 return createFileError(
"cannot open file " + Path, FileErr);
846 RootOS << llvm::formatv(
"{0:2}", ObjVal);
847 return Error::success();
853Error JSONGenerator::serializeIndex(StringRef RootDir) {
855 return Error::success();
857 json::Value ObjVal = Object();
858 Object &Obj = *ObjVal.getAsObject();
863 json::Value IndexArray = json::Array();
864 auto &IndexArrayRef = *IndexArray.getAsArray();
866 if (IndexCopy.Children.empty()) {
872 IndexArrayRef.reserve(
CDCtx->Idx.Children.size());
875 auto Children = IndexCopy.getSortedChildren();
877 for (
const auto *Idx : Children) {
878 if (Idx->Children.empty())
881 json::Value IdxVal =
Object();
882 auto &IdxObj = *IdxVal.getAsObject();
884 TypeStr.at(0) = toUppercase(TypeStr.at(0));
885 IdxObj[
"Type"] = TypeStr;
886 serializeReference(*Idx, IdxObj);
887 IndexArrayRef.push_back(IdxVal);
889 Obj[
"Index"] = IndexArray;
891 SmallString<128> IndexFilePath(RootDir);
892 sys::path::append(IndexFilePath,
"/json/index.json");
893 std::error_code FileErr;
894 raw_fd_ostream RootOS(IndexFilePath, FileErr, sys::fs::OF_Text);
896 return createFileError(
"cannot open file " + IndexFilePath, FileErr);
897 RootOS << llvm::formatv(
"{0:2}", ObjVal);
898 return Error::success();
907 auto &ParentInfo = Infos.at(llvm::toHex(ParentUSR));
910 Context GlobalRef(ParentInfo->USR,
"Global Namespace",
912 SmallString<16>(
"index"));
917 Context ParentRef(*ParentInfo);
919 ParentUSR = ParentInfo->ParentUSR;
926 this->CDCtx = &
CDCtx;
927 StringSet<> CreatedDirs;
928 StringMap<std::vector<doc::Info *>> FileToInfos;
929 for (
const auto &Group : Infos) {
932 SmallString<128> Path;
933 auto RootDirStr = RootDir.str() +
"/json";
934 StringRef JSONDir = StringRef(RootDirStr);
935 sys::path::native(JSONDir, Path);
937 if (!CreatedDirs.contains(Path)) {
938 if (std::error_code Err = sys::fs::create_directories(Path);
939 Err != std::error_code())
940 return createFileError(Twine(Path), Err);
941 CreatedDirs.insert(Path);
944 SmallString<16> FileName = determineFileName(
Info, Path);
945 if (FileToInfos.contains(Path))
947 FileToInfos[Path].push_back(
Info);
953 if (
auto Err = serializeAllFiles(
CDCtx, RootDir))
957 for (
const auto &Group : FileToInfos) {
958 std::error_code FileErr;
959 raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_Text);
961 return createFileError(
"cannot open file " + Group.getKey(), FileErr);
963 for (
const auto &
Info : Group.getValue()) {
971 return serializeIndex(RootDir);
976 json::Object Obj = Object();
983 serializeInfo(*
static_cast<RecordInfo *
>(I), Obj);
993 return createStringError(inconvertibleErrorCode(),
"unexpected info type");
995 OS << llvm::formatv(
"{0:2}", llvm::json::Value(std::move(Obj)));
996 return Error::success();
1000 return Error::success();
1004 "Generator for JSON output.");
clang::find_all_symbols::SymbolInfo SymbolInfo
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< OwnedPtr< doc::Info > > Infos, const ClangDocContext &CDCtx, std::string DirName) override
const ClangDocContext * CDCtx
std::string Path
A typedef to represent a file path.
static constexpr unsigned getMaxParamWrapLimit()
static std::string infoTypeToString(InfoType IT)
static json::Value extractTextComments(Object *ParagraphComment)
Takes the nested "Children" array from a comment Object.
static Object serializeComment(const CommentInfo &I, Object &Description)
@ CK_InlineCommandComment
@ CK_VerbatimBlockLineComment
@ CK_VerbatimBlockComment
@ CK_TParamCommandComment
static void insertComment(Object &Description, json::Value &Comment, StringRef Key)
Insert comments into a key in the Description object.
std::unique_ptr< T > OwnedPtr
std::function< void(const Reference &, Object &)> ReferenceFunc
volatile int JSONGeneratorAnchorSource
T * getPtr(const OwnedPtr< T > &O)
llvm::StringRef getTagType(TagTypeKind AS)
static OwningVec< Index > preprocessCDCtxIndex(Index CDCtxIndex)
static GeneratorRegistry::Add< JSONGenerator > JSON(JSONGenerator::Format, "Generator for JSON output.")
static void serializeArray(const Container &Records, Object &Obj, const StringRef Key, SerializationFunc SerializeInfo, const StringRef EndKey="End", function_ref< void(Object &)> UpdateJson=[](Object &Obj) {})
std::vector< T > OwningVec
constexpr SymbolID GlobalNamespaceID
static json::Value extractVerbatimComments(json::Array VerbatimLines)
static void insertNonEmpty(StringRef Key, StringRef Value, Object &Obj)
llvm::StringRef commentKindToString(CommentKind Kind)
static void insertArray(Object &Obj, json::Value &Array, StringRef Key)
static void serializeContexts(Info *I, StringMap< OwnedPtr< Info > > &Infos)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Some operations such as code completion produce a set of candidates.
std::optional< std::string > RepositoryUrl
std::optional< std::string > RepositoryLinePrefix
OwningVec< const Index * > getSortedChildren() const
llvm::StringMap< Index > Children
SmallString< 16 > DocumentationFileName
SmallVector< Context, 4 > Contexts
llvm::SmallString< 64 > getRelativeFilePath(const StringRef &CurrentPath) const
Returns the file path for this Info relative to CurrentPath.
llvm::SmallString< 128 > Path
llvm::SmallString< 64 > getRelativeFilePath(const StringRef &CurrentPath) const
Returns the path for this Reference relative to CurrentPath.
llvm::SmallString< 16 > getFileBaseName() const
Returns the basename that should be used for this Reference.