Skip to content

Commit

Permalink
Fix documenting baremodules
Browse files Browse the repository at this point in the history
Prior to this fix attempting to document baremodules results in an infinite
error message plus segfault when trying to escape:

    julia> "..." baremodule M end

This fix imports `call` and `@doc` into the module automatically.

Also makes documenting empty baremodules an error since that was also
causing segfaults. That limitation won't impact any real-world code though.

Tests and documentation updates as well.

(cherry picked from commit 8edd917)
ref #13067
  • Loading branch information
MichaelHatherly authored and tkelman committed Sep 11, 2015
1 parent 9d50446 commit b23b11a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 4 deletions.
17 changes: 13 additions & 4 deletions base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ isdoc(x) = isexpr(x, :string, AbstractString) ||
(isexpr(x, :macrocall) && x.args[1] == symbol("@doc_str")) ||
(isexpr(x, :call) && x.args[1] == Expr(:., Base.Markdown, QuoteNode(:doc_str)))

dict_expr(d) = :(Dict($([:($(Expr(:quote, f)) => $d) for (f, d) in d]...)))
dict_expr(d) = :(Dict($([:(Pair($(Expr(:quote, f)), $d)) for (f, d) in d]...)))

function field_meta(def)
meta = Dict()
Expand Down Expand Up @@ -465,9 +465,18 @@ end

function moddoc(meta, def, name)
docex = :(@doc $meta $name)
def == nothing && return :(eval($name, $(quot(docex)))) |> esc
push!(unblock(def).args[3].args, docex)
return esc(Expr(:toplevel, def))
if def == nothing
esc(:(eval($name, $(quot(docex)))))
else
def = unblock(def)
block = def.args[3].args
if !def.args[1]
isempty(block) && error("empty baremodules are not documentable.")
insert!(block, 2, :(import Base: call, @doc))
end
push!(block, docex)
esc(Expr(:toplevel, def))
end
end

function objdoc(meta, def)
Expand Down
20 changes: 20 additions & 0 deletions doc/manual/documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,26 @@ Modules
Adds docstring ``"..."`` to the ``Module`` ``M``. Adding the docstring above the ``Module``
is the preferred syntax, however both are equivalent.

.. code-block:: julia
"..."
baremodule M
# ...
end
baremodule M
import Base: call, @doc
"..."
f(x) = x
end
Documenting a ``baremodule`` by placing a docstring above the expression automatically
imports ``call`` and ``@doc`` into the module. These imports must be done manually when the
module expression is not documented. Empty ``baremodule``\ s cannot be documented.

Global Variables
~~~~~~~~~~~~~~~~

Expand Down
39 changes: 39 additions & 0 deletions test/docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,45 @@ let fields = meta(DocsTest)[DocsTest.FieldDocs].fields
@test haskey(fields, :two) && fields[:two] == doc"two"
end

"BareModule"
baremodule BareModule

"f/1"
f(x) = x

"g/1"
function g(x) end

"h"
function h end

"@m"
macro m() end

"C"
const C = 1

"A"
abstract A

"T"
type T
"x"
x
"y"
y
end

end

@test docstrings_equal(@doc(BareModule), doc"BareModule")
@test docstrings_equal(@doc(BareModule.f), doc"f/1")
@test docstrings_equal(@doc(BareModule.g), doc"g/1")
@test docstrings_equal(@doc(BareModule.@m), doc"@m")
@test docstrings_equal(@doc(BareModule.C), doc"C")
@test docstrings_equal(@doc(BareModule.A), doc"A")
@test docstrings_equal(@doc(BareModule.T), doc"T")

# test that when no docs exist, they fallback to
# the docs for the typeof(value)
let d1 = @doc(DocsTest.val)
Expand Down

0 comments on commit b23b11a

Please sign in to comment.