18#include "llvm/Support/Error.h"
19#include "llvm/Support/MemoryBuffer.h"
20#include "llvm/Support/Mustache.h"
21#include "llvm/Support/Path.h"
22#include "llvm/Support/TimeProfiler.h"
25using namespace llvm::json;
26using namespace llvm::mustache;
31 StringRef Path, raw_fd_ostream &OS,
35 return createFileError(
"cannot open file " + FileName, EC);
42 StringMap<std::unique_ptr<doc::Info>> Infos,
51 static Expected<std::unique_ptr<MustacheTemplateFile>>
53 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrError =
54 MemoryBuffer::getFile(FileName);
55 if (
auto EC = BufferOrError.getError())
58 std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrError.get());
59 StringRef FileContent = Buffer->getBuffer();
60 return std::make_unique<MustacheTemplateFile>(FileContent);
64 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrError =
65 MemoryBuffer::getFile(FileName);
66 if (
auto EC = BufferOrError.getError())
69 std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrError.get());
70 StringRef FileContent = Buffer->getBuffer();
71 registerPartial(Name.str(), FileContent.str());
72 return Error::success();
84 StringRef TemplatePath,
85 std::vector<std::pair<StringRef, StringRef>> Partials) {
87 if (Error Err = T.takeError())
90 for (
const auto &[Name, FileName] : Partials)
91 if (
auto Err =
Template->registerPartialFile(Name, FileName))
93 return Error::success();
99 auto ConvertToNative = [](std::string &&Path) -> std::string {
100 SmallString<128> PathBuf(Path);
101 llvm::sys::path::native(PathBuf);
102 return PathBuf.str().str();
105 std::string NamespaceFilePath =
107 std::string ClassFilePath =
109 std::string CommentFilePath =
111 std::string FunctionFilePath =
113 std::string EnumFilePath =
115 std::vector<std::pair<StringRef, StringRef>> Partials = {
116 {
"Comments", CommentFilePath},
117 {
"FunctionPartial", FunctionFilePath},
118 {
"EnumPartial", EnumFilePath}};
126 return Error::success();
130 StringRef RootDir, StringMap<std::unique_ptr<doc::Info>> Infos,
133 llvm::TimeTraceScope TS(
"Setup Templates");
139 llvm::TimeTraceScope TS(
"Generate JSON for Mustache");
142 RootDir, std::move(Infos), CDCtx))
147 SmallString<128> JSONPath;
148 sys::path::native(RootDir.str() +
"/json", JSONPath);
150 StringMap<json::Value> JSONFileMap;
152 llvm::TimeTraceScope TS(
"Iterate JSON files");
154 sys::fs::directory_iterator JSONIter(JSONPath, EC);
155 std::vector<json::Value> JSONFiles;
156 JSONFiles.reserve(Infos.size());
158 return createStringError(
"Failed to create directory iterator.");
160 SmallString<128> HTMLDirPath(RootDir.str() +
"/html/");
161 if (
auto EC = sys::fs::create_directories(HTMLDirPath))
162 return createFileError(HTMLDirPath, EC);
163 while (JSONIter != sys::fs::directory_iterator()) {
165 return createFileError(
"Failed to iterate: " + JSONIter->path(), EC);
167 auto Path = StringRef(JSONIter->path());
168 if (!Path.ends_with(
".json")) {
169 JSONIter.increment(EC);
173 auto File = MemoryBuffer::getFile(Path);
174 if (EC = File.getError(); EC)
177 llvm::errs() <<
"Failed to open file: " << Path <<
" " << EC.message()
180 auto Parsed = json::parse((*File)->getBuffer());
182 return Parsed.takeError();
184 std::error_code FileErr;
185 SmallString<128> HTMLFilePath(HTMLDirPath);
186 sys::path::append(HTMLFilePath, sys::path::filename(Path));
187 sys::path::replace_extension(HTMLFilePath,
"html");
188 raw_fd_ostream InfoOS(HTMLFilePath, FileErr, sys::fs::OF_None);
193 HTMLFilePath, InfoOS, CDCtx))
195 JSONIter.increment(EC);
199 return Error::success();
203 V.getAsObject()->insert({
"ProjectName", CDCtx.
ProjectName});
204 json::Value StylesheetArr = Array();
205 SmallString<128> RelativePath(
"./");
206 sys::path::native(RelativePath, sys::path::Style::posix);
208 auto *SSA = StylesheetArr.getAsArray();
211 SmallString<128> StylesheetPath = RelativePath;
212 sys::path::append(StylesheetPath, sys::path::Style::posix,
213 sys::path::filename(FilePath));
214 SSA->emplace_back(StylesheetPath);
216 V.getAsObject()->insert({
"Stylesheets", StylesheetArr});
218 json::Value ScriptArr = Array();
219 auto *SCA = ScriptArr.getAsArray();
222 SmallString<128> JsPath = RelativePath;
223 sys::path::append(JsPath, sys::path::Style::posix,
224 sys::path::filename(Script));
225 SCA->emplace_back(JsPath);
227 V.getAsObject()->insert({
"Scripts", ScriptArr});
228 return Error::success();
232 StringRef Path, raw_fd_ostream &OS,
234 auto StrValue = (*
JSON.getAsObject())[
"InfoType"];
235 if (StrValue.kind() != json::Value::Kind::String)
236 return createStringError(
"JSON file '%s' does not contain key: 'InfoType'.",
237 Filename.str().c_str());
238 auto ObjTypeStr = StrValue.getAsString();
239 if (!ObjTypeStr.has_value())
240 return createStringError(
241 "JSON file '%s' does not contain 'InfoType' field as a string.",
242 Filename.str().c_str());
244 if (ObjTypeStr.value() ==
"namespace") {
249 }
else if (ObjTypeStr.value() ==
"record") {
255 return Error::success();
271 return createStringError(inconvertibleErrorCode(),
"unexpected InfoType");
273 return Error::success();
280 for (
const auto &FilePath : CDCtx.
JsScripts)
283 return Error::success();
288static GeneratorRegistry::Add<MustacheHTMLGenerator>
Error generateDocs(StringRef RootDir, llvm::StringMap< std::unique_ptr< doc::Info > > Infos, const ClangDocContext &CDCtx) override
static const char * Format
Error createResources(ClangDocContext &CDCtx) override
Error generateDocs(StringRef RootDir, StringMap< std::unique_ptr< doc::Info > > Infos, const ClangDocContext &CDCtx) override
Error generateDocForInfo(Info *I, raw_ostream &OS, const ClangDocContext &CDCtx) override
MustacheTemplateFile(StringRef TemplateStr)
static Expected< std::unique_ptr< MustacheTemplateFile > > createMustacheFile(StringRef FileName)
Error registerPartialFile(StringRef Name, StringRef FileName)
llvm::Error copyFile(llvm::StringRef FilePath, llvm::StringRef OutDirectory)
static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx)
static Error setupTemplate(std::unique_ptr< MustacheTemplateFile > &Template, StringRef TemplatePath, std::vector< std::pair< StringRef, StringRef > > Partials)
llvm::Expected< std::unique_ptr< Generator > > findGeneratorByName(llvm::StringRef Format)
static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V)
static std::unique_ptr< MustacheTemplateFile > RecordTemplate
static GeneratorRegistry::Add< JSONGenerator > JSON(JSONGenerator::Format, "Generator for JSON output.")
static Error generateDocForJSON(json::Value &JSON, StringRef Filename, StringRef Path, raw_fd_ostream &OS, const ClangDocContext &CDCtx)
static GeneratorRegistry::Add< MustacheHTMLGenerator > MHTML(MustacheHTMLGenerator::Format, "Generator for mustache HTML output.")
static std::unique_ptr< MustacheTemplateFile > NamespaceTemplate
static Error createFileOpenError(StringRef FileName, std::error_code EC)
volatile int MHTMLGeneratorAnchorSource
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Some operations such as code completion produce a set of candidates.
std::vector< std::string > UserStylesheets
llvm::StringMap< std::string > MustacheTemplates
std::vector< std::string > JsScripts