Skip to content

Commit

Permalink
Improve coverage heuristic in function_body_lines
Browse files Browse the repository at this point in the history
TODO: describe what's going on
  • Loading branch information
fingolfin committed Mar 7, 2019
1 parent 6c31888 commit 8a105a7
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/Coverage.jl
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ module Coverage
linestart = minimum(searchsorted(linepos, pos - 1))
ast, pos = Meta.parse(content, pos)
isa(ast, Expr) || continue
flines = function_body_lines(ast)
flines = function_body_lines(ast, coverage, linestart - 1)
if !isempty(flines)
flines .+= linestart-1
for l in flines
Expand Down
28 changes: 22 additions & 6 deletions src/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ isfuncexpr(ex::Expr) =
ex.head == :function || (ex.head == :(=) && typeof(ex.args[1]) == Expr && ex.args[1].head == :call)
isfuncexpr(arg) = false

function_body_lines(ast) = function_body_lines!(Int[], ast, false)
function_body_lines!(flines, arg, infunction) = flines
function function_body_lines!(flines, node::LineNumberNode, infunction)
function_body_lines(ast, coverage, lineoffset) = function_body_lines!(Int[], ast, coverage, lineoffset, false)

function_body_lines!(flines, arg, coverage, lineoffset, infunction) = flines

function function_body_lines!(flines, node::LineNumberNode, coverage, lineoffset, infunction)
line = node.line
if infunction
push!(flines, line)
end
flines
end
function function_body_lines!(flines, ast::Expr, infunction)

function function_body_lines!(flines, ast::Expr, coverage::Vector{CovCount}, lineoffset, infunction)
if ast.head == :line
line = ast.args[1]
if infunction
Expand Down Expand Up @@ -50,12 +53,25 @@ function function_body_lines!(flines, ast::Expr, infunction)
# and we don't want those lines to be identified as runnable code.
# In this context, ast.args[1] is the function signature and
# ast.args[2] is the method body
#
# now compute all lines in the body of this function, but for now,
# track them separately from flines
flines_new = Int[]
for arg in ast.args[2].args
flines = function_body_lines!(flines, arg, true)
function_body_lines!(flines_new, arg, coverage, lineoffset, true)
end

# if any of the lines in the body of the function already has
# coverage, we assume that the function was executed, generally
# speaking, and so we should *not* apply our heuristic (which is mean
# to mark functions which were never executed as code, which the
# coverage data returned by Julia normally does not)
if all(l -> coverage[l+lineoffset] === nothing, flines_new)
append!(flines, flines_new)
end
else
for arg in args
flines = function_body_lines!(flines, arg, infunction)
function_body_lines!(flines, arg, coverage, lineoffset, infunction)
end
end

Expand Down

0 comments on commit 8a105a7

Please sign in to comment.