in lib/coverage.go [138:183]
func (c *Coverage) Details() []LineCoverage {
nodes := make(map[int][]int64)
for id := range c.decorator.all {
line := c.ast.NativeRep().SourceInfo().GetStartLocation(id).Line()
nodes[line] = append(nodes[line], id)
}
hits := make(map[int][]int64)
for id := range c.decorator.cov {
line := c.ast.NativeRep().SourceInfo().GetStartLocation(id).Line()
hits[line] = append(hits[line], id)
}
stats := make(map[int]float64)
var lines []int
for l := range nodes {
sort.Slice(nodes[l], func(i, j int) bool { return nodes[l][i] < nodes[l][j] })
sort.Slice(hits[l], func(i, j int) bool { return hits[l][i] < hits[l][j] })
stats[l] = float64(len(hits[l])) / float64(len(nodes[l]))
lines = append(lines, l)
}
sort.Ints(lines)
cov := make([]LineCoverage, 0, len(lines))
src := c.ast.Source()
for _, l := range lines {
var missed []int64
i, j := 0, 0
for i < len(nodes[l]) && j < len(hits[l]) {
if nodes[l][i] == hits[l][j] {
i++
j++
continue
}
missed = append(missed, nodes[l][i])
i++
}
missed = append(missed, nodes[l][i:]...)
cov = append(cov, LineCoverage{
Line: l,
Coverage: stats[l],
Nodes: nodes[l],
Covered: hits[l],
Missed: missed,
Annotation: srcAnnot(c.ast, src, missed, "!"),
})
}
return cov
}