2#include "clang/Basic/Specifiers.h"
3#include "llvm/Support/JSON.h"
6using namespace llvm::json;
16 llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
31template <
typename Container,
typename SerializationFunc>
33 const std::string &Key,
34 SerializationFunc SerializeInfo);
67 llvm_unreachable(
"Unknown InfoType encountered.");
73 Object LocationObj = Object();
74 LocationObj[
"LineNumber"] =
Loc.StartLineNumber;
75 LocationObj[
"Filename"] =
Loc.Filename;
80 sys::path::append(FileURL, sys::path::Style::posix,
Loc.Filename);
81 FileURL +=
"#" + std::to_string(
Loc.StartLineNumber);
82 LocationObj[
"FileURL"] = FileURL;
88 auto DescriptionIt = Description.find(Key);
90 if (DescriptionIt == Description.end()) {
91 auto CommentsArray = json::Array();
92 CommentsArray.push_back(Comment);
93 Description[Key] = std::move(CommentsArray);
94 Description[
"Has" + Key.str()] =
true;
96 DescriptionIt->getSecond().getAsArray()->push_back(Comment);
101 if (!ParagraphComment)
102 return json::Object();
103 return *ParagraphComment->get(
"Children");
107 json::Value TextArray = json::Array();
108 auto &TextArrayRef = *TextArray.getAsArray();
109 for (
auto &
Line : VerbatimLines)
110 TextArrayRef.push_back(*
Line.getAsObject()
111 ->get(
"VerbatimBlockLineComment")
120 Object Obj = Object();
122 json::Value ChildVal = Object();
123 Object &Child = *ChildVal.getAsObject();
125 json::Value ChildArr = Array();
126 auto &CARef = *ChildArr.getAsArray();
139 if (I.
Name ==
"brief")
140 insertComment(Description, TextCommentsArray,
"BriefComments");
141 else if (I.
Name ==
"return")
142 insertComment(Description, TextCommentsArray,
"ReturnComments");
147 json::Value ArgsArr = Array();
148 auto &ARef = *ArgsArr.getAsArray();
149 ARef.reserve(I.
Args.size());
150 for (
const auto &Arg : I.
Args)
151 ARef.emplace_back(Arg);
152 Child.insert({
"Command", I.
Name});
153 Child.insert({
"Args", ArgsArr});
154 Child.insert({
"Children", ChildArr});
161 Child.insert({
"ParamName", I.
ParamName});
162 Child.insert({
"Direction", I.
Direction});
163 Child.insert({
"Explicit", I.
Explicit});
165 Child.insert({
"Children", TextCommentsArray});
175 insertComment(Description, TextCommentsArray,
"CodeComments");
183 Child.insert({
"Text", I.
Text});
184 Child.insert({
"Children", ChildArr});
190 json::Value AttrKeysArray = json::Array();
191 json::Value AttrValuesArray = json::Array();
192 auto &KeyArr = *AttrKeysArray.getAsArray();
193 auto &ValArr = *AttrValuesArray.getAsArray();
197 KeyArr.emplace_back(
K);
199 ValArr.emplace_back(V);
200 Child.insert({
"Name", I.
Name});
202 Child.insert({
"AttrKeys", AttrKeysArray});
203 Child.insert({
"AttrValues", AttrValuesArray});
204 Child.insert({
"Children", ChildArr});
210 Child.insert({
"Name", I.
Name});
211 Child.insert({
"Children", ChildArr});
218 Child.insert({
"Children", ChildArr});
219 Child[
"ParagraphComment"] =
true;
228 llvm_unreachable(
"Unknown comment kind encountered.");
234 Obj[
"Name"] = I.
Name;
235 Obj[
"USR"] = toHex(toStringRef(I.
USR));
241 Obj[
"Path"] = I.
Path;
244 Obj[
"Namespace"] = json::Array();
246 Obj[
"Namespace"].getAsArray()->push_back(NS.Name);
250 Object Description = Object();
257 if (
auto *ParagraphComment = Comment.getAsObject();
258 ParagraphComment->get(
"ParagraphComment")) {
260 insertComment(Description, TextCommentsArray,
"ParagraphComments");
263 Obj[
"Description"] = std::move(Description);
268 const auto *Symbol =
static_cast<const SymbolInfo *
>(&I);
276 ReferenceObj[
"Path"] = Ref.
Path;
277 ReferenceObj[
"Name"] = Ref.
Name;
278 ReferenceObj[
"QualName"] = Ref.
QualName;
279 ReferenceObj[
"USR"] = toHex(toStringRef(Ref.
USR));
296 Obj[
"HasEnums"] =
true;
304 Obj[
"HasRecords"] =
true;
308template <
typename Container,
typename SerializationFunc>
310 const std::string &Key,
311 SerializationFunc SerializeInfo) {
312 json::Value RecordsArray = Array();
313 auto &RecordsArrayRef = *RecordsArray.getAsArray();
314 RecordsArrayRef.reserve(
Records.size());
316 json::Value ItemVal = Object();
317 auto &ItemObj = *ItemVal.getAsObject();
320 ItemObj[
"End"] =
true;
321 RecordsArrayRef.push_back(ItemVal);
323 Obj[Key] = RecordsArray;
333 json::Value ParamsArray = Array();
334 auto &ParamsArrayRef = *ParamsArray.getAsArray();
335 ParamsArrayRef.reserve(Params.size());
336 for (
const auto &Param : Params)
337 ParamsArrayRef.push_back(Param.Contents);
338 Obj[
"Parameters"] = ParamsArray;
342 json::Value TemplateVal = Object();
343 auto &TemplateObj = *TemplateVal.getAsObject();
346 json::Value TemplateSpecializationVal = Object();
347 auto &TemplateSpecializationObj = *TemplateSpecializationVal.getAsObject();
348 TemplateSpecializationObj[
"SpecializationOf"] =
349 toHex(toStringRef(
Template.Specialization->SpecializationOf));
350 if (!
Template.Specialization->Params.empty())
352 TemplateObj[
"Specialization"] = TemplateSpecializationVal;
362 Obj[
"Template"] = TemplateVal;
376 Obj[
"USR"] = toHex(toStringRef(I.
Type.
USR));
382 Obj[
"Name"] = I.
Name;
387 const std::optional<StringRef> RepositoryURL) {
389 Obj[
"IsStatic"] = F.IsStatic;
391 auto ReturnTypeObj = Object();
393 Obj[
"ReturnType"] = std::move(ReturnTypeObj);
395 if (!F.Params.empty())
403 Obj[
"Name"] = I.
Name;
407 Obj[
"Value"] = I.
Value;
416 json::Value BaseTypeVal = Object();
417 auto &BaseTypeObj = *BaseTypeVal.getAsObject();
418 BaseTypeObj[
"Name"] = I.
BaseType->Type.Name;
419 BaseTypeObj[
"QualName"] = I.
BaseType->Type.QualName;
420 BaseTypeObj[
"USR"] = toHex(toStringRef(I.
BaseType->Type.USR));
421 Obj[
"BaseType"] = BaseTypeVal;
433 json::Value TypeVal = Object();
434 auto &TypeObj = *TypeVal.getAsObject();
436 Obj[
"Underlying"] = TypeVal;
443 Obj[
"Access"] = getAccessSpelling(I.
Access);
448 auto FriendRef = Object();
450 Obj[
"Reference"] = std::move(FriendRef);
457 auto ReturnTypeObj = Object();
459 Obj[
"ReturnType"] = std::move(ReturnTypeObj);
463static void insertArray(Object &Obj, json::Value &Array, StringRef Key) {
465 Obj[
"Has" + Key.str()] =
true;
477 json::Value PubFunctionsArray = Array();
478 json::Array &PubFunctionsArrayRef = *PubFunctionsArray.getAsArray();
479 json::Value ProtFunctionsArray = Array();
480 json::Array &ProtFunctionsArrayRef = *ProtFunctionsArray.getAsArray();
483 json::Value FunctionVal = Object();
484 auto &FunctionObj = *FunctionVal.getAsObject();
486 AccessSpecifier Access = Function.Access;
487 if (Access == AccessSpecifier::AS_public)
488 PubFunctionsArrayRef.push_back(FunctionVal);
489 else if (Access == AccessSpecifier::AS_protected)
490 ProtFunctionsArrayRef.push_back(FunctionVal);
493 if (!PubFunctionsArrayRef.empty())
494 insertArray(Obj, PubFunctionsArray,
"PublicFunctions");
495 if (!ProtFunctionsArrayRef.empty())
496 Obj[
"ProtectedFunctions"] = ProtFunctionsArray;
500 json::Value PublicMembersArray = Array();
501 json::Array &PubMembersArrayRef = *PublicMembersArray.getAsArray();
502 json::Value ProtectedMembersArray = Array();
503 json::Array &ProtMembersArrayRef = *ProtectedMembersArray.getAsArray();
506 json::Value MemberVal = Object();
507 auto &MemberObj = *MemberVal.getAsObject();
508 MemberObj[
"Name"] = Member.
Name;
509 MemberObj[
"Type"] = Member.
Type.
Name;
511 if (Member.
Access == AccessSpecifier::AS_public)
512 PubMembersArrayRef.push_back(MemberVal);
513 else if (Member.
Access == AccessSpecifier::AS_protected)
514 ProtMembersArrayRef.push_back(MemberVal);
517 if (!PubMembersArrayRef.empty())
518 insertArray(Obj, PublicMembersArray,
"PublicMembers");
519 if (!ProtMembersArrayRef.empty())
520 Obj[
"ProtectedMembers"] = ProtectedMembersArray;
523 if (!I.
Bases.empty())
525 I.
Bases, Obj,
"Bases",
527 serializeInfo(Base, BaseObj, RepositoryUrl);
550 auto TypeObj = Object();
552 Obj[
"Type"] = std::move(TypeObj);
583 auto *RecordSymbolInfo =
static_cast<SymbolInfo *
>(I);
584 FileName = RecordSymbolInfo->MangledName;
590 sys::path::append(Path,
FileName +
".json");
595 StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
597 StringSet<> CreatedDirs;
598 StringMap<std::vector<doc::Info *>> FileToInfos;
599 for (
const auto &Group : Infos) {
600 Info *
Info = Group.getValue().get();
602 SmallString<128> Path;
603 auto RootDirStr = RootDir.str() +
"/json";
604 StringRef JSONDir = StringRef(RootDirStr);
605 sys::path::native(JSONDir, Path);
606 if (!CreatedDirs.contains(Path)) {
607 if (std::error_code Err = sys::fs::create_directories(Path);
608 Err != std::error_code())
609 return createFileError(Twine(Path), Err);
610 CreatedDirs.insert(Path);
614 if (FileToInfos.contains(Path))
616 FileToInfos[Path].push_back(
Info);
620 for (
const auto &Group : FileToInfos) {
621 std::error_code FileErr;
622 raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_Text);
624 return createFileError(
"cannot open file " + Group.getKey(), FileErr);
626 for (
const auto &
Info : Group.getValue())
631 return Error::success();
636 json::Object Obj = Object();
653 return createStringError(inconvertibleErrorCode(),
"unexpected info type");
655 OS << llvm::formatv(
"{0:2}", llvm::json::Value(std::move(Obj)));
656 return Error::success();
660 return Error::success();
664 "Generator for JSON output.");
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 constexpr llvm::SourceMgr::DiagKind Error
std::vector< std::unique_ptr< HTMLNode > > Children
llvm::StringMap< llvm::TimeRecord > Records
static const char * Format
Error generateDocs(StringRef RootDir, llvm::StringMap< std::unique_ptr< doc::Info > > Infos, const ClangDocContext &CDCtx) override
Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, const ClangDocContext &CDCtx) override
Error createResources(ClangDocContext &CDCtx) 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)
@ CK_InlineCommandComment
@ CK_VerbatimBlockLineComment
@ CK_VerbatimBlockComment
@ CK_TParamCommandComment
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.
std::optional< std::string > RepositoryUrl
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
SmallString< 16 > DocumentationFileName
llvm::SmallString< 16 > getFileBaseName() const
Returns the basename that should be used for this Info.
std::vector< CommentInfo > Description
llvm::SmallString< 128 > Path
llvm::SmallVector< Reference, 4 > Namespace
llvm::SmallVector< MemberTypeInfo, 4 > Members
std::optional< TemplateInfo > Template
SmallString< 16 > FullName
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
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< VarInfo > Variables
std::vector< ConceptInfo > Concepts
SmallString< 16 > MangledName
SmallString< 16 > TypeDeclaration