yard
yard copied to clipboard
Allow method calls (namely `sig`) to be between docs and the object they're documenting
This motivation behind this is primarily introducing better support for using YARD documentation alongside Sorbet type signatures. These are specified by a sig
call before the method's definition.
Currently the YARD documentation must go in-between the sig
and definition, which feels awkward.
Steps to reproduce
Generate docs for these two snippets:
sig { returns(String) }
# This is a method.
# @return An example string.
def example
"Foobar"
end
# This is a method.
# @return An example string.
sig { returns(String) }
def example
"Foobar"
end
Actual Output
The first snippet generates the documentation fine. The second snippet generates no documentation for example
and prints:
[warn]: in YARD::Handlers::Ruby::DSLHandler: Undocumentable method, missing name
in file 'test.rb':3:
3: sig { returns(String) }
Expected Output
Both snippets should generate documentation for example
.
Environment details:
- OS: Ubuntu 18.04
- Ruby version (
ruby -v
):ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
- YARD version (
yard -v
):yard 0.9.20
- Relevant software dependency/versions:
-
Sorbet typechecker 0.4.4254
-
I have read the Contributing Guide.
I think supporting this would belong in a plugin since Sorbet is not yet a Ruby standard. Fortunately, here's a quick little YARD extension you can use to add support:
# place in something like `yardext/sorbet.rb`
module YardSorbet
class SigHandler < YARD::Handlers::Ruby::Base
namespace_only
handles method_call
process do
case statement.jump(:ident).first
when "sig"
extra_state.sorbet_signature_docstring ||= ""
extra_state.sorbet_signature_docstring += statement.docstring
else
extra_state.sorbet_signature_docstring = nil
end
end
end
module SigStopHandler
def process
super
extra_state.sorbet_signature_docstring = nil
end
end
module SigDefHandler
def process
return unless extra_state.sorbet_signature_docstring
statement.docstring = [
extra_state.sorbet_signature_docstring,
statement.docstring
].join("\n")
super
end
end
YARD::Handlers::Ruby::ClassHandler.include SigStopHandler
YARD::Handlers::Ruby::ModuleHandler.include SigStopHandler
YARD::Handlers::Ruby::MethodHandler.include SigDefHandler
end
Run with
yard -e yardext/sorbet.rb
Or add -e yardext/sorbet.rb
to your .yardopts
file.
You could turn this into a gem if you are interested, say, yard-sorbet
, at which point you (and others!) could gem install yard-sorbet
and use it via yard --plugin sorbet
A nice addition to this would be to parse out the sigs and add YARD param/return type decorations to docstrings-- fairly easy to do given the above base code. That would allow the sig { returns(String) }
stuff to get documented as a @return [String]
tag. You could even interleave into existing docs so as to allow the following to work:
# @param value the value to reverse
# @return the reversed string
sig { params(value: String).returns(String) }
def reverse(value); end
But I will leave this as an exercise for the reader 😊.
Thank you! I'll give this a try when I can.
A nice addition to this would be to parse out the sigs and add YARD param/return type decorations to docstrings-- fairly easy to do given the above base code. That would allow the sig { returns(String) } stuff to get documented as a @return [String] tag.
I've been doing almost exactly the opposite of this recently, where the sig
calls are generated from the YARD documentation: https://github.com/AaronC81/sord
The yard-sorbet plugin supports this.