diff options
Diffstat (limited to 'clang-tools-extra/clang-doc/HTMLGenerator.cpp')
-rw-r--r-- | clang-tools-extra/clang-doc/HTMLGenerator.cpp | 106 |
1 files changed, 75 insertions, 31 deletions
diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 2cc6748768e..546d7d208d7 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -301,12 +301,15 @@ genReferenceList(const llvm::SmallVectorImpl<Reference> &Refs, return Out; } -static std::vector<std::unique_ptr<TagNode>> genHTML(const EnumInfo &I); -static std::vector<std::unique_ptr<TagNode>> genHTML(const FunctionInfo &I, - StringRef ParentInfoDir); +static std::vector<std::unique_ptr<TagNode>> +genHTML(const EnumInfo &I, const ClangDocContext &CDCtx); +static std::vector<std::unique_ptr<TagNode>> +genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, + StringRef ParentInfoDir); static std::vector<std::unique_ptr<TagNode>> -genEnumsBlock(const std::vector<EnumInfo> &Enums) { +genEnumsBlock(const std::vector<EnumInfo> &Enums, + const ClangDocContext &CDCtx) { if (Enums.empty()) return {}; @@ -316,7 +319,7 @@ genEnumsBlock(const std::vector<EnumInfo> &Enums) { Out.emplace_back(llvm::make_unique<TagNode>(HTMLTag::TAG_DIV)); auto &DivBody = Out.back(); for (const auto &E : Enums) { - std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(E); + std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(E, CDCtx); AppendVector(std::move(Nodes), DivBody->Children); } return Out; @@ -335,7 +338,7 @@ genEnumMembersBlock(const llvm::SmallVector<SmallString<16>, 4> &Members) { static std::vector<std::unique_ptr<TagNode>> genFunctionsBlock(const std::vector<FunctionInfo> &Functions, - StringRef ParentInfoDir) { + const ClangDocContext &CDCtx, StringRef ParentInfoDir) { if (Functions.empty()) return {}; @@ -345,7 +348,8 @@ genFunctionsBlock(const std::vector<FunctionInfo> &Functions, Out.emplace_back(llvm::make_unique<TagNode>(HTMLTag::TAG_DIV)); auto &DivBody = Out.back(); for (const auto &F : Functions) { - std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(F, ParentInfoDir); + std::vector<std::unique_ptr<TagNode>> Nodes = + genHTML(F, CDCtx, ParentInfoDir); AppendVector(std::move(Nodes), DivBody->Children); } return Out; @@ -392,10 +396,30 @@ genReferencesBlock(const std::vector<Reference> &References, return Out; } -static std::unique_ptr<TagNode> writeFileDefinition(const Location &L) { - return llvm::make_unique<TagNode>( - HTMLTag::TAG_P, - "Defined at line " + std::to_string(L.LineNumber) + " of " + L.Filename); +static std::unique_ptr<TagNode> +writeFileDefinition(const Location &L, + llvm::Optional<StringRef> RepositoryUrl = None) { + if (!L.IsFileInRootDir || !RepositoryUrl) + return llvm::make_unique<TagNode>( + HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + + " of file " + L.Filename); + SmallString<128> FileURL(RepositoryUrl.getValue()); + llvm::sys::path::append(FileURL, llvm::sys::path::Style::posix, L.Filename); + auto Node = llvm::make_unique<TagNode>(HTMLTag::TAG_P); + Node->Children.emplace_back(llvm::make_unique<TextNode>("Defined at line ")); + auto LocNumberNode = + llvm::make_unique<TagNode>(HTMLTag::TAG_A, std::to_string(L.LineNumber)); + // The links to a specific line in the source code use the github / + // googlesource notation so it won't work for all hosting pages. + LocNumberNode->Attributes.try_emplace( + "href", (FileURL + "#" + std::to_string(L.LineNumber)).str()); + Node->Children.emplace_back(std::move(LocNumberNode)); + Node->Children.emplace_back(llvm::make_unique<TextNode>(" of file ")); + auto LocFileNode = llvm::make_unique<TagNode>( + HTMLTag::TAG_A, llvm::sys::path::filename(FileURL)); + LocFileNode->Attributes.try_emplace("href", FileURL); + Node->Children.emplace_back(std::move(LocFileNode)); + return Node; } static std::vector<std::unique_ptr<TagNode>> @@ -491,7 +515,8 @@ static std::unique_ptr<TagNode> genHTML(const std::vector<CommentInfo> &C) { return CommentBlock; } -static std::vector<std::unique_ptr<TagNode>> genHTML(const EnumInfo &I) { +static std::vector<std::unique_ptr<TagNode>> +genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { std::vector<std::unique_ptr<TagNode>> Out; std::string EnumType; if (I.Scoped) @@ -508,8 +533,13 @@ static std::vector<std::unique_ptr<TagNode>> genHTML(const EnumInfo &I) { if (Node) Out.emplace_back(std::move(Node)); - if (I.DefLoc) - Out.emplace_back(writeFileDefinition(I.DefLoc.getValue())); + if (I.DefLoc) { + if (!CDCtx.RepositoryUrl) + Out.emplace_back(writeFileDefinition(I.DefLoc.getValue())); + else + Out.emplace_back(writeFileDefinition( + I.DefLoc.getValue(), StringRef{CDCtx.RepositoryUrl.getValue()})); + } std::string Description; if (!I.Description.empty()) @@ -518,8 +548,9 @@ static std::vector<std::unique_ptr<TagNode>> genHTML(const EnumInfo &I) { return Out; } -static std::vector<std::unique_ptr<TagNode>> genHTML(const FunctionInfo &I, - StringRef ParentInfoDir) { +static std::vector<std::unique_ptr<TagNode>> +genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, + StringRef ParentInfoDir) { std::vector<std::unique_ptr<TagNode>> Out; Out.emplace_back(llvm::make_unique<TagNode>(HTMLTag::TAG_H3, I.Name)); // USR is used as id for functions instead of name to disambiguate function @@ -552,8 +583,13 @@ static std::vector<std::unique_ptr<TagNode>> genHTML(const FunctionInfo &I, } FunctionHeader->Children.emplace_back(llvm::make_unique<TextNode>(")")); - if (I.DefLoc) - Out.emplace_back(writeFileDefinition(I.DefLoc.getValue())); + if (I.DefLoc) { + if (!CDCtx.RepositoryUrl) + Out.emplace_back(writeFileDefinition(I.DefLoc.getValue())); + else + Out.emplace_back(writeFileDefinition( + I.DefLoc.getValue(), StringRef{CDCtx.RepositoryUrl.getValue()})); + } std::string Description; if (!I.Description.empty()) @@ -563,7 +599,8 @@ static std::vector<std::unique_ptr<TagNode>> genHTML(const FunctionInfo &I, } static std::vector<std::unique_ptr<TagNode>> -genHTML(const NamespaceInfo &I, Index &InfoIndex, std::string &InfoTitle) { +genHTML(const NamespaceInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, + std::string &InfoTitle) { std::vector<std::unique_ptr<TagNode>> Out; if (I.Name.str() == "") InfoTitle = "Global Namespace"; @@ -584,10 +621,10 @@ genHTML(const NamespaceInfo &I, Index &InfoIndex, std::string &InfoTitle) { AppendVector(std::move(ChildRecords), Out); std::vector<std::unique_ptr<TagNode>> ChildFunctions = - genFunctionsBlock(I.ChildFunctions, I.Path); + genFunctionsBlock(I.ChildFunctions, CDCtx, I.Path); AppendVector(std::move(ChildFunctions), Out); std::vector<std::unique_ptr<TagNode>> ChildEnums = - genEnumsBlock(I.ChildEnums); + genEnumsBlock(I.ChildEnums, CDCtx); AppendVector(std::move(ChildEnums), Out); if (!I.ChildNamespaces.empty()) @@ -604,13 +641,19 @@ genHTML(const NamespaceInfo &I, Index &InfoIndex, std::string &InfoTitle) { } static std::vector<std::unique_ptr<TagNode>> -genHTML(const RecordInfo &I, Index &InfoIndex, std::string &InfoTitle) { +genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, + std::string &InfoTitle) { std::vector<std::unique_ptr<TagNode>> Out; InfoTitle = (getTagType(I.TagType) + " " + I.Name).str(); Out.emplace_back(llvm::make_unique<TagNode>(HTMLTag::TAG_H1, InfoTitle)); - if (I.DefLoc) - Out.emplace_back(writeFileDefinition(I.DefLoc.getValue())); + if (I.DefLoc) { + if (!CDCtx.RepositoryUrl) + Out.emplace_back(writeFileDefinition(I.DefLoc.getValue())); + else + Out.emplace_back(writeFileDefinition( + I.DefLoc.getValue(), StringRef{CDCtx.RepositoryUrl.getValue()})); + } std::string Description; if (!I.Description.empty()) @@ -643,10 +686,10 @@ genHTML(const RecordInfo &I, Index &InfoIndex, std::string &InfoTitle) { AppendVector(std::move(ChildRecords), Out); std::vector<std::unique_ptr<TagNode>> ChildFunctions = - genFunctionsBlock(I.ChildFunctions, I.Path); + genFunctionsBlock(I.ChildFunctions, CDCtx, I.Path); AppendVector(std::move(ChildFunctions), Out); std::vector<std::unique_ptr<TagNode>> ChildEnums = - genEnumsBlock(I.ChildEnums); + genEnumsBlock(I.ChildEnums, CDCtx); AppendVector(std::move(ChildEnums), Out); if (!I.Members.empty()) @@ -682,26 +725,27 @@ llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, Index InfoIndex; switch (I->IT) { case InfoType::IT_namespace: { - std::vector<std::unique_ptr<TagNode>> Nodes = genHTML( - *static_cast<clang::doc::NamespaceInfo *>(I), InfoIndex, InfoTitle); + std::vector<std::unique_ptr<TagNode>> Nodes = + genHTML(*static_cast<clang::doc::NamespaceInfo *>(I), InfoIndex, CDCtx, + InfoTitle); AppendVector(std::move(Nodes), MainContentNode->Children); break; } case InfoType::IT_record: { std::vector<std::unique_ptr<TagNode>> Nodes = genHTML( - *static_cast<clang::doc::RecordInfo *>(I), InfoIndex, InfoTitle); + *static_cast<clang::doc::RecordInfo *>(I), InfoIndex, CDCtx, InfoTitle); AppendVector(std::move(Nodes), MainContentNode->Children); break; } case InfoType::IT_enum: { std::vector<std::unique_ptr<TagNode>> Nodes = - genHTML(*static_cast<clang::doc::EnumInfo *>(I)); + genHTML(*static_cast<clang::doc::EnumInfo *>(I), CDCtx); AppendVector(std::move(Nodes), MainContentNode->Children); break; } case InfoType::IT_function: { std::vector<std::unique_ptr<TagNode>> Nodes = - genHTML(*static_cast<clang::doc::FunctionInfo *>(I), ""); + genHTML(*static_cast<clang::doc::FunctionInfo *>(I), CDCtx, ""); AppendVector(std::move(Nodes), MainContentNode->Children); break; } |