[clang-tools-extra] [clang-doc] add a JSON generator (PR #142483)
Paul Kirth via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 6 13:23:43 PDT 2025
================
@@ -0,0 +1,430 @@
+#include "Generators.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/Support/JSON.h"
+
+using namespace llvm;
+using namespace llvm::json;
+
+namespace clang {
+namespace doc {
+
+class JSONGenerator : public Generator {
+public:
+ static const char *Format;
+
+ Error generateDocs(StringRef RootDir,
+ llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
+ const ClangDocContext &CDCtx) override;
+ Error createResources(ClangDocContext &CDCtx) override;
+ Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) override;
+};
+
+const char *JSONGenerator::Format = "json";
+
+static void serializeInfo(const TypedefInfo &I, json::Object &Obj,
+ std::optional<StringRef> RepositoryUrl);
+static void serializeInfo(const EnumInfo &I, json::Object &Obj,
+ std::optional<StringRef> RepositoryUrl);
+
+static json::Object serializeLocation(const Location &Loc,
+ std::optional<StringRef> RepositoryUrl) {
+ Object LocationObj = Object();
+ LocationObj["LineNumber"] = Loc.StartLineNumber;
+ LocationObj["Filename"] = Loc.Filename;
+
+ if (!Loc.IsFileInRootDir || !RepositoryUrl)
+ return LocationObj;
+ SmallString<128> FileURL(*RepositoryUrl);
+ sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename);
+ FileURL += "#" + std::to_string(Loc.StartLineNumber);
+ LocationObj["FileURL"] = FileURL;
+ return LocationObj;
+}
+
+static json::Value serializeComment(const CommentInfo &Comment) {
+ assert((Comment.Kind == "BlockCommandComment" ||
+ Comment.Kind == "FullComment" || Comment.Kind == "ParagraphComment" ||
+ Comment.Kind == "TextComment") &&
+ "Unknown Comment type in CommentInfo.");
+
+ Object Obj = Object();
+ json::Value Child = Object();
+
+ // TextComment has no children, so return it.
+ if (Comment.Kind == "TextComment") {
+ Obj["TextComment"] = Comment.Text;
+ return Obj;
+ }
+
+ // BlockCommandComment needs to generate a Command key.
+ if (Comment.Kind == "BlockCommandComment")
+ Child.getAsObject()->insert({"Command", Comment.Name});
+
+ // Use the same handling for everything else.
+ // Only valid for:
+ // - BlockCommandComment
+ // - FullComment
+ // - ParagraphComment
+ json::Value ChildArr = Array();
+ auto &CARef = *ChildArr.getAsArray();
+ CARef.reserve(Comment.Children.size());
+ for (const auto &C : Comment.Children)
+ CARef.emplace_back(serializeComment(*C));
+ Child.getAsObject()->insert({"Children", ChildArr});
+ Obj.insert({Comment.Kind, Child});
+ return Obj;
+}
+
+static void serializeCommonAttributes(const Info &I, json::Object &Obj,
+ std::optional<StringRef> RepositoryUrl) {
+ Obj["Name"] = I.Name;
+ Obj["USR"] = toHex(toStringRef(I.USR));
+
+ if (!I.Path.empty())
+ Obj["Path"] = I.Path;
+
+ if (!I.Namespace.empty()) {
+ Obj["Namespace"] = json::Array();
+ for (const auto &NS : I.Namespace)
+ Obj["Namespace"].getAsArray()->push_back(NS.Name);
+ }
+
+ if (!I.Description.empty()) {
+ json::Value DescArray = json::Array();
+ auto &DescArrayRef = *DescArray.getAsArray();
+ for (const auto &Comment : I.Description)
----------------
ilovepi wrote:
can we reserve `I.Description.size()` to avoid realloc?
https://github.com/llvm/llvm-project/pull/142483
More information about the cfe-commits
mailing list