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