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

>From 72da18f86f4ce50cbd804ae47feb6baeb275e159 Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulki...@google.com>
Date: Wed, 30 Apr 2025 08:13:46 -0700
Subject: [PATCH] [clang-doc] Implement setupTemplateValue for
 HTMLMustacheGenerator

This patch implements the business logic for setupTemplateValue, which
was split from #133161. The implementation configures the relative path
relationships between the various HTML components, and prepares them
prior to their use in the generator. The tests here are disabled by
default until we can use lit tests via tool support, since we cannot
read files in the unit tests.

Co-authored-by: Peter Chou <peter.c...@mail.utoronto.ca>
---
 .../clang-doc/HTMLMustacheGenerator.cpp       |  27 ++-
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 193 ++++++++++++++++--
 2 files changed, 199 insertions(+), 21 deletions(-)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 18ee3b8d0fc43..65dc2e93582e8 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -397,7 +397,7 @@ static json::Value extractValue(const RecordInfo &I,
 
   maybeInsertLocation(I.DefLoc, CDCtx, RecordValue);
 
-  StringRef BasePath = I.getRelativeFilePath("");
+  SmallString<64> BasePath = I.getRelativeFilePath("");
   extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
   json::Value PublicMembers = Array();
   json::Array &PubMemberRef = *PublicMembers.getAsArray();
@@ -431,8 +431,28 @@ static json::Value extractValue(const RecordInfo &I,
 
 static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
                                 Info *I) {
-  return createStringError(inconvertibleErrorCode(),
-                           "setupTemplateValue is unimplemented");
+  V.getAsObject()->insert({"ProjectName", CDCtx.ProjectName});
+  json::Value StylesheetArr = Array();
+  auto InfoPath = I->getRelativeFilePath("");
+  SmallString<128> RelativePath = computeRelativePath("", InfoPath);
+  sys::path::native(RelativePath, sys::path::Style::posix);
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+    SmallString<128> StylesheetPath = RelativePath;
+    sys::path::append(StylesheetPath, sys::path::Style::posix,
+                      sys::path::filename(FilePath));
+    StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
+  }
+  V.getAsObject()->insert({"Stylesheets", StylesheetArr});
+
+  json::Value ScriptArr = Array();
+  for (auto Script : CDCtx.JsScripts) {
+    SmallString<128> JsPath = RelativePath;
+    sys::path::append(JsPath, sys::path::Style::posix,
+                      sys::path::filename(Script));
+    ScriptArr.getAsArray()->emplace_back(JsPath);
+  }
+  V.getAsObject()->insert({"Scripts", ScriptArr});
+  return Error::success();
 }
 
 Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
@@ -443,6 +463,7 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, 
raw_ostream &OS,
         extractValue(*static_cast<clang::doc::NamespaceInfo *>(I), CDCtx);
     if (auto Err = setupTemplateValue(CDCtx, V, I))
       return Err;
+    assert(NamespaceTemplate && "NamespaceTemplate is nullptr.");
     NamespaceTemplate->render(V, OS);
     break;
   }
diff --git 
a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
index 4c8cf4fa7e460..95acd363a958e 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
@@ -20,10 +20,14 @@
 
 using namespace llvm;
 using namespace testing;
+using namespace clang;
 using namespace clang::doc;
 
-static const std::string ClangDocVersion =
-    clang::getClangToolFullVersion("clang-doc");
+// FIXME: Don't enable unit tests that can read files. Remove once we can use
+// lit to test these properties.
+#define ENABLE_LOCAL_TEST 0
+
+static const std::string ClangDocVersion = 
getClangToolFullVersion("clang-doc");
 
 static std::unique_ptr<Generator> getHTMLMustacheGenerator() {
   auto G = findGeneratorByName("mustache");
@@ -91,37 +95,190 @@ TEST(HTMLMustacheGeneratorTest, generateDocs) {
   unittest::TempDir RootTestDirectory("generateDocsTest", /*Unique=*/true);
   CDCtx.OutDirectory = RootTestDirectory.path();
 
+#if ENABLE_LOCAL_TEST
   // FIXME: We can't read files during unit tests. Migrate to lit once
   // tool support lands.
-  // getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
 
+  EXPECT_THAT_ERROR(G->generateDocs(RootTestDirectory.path(), {}, CDCtx),
+                    Succeeded())
+      << "Failed to generate docs.";
+#else
   EXPECT_THAT_ERROR(G->generateDocs(RootTestDirectory.path(), {}, CDCtx),
                     Failed())
       << "Failed to generate docs.";
+#endif
 }
 
-TEST(HTMLMustacheGeneratorTest, generateDocsForInfo) {
+TEST(HTMLGeneratorTest, emitFunctionHTML) {
+#if ENABLE_LOCAL_TEST
   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";
+
+  unittest::TempDir RootTestDirectory("emitRecordHTML",
+                                      /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+
+  // FIXME: This is a terrible hack, since we can't initialize the templates
+  // directly. We'll need to update the interfaces so that we can call
+  // SetupTemplateFiles() from outsize of HTMLMustacheGenerator.cpp
+  EXPECT_THAT_ERROR(G->generateDocs(RootTestDirectory.path(), {}, CDCtx),
+                    Succeeded())
+      << "Failed to generate docs.";
+
+  CDCtx.RepositoryUrl = "http://www.repository.com";;
+
+  FunctionInfo I;
+  I.Name = "f";
   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();
+  I.DefLoc = Location(10, 10, "dir/test.cpp", true);
+  I.Loc.emplace_back(12, 12, "test.cpp");
+
+  I.Access = AccessSpecifier::AS_none;
+
+  SmallString<16> PathTo;
+  llvm::sys::path::native("path/to", PathTo);
+  I.ReturnType = doc::TypeInfo(
+      Reference(EmptySID, "float", InfoType::IT_default, "float", PathTo));
+  I.Params.emplace_back(doc::TypeInfo("int", PathTo), "P");
+  I.IsMethod = true;
+  I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
+
+  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
+  assert(!Err);
+  std::string Expected = R"raw(IT_Function
+)raw";
+
+  // FIXME: Functions are not handled yet.
+  EXPECT_EQ(Expected, Actual.str());
+#endif
+}
+
+TEST(HTMLMustacheGeneratorTest, emitEnumHTML) {
+#if ENABLE_LOCAL_TEST
+  auto G = getHTMLMustacheGenerator();
+  assert(G && "Could not find HTMLMustacheGenerator");
+  ClangDocContext CDCtx = getClangDocContext();
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+
+  unittest::TempDir RootTestDirectory("emitEnumHTML",
+                                      /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+
+  // FIXME: This is a terrible hack, since we can't initialize the templates
+  // directly. We'll need to update the interfaces so that we can call
+  // SetupTemplateFiles() from outsize of HTMLMustacheGenerator.cpp
+  EXPECT_THAT_ERROR(G->generateDocs(RootTestDirectory.path(), {}, CDCtx),
+                    Succeeded())
+      << "Failed to generate docs.";
+
+  CDCtx.RepositoryUrl = "http://www.repository.com";;
+
+  EnumInfo I;
+  I.Name = "e";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, 10, "test.cpp", true);
+  I.Loc.emplace_back(12, 12, "test.cpp");
+
+  I.Members.emplace_back("X");
+  I.Scoped = true;
+
+  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
+  assert(!Err);
+
+  std::string Expected = R"raw(IT_enum
+)raw";
+
+  // FIXME: Enums are not handled yet.
+  EXPECT_EQ(Expected, Actual.str());
+#endif
+}
+
+TEST(HTMLMustacheGeneratorTest, emitCommentHTML) {
+#if ENABLE_LOCAL_TEST
+  auto G = getHTMLMustacheGenerator();
+  assert(G && "Could not find HTMLMustacheGenerator");
+  ClangDocContext CDCtx = getClangDocContext();
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+
+  unittest::TempDir RootTestDirectory("emitCommentHTML",
+                                      /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+
+  // FIXME: This is a terrible hack, since we can't initialize the templates
+  // directly. We'll need to update the interfaces so that we can call
+  // SetupTemplateFiles() from outsize of HTMLMustacheGenerator.cpp
+  EXPECT_THAT_ERROR(G->generateDocs(RootTestDirectory.path(), {}, CDCtx),
+                    Succeeded())
+      << "Failed to generate docs.";
+
+  CDCtx.RepositoryUrl = "http://www.repository.com";;
+
+  FunctionInfo I;
+  I.Name = "f";
+  I.DefLoc = Location(10, 10, "test.cpp", true);
+  I.ReturnType = doc::TypeInfo("void");
+  I.Params.emplace_back(doc::TypeInfo("int"), "I");
+  I.Params.emplace_back(doc::TypeInfo("int"), "J");
+  I.Access = AccessSpecifier::AS_none;
+
+  CommentInfo Top;
+  Top.Kind = "FullComment";
+
+  Top.Children.emplace_back(std::make_unique<CommentInfo>());
+  CommentInfo *BlankLine = Top.Children.back().get();
+  BlankLine->Kind = "ParagraphComment";
+  BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
+  BlankLine->Children.back()->Kind = "TextComment";
+
+  Top.Children.emplace_back(std::make_unique<CommentInfo>());
+  CommentInfo *Brief = Top.Children.back().get();
+  Brief->Kind = "ParagraphComment";
+  Brief->Children.emplace_back(std::make_unique<CommentInfo>());
+  Brief->Children.back()->Kind = "TextComment";
+  Brief->Children.back()->Name = "ParagraphComment";
+  Brief->Children.back()->Text = " Brief description.";
+
+  Top.Children.emplace_back(std::make_unique<CommentInfo>());
+  CommentInfo *Extended = Top.Children.back().get();
+  Extended->Kind = "ParagraphComment";
+  Extended->Children.emplace_back(std::make_unique<CommentInfo>());
+  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Text = " Extended description that";
+  Extended->Children.emplace_back(std::make_unique<CommentInfo>());
+  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Text = " continues onto the next line.";
+
+  Top.Children.emplace_back(std::make_unique<CommentInfo>());
+  CommentInfo *Entities = Top.Children.back().get();
+  Entities->Kind = "ParagraphComment";
+  Entities->Children.emplace_back(std::make_unique<CommentInfo>());
+  Entities->Children.back()->Kind = "TextComment";
+  Entities->Children.back()->Name = "ParagraphComment";
+  Entities->Children.back()->Text =
+      " Comment with html entities: &, <, >, \", \'.";
+
+  I.Description.emplace_back(std::move(Top));
 
-  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Failed());
+  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
+  assert(!Err);
+  std::string Expected = R"raw(IT_Function
+)raw";
 
-  std::string Expected = R"raw()raw";
-  EXPECT_THAT(Actual.str(), Eq(Expected));
+  // FIXME: Functions are not handled yet.
+  EXPECT_EQ(Expected, Actual.str());
+#endif
 }

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

Reply via email to