https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138061

>From 1925647e9577d827a87d1c7ac4326836928f90e0 Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulki...@google.com>
Date: Wed, 30 Apr 2025 08:09:41 -0700
Subject: [PATCH] [clang-doc] Add HTMLMustacheGenerator methods

Split from #133161. This patch fills in the implementation for a number
of the MustacheHTMLGenerator methods. Many of these APIs are just
stubbed out, and will have their implementation filled in by later
patches.

Co-authored-by: Peter Chou <peter.c...@mail.utoronto.ca>
---
 .../clang-doc/HTMLMustacheGenerator.cpp       | 98 +++++++++++++++++++
 .../unittests/clang-doc/CMakeLists.txt        |  1 +
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 37 ++++++-
 3 files changed, 133 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 6ba0325685599..879987b5292ed 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -70,18 +70,116 @@ class MustacheTemplateFile : public Template {
   MustacheTemplateFile(StringRef TemplateStr) : Template(TemplateStr) {}
 };
 
+static std::unique_ptr<MustacheTemplateFile> NamespaceTemplate = nullptr;
+
+static std::unique_ptr<MustacheTemplateFile> RecordTemplate = nullptr;
+
+static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
+  return Error::success();
+}
+
 Error MustacheHTMLGenerator::generateDocs(
     StringRef RootDir, StringMap<std::unique_ptr<doc::Info>> Infos,
     const clang::doc::ClangDocContext &CDCtx) {
+  if (auto Err = setupTemplateFiles(CDCtx))
+    return Err;
+  // Track which directories we already tried to create.
+  StringSet<> CreatedDirs;
+  // Collect all output by file name and create the necessary directories.
+  StringMap<std::vector<doc::Info *>> FileToInfos;
+  for (const auto &Group : Infos) {
+    doc::Info *Info = Group.getValue().get();
+
+    SmallString<128> Path;
+    sys::path::native(RootDir, Path);
+    sys::path::append(Path, Info->getRelativeFilePath(""));
+    if (!CreatedDirs.contains(Path)) {
+      if (std::error_code EC = sys::fs::create_directories(Path))
+        return createStringError(EC, "failed to create directory '%s'.",
+                                 Path.c_str());
+      CreatedDirs.insert(Path);
+    }
+
+    sys::path::append(Path, Info->getFileBaseName() + ".html");
+    FileToInfos[Path].push_back(Info);
+  }
+
+  for (const auto &Group : FileToInfos) {
+    std::error_code FileErr;
+    raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_None);
+    if (FileErr)
+      return createFileOpenError(Group.getKey(), FileErr);
+
+    for (const auto &Info : Group.getValue()) {
+      if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx))
+        return Err;
+    }
+  }
   return Error::success();
 }
 
+static json::Value extractValue(const NamespaceInfo &I,
+                                const ClangDocContext &CDCtx) {
+  Object NamespaceValue = Object();
+  return NamespaceValue;
+}
+
+static json::Value extractValue(const RecordInfo &I,
+                                const ClangDocContext &CDCtx) {
+  Object RecordValue = Object();
+  return RecordValue;
+}
+
+static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
+                                Info *I) {
+  return createStringError(inconvertibleErrorCode(),
+                           "setupTemplateValue is unimplemented");
+}
+
 Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
                                                 const ClangDocContext &CDCtx) {
+  switch (I->IT) {
+  case InfoType::IT_namespace: {
+    json::Value V =
+        extractValue(*static_cast<clang::doc::NamespaceInfo *>(I), CDCtx);
+    if (auto Err = setupTemplateValue(CDCtx, V, I))
+      return Err;
+    NamespaceTemplate->render(V, OS);
+    break;
+  }
+  case InfoType::IT_record: {
+    json::Value V =
+        extractValue(*static_cast<clang::doc::RecordInfo *>(I), CDCtx);
+    if (auto Err = setupTemplateValue(CDCtx, V, I))
+      return Err;
+    // Serialize the JSON value to the output stream in a readable format.
+    RecordTemplate->render(V, OS);
+    break;
+  }
+  case InfoType::IT_enum:
+    OS << "IT_enum\n";
+    break;
+  case InfoType::IT_function:
+    OS << "IT_Function\n";
+    break;
+  case InfoType::IT_typedef:
+    OS << "IT_typedef\n";
+    break;
+  case InfoType::IT_default:
+    return createStringError(inconvertibleErrorCode(), "unexpected InfoType");
+  }
   return Error::success();
 }
 
 Error MustacheHTMLGenerator::createResources(ClangDocContext &CDCtx) {
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+    if (Error Err = copyFile(FilePath, CDCtx.OutDirectory))
+      return Err;
+  }
+  for (const auto &FilePath : CDCtx.JsScripts) {
+    if (Error Err = copyFile(FilePath, CDCtx.OutDirectory))
+      return Err;
+  }
   return Error::success();
 }
 
diff --git a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt 
b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
index 81c18e6014072..fd14d85c63485 100644
--- a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
+++ b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
@@ -34,6 +34,7 @@ clang_target_link_libraries(ClangDocTests
   clangTooling
   clangToolingCore
   )
+
 target_link_libraries(ClangDocTests
   PRIVATE
   clangDoc
diff --git 
a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
index cd82fc5ae7fa0..773dbef8e652d 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
@@ -10,7 +10,9 @@
 #include "Generators.h"
 #include "Representation.h"
 #include "clang/Basic/Version.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Testing/Support/Error.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -40,13 +42,43 @@ getClangDocContext(std::vector<std::string> UserStylesheets 
= {},
   return CDCtx;
 }
 
+static void verifyFileContents(const Twine &Path, StringRef Contents) {
+  auto Buffer = MemoryBuffer::getFile(Path);
+  ASSERT_TRUE((bool)Buffer);
+  StringRef Data = Buffer.get()->getBuffer();
+  ASSERT_EQ(Data, Contents);
+}
+
 TEST(HTMLMustacheGeneratorTest, createResources) {
   auto G = getHTMLMustacheGenerator();
   ASSERT_THAT(G, NotNull()) << "Could not find HTMLMustacheGenerator";
   ClangDocContext CDCtx = getClangDocContext();
+  EXPECT_THAT_ERROR(G->createResources(CDCtx), Failed())
+      << "Empty UserStylesheets or JsScripts should fail!";
+
+  unittest::TempDir RootTestDirectory("createResourcesTest", /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  unittest::TempFile CSS("clang-doc-mustache", "css", "CSS");
+  unittest::TempFile JS("mustache", "js", "JavaScript");
+
+  CDCtx.UserStylesheets[0] = CSS.path();
+  CDCtx.JsScripts[0] = JS.path();
 
   EXPECT_THAT_ERROR(G->createResources(CDCtx), Succeeded())
-      << "Failed to create resources.";
+      << "Failed to create resources with valid UserStylesheets and JsScripts";
+  {
+    SmallString<256> PathBuff;
+    llvm::sys::path::append(PathBuff, RootTestDirectory.path(),
+                            "clang-doc-mustache.css");
+    verifyFileContents(PathBuff, "CSS");
+  }
+
+  {
+    SmallString<256> PathBuff;
+    llvm::sys::path::append(PathBuff, RootTestDirectory.path(), "mustache.js");
+    verifyFileContents(PathBuff, "JavaScript");
+  }
 }
 
 TEST(HTMLMustacheGeneratorTest, generateDocs) {
@@ -79,8 +111,7 @@ TEST(HTMLMustacheGeneratorTest, generateDocsForInfo) {
   I.Children.Functions.back().Name = "OneFunction";
   I.Children.Enums.emplace_back();
 
-  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Succeeded())
-      << "Failed to generate docs.";
+  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Failed());
 
   std::string Expected = R"raw()raw";
   EXPECT_THAT(Actual.str(), Eq(Expected));

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to