Author: Paul Kirth
Date: 2025-05-12T18:54:04-07:00
New Revision: 3bdfa6f3e8ebb6b3c139a7f4929f7016a6f56386

URL: 
https://github.com/llvm/llvm-project/commit/3bdfa6f3e8ebb6b3c139a7f4929f7016a6f56386
DIFF: 
https://github.com/llvm/llvm-project/commit/3bdfa6f3e8ebb6b3c139a7f4929f7016a6f56386.diff

LOG: [clang-doc] Add HTMLMustacheGenerator.cpp (#138060)

Split from #133161. This patch adds HTMLMustacheGenerator.cpp, and
the most basic class defintion for the generator. Future patches will
add functionality.

Co-authored-by: Peter Chou <peter.c...@mail.utoronto.ca>

Added: 
    clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
    clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp

Modified: 
    clang-tools-extra/clang-doc/CMakeLists.txt
    clang-tools-extra/clang-doc/Generators.cpp
    clang-tools-extra/clang-doc/Generators.h
    clang-tools-extra/clang-doc/Representation.h
    clang-tools-extra/unittests/clang-doc/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-doc/CMakeLists.txt 
b/clang-tools-extra/clang-doc/CMakeLists.txt
index 915e14c3ee16d..79563c41435eb 100644
--- a/clang-tools-extra/clang-doc/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangDoc STATIC
   Representation.cpp
   Serialize.cpp
   YAMLGenerator.cpp
+  HTMLMustacheGenerator.cpp
 
   DEPENDS
   omp_gen
@@ -24,7 +25,7 @@ add_clang_library(clangDoc STATIC
 
 clang_target_link_libraries(clangDoc
   PRIVATE
-  clangDocSupport        
+  clangDocSupport
   clangAnalysis
   clangAST
   clangASTMatchers

diff  --git a/clang-tools-extra/clang-doc/Generators.cpp 
b/clang-tools-extra/clang-doc/Generators.cpp
index 4bb5366800f7f..a3c2773412cff 100644
--- a/clang-tools-extra/clang-doc/Generators.cpp
+++ b/clang-tools-extra/clang-doc/Generators.cpp
@@ -103,6 +103,7 @@ static int LLVM_ATTRIBUTE_UNUSED MDGeneratorAnchorDest =
     MDGeneratorAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED HTMLGeneratorAnchorDest =
     HTMLGeneratorAnchorSource;
-
+static int LLVM_ATTRIBUTE_UNUSED MHTMLGeneratorAnchorDest =
+    MHTMLGeneratorAnchorSource;
 } // namespace doc
 } // namespace clang

diff  --git a/clang-tools-extra/clang-doc/Generators.h 
b/clang-tools-extra/clang-doc/Generators.h
index 2e71890389256..aee04b9d58d9d 100644
--- a/clang-tools-extra/clang-doc/Generators.h
+++ b/clang-tools-extra/clang-doc/Generators.h
@@ -57,6 +57,7 @@ std::string getTagType(TagTypeKind AS);
 extern volatile int YAMLGeneratorAnchorSource;
 extern volatile int MDGeneratorAnchorSource;
 extern volatile int HTMLGeneratorAnchorSource;
+extern volatile int MHTMLGeneratorAnchorSource;
 
 } // namespace doc
 } // namespace clang

diff  --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
new file mode 100644
index 0000000000000..6ba0325685599
--- /dev/null
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -0,0 +1,98 @@
+///===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the implementation of the MustacheHTMLGenerator class,
+/// which is Clang-Doc generator for HTML using Mustache templates.
+///
+//===----------------------------------------------------------------------===//
+
+#include "Generators.h"
+#include "Representation.h"
+#include "support/File.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Mustache.h"
+
+using namespace llvm;
+using namespace llvm::json;
+using namespace llvm::mustache;
+
+namespace clang {
+namespace doc {
+
+static Error createFileOpenError(StringRef FileName, std::error_code EC) {
+  return createFileError("cannot open file " + FileName, EC);
+}
+
+class MustacheHTMLGenerator : public Generator {
+public:
+  static const char *Format;
+  Error generateDocs(StringRef RootDir,
+                     StringMap<std::unique_ptr<doc::Info>> Infos,
+                     const ClangDocContext &CDCtx) override;
+  Error createResources(ClangDocContext &CDCtx) override;
+  Error generateDocForInfo(Info *I, raw_ostream &OS,
+                           const ClangDocContext &CDCtx) override;
+};
+
+class MustacheTemplateFile : public Template {
+public:
+  static Expected<std::unique_ptr<MustacheTemplateFile>>
+  createMustacheFile(StringRef FileName) {
+    ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrError =
+        MemoryBuffer::getFile(FileName);
+    if (auto EC = BufferOrError.getError())
+      return createFileOpenError(FileName, EC);
+
+    std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrError.get());
+    StringRef FileContent = Buffer->getBuffer();
+    return std::make_unique<MustacheTemplateFile>(FileContent);
+  }
+
+  Error registerPartialFile(StringRef Name, StringRef FileName) {
+    ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrError =
+        MemoryBuffer::getFile(FileName);
+    if (auto EC = BufferOrError.getError())
+      return createFileOpenError(FileName, EC);
+
+    std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrError.get());
+    StringRef FileContent = Buffer->getBuffer();
+    registerPartial(Name.str(), FileContent.str());
+    return Error::success();
+  }
+
+  MustacheTemplateFile(StringRef TemplateStr) : Template(TemplateStr) {}
+};
+
+Error MustacheHTMLGenerator::generateDocs(
+    StringRef RootDir, StringMap<std::unique_ptr<doc::Info>> Infos,
+    const clang::doc::ClangDocContext &CDCtx) {
+  return Error::success();
+}
+
+Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
+                                                const ClangDocContext &CDCtx) {
+  return Error::success();
+}
+
+Error MustacheHTMLGenerator::createResources(ClangDocContext &CDCtx) {
+  return Error::success();
+}
+
+const char *MustacheHTMLGenerator::Format = "mustache";
+
+static GeneratorRegistry::Add<MustacheHTMLGenerator>
+    MHTML(MustacheHTMLGenerator::Format, "Generator for mustache HTML 
output.");
+
+// This anchor is used to force the linker to link in the generated object
+// file and thus register the generator.
+volatile int MHTMLGeneratorAnchorSource = 0;
+
+} // namespace doc
+} // namespace clang

diff  --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index 9e4484ceb70a8..a2e01719eb59e 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -537,6 +537,9 @@ struct ClangDocContext {
   std::vector<std::string> JsScripts;
   // Base directory for remote repositories.
   StringRef Base;
+  // Maps mustache template types to specific mustache template files.
+  // Ex.    comment-template -> /path/to/comment-template.mustache
+  llvm::StringMap<std::string> MustacheTemplates;
   Index Idx;
 };
 

diff  --git a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt 
b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
index 043d68f5a1dcb..81c18e6014072 100644
--- a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
+++ b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
@@ -15,6 +15,7 @@ add_extra_unittest(ClangDocTests
   ClangDocTest.cpp
   GeneratorTest.cpp
   HTMLGeneratorTest.cpp
+  HTMLMustacheGeneratorTest.cpp
   MDGeneratorTest.cpp
   MergeTest.cpp
   SerializeTest.cpp
@@ -36,4 +37,5 @@ clang_target_link_libraries(ClangDocTests
 target_link_libraries(ClangDocTests
   PRIVATE
   clangDoc
+  LLVMTestingSupport
   )

diff  --git 
a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
new file mode 100644
index 0000000000000..cd82fc5ae7fa0
--- /dev/null
+++ b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
@@ -0,0 +1,87 @@
+//===-- clang-doc/HTMLMustacheGeneratorTest.cpp 
---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangDocTest.h"
+#include "Generators.h"
+#include "Representation.h"
+#include "clang/Basic/Version.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace testing;
+using namespace clang::doc;
+
+static const std::string ClangDocVersion =
+    clang::getClangToolFullVersion("clang-doc");
+
+static std::unique_ptr<Generator> getHTMLMustacheGenerator() {
+  auto G = findGeneratorByName("mustache");
+  if (!G)
+    return nullptr;
+  return std::move(G.get());
+}
+
+static ClangDocContext
+getClangDocContext(std::vector<std::string> UserStylesheets = {},
+                   StringRef RepositoryUrl = "",
+                   StringRef RepositoryLinePrefix = "", StringRef Base = "") {
+  ClangDocContext CDCtx{
+      {},   "test-project", {}, {}, {}, RepositoryUrl, RepositoryLinePrefix,
+      Base, UserStylesheets};
+  CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(), "");
+  CDCtx.JsScripts.emplace_back("");
+  return CDCtx;
+}
+
+TEST(HTMLMustacheGeneratorTest, createResources) {
+  auto G = getHTMLMustacheGenerator();
+  ASSERT_THAT(G, NotNull()) << "Could not find HTMLMustacheGenerator";
+  ClangDocContext CDCtx = getClangDocContext();
+
+  EXPECT_THAT_ERROR(G->createResources(CDCtx), Succeeded())
+      << "Failed to create resources.";
+}
+
+TEST(HTMLMustacheGeneratorTest, generateDocs) {
+  auto G = getHTMLMustacheGenerator();
+  assert(G && "Could not find HTMLMustacheGenerator");
+  ClangDocContext CDCtx = getClangDocContext();
+
+  StringRef RootDir = "";
+  EXPECT_THAT_ERROR(G->generateDocs(RootDir, {}, CDCtx), Succeeded())
+      << "Failed to generate docs.";
+}
+
+TEST(HTMLMustacheGeneratorTest, generateDocsForInfo) {
+  auto G = getHTMLMustacheGenerator();
+  assert(G && "Could not find HTMLMustacheGenerator");
+  ClangDocContext CDCtx = getClangDocContext();
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  NamespaceInfo I;
+  I.Name = "Namespace";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.Children.Namespaces.emplace_back(EmptySID, "ChildNamespace",
+                                     InfoType::IT_namespace,
+                                     "Namespace::ChildNamespace", "Namespace");
+  I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
+                                  "Namespace::ChildStruct", "Namespace");
+  I.Children.Functions.emplace_back();
+  I.Children.Functions.back().Access = clang::AccessSpecifier::AS_none;
+  I.Children.Functions.back().Name = "OneFunction";
+  I.Children.Enums.emplace_back();
+
+  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Succeeded())
+      << "Failed to generate docs.";
+
+  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