151 lines · c
1//===-- Generators.h - ClangDoc Generator ----------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// Generator classes for converting declaration information into documentation9// in a specified format.10//===----------------------------------------------------------------------===//11 12#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_GENERATOR_H13#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_GENERATOR_H14 15#include "Representation.h"16#include "llvm/Support/Error.h"17#include "llvm/Support/JSON.h"18#include "llvm/Support/Mustache.h"19#include "llvm/Support/Registry.h"20 21namespace clang {22namespace doc {23 24// Abstract base class for generators.25// This is expected to be implemented and exposed via the GeneratorRegistry.26class Generator {27public:28 virtual ~Generator() = default;29 30 // Write out the decl info for the objects in the given map in the specified31 // format.32 virtual llvm::Error generateDocumentation(33 StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos,34 const ClangDocContext &CDCtx, std::string DirName = "") = 0;35 36 // This function writes a file with the index previously constructed.37 // It can be overwritten by any of the inherited generators.38 // If the override method wants to run this it should call39 // Generator::createResources(CDCtx);40 virtual llvm::Error createResources(ClangDocContext &CDCtx);41 42 // Write out one specific decl info to the destination stream.43 virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,44 const ClangDocContext &CDCtx) = 0;45 46 static void addInfoToIndex(Index &Idx, const doc::Info *Info);47};48 49typedef llvm::Registry<Generator> GeneratorRegistry;50 51llvm::Expected<std::unique_ptr<Generator>>52findGeneratorByName(llvm::StringRef Format);53 54std::string getTagType(TagTypeKind AS);55 56llvm::Error createFileOpenError(StringRef FileName, std::error_code EC);57 58class MustacheTemplateFile {59 llvm::BumpPtrAllocator Allocator;60 llvm::StringSaver Saver;61 llvm::mustache::MustacheContext Ctx;62 llvm::mustache::Template T;63 std::unique_ptr<llvm::MemoryBuffer> Buffer;64 65public:66 static Expected<std::unique_ptr<MustacheTemplateFile>>67 createMustacheFile(StringRef FileName) {68 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferOrError =69 llvm::MemoryBuffer::getFile(FileName);70 if (auto EC = BufferOrError.getError())71 return createFileOpenError(FileName, EC);72 return std::make_unique<MustacheTemplateFile>(73 std::move(BufferOrError.get()));74 }75 76 llvm::Error registerPartialFile(StringRef Name, StringRef FileName) {77 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferOrError =78 llvm::MemoryBuffer::getFile(FileName);79 if (auto EC = BufferOrError.getError())80 return createFileOpenError(FileName, EC);81 82 std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(BufferOrError.get());83 StringRef FileContent = Buffer->getBuffer();84 T.registerPartial(Name.str(), FileContent.str());85 return llvm::Error::success();86 }87 88 void render(llvm::json::Value &V, raw_ostream &OS) { T.render(V, OS); }89 90 MustacheTemplateFile(std::unique_ptr<llvm::MemoryBuffer> &&B)91 : Saver(Allocator), Ctx(Allocator, Saver), T(B->getBuffer(), Ctx),92 Buffer(std::move(B)) {}93};94 95struct MustacheGenerator : public Generator {96 Expected<std::string> getInfoTypeStr(llvm::json::Object *Info,97 StringRef Filename);98 99 /// Used to find the relative path from the file to the format's docs root.100 /// Mainly used for the HTML resource paths.101 SmallString<128> getRelativePathToRoot(StringRef PathToFile,102 StringRef DocsRootPath);103 virtual ~MustacheGenerator() = default;104 105 /// Initializes the template files from disk and calls setupTemplate to106 /// register partials107 virtual llvm::Error setupTemplateFiles(const ClangDocContext &CDCtx) = 0;108 109 /// Populates templates with data from JSON and calls any specifics for the110 /// format. For example, for HTML it will render the paths for CSS and JS.111 virtual llvm::Error generateDocForJSON(llvm::json::Value &JSON,112 llvm::raw_fd_ostream &OS,113 const ClangDocContext &CDCtx,114 StringRef ObjectTypeStr,115 StringRef RelativeRootPath) = 0;116 117 /// Registers partials to templates.118 llvm::Error119 setupTemplate(std::unique_ptr<MustacheTemplateFile> &Template,120 StringRef TemplatePath,121 std::vector<std::pair<StringRef, StringRef>> Partials);122 123 /// \brief The main orchestrator for Mustache-based documentation.124 ///125 /// 1. Initializes templates files from disk by calling setupTemplateFiles.126 /// 2. Calls the JSON generator to write JSON to disk.127 /// 3. Iterates over the JSON files, recreates the directory structure from128 /// JSON, and calls generateDocForJSON for each file.129 /// 4. A file of the desired format is created.130 llvm::Error generateDocumentation(131 StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos,132 const clang::doc::ClangDocContext &CDCtx, std::string DirName) override;133};134 135// This anchor is used to force the linker to link in the generated object file136// and thus register the generators.137extern volatile int YAMLGeneratorAnchorSource;138extern volatile int MDGeneratorAnchorSource;139extern volatile int HTMLGeneratorAnchorSource;140extern volatile int MHTMLGeneratorAnchorSource;141extern volatile int JSONGeneratorAnchorSource;142 143} // namespace doc144} // namespace clang145 146namespace llvm {147extern template class Registry<clang::doc::Generator>;148} // namespace llvm149 150#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_GENERATOR_H151