[llvm] [llvm-cov] format cells in code coverage report with 0/0 branches/functions/lines differently (PR #75780)
Hana Dusíková via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 19 01:21:23 PST 2023
https://github.com/hanickadot updated https://github.com/llvm/llvm-project/pull/75780
>From 7a75dc696bd4de9ce8ff636a7a50fd6c035d13f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= <hanicka at hanicka.net>
Date: Mon, 18 Dec 2023 11:11:15 +0100
Subject: [PATCH 1/2] [llvm-cov] format cells in report with 0/0
branches/functions/lines differenly (gray instead red) and make the table a
bit nicer
---
.../tools/llvm-cov/coverage_watermark.test | 20 +++++++++++++++-
.../tools/llvm-cov/SourceCoverageViewHTML.cpp | 24 +++++++++++++++----
2 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/llvm/test/tools/llvm-cov/coverage_watermark.test b/llvm/test/tools/llvm-cov/coverage_watermark.test
index 1c0408dd0078c9..5c48b4f0fb4bf4 100644
--- a/llvm/test/tools/llvm-cov/coverage_watermark.test
+++ b/llvm/test/tools/llvm-cov/coverage_watermark.test
@@ -13,29 +13,47 @@ INVALID-ARRANGE: error: -coverage-watermark: invalid number range '10,20', must
RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -format html -show-region-summary -show-instantiation-summary -o %t.html.dir -path-equivalence=/tmp,%S %S/showTemplateInstantiations.cpp
RUN: FileCheck -check-prefix=ORIGIN %s -input-file %t.html.dir/index.html
+ORIGIN: Totals
+ORIGIN: <td class='column-entry-green'>
+ORIGIN: 100.00% (2/2)
ORIGIN: <td class='column-entry-green'>
ORIGIN: 100.00% (3/3)
ORIGIN: <td class='column-entry-red'>
ORIGIN: 75.00% (9/12)
ORIGIN: <td class='column-entry-red'>
ORIGIN: 66.67% (4/6)
+ORIGIN: <td class='column-entry-gray'>
+ORIGIN: - (0/0)
+ORIGIN: </tr>
-RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -format html -show-region-summary -show-instantiation-summary -o %t.html.dir -path-equivalence=/tmp,%S -coverage-watermark 80,60 %S/showTemplateInstantiations.cpp
+RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -format html -show-region-summary -show-instantiation-summary -o %t.html.dir -path-equivalence=/tmp,%S -coverage-watermark 80,70 %S/showTemplateInstantiations.cpp
RUN: FileCheck -check-prefix=DOWNGRADE1 %s -input-file %t.html.dir/index.html
+DOWNGRADE:1 Totals
+DOWNGRADE1: <td class='column-entry-green'>
+DOWNGRADE1: 100.00% (2/2)
DOWNGRADE1: <td class='column-entry-green'>
DOWNGRADE1: 100.00% (3/3)
DOWNGRADE1: <td class='column-entry-yellow'>
DOWNGRADE1: 75.00% (9/12)
DOWNGRADE1: <td class='column-entry-red'>
DOWNGRADE1: 66.67% (4/6)
+DOWNGRADE1: <td class='column-entry-gray'>
+DOWNGRADE1: - (0/0)
+DOWNGRADE1: </tr>
RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -format html -show-region-summary -show-instantiation-summary -o %t.html.dir -path-equivalence=/tmp,%S -coverage-watermark 70,50 %S/showTemplateInstantiations.cpp
RUN: FileCheck -check-prefix=DOWNGRADE2 %s -input-file %t.html.dir/index.html
+DOWNGRADE:1 Totals
+DOWNGRADE2: <td class='column-entry-green'>
+DOWNGRADE2: 100.00% (2/2)
DOWNGRADE2: <td class='column-entry-green'>
DOWNGRADE2: 100.00% (3/3)
DOWNGRADE2: <td class='column-entry-green'>
DOWNGRADE2: 75.00% (9/12)
DOWNGRADE2: <td class='column-entry-yellow'>
DOWNGRADE2: 66.67% (4/6)
+DOWNGRADE1: <td class='column-entry-gray'>
+DOWNGRADE1: - (0/0)
+DOWNGRADE1: </tr>
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index b43e9e64231e0c..e1aa5e4a05af78 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -130,10 +130,14 @@ table {
.light-row {
background: #ffffff;
border: 1px solid #dbdbdb;
+ border-left: none;
+ border-right: none;
}
.light-row-bold {
background: #ffffff;
border: 1px solid #dbdbdb;
+ border-left: none;
+ border-right: none;
font-weight: bold;
}
.column-entry {
@@ -147,21 +151,28 @@ table {
text-align: left;
background-color: #ffffd0;
}
-.column-entry-yellow:hover {
+.column-entry-yellow:hover, tr:hover .column-entry-yellow {
background-color: #fffff0;
}
.column-entry-red {
text-align: left;
background-color: #ffd0d0;
}
-.column-entry-red:hover {
+.column-entry-red:hover, tr:hover .column-entry-red {
background-color: #fff0f0;
}
+.column-entry-gray {
+ text-align: left;
+ background-color: #fbfbfb;
+}
+.column-entry-gray:hover, tr:hover .column-entry-gray {
+ background-color: #f0f0f0;
+}
.column-entry-green {
text-align: left;
background-color: #d0ffd0;
}
-.column-entry-green:hover {
+.column-entry-green:hover, tr:hover .column-entry-green {
background-color: #f0fff0;
}
.line-number {
@@ -232,6 +243,9 @@ td:last-child {
tr:hover {
background-color: #f0f0f0;
}
+tr:last-child {
+ border-bottom: none;
+}
)";
const char *EndHeader = "</head>";
@@ -309,7 +323,9 @@ void emitTableRow(raw_ostream &OS, const CoverageViewOptions &Opts,
RSO << '(' << Hit << '/' << Total << ')';
}
const char *CellClass = "column-entry-yellow";
- if (Pctg >= Opts.HighCovWatermark)
+ if (!Total) {
+ CellClass = "column-entry-gray";
+ } else if (Pctg >= Opts.HighCovWatermark)
CellClass = "column-entry-green";
else if (Pctg < Opts.LowCovWatermark)
CellClass = "column-entry-red";
>From 67c537c168bba30b66d29b64381e6fad65c8d76c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= <hanicka at hanicka.net>
Date: Tue, 19 Dec 2023 10:21:04 +0100
Subject: [PATCH 2/2] [llvm-cov] add sorting of code-coverage table by clicking
on header
---
.../test/tools/llvm-cov/branch-c-general.test | 10 +--
.../llvm-cov/hideUnexecutedSubviews.test | 10 +--
.../tools/llvm-cov/mcdc-general-none.test | 12 +--
llvm/test/tools/llvm-cov/mcdc-general.test | 12 +--
.../llvm-cov/showLineExecutionCounts.cpp | 8 +-
.../tools/llvm-cov/SourceCoverageViewHTML.cpp | 74 +++++++++++++++++--
6 files changed, 92 insertions(+), 34 deletions(-)
diff --git a/llvm/test/tools/llvm-cov/branch-c-general.test b/llvm/test/tools/llvm-cov/branch-c-general.test
index 9b5889babde366..0ec67eb1a6cfea 100644
--- a/llvm/test/tools/llvm-cov/branch-c-general.test
+++ b/llvm/test/tools/llvm-cov/branch-c-general.test
@@ -148,11 +148,11 @@
// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s
// HTML-INDEX-LABEL: <table>
-// HTML-INDEX: <td class='column-entry-bold'>Filename</td>
-// HTML-INDEX: <td class='column-entry-bold'>Function Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Line Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Region Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Branch Coverage</td>
+// HTML-INDEX: <th class='column-entry-bold'>Filename</th>
+// HTML-INDEX: <th class='column-entry-bold'>Function Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Line Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Region Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Branch Coverage</th>
// HTML-INDEX: <a href='coverage{{.*}}branch-c-general.c.html'{{.*}}branch-c-general.c</a>
// HTML-INDEX: <td class='column-entry-green'>
// HTML-INDEX: 100.00% (12/12)
diff --git a/llvm/test/tools/llvm-cov/hideUnexecutedSubviews.test b/llvm/test/tools/llvm-cov/hideUnexecutedSubviews.test
index b3fc1e63bcdee6..16859d550b6f8a 100644
--- a/llvm/test/tools/llvm-cov/hideUnexecutedSubviews.test
+++ b/llvm/test/tools/llvm-cov/hideUnexecutedSubviews.test
@@ -11,11 +11,11 @@ FILE-NOT: Unexecuted instantiation
RUN: FileCheck -check-prefix=INDEX %s -input-file %t.html.dir/index.html
-INDEX: <td class='column-entry-bold'>Filename</td>
-INDEX: <td class='column-entry-bold'>Function Coverage</td>
-INDEX: <td class='column-entry-bold'>Instantiation Coverage</td>
-INDEX: <td class='column-entry-bold'>Line Coverage</td>
-INDEX: <td class='column-entry-bold'>Region Coverage</td>
+INDEX: <th class='column-entry-bold'>Filename</th>
+INDEX: <th class='column-entry-bold'>Function Coverage</th>
+INDEX: <th class='column-entry-bold'>Instantiation Coverage</th>
+INDEX: <th class='column-entry-bold'>Line Coverage</th>
+INDEX: <th class='column-entry-bold'>Region Coverage</th>
INDEX: <td class='column-entry-red'>
INDEX: 50.00% (1/2)
INDEX: <td class='column-entry-red'>
diff --git a/llvm/test/tools/llvm-cov/mcdc-general-none.test b/llvm/test/tools/llvm-cov/mcdc-general-none.test
index bcf8f3cbd05d45..91ca7a252193c6 100644
--- a/llvm/test/tools/llvm-cov/mcdc-general-none.test
+++ b/llvm/test/tools/llvm-cov/mcdc-general-none.test
@@ -56,12 +56,12 @@
// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s
// HTML-INDEX-LABEL: <table>
-// HTML-INDEX: <td class='column-entry-bold'>Filename</td>
-// HTML-INDEX: <td class='column-entry-bold'>Function Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Line Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Region Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Branch Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>MC/DC</td>
+// HTML-INDEX: <th class='column-entry-bold'>Filename</th>
+// HTML-INDEX: <th class='column-entry-bold'>Function Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Line Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Region Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Branch Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>MC/DC</th>
// HTML-INDEX: <a href='coverage{{.*}}mcdc-general.cpp.html'{{.*}}mcdc-general.cpp</a>
// HTML-INDEX: <td class='column-entry-green'>
// HTML-INDEX: 100.00% (2/2)
diff --git a/llvm/test/tools/llvm-cov/mcdc-general.test b/llvm/test/tools/llvm-cov/mcdc-general.test
index 588aed09c16a5e..0ec38617dfbdd1 100644
--- a/llvm/test/tools/llvm-cov/mcdc-general.test
+++ b/llvm/test/tools/llvm-cov/mcdc-general.test
@@ -122,12 +122,12 @@
// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s
// HTML-INDEX-LABEL: <table>
-// HTML-INDEX: <td class='column-entry-bold'>Filename</td>
-// HTML-INDEX: <td class='column-entry-bold'>Function Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Line Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Region Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Branch Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>MC/DC</td>
+// HTML-INDEX: <th class='column-entry-bold'>Filename</th>
+// HTML-INDEX: <th class='column-entry-bold'>Function Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Line Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Region Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Branch Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>MC/DC</th>
// HTML-INDEX: <a href='coverage{{.*}}mcdc-general.cpp.html'{{.*}}mcdc-general.cpp</a>
// HTML-INDEX: <td class='column-entry-green'>
// HTML-INDEX: 100.00% (2/2)
diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
index 51ac3ae1deee55..a42928102c8560 100644
--- a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
+++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
@@ -58,10 +58,10 @@ int main() { // TEXT: [[@LINE]]| 161|int main(
//
// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s
// HTML-INDEX-LABEL: <table>
-// HTML-INDEX: <td class='column-entry-bold'>Filename</td>
-// HTML-INDEX: <td class='column-entry-bold'>Function Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Line Coverage</td>
-// HTML-INDEX: <td class='column-entry-bold'>Region Coverage</td>
+// HTML-INDEX: <th class='column-entry-bold'>Filename</th>
+// HTML-INDEX: <th class='column-entry-bold'>Function Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Line Coverage</th>
+// HTML-INDEX: <th class='column-entry-bold'>Region Coverage</th>
// HTML-INDEX: <a href='coverage{{.*}}showLineExecutionCounts.cpp.html'{{.*}}showLineExecutionCounts.cpp</a>
// HTML-INDEX: <td class='column-entry-green'>
// HTML-INDEX: 100.00% (1/1)
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index e1aa5e4a05af78..82a1809a00139d 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -231,6 +231,9 @@ th, td {
border-left: solid 1px #eee;
text-align: left;
}
+th {
+ cursor: pointer;
+}
td pre {
display: inline-block;
}
@@ -248,6 +251,42 @@ tr:last-child {
}
)";
+const char *scriptForSorting = R"js(
+ <script>
+ const getCellValue = (tr, index) => {
+ const content = tr.children[index].innerText || tr.children[index].textContent;
+
+ if (content == "- (0/0)") {
+ return Infinity;
+ }
+
+ return content;
+ };
+
+ const comparator = (index, asc) => (a, b) => {
+ if (asc) {
+ [a, b] = [b, a];
+ }
+
+ const v1 = getCellValue(a, index);
+ const v2 = getCellValue(b, index);
+
+ if (v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v1)) {
+ return v1 - v2;
+ }
+
+ return v1.toString().localeCompare(v2);
+ };
+
+ document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => {
+ const tbody = th.closest('table').querySelector('tbody');
+ Array.from(tbody.querySelectorAll('tr'))
+ .sort(comparator(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
+ .forEach(tr => tbody.appendChild(tr));
+ })));
+ </script>
+)js";
+
const char *EndHeader = "</head>";
const char *BeginCenteredDiv = "<div class='centered'>";
@@ -270,6 +309,14 @@ const char *BeginExpansionDiv = "<div class='expansion-view'>";
const char *EndExpansionDiv = "</div>";
+const char *BeginTableBody = "<tbody>";
+
+const char *EndTableBody = "</tbody>";
+
+const char *BeginTableFoot = "<tfoot>";
+
+const char *EndTableFoot = "</tfoot>";
+
const char *BeginTable = "<table>";
const char *EndTable = "</table>";
@@ -395,19 +442,19 @@ void CoveragePrinterHTML::closeViewFile(OwnedStream OS) {
static void emitColumnLabelsForIndex(raw_ostream &OS,
const CoverageViewOptions &Opts) {
SmallVector<std::string, 4> Columns;
- Columns.emplace_back(tag("td", "Filename", "column-entry-bold"));
- Columns.emplace_back(tag("td", "Function Coverage", "column-entry-bold"));
+ Columns.emplace_back(tag("th", "Filename", "column-entry-bold"));
+ Columns.emplace_back(tag("th", "Function Coverage", "column-entry-bold"));
if (Opts.ShowInstantiationSummary)
Columns.emplace_back(
- tag("td", "Instantiation Coverage", "column-entry-bold"));
- Columns.emplace_back(tag("td", "Line Coverage", "column-entry-bold"));
+ tag("th", "Instantiation Coverage", "column-entry-bold"));
+ Columns.emplace_back(tag("th", "Line Coverage", "column-entry-bold"));
if (Opts.ShowRegionSummary)
- Columns.emplace_back(tag("td", "Region Coverage", "column-entry-bold"));
+ Columns.emplace_back(tag("th", "Region Coverage", "column-entry-bold"));
if (Opts.ShowBranchSummary)
- Columns.emplace_back(tag("td", "Branch Coverage", "column-entry-bold"));
+ Columns.emplace_back(tag("th", "Branch Coverage", "column-entry-bold"));
if (Opts.ShowMCDCSummary)
- Columns.emplace_back(tag("td", "MC/DC", "column-entry-bold"));
- OS << tag("tr", join(Columns.begin(), Columns.end(), ""));
+ Columns.emplace_back(tag("th", "MC/DC", "column-entry-bold"));
+ OS << tag("thead", tag("tr", join(Columns.begin(), Columns.end(), "")));
}
std::string
@@ -490,6 +537,7 @@ Error CoveragePrinterHTML::createIndexFile(
emitReportHeader(OSRef, "Coverage Report");
+ OSRef << BeginTableBody;
FileCoverageSummary Totals("TOTALS");
auto FileReports = CoverageReport::prepareFileReports(
Coverage, Totals, SourceFiles, Opts, Filters);
@@ -500,7 +548,11 @@ Error CoveragePrinterHTML::createIndexFile(
else
EmptyFiles = true;
}
+ OSRef << EndTableBody;
+
+ OSRef << BeginTableFoot;
emitFileSummary(OSRef, "Totals", Totals, /*IsTotals=*/true);
+ OSRef << EndTableFoot;
OSRef << EndTable << EndCenteredDiv;
// Emit links to files which don't contain any functions. These are normally
@@ -518,6 +570,8 @@ Error CoveragePrinterHTML::createIndexFile(
}
OSRef << EndTable << EndCenteredDiv;
}
+
+ OSRef << scriptForSorting;
OSRef << tag("h5", escape(Opts.getLLVMVersionString(), Opts));
emitEpilog(OSRef);
@@ -559,6 +613,7 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport {
std::vector<const FileCoverageSummary *> EmptyFiles;
+ OSRef << BeginTableBody;
// Make directories at the top of the table.
for (auto &&SubDir : SubDirs) {
auto &Report = SubDir.second.first;
@@ -577,9 +632,12 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport {
emitTableRow(OSRef, Options, buildRelLinkToFile(Report.Name), Report,
/*IsTotals=*/false);
}
+ OSRef << EndTableBody;
// Emit the totals row.
+ OSRef << BeginTableFoot;
emitTableRow(OSRef, Options, "Totals", SubTotals, /*IsTotals=*/false);
+ OSRef << EndTableFoot;
OSRef << EndTable << EndCenteredDiv;
// Emit links to files which don't contain any functions. These are normally
More information about the llvm-commits
mailing list