Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Docs.undocumented_names #52413

Merged
merged 17 commits into from
Dec 31, 2023
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ New library features
write the output to a stream rather than returning a string ([#48625]).
* `sizehint!(s, n)` now supports an optional `shrink` argument to disable shrinking ([#51929]).
* New function `Docs.hasdoc(module, symbol)` tells whether a name has a docstring ([#52139]).
* New function `Docs.undocumented_names(module; all)` returns a module's undocumented names ([#52413]).
* Passing an IOBuffer as a stdout argument for Process spawn now works as
expected, synchronized with `wait` or `success`, so a `Base.BufferStream` is
no longer required there for correctness to avoid data-races ([#TBD]).
Expand Down
15 changes: 15 additions & 0 deletions base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -675,4 +675,19 @@ function hasdoc(binding::Docs.Binding, sig::Type = Union{})
end


"""
undocumented_names(mod::Module; all=false)
jariji marked this conversation as resolved.
Show resolved Hide resolved

Return an array of undocumented symbols in `module` (that is, lacking docstrings).
`all=false` returns only exported symbols; whereas `all=true` also includes
non-exported symbols, following the behavior of [`names`](@ref).
jariji marked this conversation as resolved.
Show resolved Hide resolved

See also: [`names`](@ref), [`Docs.hasdoc`](@ref).
"""
function undocumented_names(mod::Module; all::Bool=false, identifiers::Bool=true)
filter!(names(mod; all)) do sym
!hasdoc(mod, sym) && (!identifiers || Base.isidentifier(sym))
end
end

end
3 changes: 2 additions & 1 deletion doc/src/manual/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ environments provide a way to access documentation directly:
under the cursor.


`Docs.hasdoc(module, name)::Bool` tells whether a name has a docstring.
`Docs.hasdoc(module, name)::Bool` tells whether a name has a docstring. `Docs.undocumented_names(module; all)`
returns the undocumented names in a module.
jariji marked this conversation as resolved.
Show resolved Hide resolved

## Writing Documentation

Expand Down
19 changes: 19 additions & 0 deletions test/docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,25 @@ function break_me_docs end
@test !isdefined(Base, :_this_name_doesnt_exist_) && !Docs.hasdoc(Base, :_this_name_doesnt_exist_)
@test isdefined(Base, :_typed_vcat) && !Docs.hasdoc(Base, :_typed_vcat)

"This module has names without documentation."
module _ModuleWithUndocumentedNames
export f
f() = 1
end

"This module has some documentation."
module _ModuleWithSomeDocumentedNames
export f
"f() is 1."
f() = 1
g() = 2
end

@test Docs.undocumented_names(_ModuleWithUndocumentedNames) == [:f]
@test isempty(Docs.undocumented_names(_ModuleWithSomeDocumentedNames))
@test Docs.undocumented_names(_ModuleWithSomeDocumentedNames; all=true) == [:g]
jariji marked this conversation as resolved.
Show resolved Hide resolved


# issue #11548

module ModuleMacroDoc
Expand Down