diff options
| author | Taras Madan <tarasmadan@google.com> | 2024-03-15 11:13:29 +0100 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2024-03-19 11:15:33 +0000 |
| commit | e104824c06ba54122c1d17b5b26dd21c57e427b6 (patch) | |
| tree | 3ee1c9f7210e8fc7d5afa2a9eb9b2fadb07bb76b /pkg/cover/html.go | |
| parent | 41ee133f71cd3d24faeac9b158c749637acb8e8d (diff) | |
pkg/cover: export the frames data as jsonl
jsonl is new-line-new-json format.
It is good for streaming because you can read data line-by-line.
This pipeline will stream a lot eventually (x00 megabytes).
Diffstat (limited to 'pkg/cover/html.go')
| -rw-r--r-- | pkg/cover/html.go | 85 |
1 files changed, 34 insertions, 51 deletions
diff --git a/pkg/cover/html.go b/pkg/cover/html.go index e25c9fbf3..1411bdf62 100644 --- a/pkg/cover/html.go +++ b/pkg/cover/html.go @@ -211,67 +211,50 @@ func (rg *ReportGenerator) DoRawCoverFiles(w io.Writer, params CoverHandlerParam return nil } -type covCallbacksStat struct { - TotalCount int `json:"total_cb_count"` - CoveredCount int `json:"covered_cb_count"` -} - -type covFuncDetails struct { - covCallbacksStat -} - -type covFileDetails struct { - covCallbacksStat - Functions map[string]*covFuncDetails `json:"functions,omitempty"` -} - type coverageInfo struct { - Version int `json:"version"` - covCallbacksStat - Files map[string]*covFileDetails `json:"files,omitempty"` -} - -type visitFuncCb func(filePath, funcName string, funcObj *function) - -func forEachFunction(fm fileMap, cb visitFuncCb) { - for filePath, fileObj := range fm { - for _, funcObj := range fileObj.functions { - cb(filePath, funcObj.name, funcObj) - } - } + Version int `json:"version"` + FilePath string `json:"file_path"` + FuncName string `json:"func_name"` + StartLine int `json:"sl"` + StartCol int `json:"sc"` + EndLine int `json:"el"` + EndCol int `json:"ec"` + HitCount int `json:"hit_count"` + Inline bool `json:"inline"` + PC uint64 `json:"pc"` } -// DoCoverJSON is a handler for "/cover&json=1". -func (rg *ReportGenerator) DoCoverJSON(w io.Writer, params CoverHandlerParams) error { +// DoCoverJSONL is a handler for "/cover?jsonl=1". +func (rg *ReportGenerator) DoCoverJSONL(w io.Writer, params CoverHandlerParams) error { var progs = fixUpPCs(rg.target.Arch, params.Progs, params.CoverFilter) fm, err := rg.prepareFileMap(progs, params.Debug) if err != nil { return fmt.Errorf("failed to rg.prepareFileMap(): %w", err) } - c := &coverageInfo{ - Version: 1, - Files: make(map[string]*covFileDetails), - } - forEachFunction(fm, func(filePath, funcName string, funcObj *function) { - if _, ok := c.Files[filePath]; !ok { - c.Files[filePath] = &covFileDetails{ - Functions: make(map[string]*covFuncDetails), - } + + encoder := json.NewEncoder(w) + for _, frame := range rg.Frames { + endCol := frame.Range.EndCol + if endCol == backend.LineEnd { + endCol = -1 } - c.TotalCount += funcObj.pcs - c.CoveredCount += funcObj.covered - fileCbStat := c.Files[filePath] - fileCbStat.TotalCount += funcObj.pcs - fileCbStat.CoveredCount += funcObj.covered - fileCbStat.Functions[funcName] = &covFuncDetails{ - covCallbacksStat: covCallbacksStat{ - TotalCount: funcObj.pcs, - CoveredCount: funcObj.covered, - }, + pcProgCount := FileByFrame(fm, &frame).lines[frame.StartLine].pcProgCount + hitCount := pcProgCount[frame.PC] + covInfo := &coverageInfo{ + Version: 1, + FilePath: frame.Name, + FuncName: frame.FuncName, + StartLine: frame.Range.StartLine, + StartCol: frame.Range.StartCol, + EndLine: frame.Range.EndLine, + EndCol: endCol, + HitCount: hitCount, + Inline: frame.Inline, + PC: frame.PC, + } + if err = encoder.Encode(covInfo); err != nil { + return fmt.Errorf("failed to json.Encode(): %w", err) } - }) - if err = json.NewEncoder(w).Encode(c); err != nil { - return fmt.Errorf("failed to json.Encode(): %w", err) } return nil } |
