Skip to content

Commit 1b183b9

Browse files
jarijistevengj
andauthored
Add Docs.undocumented_names (#52413)
Fixes #51174 --------- Co-authored-by: Steven G. Johnson <stevenj@alum.mit.edu> Co-authored-by: Steven G. Johnson <stevenj@mit.edu>
1 parent 89cae45 commit 1b183b9

File tree

7 files changed

+52
-5
lines changed

7 files changed

+52
-5
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ New library features
8484
write the output to a stream rather than returning a string ([#48625]).
8585
* `sizehint!(s, n)` now supports an optional `shrink` argument to disable shrinking ([#51929]).
8686
* New function `Docs.hasdoc(module, symbol)` tells whether a name has a docstring ([#52139]).
87+
* New function `Docs.undocumented_names(module; all)` returns a module's undocumented names ([#52413]).
8788
* Passing an `IOBuffer` as a stdout argument for `Process` spawn now works as
8889
expected, synchronized with `wait` or `success`, so a `Base.BufferStream` is
8990
no longer required there for correctness to avoid data races ([#52461]).

base/docs/Docs.jl

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44
Docs
55
6-
The `Docs` module provides the `@doc` macro which can be used to set and retrieve
6+
The `Docs` module provides the [`@doc`](@ref) macro which can be used to set and retrieve
77
documentation metadata for Julia objects.
88
99
Please see the manual section on [documentation](@ref man-documentation) for more
@@ -675,4 +675,20 @@ function hasdoc(binding::Docs.Binding, sig::Type = Union{})
675675
end
676676

677677

678+
"""
679+
undocumented_names(mod::Module; all=false)
680+
681+
Return an array of undocumented symbols in `module` (that is, lacking docstrings).
682+
`all=false` returns only exported symbols; whereas `all=true` also includes
683+
non-exported symbols, following the behavior of [`names`](@ref). Only valid identifiers
684+
are included. Names are returned in sorted order.
685+
686+
See also: [`names`](@ref), [`Docs.hasdoc`](@ref), [`Base.isidentifier`](@ref).
687+
"""
688+
function undocumented_names(mod::Module; all::Bool=false)
689+
filter!(names(mod; all)) do sym
690+
!hasdoc(mod, sym) && Base.isidentifier(sym)
691+
end
692+
end
693+
678694
end

base/docs/utils.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ You can also use a stream for large amounts of data:
2323
`HTML` is currently exported to maintain
2424
backwards compatibility, but this export
2525
is deprecated. It is recommended to use
26-
this type as `Docs.HTML` or to explicitly
26+
this type as [`Docs.HTML`](@ref) or to explicitly
2727
import it from `Docs`.
2828
"""
2929
mutable struct HTML{T}
@@ -81,7 +81,7 @@ You can also use a stream for large amounts of data:
8181
`Text` is currently exported to maintain
8282
backwards compatibility, but this export
8383
is deprecated. It is recommended to use
84-
this type as `Docs.Text` or to explicitly
84+
this type as [`Docs.Text`](@ref) or to explicitly
8585
import it from `Docs`.
8686
"""
8787
mutable struct Text{T}

base/reflection.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Get an array of the public names of a `Module`, excluding deprecated names.
7979
If `all` is true, then the list also includes non-public names defined in the module,
8080
deprecated names, and compiler-generated names.
8181
If `imported` is true, then names explicitly imported from other modules
82-
are also included.
82+
are also included. Names are returned in sorted order.
8383
8484
As a special case, all names defined in `Main` are considered \"public\",
8585
since it is not idiomatic to explicitly mark names from `Main` as public.

doc/src/base/base.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,16 @@ Base.functionloc(::Method)
462462
Base.@locals
463463
```
464464

465+
## Documentation
466+
(See also the [documentation](@ref man-documentation) chapter.)
467+
```@docs
468+
Base.@doc
469+
Docs.HTML
470+
Docs.Text
471+
Docs.hasdoc
472+
Docs.undocumented_names
473+
```
474+
465475
## Code loading
466476

467477
```@docs

doc/src/manual/documentation.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ environments provide a way to access documentation directly:
2020
under the cursor.
2121

2222

23-
`Docs.hasdoc(module, name)::Bool` tells whether a name has a docstring.
23+
`Docs.hasdoc(module, name)::Bool` tells whether a name has a docstring. `Docs.undocumented_names(module; all)`
24+
returns the undocumented names in a module.
2425

2526
## Writing Documentation
2627

test/docs.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,25 @@ function break_me_docs end
7676
@test !isdefined(Base, :_this_name_doesnt_exist_) && !Docs.hasdoc(Base, :_this_name_doesnt_exist_)
7777
@test isdefined(Base, :_typed_vcat) && !Docs.hasdoc(Base, :_typed_vcat)
7878

79+
"This module has names without documentation."
80+
module _ModuleWithUndocumentedNames
81+
export f
82+
f() = 1
83+
end
84+
85+
"This module has some documentation."
86+
module _ModuleWithSomeDocumentedNames
87+
export f
88+
"f() is 1."
89+
f() = 1
90+
g() = 2
91+
end
92+
93+
@test Docs.undocumented_names(_ModuleWithUndocumentedNames) == [:f]
94+
@test isempty(Docs.undocumented_names(_ModuleWithSomeDocumentedNames))
95+
@test Docs.undocumented_names(_ModuleWithSomeDocumentedNames; all=true) == [:eval, :g, :include]
96+
97+
7998
# issue #11548
8099

81100
module ModuleMacroDoc

0 commit comments

Comments
 (0)