xref: /aosp_15_r20/external/pytorch/tools/code_coverage/package/tool/parser/gcov_coverage_parser.py (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1from __future__ import annotations
2
3from typing import Any
4
5from .coverage_record import CoverageRecord
6
7
8class GcovCoverageParser:
9    """
10    Accepts a parsed json produced by gcov --json-format -- typically,
11    representing a single C++ test and produces a list
12    of CoverageRecord(s).
13    """
14
15    def __init__(self, llvm_coverage: dict[str, Any]) -> None:
16        self._llvm_coverage = llvm_coverage
17
18    @staticmethod
19    def _skip_coverage(path: str) -> bool:
20        """
21        Returns True if file path should not be processed.
22        This is repo-specific and only makes sense for the current state of
23        ovrsource.
24        """
25        return "third-party" in path
26
27    def parse(self) -> list[CoverageRecord]:
28        # The JSON format is described in the gcov source code
29        # https://gcc.gnu.org/onlinedocs/gcc/Invoking-Gcov.html
30        records: list[CoverageRecord] = []
31        for file_info in self._llvm_coverage["files"]:
32            filepath = file_info["file"]
33            if self._skip_coverage(filepath):
34                continue
35            # parse json file
36            covered_lines: set[int] = set()
37            uncovered_lines: set[int] = set()
38            for line in file_info["lines"]:
39                line_number = line["line_number"]
40                count = line["count"]
41                if count == 0:
42                    uncovered_lines.update([line_number])
43                else:
44                    covered_lines.update([line_number])
45
46            records.append(
47                CoverageRecord(filepath, sorted(covered_lines), sorted(uncovered_lines))
48            )
49
50        return records
51