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,
18 std::string DirName)
override;
32template <
typename Container,
typename SerializationFunc>
34 const std::string &Key,
35 SerializationFunc SerializeInfo);
68 llvm_unreachable(
"Unknown InfoType encountered.");
74 Object LocationObj = Object();
76 LocationObj[
"Filename"] = Loc.
Filename;
81 sys::path::append(FileURL, sys::path::Style::posix, Loc.
Filename);
83 LocationObj[
"FileURL"] = FileURL;
89 auto DescriptionIt = Description.find(Key);
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;
97 DescriptionIt->getSecond().getAsArray()->push_back(Comment);
102 if (!ParagraphComment)
103 return json::Object();
104 return *ParagraphComment->get(
"Children");
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")
121 Object Obj = Object();
123 json::Value ChildVal = Object();
124 Object &Child = *ChildVal.getAsObject();
126 json::Value ChildArr = Array();
127 auto &CARef = *ChildArr.getAsArray();
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;
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});
169 Child.insert({
"ParamName", I.
ParamName});
170 Child.insert({
"Direction", I.
Direction});
171 Child.insert({
"Explicit", I.
Explicit});
173 Child.insert({
"Children", TextCommentsArray});
183 insertComment(Description, TextCommentsArray,
"CodeComments");
191 Child.insert({
"Text", I.
Text});
192 Child.insert({
"Children", ChildArr});
198 json::Value AttrKeysArray = json::Array();
199 json::Value AttrValuesArray = json::Array();
200 auto &KeyArr = *AttrKeysArray.getAsArray();
201 auto &ValArr = *AttrValuesArray.getAsArray();
205 KeyArr.emplace_back(K);
207 ValArr.emplace_back(V);
208 Child.insert({
"Name", I.
Name});
210 Child.insert({
"AttrKeys", AttrKeysArray});
211 Child.insert({
"AttrValues", AttrValuesArray});
212 Child.insert({
"Children", ChildArr});
218 Child.insert({
"Name", I.
Name});
219 Child.insert({
"Children", ChildArr});
226 Child.insert({
"Children", ChildArr});
227 Child[
"ParagraphComment"] =
true;
236 llvm_unreachable(
"Unknown comment kind encountered.");
242 Obj[
"Name"] = I.
Name;
243 Obj[
"USR"] = toHex(toStringRef(I.
USR));
249 Obj[
"Path"] = I.
Path;
252 Obj[
"Namespace"] = json::Array();
254 Obj[
"Namespace"].getAsArray()->push_back(NS.Name);
258 Object Description = Object();
265 if (
auto *ParagraphComment = Comment.getAsObject();
266 ParagraphComment->get(
"ParagraphComment")) {
268 insertComment(Description, TextCommentsArray,
"ParagraphComments");
271 Obj[
"Description"] = std::move(Description);
276 const auto *Symbol =
static_cast<const SymbolInfo *
>(&I);
284 ReferenceObj[
"Path"] = Ref.
Path;
285 ReferenceObj[
"Name"] = Ref.
Name;
286 ReferenceObj[
"QualName"] = Ref.
QualName;
287 ReferenceObj[
"USR"] = toHex(toStringRef(Ref.
USR));
302 if (!Children.Enums.empty()) {
304 Obj[
"HasEnums"] =
true;
307 if (!Children.Typedefs.empty())
308 serializeArray(Children.Typedefs, Obj,
"Typedefs", SerializeInfo);
310 if (!Children.Records.empty()) {
312 Obj[
"HasRecords"] =
true;
316template <
typename Container,
typename SerializationFunc>
318 const std::string &Key,
319 SerializationFunc SerializeInfo) {
320 json::Value RecordsArray = Array();
321 auto &RecordsArrayRef = *RecordsArray.getAsArray();
322 RecordsArrayRef.reserve(Records.size());
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);
331 Obj[Key] = RecordsArray;
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;
350 json::Value TemplateVal = Object();
351 auto &TemplateObj = *TemplateVal.getAsObject();
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;
363 if (!Template.Params.empty())
366 if (!Template.Constraints.empty())
370 Obj[
"Template"] = TemplateVal;
384 Obj[
"USR"] = toHex(toStringRef(I.
Type.
USR));
390 Obj[
"Name"] = I.
Name;
395 const std::optional<StringRef> RepositoryURL) {
399 auto ReturnTypeObj = Object();
401 Obj[
"ReturnType"] = std::move(ReturnTypeObj);
411 Obj[
"Name"] = I.
Name;
415 Obj[
"Value"] = I.
Value;
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;
441 json::Value TypeVal = Object();
442 auto &TypeObj = *TypeVal.getAsObject();
444 Obj[
"Underlying"] = TypeVal;
451 Obj[
"Access"] = getAccessSpelling(I.
Access);
456 auto FriendRef = Object();
458 Obj[
"Reference"] = std::move(FriendRef);
465 auto ReturnTypeObj = Object();
467 Obj[
"ReturnType"] = std::move(ReturnTypeObj);
471static void insertArray(Object &Obj, json::Value &Array, StringRef Key) {
473 Obj[
"Has" + Key.str()] =
true;
484 json::Value PubFunctionsArray = Array();
485 json::Array &PubFunctionsArrayRef = *PubFunctionsArray.getAsArray();
486 json::Value ProtFunctionsArray = Array();
487 json::Array &ProtFunctionsArrayRef = *ProtFunctionsArray.getAsArray();
490 json::Value FunctionVal = Object();
491 auto &FunctionObj = *FunctionVal.getAsObject();
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);
500 if (!PubFunctionsArrayRef.empty())
501 insertArray(Obj, PubFunctionsArray,
"PublicFunctions");
502 if (!ProtFunctionsArrayRef.empty())
503 Obj[
"ProtectedFunctions"] = ProtFunctionsArray;
507 json::Value PublicMembersArray = Array();
508 json::Array &PubMembersArrayRef = *PublicMembersArray.getAsArray();
509 json::Value ProtectedMembersArray = Array();
510 json::Array &ProtMembersArrayRef = *ProtectedMembersArray.getAsArray();
513 json::Value MemberVal = Object();
514 auto &MemberObj = *MemberVal.getAsObject();
515 MemberObj[
"Name"] = Member.
Name;
516 MemberObj[
"Type"] = Member.
Type.
Name;
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);
524 if (!PubMembersArrayRef.empty())
525 insertArray(Obj, PublicMembersArray,
"PublicMembers");
526 if (!ProtMembersArrayRef.empty())
527 Obj[
"ProtectedMembers"] = ProtectedMembersArray;
530 if (!I.
Bases.empty())
532 I.
Bases, Obj,
"Bases",
534 serializeInfo(Base, BaseObj, RepositoryUrl);
557 auto TypeObj = Object();
559 Obj[
"Type"] = std::move(TypeObj);
588 SmallString<16> FileName;
590 auto *RecordSymbolInfo =
static_cast<SymbolInfo *
>(I);
596 sys::path::append(Path, FileName +
".json");
601 StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
603 StringSet<> CreatedDirs;
604 StringMap<std::vector<doc::Info *>> FileToInfos;
605 for (
const auto &Group : Infos) {
606 Info *
Info = Group.getValue().get();
608 SmallString<128> Path;
609 auto RootDirStr = RootDir.str() +
"/json";
610 StringRef JSONDir = StringRef(RootDirStr);
611 sys::path::native(JSONDir, Path);
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);
621 if (FileToInfos.contains(Path))
623 FileToInfos[Path].push_back(
Info);
627 for (
const auto &Group : FileToInfos) {
628 std::error_code FileErr;
629 raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_Text);
631 return createFileError(
"cannot open file " + Group.getKey(), FileErr);
633 for (
const auto &
Info : Group.getValue())
638 return Error::success();
643 json::Object Obj = Object();
660 return createStringError(inconvertibleErrorCode(),
"unexpected info type");
662 OS << llvm::formatv(
"{0:2}", llvm::json::Value(std::move(Obj)));
663 return Error::success();
667 return Error::success();
671 "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 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)
@ 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
llvm::SmallVector< FieldTypeInfo, 4 > Params
std::optional< TemplateInfo > Template
SmallString< 16 > DocumentationFileName
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
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< VarInfo > Variables
std::vector< ConceptInfo > Concepts
SmallString< 16 > MangledName
SmallString< 16 > TypeDeclaration