Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang-tools-extra/clang-doc/Generators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ Error MustacheGenerator::generateDocumentation(

Expected<std::string> MustacheGenerator::getInfoTypeStr(Object *Info,
StringRef Filename) {
// Checking for a USR ensures that only the special top-level index file is
// caught here, since it is not an Info.
if (Filename == "index" && !Info->get("USR"))
return "index";
auto StrValue = (*Info)["InfoType"];
if (StrValue.kind() != json::Value::Kind::String)
return createStringError("JSON file '%s' does not contain key: 'InfoType'.",
Expand Down
12 changes: 12 additions & 0 deletions clang-tools-extra/clang-doc/HTMLGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ static std::unique_ptr<MustacheTemplateFile> NamespaceTemplate = nullptr;

static std::unique_ptr<MustacheTemplateFile> RecordTemplate = nullptr;

static std::unique_ptr<MustacheTemplateFile> IndexTemplate = nullptr;

class HTMLGenerator : public MustacheGenerator {
public:
static const char *Format;
Expand Down Expand Up @@ -60,6 +62,8 @@ Error HTMLGenerator::setupTemplateFiles(const ClangDocContext &CDCtx) {
ConvertToNative(CDCtx.MustacheTemplates.lookup("namespace-template"));
std::string ClassFilePath =
ConvertToNative(CDCtx.MustacheTemplates.lookup("class-template"));
std::string IndexFilePath =
ConvertToNative(CDCtx.MustacheTemplates.lookup("index-template"));
std::string CommentFilePath =
ConvertToNative(CDCtx.MustacheTemplates.lookup("comment-template"));
std::string FunctionFilePath =
Expand All @@ -83,6 +87,9 @@ Error HTMLGenerator::setupTemplateFiles(const ClangDocContext &CDCtx) {
if (Error Err = setupTemplate(RecordTemplate, ClassFilePath, Partials))
return Err;

if (Error Err = setupTemplate(IndexTemplate, IndexFilePath, Partials))
return Err;

return Error::success();
}

Expand Down Expand Up @@ -130,6 +137,11 @@ Error HTMLGenerator::generateDocForJSON(json::Value &JSON, raw_fd_ostream &OS,
return Err;
assert(RecordTemplate && "RecordTemplate is nullptr.");
RecordTemplate->render(JSON, OS);
} else if (ObjTypeStr == "index") {
if (auto Err = setupTemplateResources(CDCtx, JSON, RelativeRootPath))
return Err;
assert(IndexTemplate && "IndexTemplate is nullptr.");
IndexTemplate->render(JSON, OS);
}
return Error::success();
}
Expand Down
54 changes: 53 additions & 1 deletion clang-tools-extra/clang-doc/JSONGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,8 @@ serializeCommonAttributes(const Info &I, json::Object &Obj,
}

static void serializeReference(const Reference &Ref, Object &ReferenceObj) {
ReferenceObj["Path"] = Ref.Path;
if (!Ref.Path.empty())
ReferenceObj["Path"] = Ref.Path;
ReferenceObj["Name"] = Ref.Name;
ReferenceObj["QualName"] = Ref.QualName;
ReferenceObj["USR"] = toHex(toStringRef(Ref.USR));
Expand Down Expand Up @@ -647,6 +648,54 @@ static SmallString<16> determineFileName(Info *I, SmallString<128> &Path) {
return FileName;
}

// Creates a JSON file above the global namespace directory.
// An index can be used to create the top-level HTML index page or the Markdown
// index file.
static Error serializeIndex(const ClangDocContext &CDCtx, StringRef RootDir) {
if (CDCtx.Idx.Children.empty())
return Error::success();

json::Value ObjVal = Object();
Object &Obj = *ObjVal.getAsObject();
if (!CDCtx.ProjectName.empty())
Obj["ProjectName"] = CDCtx.ProjectName;

auto IndexCopy = CDCtx.Idx;
IndexCopy.sort();
json::Value IndexArray = json::Array();
auto &IndexArrayRef = *IndexArray.getAsArray();

if (IndexCopy.Children.empty()) {
// If the index is empty, default to displaying the global namespace.
IndexCopy.Children.emplace_back(GlobalNamespaceID, "",
InfoType::IT_namespace, "GlobalNamespace");
} else {
IndexArrayRef.reserve(CDCtx.Idx.Children.size());
}

for (auto &Idx : IndexCopy.Children) {
if (!Idx.Children.empty()) {
std::string TypeStr = infoTypeToString(Idx.RefType);
// MD output expects a capitalized type string
TypeStr[0] = toUppercase(TypeStr[0]);
json::Value IdxVal = Object();
auto &IdxObj = *IdxVal.getAsObject();
serializeReference(Idx, IdxObj);
IndexArrayRef.push_back(IdxVal);
}
}
Obj["Index"] = IndexArray;

SmallString<128> IndexFilePath(RootDir);
sys::path::append(IndexFilePath, "/json/index.json");
std::error_code FileErr;
raw_fd_ostream RootOS(IndexFilePath, FileErr, sys::fs::OF_Text);
if (FileErr)
return createFileError("cannot open file " + IndexFilePath, FileErr);
RootOS << llvm::formatv("{0:2}", ObjVal);
return Error::success();
}

Error JSONGenerator::generateDocumentation(
StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
const ClangDocContext &CDCtx, std::string DirName) {
Expand Down Expand Up @@ -685,6 +734,9 @@ Error JSONGenerator::generateDocumentation(
return Err;
}

if (auto Err = serializeIndex(CDCtx, RootDir))
return Err;

return Error::success();
}

Expand Down
41 changes: 41 additions & 0 deletions clang-tools-extra/clang-doc/assets/index-template.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
{{>HeadPartial}}
<body>
{{>NavbarPartial}}
<main>
<div class="container">
<div class="sidebar">
<h2>{{ProjectName}}</h2>
<ul>
<li class="sidebar-section">
<a class="sidebar-item" href="#Namespaces">Namespaces</a>
</li>
<li>
<ul>
{{#Index}}
<li class="sidebar-item-container">
<a class="sidebar-item" href="#{{Name}}">{{Name}}</a>
</li>
{{/Index}}
</ul>
</li>
</ul>
</div>
<div class="resizer" id="resizer"></div>
<div class="content">
<section id="Index" class="section-container">
<h2>Index</h2>
{{#Index}}
<div>
<a href="{{#Path}}{{Path}}/{{/Path}}{{Name}}/index.html">
<pre><code class="language-cpp code-clang-doc">namespace {{Name}}</code></pre>
</a>
</div>
{{/Index}}
</section>
</div>
</div>
</main>
</body>
</html>
3 changes: 3 additions & 0 deletions clang-tools-extra/clang-doc/support/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ void getHtmlFiles(StringRef AssetsPath, clang::doc::ClangDocContext &CDCtx) {
appendPathPosix(AssetsPath, "head-template.mustache");
SmallString<128> NavbarTemplate =
appendPathPosix(AssetsPath, "navbar-template.mustache");
SmallString<128> IndexTemplate =
appendPathPosix(AssetsPath, "index-template.mustache");

CDCtx.MustacheTemplates.insert(
{"namespace-template", NamespaceTemplate.c_str()});
Expand All @@ -70,4 +72,5 @@ void getHtmlFiles(StringRef AssetsPath, clang::doc::ClangDocContext &CDCtx) {
CDCtx.MustacheTemplates.insert({"comment-template", CommentTemplate.c_str()});
CDCtx.MustacheTemplates.insert({"head-template", HeadTemplate.c_str()});
CDCtx.MustacheTemplates.insert({"navbar-template", NavbarTemplate.c_str()});
CDCtx.MustacheTemplates.insert({"index-template", IndexTemplate.c_str()});
}
1 change: 1 addition & 0 deletions clang-tools-extra/clang-doc/tool/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ set(assets
template.mustache
head-template.mustache
navbar-template.mustache
index-template.mustache
)

set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets")
Expand Down
63 changes: 63 additions & 0 deletions clang-tools-extra/test/clang-doc/index.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: clang-doc --format=html --output=%t --executor=standalone %s
// RUN: FileCheck %s < %t/json/index.json -check-prefix=CHECK-JSON
// RUN: FileCheck %s < %t/html/index.html -check-prefix=CHECK-HTML

class Foo {};

namespace inner {
class Bar {};
}

{
// CHECK-JSON: "Index": [
// CHECK-JSON-NEXT: {
// CHECK-JSON-NEXT: "Name": "GlobalNamespace",
// CHECK-JSON-NEXT: "QualName": "GlobalNamespace",
// CHECK-JSON-NEXT: "USR": "0000000000000000000000000000000000000000"
// CHECK-JSON-NEXT: },
// CHECK-JSON-NEXT: {
// CHECK-JSON-NEXT: "Name": "inner",
// CHECK-JSON-NEXT: "QualName": "inner",
// CHECK-JSON-NEXT: "USR": "96AD5C6626E13385428E4BF18C3523B9AF6508B8"
// CHECK-JSON-NEXT: }
// CHECK-JSON-NEXT: ]

// CHECK-HTML: <main>
// CHECK-HTML-NEXT: <div class="container">
// CHECK-HTML-NEXT: <div class="sidebar">
// CHECK-HTML-NEXT: <h2></h2>
// CHECK-HTML-NEXT: <ul>
// CHECK-HTML-NEXT: <li class="sidebar-section">
// CHECK-HTML-NEXT: <a class="sidebar-item" href="#Namespaces">Namespaces</a>
// CHECK-HTML-NEXT: </li>
// CHECK-HTML-NEXT: <li>
// CHECK-HTML-NEXT: <ul>
// CHECK-HTML-NEXT: <li class="sidebar-item-container">
// CHECK-HTML-NEXT: <a class="sidebar-item" href="#GlobalNamespace">GlobalNamespace</a>
// CHECK-HTML-NEXT: </li>
// CHECK-HTML-NEXT: <li class="sidebar-item-container">
// CHECK-HTML-NEXT: <a class="sidebar-item" href="#inner">inner</a>
// CHECK-HTML-NEXT: </li>
// CHECK-HTML-NEXT: </ul>
// CHECK-HTML-NEXT: </li>
// CHECK-HTML-NEXT: </ul>
// CHECK-HTML-NEXT: </div>
// CHECK-HTML-NEXT: <div class="resizer" id="resizer"></div>
// CHECK-HTML-NEXT: <div class="content">
// CHECK-HTML-NEXT: <section id="Index" class="section-container">
// CHECK-HTML-NEXT: <h2>Index</h2>
// CHECK-HTML-NEXT: <div>
// CHECK-HTML-NEXT: <a href="GlobalNamespace/index.html">
// CHECK-HTML-NEXT: <pre><code class="language-cpp code-clang-doc">namespace GlobalNamespace</code></pre>
// CHECK-HTML-NEXT: </a>
// CHECK-HTML-NEXT: </div>
// CHECK-HTML-NEXT: <div>
// CHECK-HTML-NEXT: <a href="inner/index.html">
// CHECK-HTML-NEXT: <pre><code class="language-cpp code-clang-doc">namespace inner</code></pre>
// CHECK-HTML-NEXT: </a>
// CHECK-HTML-NEXT: </div>
// CHECK-HTML-NEXT: </section>
// CHECK-HTML-NEXT: </div>
// CHECK-HTML-NEXT: </div>
// CHECK-HTML-NEXT: </main>
1 change: 0 additions & 1 deletion clang-tools-extra/test/clang-doc/json/class-requires.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ struct MyClass;
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Addable<T>",
// CHECK-NEXT: "Name": "Addable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Addable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
Expand Down
1 change: 0 additions & 1 deletion clang-tools-extra/test/clang-doc/json/class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ struct MyClass {
// CHECK-NEXT: ],
// CHECK-NEXT: "Reference": {
// CHECK-NEXT: "Name": "friendFunction",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "friendFunction",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
Expand Down
11 changes: 0 additions & 11 deletions clang-tools-extra/test/clang-doc/json/compound-constraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,13 @@ template<typename T> requires (Incrementable<T> && Decrementable<T>) || PreIncre
// CHECK-NEXT: {
// CHECK-NEXT: "Expression": "Incrementable<T>",
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Incrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Decrementable<T>",
// CHECK-NEXT: "Name": "Decrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Decrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
Expand All @@ -51,15 +49,13 @@ template<typename T> requires (Incrementable<T> && Decrementable<T>) || PreIncre
// CHECK-NEXT: {
// CHECK-NEXT: "Expression": "Incrementable<T>",
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Incrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Decrementable<T>",
// CHECK-NEXT: "Name": "Decrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Decrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
Expand All @@ -70,29 +66,25 @@ template<typename T> requires (Incrementable<T> && Decrementable<T>) || PreIncre
// CHECK-NEXT: {
// CHECK-NEXT: "Expression": "Incrementable<T>",
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Incrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "Expression": "Decrementable<T>",
// CHECK-NEXT: "Name": "Decrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Decrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "Expression": "PreIncrementable<T>",
// CHECK-NEXT: "Name": "PreIncrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "PreIncrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "PreDecrementable<T>",
// CHECK-NEXT: "Name": "PreDecrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "PreDecrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
Expand All @@ -103,22 +95,19 @@ template<typename T> requires (Incrementable<T> && Decrementable<T>) || PreIncre
// CHECK-NEXT: {
// CHECK-NEXT: "Expression": "Incrementable<T>",
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Incrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "Expression": "Decrementable<T>",
// CHECK-NEXT: "Name": "Decrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Decrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "PreIncrementable<T>",
// CHECK-NEXT: "Name": "PreIncrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "PreIncrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
Expand Down
2 changes: 0 additions & 2 deletions clang-tools-extra/test/clang-doc/json/function-requires.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ template<Incrementable T> Incrementable auto incrementTwo(T t);
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Incrementable<T>",
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Incrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
Expand Down Expand Up @@ -73,7 +72,6 @@ template<Incrementable T> Incrementable auto incrementTwo(T t);
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Incrementable<T>",
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "Incrementable",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
Expand Down
1 change: 0 additions & 1 deletion clang-tools-extra/test/clang-doc/json/namespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ typedef int MyTypedef;
// CHECK-NEXT: {
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "NestedNamespace",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "NestedNamespace",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/test/clang-doc/namespace.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: clang-doc --format=html --output=%t --executor=standalone %s
// RUN: clang-doc --format=md --output=%t --executor=standalone %s
// RUN: FileCheck %s < %t/@nonymous_namespace/AnonClass.md -check-prefix=MD-ANON-CLASS-LINE
// run: filecheck %s < %t/@nonymous_namespace/anonclass.md -check-prefix=md-anon-class-line
// RUN: FileCheck %s < %t/@nonymous_namespace/AnonClass.md -check-prefix=MD-ANON-CLASS
// RUN: FileCheck %s < %t/@nonymous_namespace/index.md -check-prefix=MD-ANON-INDEX-LINE
// RUN: FileCheck %s < %t/@nonymous_namespace/index.md -check-prefix=MD-ANON-INDEX
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
{
"End": true,
"Name": "F",
"Path": "",
"QualName": "",
"USR": "0000000000000000000000000000000000000000"
}
Expand Down