https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/131280
>From bf9bd4156cb7f652c9cf0477f537e5c58b470448 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Fri, 14 Mar 2025 07:39:15 +0200 Subject: [PATCH 01/18] [clang-doc] [feat] add `--repository-line-prefix` argument (fix #59814) --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 66 ++++++++++++------- clang-tools-extra/clang-doc/MDGenerator.cpp | 7 +- .../clang-doc/Representation.cpp | 4 ++ clang-tools-extra/clang-doc/Representation.h | 5 +- .../clang-doc/tool/ClangDocMain.cpp | 13 ++-- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 18a0de826630c..967275f93193b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -491,9 +491,9 @@ genReferencesBlock(const std::vector<Reference> &References, return Out; } -static std::unique_ptr<TagNode> -writeFileDefinition(const Location &L, - std::optional<StringRef> RepositoryUrl = std::nullopt) { +static std::unique_ptr<TagNode> writeFileDefinition( + const Location &L, std::optional<StringRef> RepositoryUrl = std::nullopt, + std::optional<StringRef> RepositoryLinePrefix = std::nullopt) { if (!L.IsFileInRootDir && !RepositoryUrl) return std::make_unique<TagNode>( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + @@ -514,17 +514,21 @@ writeFileDefinition(const Location &L, Node->Children.emplace_back(std::make_unique<TextNode>("Defined at line ")); auto LocNumberNode = std::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. - // FIXME: we probably should have a configuration setting for line number - // rendering in the HTML. For example, GitHub uses #L22, while googlesource - // uses #22 for line numbers. - LocNumberNode->Attributes.emplace_back( - "href", (FileURL + "#" + std::to_string(L.LineNumber)).str()); + + std::string LineAnchor = "#"; + + if (RepositoryLinePrefix) + LineAnchor += RepositoryLinePrefix.value().str(); + + LineAnchor += std::to_string(L.LineNumber); + + LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); Node->Children.emplace_back(std::move(LocNumberNode)); Node->Children.emplace_back(std::make_unique<TextNode>(" of file ")); + auto LocFileNode = std::make_unique<TagNode>( HTMLTag::TAG_A, llvm::sys::path::filename(FileURL)); + LocFileNode->Attributes.emplace_back("href", std::string(FileURL)); Node->Children.emplace_back(std::move(LocFileNode)); return Node; @@ -750,11 +754,15 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); if (I.DefLoc) { - if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); - else - Out.emplace_back( - writeFileDefinition(*I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); + std::optional<StringRef> RepoUrl; + std::optional<StringRef> RepoLinePrefix; + + if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; + if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + + Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -799,11 +807,15 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, FunctionHeader->Children.emplace_back(std::make_unique<TextNode>(")")); if (I.DefLoc) { - if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); - else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); + std::optional<StringRef> RepoUrl; + std::optional<StringRef> RepoLinePrefix; + + if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; + if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + + Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -866,11 +878,15 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H1, InfoTitle)); if (I.DefLoc) { - if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); - else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); + std::optional<StringRef> RepoUrl; + std::optional<StringRef> RepoLinePrefix; + + if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; + if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + + Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index 7bef2c0db04d8..a3bade238635c 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -57,7 +57,12 @@ static void writeFileDefinition(const ClangDocContext &CDCtx, const Location &L, OS << "*Defined at " << L.Filename << "#" << std::to_string(L.LineNumber) << "*"; } else { - OS << "*Defined at [" << L.Filename << "#" << std::to_string(L.LineNumber) + OS << "*Defined at [" << L.Filename << "#"; + + if (!CDCtx.RepositoryLinePrefix) + OS << StringRef{*CDCtx.RepositoryLinePrefix}; + + OS << std::to_string(L.LineNumber) << "](" << StringRef{*CDCtx.RepositoryUrl} << llvm::sys::path::relative_path(L.Filename) << "#" << std::to_string(L.LineNumber) << ")" diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp index 4da93b24c131f..74f867dfb9f0c 100644 --- a/clang-tools-extra/clang-doc/Representation.cpp +++ b/clang-tools-extra/clang-doc/Representation.cpp @@ -368,6 +368,7 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName, bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot, StringRef RepositoryUrl, + StringRef RepositoryLinePrefix, std::vector<std::string> UserStylesheets) : ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly), OutDirectory(OutDirectory), UserStylesheets(UserStylesheets) { @@ -381,6 +382,9 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx, if (!RepositoryUrl.empty() && !RepositoryUrl.starts_with("http://") && !RepositoryUrl.starts_with("https://")) this->RepositoryUrl->insert(0, "https://"); + + if (!RepositoryLinePrefix.empty()) + this->RepositoryLinePrefix = std::string(RepositoryLinePrefix); } } diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h index bb0c534af7b74..88b3e47dfb1ee 100644 --- a/clang-tools-extra/clang-doc/Representation.h +++ b/clang-tools-extra/clang-doc/Representation.h @@ -508,6 +508,7 @@ struct ClangDocContext { ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName, bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot, StringRef RepositoryUrl, + StringRef RepositoryCodeLinePrefix, std::vector<std::string> UserStylesheets); tooling::ExecutionContext *ECtx; std::string ProjectName; // Name of project clang-doc is documenting. @@ -518,10 +519,12 @@ struct ClangDocContext { // the file is in this dir. // URL of repository that hosts code used for links to definition locations. std::optional<std::string> RepositoryUrl; + // Prefix of line code for repository. + std::optional<std::string> RepositoryLinePrefix; // Path of CSS stylesheets that will be copied to OutDirectory and used to // style all HTML files. std::vector<std::string> UserStylesheets; - // JavaScript files that will be imported in allHTML file. + // JavaScript files that will be imported in all HTML file. std::vector<std::string> JsScripts; Index Idx; }; diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 2ce707feb3d5e..237f60885b3dd 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -99,6 +99,12 @@ URL of repository that hosts code. Used for links to definition locations.)"), llvm::cl::cat(ClangDocCategory)); +static llvm::cl::opt<std::string> + RepositoryCodeLinePrefix("repository-line-prefix", llvm::cl::desc(R"( +Prefix of line code for repository. +)"), + llvm::cl::cat(ClangDocCategory)); + enum OutputFormatTy { md, yaml, @@ -141,8 +147,7 @@ llvm::Error getAssetFiles(clang::doc::ClangDocContext &CDCtx) { using DirIt = llvm::sys::fs::directory_iterator; std::error_code FileErr; llvm::SmallString<128> FilePath(UserAssetPath); - for (DirIt DirStart = DirIt(UserAssetPath, FileErr), - DirEnd; + for (DirIt DirStart = DirIt(UserAssetPath, FileErr), DirEnd; !FileErr && DirStart != DirEnd; DirStart.increment(FileErr)) { FilePath = DirStart->path(); if (llvm::sys::fs::is_regular_file(FilePath)) { @@ -268,8 +273,8 @@ Example usage for a project using a compile commands database: OutDirectory, SourceRoot, RepositoryUrl, - {UserStylesheets.begin(), UserStylesheets.end()} - }; + RepositoryCodeLinePrefix, + {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { >From fea0a3d818de29fa61c3e9225562271457d4b1d1 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Fri, 14 Mar 2025 07:39:21 +0200 Subject: [PATCH 02/18] [clang-doc][test] reuse `basic-project.test` for testing `--repository-line-prefix` --- .../basic-project-with-line-prefix.test | 342 ++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 clang-tools-extra/test/clang-doc/basic-project-with-line-prefix.test diff --git a/clang-tools-extra/test/clang-doc/basic-project-with-line-prefix.test b/clang-tools-extra/test/clang-doc/basic-project-with-line-prefix.test new file mode 100644 index 0000000000000..b393e1d12dfba --- /dev/null +++ b/clang-tools-extra/test/clang-doc/basic-project-with-line-prefix.test @@ -0,0 +1,342 @@ +// RUN: rm -rf %t && mkdir -p %t/docs %t/build +// RUN: sed 's|$test_dir|%/S|g' %S/Inputs/basic-project/database_template.json > %t/build/compile_commands.json +// RUN: clang-doc --format=html --output=%t/docs --executor=all-TUs %t/build/compile_commands.json --repository=https://repository.com --repository-line-prefix=LLL +// RUN: FileCheck %s -input-file=%t/docs/index_json.js -check-prefix=JSON-INDEX +// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Shape.html -check-prefix=HTML-SHAPE +// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Calculator.html -check-prefix=HTML-CALC +// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Rectangle.html -check-prefix=HTML-RECTANGLE +// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Circle.html -check-prefix=HTML-CIRCLE + +// JSON-INDEX: async function LoadIndex() { +// JSON-INDEX-NEXT: return{ +// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", +// JSON-INDEX-NEXT: "Name": "", +// JSON-INDEX-NEXT: "RefType": "default", +// JSON-INDEX-NEXT: "Path": "", +// JSON-INDEX-NEXT: "Children": [ +// JSON-INDEX-NEXT: { +// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", +// JSON-INDEX-NEXT: "Name": "GlobalNamespace", +// JSON-INDEX-NEXT: "RefType": "namespace", +// JSON-INDEX-NEXT: "Path": "GlobalNamespace", +// JSON-INDEX-NEXT: "Children": [ +// JSON-INDEX-NEXT: { +// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", +// JSON-INDEX-NEXT: "Name": "Calculator", +// JSON-INDEX-NEXT: "RefType": "record", +// JSON-INDEX-NEXT: "Path": "GlobalNamespace", +// JSON-INDEX-NEXT: "Children": [] +// JSON-INDEX-NEXT: }, +// JSON-INDEX-NEXT: { +// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", +// JSON-INDEX-NEXT: "Name": "Circle", +// JSON-INDEX-NEXT: "RefType": "record", +// JSON-INDEX-NEXT: "Path": "GlobalNamespace", +// JSON-INDEX-NEXT: "Children": [] +// JSON-INDEX-NEXT: }, +// JSON-INDEX-NEXT: { +// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", +// JSON-INDEX-NEXT: "Name": "Rectangle", +// JSON-INDEX-NEXT: "RefType": "record", +// JSON-INDEX-NEXT: "Path": "GlobalNamespace", +// JSON-INDEX-NEXT: "Children": [] +// JSON-INDEX-NEXT: }, +// JSON-INDEX-NEXT: { +// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", +// JSON-INDEX-NEXT: "Name": "Shape", +// JSON-INDEX-NEXT: "RefType": "record", +// JSON-INDEX-NEXT: "Path": "GlobalNamespace", +// JSON-INDEX-NEXT: "Children": [] +// JSON-INDEX-NEXT: } +// JSON-INDEX-NEXT: ] +// JSON-INDEX-NEXT: } +// JSON-INDEX-NEXT: ] +// JSON-INDEX-NEXT: }; +// JSON-INDEX-NEXT: } + +// HTML-SHAPE: <h1>class Shape</h1> +// HTML-SHAPE-NEXT: <p> +// HTML-SHAPE-NEXT: Defined at line +// HTML-SHAPE-NEXT: <a href="https://repository.com/./include/Shape.h#LLL8">8</a> +// HTML-SHAPE-NEXT: of file +// HTML-SHAPE-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> +// HTML-SHAPE-NEXT: </p> +// HTML-SHAPE: <div>brief</div> +// HTML-SHAPE: <p> Abstract base class for shapes.</p> +// HTML-SHAPE: <p> Provides a common interface for different types of shapes.</p> +// HTML-SHAPE: <h2 id="Functions">Functions</h2> +// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">area</h3> +// HTML-SHAPE: <p>public double area()</p> +// HTML-SHAPE: <div>brief</div> +// HTML-SHAPE: <p> Calculates the area of the shape.</p> +// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3> +// HTML-SHAPE: <p>public double perimeter()</p> +// HTML-SHAPE: <div>brief</div> +// HTML-SHAPE: <p> Calculates the perimeter of the shape.</p> +// HTML-SHAPE: <div>return</div> +// HTML-SHAPE: <p> double The perimeter of the shape.</p> +// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">~Shape</h3> +// HTML-SHAPE: <p>public void ~Shape()</p> +// HTML-SHAPE: Defined at line +// HTML-SHAPE-NEXT: <a href="https://repository.com/./include/Shape.h#LLL13">13</a> +// HTML-SHAPE-NEXT: of file +// HTML-SHAPE-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> +// HTML-SHAPE: <div>brief</div> +// HTML-SHAPE: <p> Virtual destructor.</p> + +// HTML-CALC: <h1>class Calculator</h1> +// HTML-CALC-NEXT: <p> +// HTML-CALC-NEXT: Defined at line +// HTML-CALC-NEXT: <a href="https://repository.com/./include/Calculator.h#LLL8">8</a> +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: <a href="https://repository.com/./include/Calculator.h">Calculator.h</a> +// HTML-CALC-NEXT: </p> +// HTML-CALC: <div>brief</div> +// HTML-CALC: <p> A simple calculator class.</p> +// HTML-CALC: <p> Provides basic arithmetic operations.</p> +// HTML-CALC: <h2 id="Functions">Functions</h2> +// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">add</h3> +// HTML-CALC: <p>public int add(int a, int b)</p> +// HTML-CALC: Defined at line +// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp#LLL3">3</a> +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> +// HTML-CALC: <div>brief</div> +// HTML-CALC: <p> Adds two integers.</p> +// HTML-CALC: <div>return</div> +// HTML-CALC: <p> int The sum of a and b.</p> +// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">subtract</h3> +// HTML-CALC: <p>public int subtract(int a, int b)</p> +// HTML-CALC: Defined at line +// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp#LLL7">7</a> +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> +// HTML-CALC: <div>brief</div> +// HTML-CALC: <p> Subtracts the second integer from the first.</p> +// HTML-CALC: <div>return</div> +// HTML-CALC: <p> int The result of a - b.</p> +// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">multiply</h3> +// HTML-CALC: <p>public int multiply(int a, int b)</p> +// HTML-CALC: Defined at line +// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp#LLL11">11</a> +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> +// HTML-CALC: <div>brief</div> +// HTML-CALC: <p> Multiplies two integers.</p> +// HTML-CALC: <div>return</div> +// HTML-CALC: <p> int The product of a and b.</p> +// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">divide</h3> +// HTML-CALC: <p>public double divide(int a, int b)</p> +// HTML-CALC: Defined at line +// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp#LLL15">15</a> +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> +// HTML-CALC: <div>brief</div> +// HTML-CALC: <p> Divides the first integer by the second.</p> +// HTML-CALC: <div>return</div> +// HTML-CALC: <p> double The result of a / b.</p> +// HTML-CALC: <div>throw</div> +// HTML-CALC: <p>if b is zero.</p> + +// HTML-RECTANGLE: <h1>class Rectangle</h1> +// HTML-RECTANGLE-NEXT: <p> +// HTML-RECTANGLE-NEXT: Defined at line +// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./include/Rectangle.h#LLL10">10</a> +// HTML-RECTANGLE-NEXT: of file +// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./include/Rectangle.h">Rectangle.h</a> +// HTML-RECTANGLE-NEXT: </p> +// HTML-RECTANGLE: <p> Represents a rectangle with a given width and height.</p> +// HTML-RECTANGLE: <p> +// HTML-RECTANGLE: Inherits from +// HTML-RECTANGLE: <a href="Shape.html">Shape</a> +// HTML-RECTANGLE: </p> +// HTML-RECTANGLE: <h2 id="Members">Members</h2> +// HTML-RECTANGLE: <p> Width of the rectangle.</p> +// HTML-RECTANGLE: <div>private double width_</div> +// HTML-RECTANGLE: <p> Height of the rectangle.</p> +// HTML-RECTANGLE: <div>private double height_</div> +// HTML-RECTANGLE: <h2 id="Functions">Functions</h2> +// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">Rectangle</h3> +// HTML-RECTANGLE: <p>public void Rectangle(double width, double height)</p> +// HTML-RECTANGLE: Defined at line +// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#LLL3">3</a> +// HTML-RECTANGLE-NEXT: of file +// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> +// HTML-RECTANGLE: <div>brief</div> +// HTML-RECTANGLE: <p> Constructs a new Rectangle object.</p> +// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">area</h3> +// HTML-RECTANGLE: <p>public double area()</p> +// HTML-RECTANGLE: Defined at line +// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#LLL6">6</a> +// HTML-RECTANGLE-NEXT: of file +// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> +// HTML-RECTANGLE: <div>brief</div> +// HTML-RECTANGLE: <p> Calculates the area of the rectangle.</p> +// HTML-RECTANGLE: <div>return</div> +// HTML-RECTANGLE: <p> double The area of the rectangle.</p> +// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3> +// HTML-RECTANGLE: <p>public double perimeter()</p> +// HTML-RECTANGLE: Defined at line +// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#LLL10">10</a> +// HTML-RECTANGLE-NEXT: of file +// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> +// HTML-RECTANGLE: <div>brief</div> +// HTML-RECTANGLE: <p> Calculates the perimeter of the rectangle.</p> +// HTML-RECTANGLE: <div>return</div> +// HTML-RECTANGLE: <p> double The perimeter of the rectangle.</p> + +// HTML-CIRCLE: <h1>class Circle</h1> +// HTML-CIRCLE-NEXT: <p> +// HTML-CIRCLE-NEXT: Defined at line +// HTML-CIRCLE-NEXT: <a href="https://repository.com/./include/Circle.h#LLL10">10</a> +// HTML-CIRCLE-NEXT: of file +// HTML-CIRCLE-NEXT: <a href="https://repository.com/./include/Circle.h">Circle.h</a> +// HTML-CIRCLE-NEXT: </p> +// HTML-CIRCLE: <div>brief</div> +// HTML-CIRCLE: <p> Circle class derived from Shape.</p> +// HTML-CIRCLE: <p> Represents a circle with a given radius.</p> +// HTML-CIRCLE: <p> +// HTML-CIRCLE: Inherits from +// HTML-CIRCLE: <a href="Shape.html">Shape</a> +// HTML-CIRCLE: </p> +// HTML-CIRCLE: <h2 id="Members">Members</h2> +// HTML-CIRCLE: <p> Radius of the circle.</p> +// HTML-CIRCLE: <div>private double radius_</div> +// HTML-CIRCLE: <h2 id="Functions">Functions</h2> +// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">Circle</h3> +// HTML-CIRCLE: <p>public void Circle(double radius)</p> +// HTML-CIRCLE: Defined at line +// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp#LLL3">3</a> +// HTML-CIRCLE-NEXT: of file +// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> +// HTML-CIRCLE: <div>brief</div> +// HTML-CIRCLE: <p> Constructs a new Circle object.</p> +// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">area</h3> +// HTML-CIRCLE: <p>public double area()</p> +// HTML-CIRCLE: Defined at line +// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp#LLL5">5</a> +// HTML-CIRCLE-NEXT: of file +// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> +// HTML-CIRCLE: <div>brief</div> +// HTML-CIRCLE: <p> Calculates the area of the circle.</p> +// HTML-CIRCLE: <div>return</div> +// HTML-CIRCLE: <p> double The area of the circle.</p> +// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3> +// HTML-CIRCLE: <p>public double perimeter()</p> +// HTML-CIRCLE: Defined at line +// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp#LLL9">9</a> +// HTML-CIRCLE-NEXT: of file +// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> +// HTML-CIRCLE: <div>brief</div> +// HTML-CIRCLE: <p> Calculates the perimeter of the circle.</p> +// HTML-CIRCLE: <div>return</div> +// HTML-CIRCLE: <p> double The perimeter of the circle.</p> + +// MD-CALC: # class Calculator +// MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#LLL8* +// MD-CALC: **brief** A simple calculator class. +// MD-CALC: Provides basic arithmetic operations. +// MD-CALC: ## Functions +// MD-CALC: ### add +// MD-CALC: *public int add(int a, int b)* +// MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#LLL3* +// MD-CALC: **brief** Adds two integers. +// MD-CALC: **a** First integer. +// MD-CALC: **b** Second integer. +// MD-CALC: **return** int The sum of a and b. +// MD-CALC: ### subtract +// MD-CALC: *public int subtract(int a, int b)* +// MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#LLL7* +// MD-CALC: **brief** Subtracts the second integer from the first. +// MD-CALC: **a** First integer. +// MD-CALC: **b** Second integer. +// MD-CALC: **return** int The result of a - b. +// MD-CALC: ### multiply +// MD-CALC: *public int multiply(int a, int b)* +// MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#LLL11* +// MD-CALC: **brief** Multiplies two integers. +// MD-CALC: **a** First integer. +// MD-CALC: **b** Second integer. +// MD-CALC: **return** int The product of a and b. +// MD-CALC: ### divide +// MD-CALC: *public double divide(int a, int b)* +// MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#LLL15* +// MD-CALC: **brief** Divides the first integer by the second. +// MD-CALC: **a** First integer. +// MD-CALC: **b** Second integer. +// MD-CALC: **return** double The result of a / b. +// MD-CALC: **throw**if b is zero. + +// MD-CIRCLE: # class Circle +// MD-CIRCLE: *Defined at .{{[\/]}}include{{[\/]}}Circle.h#LLL10* +// MD-CIRCLE: **brief** Circle class derived from Shape. +// MD-CIRCLE: Represents a circle with a given radius. +// MD-CIRCLE: Inherits from Shape +// MD-CIRCLE: ## Members +// MD-CIRCLE: private double radius_ +// MD-CIRCLE: ## Functions +// MD-CIRCLE: ### Circle +// MD-CIRCLE: *public void Circle(double radius)* +// MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#LLL3* +// MD-CIRCLE: **brief** Constructs a new Circle object. +// MD-CIRCLE: **radius** Radius of the circle. +// MD-CIRCLE: ### area +// MD-CIRCLE: *public double area()* +// MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#LLL5* +// MD-CIRCLE: **brief** Calculates the area of the circle. +// MD-CIRCLE: **return** double The area of the circle. +// MD-CIRCLE: ### perimeter +// MD-CIRCLE: *public double perimeter()* +// MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#LLL9* +// MD-CIRCLE: **brief** Calculates the perimeter of the circle. +// MD-CIRCLE: **return** double The perimeter of the circle. + +// MD-RECTANGLE: # class Rectangle +// MD-RECTANGLE: *Defined at .{{[\/]}}include{{[\/]}}Rectangle.h#LLL10* +// MD-RECTANGLE: **brief** Rectangle class derived from Shape. +// MD-RECTANGLE: Represents a rectangle with a given width and height. +// MD-RECTANGLE: Inherits from Shape +// MD-RECTANGLE: ## Members +// MD-RECTANGLE: private double width_ +// MD-RECTANGLE: private double height_ +// MD-RECTANGLE: ## Functions +// MD-RECTANGLE: ### Rectangle +// MD-RECTANGLE: *public void Rectangle(double width, double height)* +// MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#LLL3* +// MD-RECTANGLE: **brief** Constructs a new Rectangle object. +// MD-RECTANGLE: **width** Width of the rectangle. +// MD-RECTANGLE: **height** Height of the rectangle. +// MD-RECTANGLE: ### area +// MD-RECTANGLE: *public double area()* +// MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#LLL6* +// MD-RECTANGLE: **brief** Calculates the area of the rectangle. +// MD-RECTANGLE: **return** double The area of the rectangle. +// MD-RECTANGLE: ### perimeter +// MD-RECTANGLE: *public double perimeter()* +// MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#LLL10* +// MD-RECTANGLE: **brief** Calculates the perimeter of the rectangle. +// MD-RECTANGLE: **return** double The perimeter of the rectangle. + +// MD-SHAPE: # class Shape +// MD-SHAPE: *Defined at .{{[\/]}}include{{[\/]}}Shape.h#LLL8* +// MD-SHAPE: **brief** Abstract base class for shapes. +// MD-SHAPE: Provides a common interface for different types of shapes. +// MD-SHAPE: ## Functions +// MD-SHAPE: ### ~Shape +// MD-SHAPE: *public void ~Shape()* +// MD-SHAPE: *Defined at .{{[\/]}}include{{[\/]}}Shape.h#LLL13* +// MD-SHAPE: **brief** Virtual destructor. +// MD-SHAPE: ### area +// MD-SHAPE: *public double area()* +// MD-SHAPE: **brief** Calculates the area of the shape. +// MD-SHAPE: **return** double The area of the shape. +// MD-SHAPE: ### perimeter +// MD-SHAPE: *public double perimeter()* +// MD-SHAPE: **brief** Calculates the perimeter of the shape. +// MD-SHAPE: **return** double The perimeter of the shape. + +// MD-ALL-FILES: # All Files +// MD-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md) + +// MD-INDEX: # C/C++ Reference +// MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) >From 4b769dd570ed0a82d007429d941fa3c80af2ad0d Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Mon, 17 Mar 2025 21:59:52 +0200 Subject: [PATCH 03/18] [clang] [chore] revert important notes --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 967275f93193b..9711ca20c56fa 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -514,7 +514,8 @@ static std::unique_ptr<TagNode> writeFileDefinition( Node->Children.emplace_back(std::make_unique<TextNode>("Defined at line ")); auto LocNumberNode = std::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. std::string LineAnchor = "#"; if (RepositoryLinePrefix) >From a7f7f6c16b57d176bda4122a385703239a5817d2 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Mon, 17 Mar 2025 22:10:19 +0200 Subject: [PATCH 04/18] [clang] fix formatting for help of `--repository-line-prefix` --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 237f60885b3dd..e7713efde2db1 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -99,11 +99,10 @@ URL of repository that hosts code. Used for links to definition locations.)"), llvm::cl::cat(ClangDocCategory)); -static llvm::cl::opt<std::string> - RepositoryCodeLinePrefix("repository-line-prefix", llvm::cl::desc(R"( -Prefix of line code for repository. -)"), - llvm::cl::cat(ClangDocCategory)); +static llvm::cl::opt<std::string> RepositoryCodeLinePrefix( + "repository-line-prefix", + llvm::cl::desc("Prefix of line code for repository."), + llvm::cl::cat(ClangDocCategory)); enum OutputFormatTy { md, >From b61c01fce206ddaf18ac48e6fec12b5310157302 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Thu, 20 Mar 2025 19:31:00 +0200 Subject: [PATCH 05/18] [clang] formatting `LineAnchor` using `formatv` --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 6 +----- clang-tools-extra/clang-doc/MDGenerator.cpp | 18 ++++++++---------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 9711ca20c56fa..713c328fbb681 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -516,12 +516,8 @@ static std::unique_ptr<TagNode> writeFileDefinition( std::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. - std::string LineAnchor = "#"; + std::string LineAnchor = formatv("#{0}{1}", RepositoryLinePrefix.value_or(""), L.LineNumber); - if (RepositoryLinePrefix) - LineAnchor += RepositoryLinePrefix.value().str(); - - LineAnchor += std::to_string(L.LineNumber); LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); Node->Children.emplace_back(std::move(LocNumberNode)); diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index a3bade238635c..993596c708489 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -8,6 +8,7 @@ #include "Generators.h" #include "Representation.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" @@ -57,16 +58,13 @@ static void writeFileDefinition(const ClangDocContext &CDCtx, const Location &L, OS << "*Defined at " << L.Filename << "#" << std::to_string(L.LineNumber) << "*"; } else { - OS << "*Defined at [" << L.Filename << "#"; - - if (!CDCtx.RepositoryLinePrefix) - OS << StringRef{*CDCtx.RepositoryLinePrefix}; - - OS << std::to_string(L.LineNumber) - << "](" << StringRef{*CDCtx.RepositoryUrl} - << llvm::sys::path::relative_path(L.Filename) << "#" - << std::to_string(L.LineNumber) << ")" - << "*"; + + std::string LineAnchor = + formatv("#{0}{1}", CDCtx.RepositoryLinePrefix.value_or(""), + std::to_string(L.LineNumber)); + + OS << formatv("*Defined at [{0}{1}]({0}{2})*", LineAnchor, L.Filename, + StringRef{*CDCtx.RepositoryUrl}); } OS << "\n\n"; } >From 74952a48b5e23bf7633783f397f97c3b95317520 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Thu, 20 Mar 2025 19:31:08 +0200 Subject: [PATCH 06/18] [clang-doc] add `--repository-line-prefix` to the existing test instead of new test --- .../basic-project-with-line-prefix.test | 342 ------------------ .../test/clang-doc/basic-project.test | 63 +++- 2 files changed, 62 insertions(+), 343 deletions(-) delete mode 100644 clang-tools-extra/test/clang-doc/basic-project-with-line-prefix.test diff --git a/clang-tools-extra/test/clang-doc/basic-project-with-line-prefix.test b/clang-tools-extra/test/clang-doc/basic-project-with-line-prefix.test deleted file mode 100644 index b393e1d12dfba..0000000000000 --- a/clang-tools-extra/test/clang-doc/basic-project-with-line-prefix.test +++ /dev/null @@ -1,342 +0,0 @@ -// RUN: rm -rf %t && mkdir -p %t/docs %t/build -// RUN: sed 's|$test_dir|%/S|g' %S/Inputs/basic-project/database_template.json > %t/build/compile_commands.json -// RUN: clang-doc --format=html --output=%t/docs --executor=all-TUs %t/build/compile_commands.json --repository=https://repository.com --repository-line-prefix=LLL -// RUN: FileCheck %s -input-file=%t/docs/index_json.js -check-prefix=JSON-INDEX -// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Shape.html -check-prefix=HTML-SHAPE -// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Calculator.html -check-prefix=HTML-CALC -// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Rectangle.html -check-prefix=HTML-RECTANGLE -// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Circle.html -check-prefix=HTML-CIRCLE - -// JSON-INDEX: async function LoadIndex() { -// JSON-INDEX-NEXT: return{ -// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", -// JSON-INDEX-NEXT: "Name": "", -// JSON-INDEX-NEXT: "RefType": "default", -// JSON-INDEX-NEXT: "Path": "", -// JSON-INDEX-NEXT: "Children": [ -// JSON-INDEX-NEXT: { -// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", -// JSON-INDEX-NEXT: "Name": "GlobalNamespace", -// JSON-INDEX-NEXT: "RefType": "namespace", -// JSON-INDEX-NEXT: "Path": "GlobalNamespace", -// JSON-INDEX-NEXT: "Children": [ -// JSON-INDEX-NEXT: { -// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", -// JSON-INDEX-NEXT: "Name": "Calculator", -// JSON-INDEX-NEXT: "RefType": "record", -// JSON-INDEX-NEXT: "Path": "GlobalNamespace", -// JSON-INDEX-NEXT: "Children": [] -// JSON-INDEX-NEXT: }, -// JSON-INDEX-NEXT: { -// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", -// JSON-INDEX-NEXT: "Name": "Circle", -// JSON-INDEX-NEXT: "RefType": "record", -// JSON-INDEX-NEXT: "Path": "GlobalNamespace", -// JSON-INDEX-NEXT: "Children": [] -// JSON-INDEX-NEXT: }, -// JSON-INDEX-NEXT: { -// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", -// JSON-INDEX-NEXT: "Name": "Rectangle", -// JSON-INDEX-NEXT: "RefType": "record", -// JSON-INDEX-NEXT: "Path": "GlobalNamespace", -// JSON-INDEX-NEXT: "Children": [] -// JSON-INDEX-NEXT: }, -// JSON-INDEX-NEXT: { -// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}", -// JSON-INDEX-NEXT: "Name": "Shape", -// JSON-INDEX-NEXT: "RefType": "record", -// JSON-INDEX-NEXT: "Path": "GlobalNamespace", -// JSON-INDEX-NEXT: "Children": [] -// JSON-INDEX-NEXT: } -// JSON-INDEX-NEXT: ] -// JSON-INDEX-NEXT: } -// JSON-INDEX-NEXT: ] -// JSON-INDEX-NEXT: }; -// JSON-INDEX-NEXT: } - -// HTML-SHAPE: <h1>class Shape</h1> -// HTML-SHAPE-NEXT: <p> -// HTML-SHAPE-NEXT: Defined at line -// HTML-SHAPE-NEXT: <a href="https://repository.com/./include/Shape.h#LLL8">8</a> -// HTML-SHAPE-NEXT: of file -// HTML-SHAPE-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> -// HTML-SHAPE-NEXT: </p> -// HTML-SHAPE: <div>brief</div> -// HTML-SHAPE: <p> Abstract base class for shapes.</p> -// HTML-SHAPE: <p> Provides a common interface for different types of shapes.</p> -// HTML-SHAPE: <h2 id="Functions">Functions</h2> -// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">area</h3> -// HTML-SHAPE: <p>public double area()</p> -// HTML-SHAPE: <div>brief</div> -// HTML-SHAPE: <p> Calculates the area of the shape.</p> -// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3> -// HTML-SHAPE: <p>public double perimeter()</p> -// HTML-SHAPE: <div>brief</div> -// HTML-SHAPE: <p> Calculates the perimeter of the shape.</p> -// HTML-SHAPE: <div>return</div> -// HTML-SHAPE: <p> double The perimeter of the shape.</p> -// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">~Shape</h3> -// HTML-SHAPE: <p>public void ~Shape()</p> -// HTML-SHAPE: Defined at line -// HTML-SHAPE-NEXT: <a href="https://repository.com/./include/Shape.h#LLL13">13</a> -// HTML-SHAPE-NEXT: of file -// HTML-SHAPE-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> -// HTML-SHAPE: <div>brief</div> -// HTML-SHAPE: <p> Virtual destructor.</p> - -// HTML-CALC: <h1>class Calculator</h1> -// HTML-CALC-NEXT: <p> -// HTML-CALC-NEXT: Defined at line -// HTML-CALC-NEXT: <a href="https://repository.com/./include/Calculator.h#LLL8">8</a> -// HTML-CALC-NEXT: of file -// HTML-CALC-NEXT: <a href="https://repository.com/./include/Calculator.h">Calculator.h</a> -// HTML-CALC-NEXT: </p> -// HTML-CALC: <div>brief</div> -// HTML-CALC: <p> A simple calculator class.</p> -// HTML-CALC: <p> Provides basic arithmetic operations.</p> -// HTML-CALC: <h2 id="Functions">Functions</h2> -// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">add</h3> -// HTML-CALC: <p>public int add(int a, int b)</p> -// HTML-CALC: Defined at line -// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp#LLL3">3</a> -// HTML-CALC-NEXT: of file -// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> -// HTML-CALC: <div>brief</div> -// HTML-CALC: <p> Adds two integers.</p> -// HTML-CALC: <div>return</div> -// HTML-CALC: <p> int The sum of a and b.</p> -// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">subtract</h3> -// HTML-CALC: <p>public int subtract(int a, int b)</p> -// HTML-CALC: Defined at line -// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp#LLL7">7</a> -// HTML-CALC-NEXT: of file -// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> -// HTML-CALC: <div>brief</div> -// HTML-CALC: <p> Subtracts the second integer from the first.</p> -// HTML-CALC: <div>return</div> -// HTML-CALC: <p> int The result of a - b.</p> -// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">multiply</h3> -// HTML-CALC: <p>public int multiply(int a, int b)</p> -// HTML-CALC: Defined at line -// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp#LLL11">11</a> -// HTML-CALC-NEXT: of file -// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> -// HTML-CALC: <div>brief</div> -// HTML-CALC: <p> Multiplies two integers.</p> -// HTML-CALC: <div>return</div> -// HTML-CALC: <p> int The product of a and b.</p> -// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">divide</h3> -// HTML-CALC: <p>public double divide(int a, int b)</p> -// HTML-CALC: Defined at line -// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp#LLL15">15</a> -// HTML-CALC-NEXT: of file -// HTML-CALC-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> -// HTML-CALC: <div>brief</div> -// HTML-CALC: <p> Divides the first integer by the second.</p> -// HTML-CALC: <div>return</div> -// HTML-CALC: <p> double The result of a / b.</p> -// HTML-CALC: <div>throw</div> -// HTML-CALC: <p>if b is zero.</p> - -// HTML-RECTANGLE: <h1>class Rectangle</h1> -// HTML-RECTANGLE-NEXT: <p> -// HTML-RECTANGLE-NEXT: Defined at line -// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./include/Rectangle.h#LLL10">10</a> -// HTML-RECTANGLE-NEXT: of file -// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./include/Rectangle.h">Rectangle.h</a> -// HTML-RECTANGLE-NEXT: </p> -// HTML-RECTANGLE: <p> Represents a rectangle with a given width and height.</p> -// HTML-RECTANGLE: <p> -// HTML-RECTANGLE: Inherits from -// HTML-RECTANGLE: <a href="Shape.html">Shape</a> -// HTML-RECTANGLE: </p> -// HTML-RECTANGLE: <h2 id="Members">Members</h2> -// HTML-RECTANGLE: <p> Width of the rectangle.</p> -// HTML-RECTANGLE: <div>private double width_</div> -// HTML-RECTANGLE: <p> Height of the rectangle.</p> -// HTML-RECTANGLE: <div>private double height_</div> -// HTML-RECTANGLE: <h2 id="Functions">Functions</h2> -// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">Rectangle</h3> -// HTML-RECTANGLE: <p>public void Rectangle(double width, double height)</p> -// HTML-RECTANGLE: Defined at line -// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#LLL3">3</a> -// HTML-RECTANGLE-NEXT: of file -// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> -// HTML-RECTANGLE: <div>brief</div> -// HTML-RECTANGLE: <p> Constructs a new Rectangle object.</p> -// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">area</h3> -// HTML-RECTANGLE: <p>public double area()</p> -// HTML-RECTANGLE: Defined at line -// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#LLL6">6</a> -// HTML-RECTANGLE-NEXT: of file -// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> -// HTML-RECTANGLE: <div>brief</div> -// HTML-RECTANGLE: <p> Calculates the area of the rectangle.</p> -// HTML-RECTANGLE: <div>return</div> -// HTML-RECTANGLE: <p> double The area of the rectangle.</p> -// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3> -// HTML-RECTANGLE: <p>public double perimeter()</p> -// HTML-RECTANGLE: Defined at line -// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#LLL10">10</a> -// HTML-RECTANGLE-NEXT: of file -// HTML-RECTANGLE-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> -// HTML-RECTANGLE: <div>brief</div> -// HTML-RECTANGLE: <p> Calculates the perimeter of the rectangle.</p> -// HTML-RECTANGLE: <div>return</div> -// HTML-RECTANGLE: <p> double The perimeter of the rectangle.</p> - -// HTML-CIRCLE: <h1>class Circle</h1> -// HTML-CIRCLE-NEXT: <p> -// HTML-CIRCLE-NEXT: Defined at line -// HTML-CIRCLE-NEXT: <a href="https://repository.com/./include/Circle.h#LLL10">10</a> -// HTML-CIRCLE-NEXT: of file -// HTML-CIRCLE-NEXT: <a href="https://repository.com/./include/Circle.h">Circle.h</a> -// HTML-CIRCLE-NEXT: </p> -// HTML-CIRCLE: <div>brief</div> -// HTML-CIRCLE: <p> Circle class derived from Shape.</p> -// HTML-CIRCLE: <p> Represents a circle with a given radius.</p> -// HTML-CIRCLE: <p> -// HTML-CIRCLE: Inherits from -// HTML-CIRCLE: <a href="Shape.html">Shape</a> -// HTML-CIRCLE: </p> -// HTML-CIRCLE: <h2 id="Members">Members</h2> -// HTML-CIRCLE: <p> Radius of the circle.</p> -// HTML-CIRCLE: <div>private double radius_</div> -// HTML-CIRCLE: <h2 id="Functions">Functions</h2> -// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">Circle</h3> -// HTML-CIRCLE: <p>public void Circle(double radius)</p> -// HTML-CIRCLE: Defined at line -// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp#LLL3">3</a> -// HTML-CIRCLE-NEXT: of file -// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> -// HTML-CIRCLE: <div>brief</div> -// HTML-CIRCLE: <p> Constructs a new Circle object.</p> -// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">area</h3> -// HTML-CIRCLE: <p>public double area()</p> -// HTML-CIRCLE: Defined at line -// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp#LLL5">5</a> -// HTML-CIRCLE-NEXT: of file -// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> -// HTML-CIRCLE: <div>brief</div> -// HTML-CIRCLE: <p> Calculates the area of the circle.</p> -// HTML-CIRCLE: <div>return</div> -// HTML-CIRCLE: <p> double The area of the circle.</p> -// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3> -// HTML-CIRCLE: <p>public double perimeter()</p> -// HTML-CIRCLE: Defined at line -// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp#LLL9">9</a> -// HTML-CIRCLE-NEXT: of file -// HTML-CIRCLE-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> -// HTML-CIRCLE: <div>brief</div> -// HTML-CIRCLE: <p> Calculates the perimeter of the circle.</p> -// HTML-CIRCLE: <div>return</div> -// HTML-CIRCLE: <p> double The perimeter of the circle.</p> - -// MD-CALC: # class Calculator -// MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#LLL8* -// MD-CALC: **brief** A simple calculator class. -// MD-CALC: Provides basic arithmetic operations. -// MD-CALC: ## Functions -// MD-CALC: ### add -// MD-CALC: *public int add(int a, int b)* -// MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#LLL3* -// MD-CALC: **brief** Adds two integers. -// MD-CALC: **a** First integer. -// MD-CALC: **b** Second integer. -// MD-CALC: **return** int The sum of a and b. -// MD-CALC: ### subtract -// MD-CALC: *public int subtract(int a, int b)* -// MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#LLL7* -// MD-CALC: **brief** Subtracts the second integer from the first. -// MD-CALC: **a** First integer. -// MD-CALC: **b** Second integer. -// MD-CALC: **return** int The result of a - b. -// MD-CALC: ### multiply -// MD-CALC: *public int multiply(int a, int b)* -// MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#LLL11* -// MD-CALC: **brief** Multiplies two integers. -// MD-CALC: **a** First integer. -// MD-CALC: **b** Second integer. -// MD-CALC: **return** int The product of a and b. -// MD-CALC: ### divide -// MD-CALC: *public double divide(int a, int b)* -// MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#LLL15* -// MD-CALC: **brief** Divides the first integer by the second. -// MD-CALC: **a** First integer. -// MD-CALC: **b** Second integer. -// MD-CALC: **return** double The result of a / b. -// MD-CALC: **throw**if b is zero. - -// MD-CIRCLE: # class Circle -// MD-CIRCLE: *Defined at .{{[\/]}}include{{[\/]}}Circle.h#LLL10* -// MD-CIRCLE: **brief** Circle class derived from Shape. -// MD-CIRCLE: Represents a circle with a given radius. -// MD-CIRCLE: Inherits from Shape -// MD-CIRCLE: ## Members -// MD-CIRCLE: private double radius_ -// MD-CIRCLE: ## Functions -// MD-CIRCLE: ### Circle -// MD-CIRCLE: *public void Circle(double radius)* -// MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#LLL3* -// MD-CIRCLE: **brief** Constructs a new Circle object. -// MD-CIRCLE: **radius** Radius of the circle. -// MD-CIRCLE: ### area -// MD-CIRCLE: *public double area()* -// MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#LLL5* -// MD-CIRCLE: **brief** Calculates the area of the circle. -// MD-CIRCLE: **return** double The area of the circle. -// MD-CIRCLE: ### perimeter -// MD-CIRCLE: *public double perimeter()* -// MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#LLL9* -// MD-CIRCLE: **brief** Calculates the perimeter of the circle. -// MD-CIRCLE: **return** double The perimeter of the circle. - -// MD-RECTANGLE: # class Rectangle -// MD-RECTANGLE: *Defined at .{{[\/]}}include{{[\/]}}Rectangle.h#LLL10* -// MD-RECTANGLE: **brief** Rectangle class derived from Shape. -// MD-RECTANGLE: Represents a rectangle with a given width and height. -// MD-RECTANGLE: Inherits from Shape -// MD-RECTANGLE: ## Members -// MD-RECTANGLE: private double width_ -// MD-RECTANGLE: private double height_ -// MD-RECTANGLE: ## Functions -// MD-RECTANGLE: ### Rectangle -// MD-RECTANGLE: *public void Rectangle(double width, double height)* -// MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#LLL3* -// MD-RECTANGLE: **brief** Constructs a new Rectangle object. -// MD-RECTANGLE: **width** Width of the rectangle. -// MD-RECTANGLE: **height** Height of the rectangle. -// MD-RECTANGLE: ### area -// MD-RECTANGLE: *public double area()* -// MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#LLL6* -// MD-RECTANGLE: **brief** Calculates the area of the rectangle. -// MD-RECTANGLE: **return** double The area of the rectangle. -// MD-RECTANGLE: ### perimeter -// MD-RECTANGLE: *public double perimeter()* -// MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#LLL10* -// MD-RECTANGLE: **brief** Calculates the perimeter of the rectangle. -// MD-RECTANGLE: **return** double The perimeter of the rectangle. - -// MD-SHAPE: # class Shape -// MD-SHAPE: *Defined at .{{[\/]}}include{{[\/]}}Shape.h#LLL8* -// MD-SHAPE: **brief** Abstract base class for shapes. -// MD-SHAPE: Provides a common interface for different types of shapes. -// MD-SHAPE: ## Functions -// MD-SHAPE: ### ~Shape -// MD-SHAPE: *public void ~Shape()* -// MD-SHAPE: *Defined at .{{[\/]}}include{{[\/]}}Shape.h#LLL13* -// MD-SHAPE: **brief** Virtual destructor. -// MD-SHAPE: ### area -// MD-SHAPE: *public double area()* -// MD-SHAPE: **brief** Calculates the area of the shape. -// MD-SHAPE: **return** double The area of the shape. -// MD-SHAPE: ### perimeter -// MD-SHAPE: *public double perimeter()* -// MD-SHAPE: **brief** Calculates the perimeter of the shape. -// MD-SHAPE: **return** double The perimeter of the shape. - -// MD-ALL-FILES: # All Files -// MD-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md) - -// MD-INDEX: # C/C++ Reference -// MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) diff --git a/clang-tools-extra/test/clang-doc/basic-project.test b/clang-tools-extra/test/clang-doc/basic-project.test index 1f5ba8bdc0703..ebd1278888a88 100644 --- a/clang-tools-extra/test/clang-doc/basic-project.test +++ b/clang-tools-extra/test/clang-doc/basic-project.test @@ -6,6 +6,11 @@ // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Calculator.html -check-prefix=HTML-CALC // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Rectangle.html -check-prefix=HTML-RECTANGLE // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Circle.html -check-prefix=HTML-CIRCLE +// RUN: clang-doc --format=html --output=%t/docs-with-prefix --executor=all-TUs %t/build/compile_commands.json --repository=https://repository.com --repository-line-prefix=L +// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Shape.html -check-prefix=HTML-SHAPE-PREFIX +// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Calculator.html -check-prefix=HTML-CALC-PREFIX +// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Rectangle.html -check-prefix=HTML-RECTANGLE-PREFIX +// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Circle.html -check-prefix=HTML-CIRCLE-PREFIX // JSON-INDEX: async function LoadIndex() { // JSON-INDEX-NEXT: return{ @@ -232,6 +237,62 @@ // HTML-CIRCLE: <div>return</div> // HTML-CIRCLE: <p> double The perimeter of the circle.</p> +// HTML-SHAPE-PREFIX: <h1>class Shape</h1> +// HTML-SHAPE-PREFIX-NEXT: <p> +// HTML-SHAPE-PREFIX-NEXT: Defined at line +// HTML-SHAPE-PREFIX-NEXT: <a href="https://repository.com/./include/Shape.h#L8">8</a> +// HTML-SHAPE-PREFIX-NEXT: of file +// HTML-SHAPE-PREFIX-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> +// HTML-SHAPE-PREFIX-NEXT: </p> +// HTML-SHAPE-PREFIX: <h3 id="{{([0-9A-F]{40})}}">~Shape</h3> +// HTML-SHAPE-PREFIX: <p>public void ~Shape()</p> +// HTML-SHAPE-PREFIX: Defined at line +// HTML-SHAPE-PREFIX-NEXT: <a href="https://repository.com/./include/Shape.h#L13">13</a> +// HTML-SHAPE-PREFIX-NEXT: of file +// HTML-SHAPE-PREFIX-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> + +// HTML-CALC-PREFIX: <h1>class Calculator</h1> +// HTML-CALC-PREFIX-NEXT: <p> +// HTML-CALC-PREFIX-NEXT: Defined at line +// HTML-CALC-PREFIX-NEXT: <a href="https://repository.com/./include/Calculator.h#L8">8</a> +// HTML-CALC-PREFIX-NEXT: of file +// HTML-CALC-PREFIX-NEXT: <a href="https://repository.com/./include/Calculator.h">Calculator.h</a> +// HTML-CALC-PREFIX-NEXT: </p> +// HTML-CALC-PREFIX: <h3 id="{{([0-9A-F]{40})}}">add</h3> +// HTML-CALC-PREFIX: <p>public int add(int a, int b)</p> +// HTML-CALC-PREFIX: Defined at line +// HTML-CALC-PREFIX-NEXT: <a href="https://repository.com/./src/Calculator.cpp#L3">3</a> +// HTML-CALC-PREFIX-NEXT: of file +// HTML-CALC-PREFIX-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> + +// HTML-RECTANGLE-PREFIX: <h1>class Rectangle</h1> +// HTML-RECTANGLE-PREFIX-NEXT: <p> +// HTML-RECTANGLE-PREFIX-NEXT: Defined at line +// HTML-RECTANGLE-PREFIX-NEXT: <a href="https://repository.com/./include/Rectangle.h#L10">10</a> +// HTML-RECTANGLE-PREFIX-NEXT: of file +// HTML-RECTANGLE-PREFIX-NEXT: <a href="https://repository.com/./include/Rectangle.h">Rectangle.h</a> +// HTML-RECTANGLE-PREFIX-NEXT: </p> +// HTML-RECTANGLE-PREFIX: <h3 id="{{([0-9A-F]{40})}}">area</h3> +// HTML-RECTANGLE-PREFIX: <p>public double area()</p> +// HTML-RECTANGLE-PREFIX: Defined at line +// HTML-RECTANGLE-PREFIX-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#L6">6</a> +// HTML-RECTANGLE-PREFIX-NEXT: of file +// HTML-RECTANGLE-PREFIX-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> + +// HTML-CIRCLE-PREFIX: <h1>class Circle</h1> +// HTML-CIRCLE-PREFIX-NEXT: <p> +// HTML-CIRCLE-PREFIX-NEXT: Defined at line +// HTML-CIRCLE-PREFIX-NEXT: <a href="https://repository.com/./include/Circle.h#L10">10</a> +// HTML-CIRCLE-PREFIX-NEXT: of file +// HTML-CIRCLE-PREFIX-NEXT: <a href="https://repository.com/./include/Circle.h">Circle.h</a> +// HTML-CIRCLE-PREFIX-NEXT: </p> +// HTML-CIRCLE-PREFIX: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3> +// HTML-CIRCLE-PREFIX: <p>public double perimeter()</p> +// HTML-CIRCLE-PREFIX: Defined at line +// HTML-CIRCLE-PREFIX-NEXT: <a href="https://repository.com/./src/Circle.cpp#L9">9</a> +// HTML-CIRCLE-PREFIX-NEXT: of file +// HTML-CIRCLE-PREFIX-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> + // MD-CALC: # class Calculator // MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#8* // MD-CALC: **brief** A simple calculator class. @@ -339,4 +400,4 @@ // MD-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md) // MD-INDEX: # C/C++ Reference -// MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) +// MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) \ No newline at end of file >From 5d184b0def15cc66c037d61c2221ca5458cfe1a8 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Sat, 22 Mar 2025 05:06:24 +0200 Subject: [PATCH 07/18] [clang-doc][refactor] improve `HtmlGenerator::writeFileDescription` --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 55 +++++-------------- 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index caeca5b0afc60..0f87a702b1f7c 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -490,15 +490,17 @@ genReferencesBlock(const std::vector<Reference> &References, } return Out; } +static std::unique_ptr<TagNode> +writeFileDefinition(const ClangDocContext &CDCtx, const Location &L) { + std::string RepositoryUrl = CDCtx.RepositoryUrl.value_or(""); + std::string RepositoryLinePrefix = CDCtx.RepositoryLinePrefix.value_or(""); -static std::unique_ptr<TagNode> writeFileDefinition( - const Location &L, std::optional<StringRef> RepositoryUrl = std::nullopt, - std::optional<StringRef> RepositoryLinePrefix = std::nullopt) { - if (!L.IsFileInRootDir && !RepositoryUrl) + if (!L.IsFileInRootDir && RepositoryUrl.empty()) return std::make_unique<TagNode>( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + " of file " + L.Filename); - SmallString<128> FileURL(RepositoryUrl.value_or("")); + + SmallString<128> FileURL(RepositoryUrl); llvm::sys::path::append( FileURL, llvm::sys::path::Style::posix, // If we're on Windows, the file name will be in the wrong format, and @@ -516,8 +518,8 @@ static std::unique_ptr<TagNode> writeFileDefinition( std::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. - std::string LineAnchor = formatv("#{0}{1}", RepositoryLinePrefix.value_or(""), L.LineNumber); - + std::string LineAnchor = + formatv("#{0}{1}", RepositoryLinePrefix, L.LineNumber); LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); Node->Children.emplace_back(std::move(LocNumberNode)); @@ -750,17 +752,8 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); - if (I.DefLoc) { - std::optional<StringRef> RepoUrl; - std::optional<StringRef> RepoLinePrefix; - - if (CDCtx.RepositoryUrl) - RepoUrl = StringRef{*CDCtx.RepositoryUrl}; - if (CDCtx.RepositoryLinePrefix) - RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; - - Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); - } + if (I.DefLoc) + Out.emplace_back(writeFileDefinition(CDCtx, *I.DefLoc)); std::string Description; if (!I.Description.empty()) @@ -803,17 +796,8 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, } FunctionHeader->Children.emplace_back(std::make_unique<TextNode>(")")); - if (I.DefLoc) { - std::optional<StringRef> RepoUrl; - std::optional<StringRef> RepoLinePrefix; - - if (CDCtx.RepositoryUrl) - RepoUrl = StringRef{*CDCtx.RepositoryUrl}; - if (CDCtx.RepositoryLinePrefix) - RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; - - Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); - } + if (I.DefLoc) + Out.emplace_back(writeFileDefinition(CDCtx, *I.DefLoc)); std::string Description; if (!I.Description.empty()) @@ -874,17 +858,8 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, InfoTitle = (getTagType(I.TagType) + " " + I.Name).str(); Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H1, InfoTitle)); - if (I.DefLoc) { - std::optional<StringRef> RepoUrl; - std::optional<StringRef> RepoLinePrefix; - - if (CDCtx.RepositoryUrl) - RepoUrl = StringRef{*CDCtx.RepositoryUrl}; - if (CDCtx.RepositoryLinePrefix) - RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; - - Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); - } + if (I.DefLoc) + Out.emplace_back(writeFileDefinition(CDCtx, *I.DefLoc)); std::string Description; if (!I.Description.empty()) >From 7f57fe60cfc6dcea64860ea3e8497494fc87cca3 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Sat, 22 Mar 2025 05:30:21 +0200 Subject: [PATCH 08/18] [clang-doc] fix formatting --- clang-tools-extra/clang-doc/MDGenerator.cpp | 4 ++-- clang-tools-extra/clang-doc/Representation.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index 993596c708489..7b7473f5e492a 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -8,9 +8,9 @@ #include "Generators.h" #include "Representation.h" -#include "llvm/Support/FormatVariadic.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include <string> @@ -61,7 +61,7 @@ static void writeFileDefinition(const ClangDocContext &CDCtx, const Location &L, std::string LineAnchor = formatv("#{0}{1}", CDCtx.RepositoryLinePrefix.value_or(""), - std::to_string(L.LineNumber)); + std::to_string(L.LineNumber)); OS << formatv("*Defined at [{0}{1}]({0}{2})*", LineAnchor, L.Filename, StringRef{*CDCtx.RepositoryUrl}); diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h index 04293edc988eb..bf6e6a8513bb5 100644 --- a/clang-tools-extra/clang-doc/Representation.h +++ b/clang-tools-extra/clang-doc/Representation.h @@ -507,8 +507,7 @@ struct ClangDocContext { ClangDocContext() = default; ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName, bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot, - StringRef RepositoryUrl, - StringRef RepositoryCodeLinePrefix, + StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix, std::vector<std::string> UserStylesheets); tooling::ExecutionContext *ECtx; std::string ProjectName; // Name of project clang-doc is documenting. >From 2fce1c1612d172887b130e1414a6427aca4a5bc1 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Mon, 24 Mar 2025 00:10:13 +0200 Subject: [PATCH 09/18] fix: avoid useless string copies --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 11 +++++------ clang-tools-extra/clang-doc/MDGenerator.cpp | 8 +++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 0f87a702b1f7c..f4d19d9bd84eb 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -518,16 +518,15 @@ writeFileDefinition(const ClangDocContext &CDCtx, const Location &L) { std::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. - std::string LineAnchor = - formatv("#{0}{1}", RepositoryLinePrefix, L.LineNumber); - - LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); + LocNumberNode->Attributes.emplace_back( + "href", + (FileURL + formatv("#{0}{1}", CDCtx.RepositoryLinePrefix.value_or(""), + L.LineNumber)) + .str()); Node->Children.emplace_back(std::move(LocNumberNode)); Node->Children.emplace_back(std::make_unique<TextNode>(" of file ")); - auto LocFileNode = std::make_unique<TagNode>( HTMLTag::TAG_A, llvm::sys::path::filename(FileURL)); - LocFileNode->Attributes.emplace_back("href", std::string(FileURL)); Node->Children.emplace_back(std::move(LocFileNode)); return Node; diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index 7b7473f5e492a..31f6586815f47 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -59,11 +59,9 @@ static void writeFileDefinition(const ClangDocContext &CDCtx, const Location &L, << "*"; } else { - std::string LineAnchor = - formatv("#{0}{1}", CDCtx.RepositoryLinePrefix.value_or(""), - std::to_string(L.LineNumber)); - - OS << formatv("*Defined at [{0}{1}]({0}{2})*", LineAnchor, L.Filename, + OS << formatv("*Defined at [#{0}{1}{2}](#{0}{1}{3})*", + CDCtx.RepositoryLinePrefix.value_or(""), + std::to_string(L.LineNumber), L.Filename, StringRef{*CDCtx.RepositoryUrl}); } OS << "\n\n"; >From 02c9e07b60d9ba55f3ac8394b457cd58bbd99aaa Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Mon, 24 Mar 2025 03:30:40 +0200 Subject: [PATCH 10/18] [clang-doc] improving `LINE-PREFIX` test --- .../test/clang-doc/basic-project.test | 83 +++++-------------- 1 file changed, 22 insertions(+), 61 deletions(-) diff --git a/clang-tools-extra/test/clang-doc/basic-project.test b/clang-tools-extra/test/clang-doc/basic-project.test index 74bebc4143df4..9dc82f99f5f05 100644 --- a/clang-tools-extra/test/clang-doc/basic-project.test +++ b/clang-tools-extra/test/clang-doc/basic-project.test @@ -7,11 +7,12 @@ // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Calculator.html -check-prefix=HTML-CALC // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Rectangle.html -check-prefix=HTML-RECTANGLE // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Circle.html -check-prefix=HTML-CIRCLE + // RUN: clang-doc --format=html --output=%t/docs-with-prefix --executor=all-TUs %t/build/compile_commands.json --repository=https://repository.com --repository-line-prefix=L -// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Shape.html -check-prefix=HTML-SHAPE-PREFIX -// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Calculator.html -check-prefix=HTML-CALC-PREFIX -// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Rectangle.html -check-prefix=HTML-RECTANGLE-PREFIX -// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Circle.html -check-prefix=HTML-CIRCLE-PREFIX +// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Shape.html -check-prefixes=HTML-SHAPE,SHAPE-LINE-PREFIX +// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Calculator.html -check-prefixes=HTML-CALC,CALC-LINE-PREFIX +// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Rectangle.html -check-prefixes=HTML-RECTANGLE,RECTANGLE-LINE-PREFIX +// RUN: FileCheck %s -input-file=%t/docs-with-prefix/GlobalNamespace/Circle.html -check-prefixes=HTML-CIRCLE,CIRCLE-LINE-PREFIX // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Shape.html -check-prefixes=HTML-SHAPE,SHAPE-NO-REPOSITORY // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Calculator.html -check-prefixes=HTML-CALC,CALC-NO-REPOSITORY @@ -85,6 +86,7 @@ // SHAPE-REPOSITORY: <p> // SHAPE-REPOSITORY-NEXT: Defined at line // SHAPE-REPOSITORY-NEXT: <a href="https://repository.com/./include/Shape.h#8">8</a> +// SHAPE-LINE-PREFIX: <a href="https://repository.com/./include/Shape.h#L8">8</a> // SHAPE-REPOSITORY-NEXT: of file // SHAPE-REPOSITORY-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> // SHAPE-REPOSITORY-NEXT: </p> @@ -108,6 +110,7 @@ // SHAPE-NO-REPOSITORY: Defined at line 13 of file .{{.}}include{{.}}Shape.h // SHAPE-REPOSITORY: Defined at line // SHAPE-REPOSITORY-NEXT: <a href="https://repository.com/./include/Shape.h#13">13</a> +// SHAPE-LINE-PREFIX: <a href="https://repository.com/./include/Shape.h#L13">13</a> // SHAPE-REPOSITORY-NEXT: of file // SHAPE-REPOSITORY-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> @@ -119,6 +122,7 @@ // CALC-REPOSITORY: <p> // CALC-REPOSITORY-NEXT: Defined at line // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./include/Calculator.h#8">8</a> +// CALC-LINE-PREFIX: <a href="https://repository.com/./include/Calculator.h#L8">8</a> // CALC-REPOSITORY-NEXT: of file // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./include/Calculator.h">Calculator.h</a> // CALC-REPOSITORY-NEXT: </p> @@ -131,6 +135,7 @@ // CALC-NO-REPOSITORY: Defined at line 3 of file .{{.}}src{{.}}Calculator.cpp // CALC-REPOSITORY: Defined at line // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp#3">3</a> +// CALC-LINE-PREFIX: <a href="https://repository.com/./src/Calculator.cpp#L3">3</a> // CALC-REPOSITORY-NEXT: of file // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> @@ -143,6 +148,7 @@ // CALC-NO-REPOSITORY: Defined at line 7 of file .{{.}}src{{.}}Calculator.cpp // CALC-REPOSITORY: Defined at line // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp#7">7</a> +// CALC-LINE-PREFIX: <a href="https://repository.com/./src/Calculator.cpp#L7">7</a> // CALC-REPOSITORY-NEXT: of file // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> @@ -155,6 +161,7 @@ // CALC-NO-REPOSITORY: Defined at line 11 of file .{{.}}src{{.}}Calculator.cpp // CALC-REPOSITORY: Defined at line // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp#11">11</a> +// CALC-LINE-PREFIX: <a href="https://repository.com/./src/Calculator.cpp#L11">11</a> // CALC-REPOSITORY-NEXT: of file // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> @@ -167,6 +174,7 @@ // CALC-NO-REPOSITORY: Defined at line 15 of file .{{.}}src{{.}}Calculator.cpp // CALC-REPOSITORY: Defined at line // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp#15">15</a> +// CALC-LINE-PREFIX: <a href="https://repository.com/./src/Calculator.cpp#L15">15</a> // CALC-REPOSITORY-NEXT: of file // CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> @@ -182,6 +190,7 @@ // RECTANGLE-REPOSITORY: <p> // RECTANGLE-REPOSITORY-NEXT: Defined at line // RECTANGLE-REPOSITORY-NEXT: <a href="https://repository.com/./include/Rectangle.h#10">10</a> +// RECTANGLE-LINE-PREFIX: <a href="https://repository.com/./include/Rectangle.h#L10">10</a> // RECTANGLE-REPOSITORY-NEXT: of file // RECTANGLE-REPOSITORY-NEXT: <a href="https://repository.com/./include/Rectangle.h">Rectangle.h</a> // RECTANGLE-REPOSITORY-NEXT: </p> @@ -202,6 +211,7 @@ // RECTANGLE-NO-REPOSITORY: Defined at line 3 of file .{{.}}src{{.}}Rectangle.cpp // RECTANGLE-REPOSITORY: Defined at line // RECTANGLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#3">3</a> +// RECTANGLE-LINE-PREFIX: <a href="https://repository.com/./src/Rectangle.cpp#L3">3</a> // RECTANGLE-REPOSITORY-NEXT: of file // RECTANGLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> @@ -212,6 +222,7 @@ // RECTANGLE-NO-REPOSITORY: Defined at line 6 of file .{{.}}src{{.}}Rectangle.cpp // RECTANGLE-REPOSITORY: Defined at line // RECTANGLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#6">6</a> +// RECTANGLE-LINE-PREFIX: <a href="https://repository.com/./src/Rectangle.cpp#L6">6</a> // RECTANGLE-REPOSITORY-NEXT: of file // RECTANGLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> @@ -224,6 +235,7 @@ // RECTANGLE-NO-REPOSITORY: Defined at line 10 of file .{{.}}src{{.}}Rectangle.cpp // RECTANGLE-REPOSITORY: Defined at line // RECTANGLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#10">10</a> +// RECTANGLE-LINE-PREFIX: <a href="https://repository.com/./src/Rectangle.cpp#L10">10</a> // RECTANGLE-REPOSITORY-NEXT: of file // RECTANGLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> // HTML-RECTANGLE: <div>brief</div> @@ -236,6 +248,7 @@ // CIRCLE-REPOSITORY: <p> // CIRCLE-REPOSITORY-NEXT: Defined at line // CIRCLE-REPOSITORY-NEXT: <a href="https://repository.com/./include/Circle.h#10">10</a> +// CIRCLE-LINE-PREFIX: <a href="https://repository.com/./include/Circle.h#L10">10</a> // CIRCLE-REPOSITORY-NEXT: of file // CIRCLE-REPOSITORY-NEXT: <a href="https://repository.com/./include/Circle.h">Circle.h</a> // CIRCLE-REPOSITORY-NEXT: </p> @@ -256,6 +269,7 @@ // CIRCLE-NO-REPOSITORY: Defined at line 3 of file .{{.}}src{{.}}Circle.cpp // CIRCLE-REPOSITORY: Defined at line // CIRCLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Circle.cpp#3">3</a> +// CIRCLE-LINE-PREFIX: <a href="https://repository.com/./src/Circle.cpp#L3">3</a> // CIRCLE-REPOSITORY-NEXT: of file // CIRCLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> @@ -266,6 +280,7 @@ // CIRCLE-NO-REPOSITORY: Defined at line 5 of file .{{.}}src{{.}}Circle.cpp // CIRCLE-REPOSITORY: Defined at line // CIRCLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Circle.cpp#5">5</a> +// CIRCLE-LINE-PREFIX: <a href="https://repository.com/./src/Circle.cpp#L5">5</a> // CIRCLE-REPOSITORY-NEXT: of file // CIRCLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> @@ -278,6 +293,7 @@ // CIRCLE-NO-REPOSITORY: Defined at line 9 of file .{{.}}src{{.}}Circle.cpp // CIRCLE-REPOSITORY: Defined at line // CIRCLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Circle.cpp#9">9</a> +// CIRCLE-LINE-PREFIX: <a href="https://repository.com/./src/Circle.cpp#L9">9</a> // CIRCLE-REPOSITORY-NEXT: of file // CIRCLE-REPOSITORY-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> @@ -286,62 +302,6 @@ // HTML-CIRCLE: <div>return</div> // HTML-CIRCLE: <p> double The perimeter of the circle.</p> -// HTML-SHAPE-PREFIX: <h1>class Shape</h1> -// HTML-SHAPE-PREFIX-NEXT: <p> -// HTML-SHAPE-PREFIX-NEXT: Defined at line -// HTML-SHAPE-PREFIX-NEXT: <a href="https://repository.com/./include/Shape.h#L8">8</a> -// HTML-SHAPE-PREFIX-NEXT: of file -// HTML-SHAPE-PREFIX-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> -// HTML-SHAPE-PREFIX-NEXT: </p> -// HTML-SHAPE-PREFIX: <h3 id="{{([0-9A-F]{40})}}">~Shape</h3> -// HTML-SHAPE-PREFIX: <p>public void ~Shape()</p> -// HTML-SHAPE-PREFIX: Defined at line -// HTML-SHAPE-PREFIX-NEXT: <a href="https://repository.com/./include/Shape.h#L13">13</a> -// HTML-SHAPE-PREFIX-NEXT: of file -// HTML-SHAPE-PREFIX-NEXT: <a href="https://repository.com/./include/Shape.h">Shape.h</a> - -// HTML-CALC-PREFIX: <h1>class Calculator</h1> -// HTML-CALC-PREFIX-NEXT: <p> -// HTML-CALC-PREFIX-NEXT: Defined at line -// HTML-CALC-PREFIX-NEXT: <a href="https://repository.com/./include/Calculator.h#L8">8</a> -// HTML-CALC-PREFIX-NEXT: of file -// HTML-CALC-PREFIX-NEXT: <a href="https://repository.com/./include/Calculator.h">Calculator.h</a> -// HTML-CALC-PREFIX-NEXT: </p> -// HTML-CALC-PREFIX: <h3 id="{{([0-9A-F]{40})}}">add</h3> -// HTML-CALC-PREFIX: <p>public int add(int a, int b)</p> -// HTML-CALC-PREFIX: Defined at line -// HTML-CALC-PREFIX-NEXT: <a href="https://repository.com/./src/Calculator.cpp#L3">3</a> -// HTML-CALC-PREFIX-NEXT: of file -// HTML-CALC-PREFIX-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a> - -// HTML-RECTANGLE-PREFIX: <h1>class Rectangle</h1> -// HTML-RECTANGLE-PREFIX-NEXT: <p> -// HTML-RECTANGLE-PREFIX-NEXT: Defined at line -// HTML-RECTANGLE-PREFIX-NEXT: <a href="https://repository.com/./include/Rectangle.h#L10">10</a> -// HTML-RECTANGLE-PREFIX-NEXT: of file -// HTML-RECTANGLE-PREFIX-NEXT: <a href="https://repository.com/./include/Rectangle.h">Rectangle.h</a> -// HTML-RECTANGLE-PREFIX-NEXT: </p> -// HTML-RECTANGLE-PREFIX: <h3 id="{{([0-9A-F]{40})}}">area</h3> -// HTML-RECTANGLE-PREFIX: <p>public double area()</p> -// HTML-RECTANGLE-PREFIX: Defined at line -// HTML-RECTANGLE-PREFIX-NEXT: <a href="https://repository.com/./src/Rectangle.cpp#L6">6</a> -// HTML-RECTANGLE-PREFIX-NEXT: of file -// HTML-RECTANGLE-PREFIX-NEXT: <a href="https://repository.com/./src/Rectangle.cpp">Rectangle.cpp</a> - -// HTML-CIRCLE-PREFIX: <h1>class Circle</h1> -// HTML-CIRCLE-PREFIX-NEXT: <p> -// HTML-CIRCLE-PREFIX-NEXT: Defined at line -// HTML-CIRCLE-PREFIX-NEXT: <a href="https://repository.com/./include/Circle.h#L10">10</a> -// HTML-CIRCLE-PREFIX-NEXT: of file -// HTML-CIRCLE-PREFIX-NEXT: <a href="https://repository.com/./include/Circle.h">Circle.h</a> -// HTML-CIRCLE-PREFIX-NEXT: </p> -// HTML-CIRCLE-PREFIX: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3> -// HTML-CIRCLE-PREFIX: <p>public double perimeter()</p> -// HTML-CIRCLE-PREFIX: Defined at line -// HTML-CIRCLE-PREFIX-NEXT: <a href="https://repository.com/./src/Circle.cpp#L9">9</a> -// HTML-CIRCLE-PREFIX-NEXT: of file -// HTML-CIRCLE-PREFIX-NEXT: <a href="https://repository.com/./src/Circle.cpp">Circle.cpp</a> - // MD-CALC: # class Calculator // MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#8* // MD-CALC: **brief** A simple calculator class. @@ -449,4 +409,5 @@ // MD-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md) // MD-INDEX: # C/C++ Reference -// MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) \ No newline at end of file +// MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) + \ No newline at end of file >From 91d9bcdc0ce59dfda4123a7ec1f4b9ebc42268f4 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Mon, 24 Mar 2025 22:43:10 +0200 Subject: [PATCH 11/18] avoid unnecessary string copies --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index f4d19d9bd84eb..c3874e1d47e6a 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -492,15 +492,13 @@ genReferencesBlock(const std::vector<Reference> &References, } static std::unique_ptr<TagNode> writeFileDefinition(const ClangDocContext &CDCtx, const Location &L) { - std::string RepositoryUrl = CDCtx.RepositoryUrl.value_or(""); - std::string RepositoryLinePrefix = CDCtx.RepositoryLinePrefix.value_or(""); - if (!L.IsFileInRootDir && RepositoryUrl.empty()) + if (!L.IsFileInRootDir && !CDCtx.RepositoryUrl) return std::make_unique<TagNode>( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + " of file " + L.Filename); - SmallString<128> FileURL(RepositoryUrl); + SmallString<128> FileURL(CDCtx.RepositoryUrl.value_or("")); llvm::sys::path::append( FileURL, llvm::sys::path::Style::posix, // If we're on Windows, the file name will be in the wrong format, and >From 322a188a7595d97db8bef1e8c0d9fef4b570897f Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Mon, 24 Mar 2025 23:55:32 +0200 Subject: [PATCH 12/18] [clang-doc] make a helper function for creating file definition --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 16 +++++++++------ clang-tools-extra/clang-doc/MDGenerator.cpp | 20 +++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index c3874e1d47e6a..ee13181f46e79 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -530,6 +530,13 @@ writeFileDefinition(const ClangDocContext &CDCtx, const Location &L) { return Node; } +static void createFileDefinition(std::vector<std::unique_ptr<TagNode>> &Out, + const ClangDocContext &CDCtx, + const std::optional<Location> &DefLoc) { + if (DefLoc) + Out.emplace_back(writeFileDefinition(CDCtx, *DefLoc)); +} + static std::vector<std::unique_ptr<TagNode>> genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList); @@ -749,8 +756,7 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); - if (I.DefLoc) - Out.emplace_back(writeFileDefinition(CDCtx, *I.DefLoc)); + createFileDefinition(Out, CDCtx, I.DefLoc); std::string Description; if (!I.Description.empty()) @@ -793,8 +799,7 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, } FunctionHeader->Children.emplace_back(std::make_unique<TextNode>(")")); - if (I.DefLoc) - Out.emplace_back(writeFileDefinition(CDCtx, *I.DefLoc)); + createFileDefinition(Out, CDCtx, I.DefLoc); std::string Description; if (!I.Description.empty()) @@ -855,8 +860,7 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, InfoTitle = (getTagType(I.TagType) + " " + I.Name).str(); Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H1, InfoTitle)); - if (I.DefLoc) - Out.emplace_back(writeFileDefinition(CDCtx, *I.DefLoc)); + createFileDefinition(Out, CDCtx, I.DefLoc); std::string Description; if (!I.Description.empty()) diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index 31f6586815f47..a783814668d88 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -12,6 +12,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" #include <string> using namespace llvm; @@ -67,6 +68,13 @@ static void writeFileDefinition(const ClangDocContext &CDCtx, const Location &L, OS << "\n\n"; } +static void createFileDefinition(llvm::raw_ostream &OS, + const ClangDocContext &CDCtx, + const std::optional<Location> &DefLoc) { + if (DefLoc) + writeFileDefinition(CDCtx, *DefLoc, OS); +} + static void writeDescription(const CommentInfo &I, raw_ostream &OS) { if (I.Kind == "FullComment") { for (const auto &Child : I.Children) @@ -143,8 +151,8 @@ static void genMarkdown(const ClangDocContext &CDCtx, const EnumInfo &I, for (const auto &N : I.Members) Members << "| " << N.Name << " |\n"; writeLine(Members.str(), OS); - if (I.DefLoc) - writeFileDefinition(CDCtx, *I.DefLoc, OS); + + createFileDefinition(OS, CDCtx, I.DefLoc); for (const auto &C : I.Description) writeDescription(C, OS); @@ -171,8 +179,8 @@ static void genMarkdown(const ClangDocContext &CDCtx, const FunctionInfo &I, writeLine(genItalic(I.ReturnType.Type.QualName + " " + I.Name + "(" + Stream.str() + ")"), OS); - if (I.DefLoc) - writeFileDefinition(CDCtx, *I.DefLoc, OS); + + createFileDefinition(OS, CDCtx, I.DefLoc); for (const auto &C : I.Description) writeDescription(C, OS); @@ -231,8 +239,8 @@ static void genMarkdown(const ClangDocContext &CDCtx, const NamespaceInfo &I, static void genMarkdown(const ClangDocContext &CDCtx, const RecordInfo &I, llvm::raw_ostream &OS) { writeHeader(getTagType(I.TagType) + " " + I.Name, 1, OS); - if (I.DefLoc) - writeFileDefinition(CDCtx, *I.DefLoc, OS); + + createFileDefinition(OS, CDCtx, I.DefLoc); if (!I.Description.empty()) { for (const auto &C : I.Description) >From a33876d727634dc6cd587f209b9ca479297b8d41 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Tue, 25 Mar 2025 19:52:21 +0200 Subject: [PATCH 13/18] [clang-doc] avoid unnecessary string casting and concatenatation --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 6 ++---- clang-tools-extra/clang-doc/MDGenerator.cpp | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index ee13181f46e79..8a3045b456c0e 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -517,10 +517,8 @@ writeFileDefinition(const ClangDocContext &CDCtx, const Location &L) { // 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.emplace_back( - "href", - (FileURL + formatv("#{0}{1}", CDCtx.RepositoryLinePrefix.value_or(""), - L.LineNumber)) - .str()); + "href", formatv("{0}#{1}{2}", FileURL, + CDCtx.RepositoryLinePrefix.value_or(""), L.LineNumber)); Node->Children.emplace_back(std::move(LocNumberNode)); Node->Children.emplace_back(std::make_unique<TextNode>(" of file ")); auto LocFileNode = std::make_unique<TagNode>( diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index a783814668d88..a6dd815dcab2d 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -61,9 +61,8 @@ static void writeFileDefinition(const ClangDocContext &CDCtx, const Location &L, } else { OS << formatv("*Defined at [#{0}{1}{2}](#{0}{1}{3})*", - CDCtx.RepositoryLinePrefix.value_or(""), - std::to_string(L.LineNumber), L.Filename, - StringRef{*CDCtx.RepositoryUrl}); + CDCtx.RepositoryLinePrefix.value_or(""), L.LineNumber, + L.Filename, *CDCtx.RepositoryUrl); } OS << "\n\n"; } >From 779117ad5eceb4ad80b1e8ff35c9b8643fca097c Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Tue, 25 Mar 2025 19:53:08 +0200 Subject: [PATCH 14/18] [clang-doc][refactor] improve naming of `writeFileDefinition` --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 12 ++++++------ clang-tools-extra/clang-doc/MDGenerator.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 8a3045b456c0e..3f55cdd28f662 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -491,7 +491,7 @@ genReferencesBlock(const std::vector<Reference> &References, return Out; } static std::unique_ptr<TagNode> -writeFileDefinition(const ClangDocContext &CDCtx, const Location &L) { +writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L) { if (!L.IsFileInRootDir && !CDCtx.RepositoryUrl) return std::make_unique<TagNode>( @@ -528,11 +528,11 @@ writeFileDefinition(const ClangDocContext &CDCtx, const Location &L) { return Node; } -static void createFileDefinition(std::vector<std::unique_ptr<TagNode>> &Out, +static void maybeWriteSourceFileRef(std::vector<std::unique_ptr<TagNode>> &Out, const ClangDocContext &CDCtx, const std::optional<Location> &DefLoc) { if (DefLoc) - Out.emplace_back(writeFileDefinition(CDCtx, *DefLoc)); + Out.emplace_back(writeSourceFileRef(CDCtx, *DefLoc)); } static std::vector<std::unique_ptr<TagNode>> @@ -754,7 +754,7 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); - createFileDefinition(Out, CDCtx, I.DefLoc); + maybeWriteSourceFileRef(Out, CDCtx, I.DefLoc); std::string Description; if (!I.Description.empty()) @@ -797,7 +797,7 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, } FunctionHeader->Children.emplace_back(std::make_unique<TextNode>(")")); - createFileDefinition(Out, CDCtx, I.DefLoc); + maybeWriteSourceFileRef(Out, CDCtx, I.DefLoc); std::string Description; if (!I.Description.empty()) @@ -858,7 +858,7 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, InfoTitle = (getTagType(I.TagType) + " " + I.Name).str(); Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H1, InfoTitle)); - createFileDefinition(Out, CDCtx, I.DefLoc); + maybeWriteSourceFileRef(Out, CDCtx, I.DefLoc); std::string Description; if (!I.Description.empty()) diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index a6dd815dcab2d..88204d3703d97 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -52,7 +52,7 @@ static void writeHeader(const Twine &Text, unsigned int Num, raw_ostream &OS) { OS << std::string(Num, '#') + " " + Text << "\n\n"; } -static void writeFileDefinition(const ClangDocContext &CDCtx, const Location &L, +static void writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L, raw_ostream &OS) { if (!CDCtx.RepositoryUrl) { @@ -67,11 +67,11 @@ static void writeFileDefinition(const ClangDocContext &CDCtx, const Location &L, OS << "\n\n"; } -static void createFileDefinition(llvm::raw_ostream &OS, +static void maybeWriteSourceFileRef(llvm::raw_ostream &OS, const ClangDocContext &CDCtx, const std::optional<Location> &DefLoc) { if (DefLoc) - writeFileDefinition(CDCtx, *DefLoc, OS); + writeSourceFileRef(CDCtx, *DefLoc, OS); } static void writeDescription(const CommentInfo &I, raw_ostream &OS) { @@ -151,7 +151,7 @@ static void genMarkdown(const ClangDocContext &CDCtx, const EnumInfo &I, Members << "| " << N.Name << " |\n"; writeLine(Members.str(), OS); - createFileDefinition(OS, CDCtx, I.DefLoc); + maybeWriteSourceFileRef(OS, CDCtx, I.DefLoc); for (const auto &C : I.Description) writeDescription(C, OS); @@ -179,7 +179,7 @@ static void genMarkdown(const ClangDocContext &CDCtx, const FunctionInfo &I, Stream.str() + ")"), OS); - createFileDefinition(OS, CDCtx, I.DefLoc); + maybeWriteSourceFileRef(OS, CDCtx, I.DefLoc); for (const auto &C : I.Description) writeDescription(C, OS); @@ -239,7 +239,7 @@ static void genMarkdown(const ClangDocContext &CDCtx, const RecordInfo &I, llvm::raw_ostream &OS) { writeHeader(getTagType(I.TagType) + " " + I.Name, 1, OS); - createFileDefinition(OS, CDCtx, I.DefLoc); + maybeWriteSourceFileRef(OS, CDCtx, I.DefLoc); if (!I.Description.empty()) { for (const auto &C : I.Description) >From 54ede2361bdcc1d6b154893056cac211e4e70004 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Tue, 25 Mar 2025 19:57:02 +0200 Subject: [PATCH 15/18] [clang-doc] add missing new line to clang-doc basic-project test --- clang-tools-extra/test/clang-doc/basic-project.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-doc/basic-project.test b/clang-tools-extra/test/clang-doc/basic-project.test index 9dc82f99f5f05..ef26e5b8916b4 100644 --- a/clang-tools-extra/test/clang-doc/basic-project.test +++ b/clang-tools-extra/test/clang-doc/basic-project.test @@ -410,4 +410,4 @@ // MD-INDEX: # C/C++ Reference // MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) - \ No newline at end of file + >From af71ae8c2bdb01f4fc4824deeba81f31cff85309 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Tue, 25 Mar 2025 22:25:44 +0200 Subject: [PATCH 16/18] fix formatting --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 8 ++++---- clang-tools-extra/clang-doc/MDGenerator.cpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 3f55cdd28f662..7147057191daa 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -490,8 +490,8 @@ genReferencesBlock(const std::vector<Reference> &References, } return Out; } -static std::unique_ptr<TagNode> -writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L) { +static std::unique_ptr<TagNode> writeSourceFileRef(const ClangDocContext &CDCtx, + const Location &L) { if (!L.IsFileInRootDir && !CDCtx.RepositoryUrl) return std::make_unique<TagNode>( @@ -529,8 +529,8 @@ writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L) { } static void maybeWriteSourceFileRef(std::vector<std::unique_ptr<TagNode>> &Out, - const ClangDocContext &CDCtx, - const std::optional<Location> &DefLoc) { + const ClangDocContext &CDCtx, + const std::optional<Location> &DefLoc) { if (DefLoc) Out.emplace_back(writeSourceFileRef(CDCtx, *DefLoc)); } diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index 88204d3703d97..5c782fcc10da5 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -53,7 +53,7 @@ static void writeHeader(const Twine &Text, unsigned int Num, raw_ostream &OS) { } static void writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L, - raw_ostream &OS) { + raw_ostream &OS) { if (!CDCtx.RepositoryUrl) { OS << "*Defined at " << L.Filename << "#" << std::to_string(L.LineNumber) @@ -68,8 +68,8 @@ static void writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L, } static void maybeWriteSourceFileRef(llvm::raw_ostream &OS, - const ClangDocContext &CDCtx, - const std::optional<Location> &DefLoc) { + const ClangDocContext &CDCtx, + const std::optional<Location> &DefLoc) { if (DefLoc) writeSourceFileRef(CDCtx, *DefLoc, OS); } >From 331c786f792975a9ef59defbd0372a79ea213486 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Tue, 25 Mar 2025 22:27:33 +0200 Subject: [PATCH 17/18] fix: building error in `HTMLGeneratorTest.cpp` --- .../unittests/clang-doc/HTMLGeneratorTest.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp index 97afa12cab6d3..7ba06836e021b 100644 --- a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp +++ b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp @@ -28,9 +28,16 @@ std::unique_ptr<Generator> getHTMLGenerator() { ClangDocContext getClangDocContext(std::vector<std::string> UserStylesheets = {}, - StringRef RepositoryUrl = "") { - ClangDocContext CDCtx{ - {}, "test-project", {}, {}, {}, RepositoryUrl, UserStylesheets}; + StringRef RepositoryUrl = "", + StringRef RepositoryLinePrefix = "") { + ClangDocContext CDCtx{{}, + "test-project", + {}, + {}, + {}, + RepositoryUrl, + RepositoryLinePrefix, + UserStylesheets}; CDCtx.UserStylesheets.insert( CDCtx.UserStylesheets.begin(), "../share/clang/clang-doc-default-stylesheet.css"); >From d6477a9e83ec55ccc9dd43fbbf2a0df07c9ec863 Mon Sep 17 00:00:00 2001 From: hulxv <hul...@gmail.com> Date: Fri, 28 Mar 2025 22:23:41 +0200 Subject: [PATCH 18/18] [clang-doc] fix formatting --- clang-tools-extra/clang-doc/Representation.cpp | 3 +-- clang-tools-extra/clang-doc/Representation.h | 3 +-- .../unittests/clang-doc/HTMLGeneratorTest.cpp | 15 ++++----------- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp index 03ada0215cfc8..0947ecff72272 100644 --- a/clang-tools-extra/clang-doc/Representation.cpp +++ b/clang-tools-extra/clang-doc/Representation.cpp @@ -368,8 +368,7 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName, bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot, StringRef RepositoryUrl, - StringRef RepositoryLinePrefix, - StringRef Base, + StringRef RepositoryLinePrefix, StringRef Base, std::vector<std::string> UserStylesheets) : ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly), OutDirectory(OutDirectory), UserStylesheets(UserStylesheets), Base(Base) { diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h index 2e880a1f5f911..2153b62864ee3 100644 --- a/clang-tools-extra/clang-doc/Representation.h +++ b/clang-tools-extra/clang-doc/Representation.h @@ -508,8 +508,7 @@ struct ClangDocContext { ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName, bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot, StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix, - StringRef Base, - std::vector<std::string> UserStylesheets); + StringRef Base, std::vector<std::string> UserStylesheets); tooling::ExecutionContext *ECtx; std::string ProjectName; // Name of project clang-doc is documenting. bool PublicOnly; // Indicates if only public declarations are documented. diff --git a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp index 6750400f8fbaa..e440e11c07fdb 100644 --- a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp +++ b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp @@ -29,17 +29,10 @@ std::unique_ptr<Generator> getHTMLGenerator() { ClangDocContext getClangDocContext(std::vector<std::string> UserStylesheets = {}, StringRef RepositoryUrl = "", - StringRef RepositoryLinePrefix = "", - StringRef Base = "") { - ClangDocContext CDCtx{{}, - "test-project", - {}, - {}, - {}, - RepositoryUrl, - RepositoryLinePrefix, - Base, - UserStylesheets}; + StringRef RepositoryLinePrefix = "", StringRef Base = "") { + ClangDocContext CDCtx{ + {}, "test-project", {}, {}, {}, RepositoryUrl, RepositoryLinePrefix, + Base, UserStylesheets}; CDCtx.UserStylesheets.insert( CDCtx.UserStylesheets.begin(), "../share/clang/clang-doc-default-stylesheet.css"); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits