1from __future__ import annotations 2 3from typing import Any 4 5from .coverage_record import CoverageRecord 6from .llvm_coverage_segment import LlvmCoverageSegment, parse_segments 7 8 9class LlvmCoverageParser: 10 """ 11 Accepts a parsed json produced by llvm-cov export -- typically, 12 representing a single C++ test and produces a list 13 of CoverageRecord(s). 14 15 """ 16 17 def __init__(self, llvm_coverage: dict[str, Any]) -> None: 18 self._llvm_coverage = llvm_coverage 19 20 @staticmethod 21 def _skip_coverage(path: str) -> bool: 22 """ 23 Returns True if file path should not be processed. 24 This is repo-specific and only makes sense for the current state of 25 ovrsource. 26 """ 27 return "/third-party/" in path 28 29 @staticmethod 30 def _collect_coverage( 31 segments: list[LlvmCoverageSegment], 32 ) -> tuple[list[int], list[int]]: 33 """ 34 Stateful parsing of coverage segments. 35 """ 36 covered_lines: set[int] = set() 37 uncovered_lines: set[int] = set() 38 prev_segment = LlvmCoverageSegment(1, 0, 0, 0, 0, None) 39 for segment in segments: 40 covered_range, uncovered_range = segment.get_coverage(prev_segment) 41 covered_lines.update(covered_range) 42 uncovered_lines.update(uncovered_range) 43 prev_segment = segment 44 45 uncovered_lines.difference_update(covered_lines) 46 return sorted(covered_lines), sorted(uncovered_lines) 47 48 def parse(self, repo_name: str) -> list[CoverageRecord]: 49 # The JSON format is described in the LLVM source code 50 # https://github.com/llvm-mirror/llvm/blob/master/tools/llvm-cov/CoverageExporterJson.cpp 51 records: list[CoverageRecord] = [] 52 for export_unit in self._llvm_coverage["data"]: 53 for file_info in export_unit["files"]: 54 filepath = file_info["filename"] 55 if self._skip_coverage(filepath): 56 continue 57 58 if filepath is None: 59 continue 60 61 segments = file_info["segments"] 62 63 covered_lines, uncovered_lines = self._collect_coverage( 64 parse_segments(segments) 65 ) 66 67 records.append(CoverageRecord(filepath, covered_lines, uncovered_lines)) 68 69 return records 70