@@ -10,16 +10,19 @@ isfuncexpr(ex::Expr) =
1010 ex. head == :function || (ex. head == :(= ) && typeof (ex. args[1 ]) == Expr && ex. args[1 ]. head == :call )
1111isfuncexpr (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
2123end
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