Skip to content

Commit

Permalink
Filter out more doc signature expressions
Browse files Browse the repository at this point in the history
Revise extracts the documented expression and puts that before the full
doc expression in the revision queue. E.g. in `"docs" f(x) = x` there
will be a revision of `f(x) = x` followed by a revision of the full
expresion (`"docs" f(x) = x`). However, in many cases a docstring is
only attached to a signature (not a function body/struct definition,
etc.) and in this case the revision of the signature is not needed.

Revise already filters out the base case, `"docs" f(x)`. This patch
extends this filtering to also apply to `where`-clauses such as e.g.
`"docs" f(x::T) where T <: Integer`.

Concretely, this patch fixes #735, i.e. revising doc expressions where
the signature doesn't lower without the context of the doc macro. As a
bonus, slightly less work has to be done for e.g. `"docs" f(x::T) where
T` since this is also filtered out.
  • Loading branch information
fredrikekre committed Nov 9, 2023
1 parent 6f71e52 commit bf687e7
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,20 @@ istrivial(a) = a === nothing || isa(a, LineNumberNode)

isgoto(stmt) = isa(stmt, Core.GotoNode) | isexpr(stmt, :gotoifnot)

function unwrap_where(ex::Expr)
while isexpr(ex, :where)
ex = ex.args[1]
end
return ex
end

function pushex!(exsigs::ExprsSigs, ex::Expr)
uex = unwrap(ex)
if is_doc_expr(uex)
body = uex.args[4]
if isa(body, Expr) && body.head !== :call # don't trigger for docexprs like `"docstr" f(x::Int)`
# Don't trigger for exprs where the documented expression is just a signature
# (e.g. `"docstr" f(x::Int)`, `"docstr" f(x::T) where T` etc.)
if isa(body, Expr) && unwrap_where(body).head !== :call
exsigs[RelocatableExpr(body)] = nothing
end
if length(uex.args) < 5
Expand Down
17 changes: 17 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,23 @@ const issue639report = []
pop!(LOAD_PATH)
end

do_test("doc expr signature") && @testset "Docstring attached to signatures" begin
md = Revise.ModuleExprsSigs(Main)
Revise.parse_source!(md, """
module DocstringSigsOnly
function f end
"basecase" f(x)
"basecase with type" f(x::Int)
"basecase no varname" f(::Float64)
"where" f(x::T) where T <: Int8
"where no varname" f(::T) where T <: String
end
""", "test2", Main)
# Simply test that the "bodies" of the doc exprs are not included as
# standalone expressions.
@test length(md[Main.DocstringSigsOnly]) == 6 # 1 func + 5 doc exprs
end

do_test("Undef in docstrings") && @testset "Undef in docstrings" begin
fn = Base.find_source_file("abstractset.jl") # has lots of examples of """str""" func1, func2
mexsold = Revise.parse_source(fn, Base)
Expand Down

0 comments on commit bf687e7

Please sign in to comment.