Skip to content

Commit f06e6fe

Browse files
committed
Improve coverage heuristic in function_body_lines
TODO: describe what's going on
1 parent 6c31888 commit f06e6fe

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

src/Coverage.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ module Coverage
175175
linestart = minimum(searchsorted(linepos, pos - 1))
176176
ast, pos = Meta.parse(content, pos)
177177
isa(ast, Expr) || continue
178-
flines = function_body_lines(ast)
178+
flines = function_body_lines(ast, coverage, linestart - 1)
179179
if !isempty(flines)
180180
flines .+= linestart-1
181181
for l in flines

src/parser.jl

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,19 @@ isfuncexpr(ex::Expr) =
1010
ex.head == :function || (ex.head == :(=) && typeof(ex.args[1]) == Expr && ex.args[1].head == :call)
1111
isfuncexpr(arg) = false
1212

13-
function_body_lines(ast) = function_body_lines!(Int[], ast, false)
14-
function_body_lines!(flines, arg, infunction) = flines
15-
function function_body_lines!(flines, node::LineNumberNode, infunction)
13+
function_body_lines(ast, coverage, lineoffset) = function_body_lines!(Int[], ast, coverage, lineoffset, false)
14+
15+
function_body_lines!(flines, arg, coverage, lineoffset, infunction) = flines
16+
17+
function function_body_lines!(flines, node::LineNumberNode, coverage, lineoffset, infunction)
1618
line = node.line
1719
if infunction
1820
push!(flines, line)
1921
end
2022
flines
2123
end
22-
function function_body_lines!(flines, ast::Expr, infunction)
24+
25+
function function_body_lines!(flines, ast::Expr, coverage::Vector{CovCount}, lineoffset, infunction)
2326
if ast.head == :line
2427
line = ast.args[1]
2528
if infunction
@@ -50,12 +53,20 @@ function function_body_lines!(flines, ast::Expr, infunction)
5053
# and we don't want those lines to be identified as runnable code.
5154
# In this context, ast.args[1] is the function signature and
5255
# ast.args[2] is the method body
53-
for arg in ast.args[2].args
54-
flines = function_body_lines!(flines, arg, true)
56+
args = ast.args[2].args
57+
infunction = true
58+
flines_new = Int[]
59+
for arg in args
60+
function_body_lines!(flines_new, arg, coverage, lineoffset, infunction)
61+
end
62+
# if any of the lines in flines_new already has coverage, we should
63+
# *not* apply our heuristic
64+
if all(l -> coverage[l+lineoffset] === nothing, flines_new)
65+
append!(flines, flines_new)
5566
end
5667
else
5768
for arg in args
58-
flines = function_body_lines!(flines, arg, infunction)
69+
function_body_lines!(flines, arg, coverage, lineoffset, infunction)
5970
end
6071
end
6172

0 commit comments

Comments
 (0)