Skip to content

Commit 6ed90b4

Browse files
committed
Add support for Ruby Signature Files (.rbs)
1 parent 82f3e63 commit 6ed90b4

20 files changed

Lines changed: 1406 additions & 5 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# main
22

3+
- Add support for Ruby .rbs files (docstrings included)
34
- Add support for `#-` as a comment-block separator. See Getting Started Guide.
45
- Fix false self-referential mixin when bare name matches ancestor namespace (#1672)
56
- Fix bracket/brace map corruption from Ruby 3.0+ pattern matching deconstruction (#1671)

docs/WhatsNew.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
# What's New in 0.9.x?
44

5-
## `#-` comment block separators
5+
## Support for Ruby Signature Files (.rbs) (0.9.40)
6+
7+
YARD now supports parsing Ruby signature files (.rbs) with full docstring support. This means you can write your documentation in `.rbs` files and have it show up in generated documentation, and use `.rbs` files alongside `.rb` sources to supplement type and API information.
8+
9+
## `#-` comment block separators (0.9.40)
610

711
YARD now recognizes a trailing `#-` line as a separator between comment
812
blocks. This is useful when you want to keep a file header comment at the top
@@ -22,7 +26,7 @@ In the example above, the file header stays disconnected from `Client`.
2226
Note that `# -` does **not** act as a separator; only an attached `#-`
2327
line has this behavior.
2428

25-
## Ruby 4.x support
29+
## Ruby 4.x support (0.9.39)
2630

2731
Added support for Ruby 4.x along with new syntaxes.
2832

lib/yard/autoload.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ module Common
6969
autoload :MethodHandler, __p('handlers/common/method_handler')
7070
end
7171

72+
# RBS type signature handlers
73+
module RBS
74+
autoload :Base, __p('handlers/rbs/base')
75+
autoload :AttributeHandler, __p('handlers/rbs/attribute_handler')
76+
autoload :ConstantHandler, __p('handlers/rbs/constant_handler')
77+
autoload :MethodHandler, __p('handlers/rbs/method_handler')
78+
autoload :MixinHandler, __p('handlers/rbs/mixin_handler')
79+
autoload :NamespaceHandler, __p('handlers/rbs/namespace_handler')
80+
end
81+
7282
# CRuby Handlers
7383
# @since 0.8.0
7484
module C
@@ -183,6 +193,12 @@ module Legacy # Handles Ruby parsing in Ruby 1.8.
183193
autoload :TokenResolver, __p('parser/ruby/token_resolver')
184194
end
185195

196+
# RBS type signature parser
197+
module RBS
198+
autoload :RbsParser, __p('parser/rbs/rbs_parser')
199+
autoload :Statement, __p('parser/rbs/statement')
200+
end
201+
186202
autoload :Base, __p('parser/base')
187203
autoload :ParserSyntaxError, __p('parser/source_parser')
188204
autoload :SourceParser, __p('parser/source_parser')

lib/yard/handlers/processor.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def namespace_for_handler; @@parser_type_extensions ||= {} end
3535
register_handler_namespace :ruby, Ruby
3636
register_handler_namespace :ruby18, Ruby::Legacy
3737
register_handler_namespace :c, C
38+
register_handler_namespace :rbs, RBS
3839

3940
# @return [String] the filename
4041
attr_accessor :file
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# frozen_string_literal: true
2+
# Handles RBS attr_reader, attr_writer, and attr_accessor declarations.
3+
#
4+
# Registers one or two {YARD::CodeObjects::MethodObject} instances (reader
5+
# and/or writer) with @return / @param tags derived from the RBS type.
6+
class YARD::Handlers::RBS::AttributeHandler < YARD::Handlers::RBS::Base
7+
handles :attr_reader, :attr_writer, :attr_accessor
8+
9+
process do
10+
attr_name = statement.name
11+
rbs_type = statement.attr_rbs_type
12+
yard_types = rbs_type ? YARD::Handlers::RBS::MethodHandler.rbs_type_to_yard_types(rbs_type) : nil
13+
mscope = statement.visibility == :class ? :class : :instance
14+
15+
case statement.type
16+
when :attr_reader
17+
register_reader(attr_name, yard_types, mscope)
18+
when :attr_writer
19+
register_writer(attr_name, yard_types, mscope)
20+
when :attr_accessor
21+
register_reader(attr_name, yard_types, mscope)
22+
register_writer(attr_name, yard_types, mscope)
23+
end
24+
end
25+
26+
private
27+
28+
def register_reader(name, types, scope)
29+
obj = register MethodObject.new(namespace, name, scope)
30+
if types && !obj.has_tag?(:return)
31+
obj.add_tag YARD::Tags::Tag.new(:return, '', types)
32+
end
33+
obj
34+
end
35+
36+
def register_writer(name, types, scope)
37+
obj = register MethodObject.new(namespace, "#{name}=", scope)
38+
if types && !obj.has_tag?(:param)
39+
obj.add_tag YARD::Tags::Tag.new(:param, '', types, "value")
40+
end
41+
obj
42+
end
43+
end

lib/yard/handlers/rbs/base.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# frozen_string_literal: true
2+
module YARD
3+
module Handlers
4+
# Handlers for RBS (Ruby type signature) files.
5+
module RBS
6+
# Base class for all RBS handlers.
7+
# Handlers match on the {Parser::RBS::Statement#type} symbol of the
8+
# current statement and process it to create or annotate code objects.
9+
class Base < Handlers::Base
10+
# @return [Boolean] whether this handler matches the given statement
11+
def self.handles?(statement, _processor)
12+
handlers.any? do |matcher|
13+
case matcher
14+
when Symbol
15+
statement.type == matcher
16+
when String
17+
statement.type.to_s == matcher
18+
when Regexp
19+
(statement.source || '') =~ matcher
20+
else
21+
false
22+
end
23+
end
24+
end
25+
26+
# Recurse into the body of a namespace statement.
27+
# @param opts [Hash] state overrides
28+
# @see #push_state
29+
def parse_block(opts = {})
30+
return if statement.block.nil? || statement.block.empty?
31+
push_state(opts) do
32+
parser.process(statement.block)
33+
end
34+
end
35+
end
36+
end
37+
end
38+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# frozen_string_literal: true
2+
# Handles RBS constant declarations: `Name: Type`
3+
class YARD::Handlers::RBS::ConstantHandler < YARD::Handlers::RBS::Base
4+
handles :constant
5+
6+
process do
7+
obj = register ConstantObject.new(namespace, statement.name)
8+
if statement.attr_rbs_type && !obj.has_tag?(:return)
9+
obj.add_tag YARD::Tags::Tag.new(:return, '', rbs_types(statement.attr_rbs_type))
10+
end
11+
end
12+
13+
private
14+
15+
def rbs_types(type_str)
16+
YARD::Handlers::RBS::MethodHandler.rbs_type_to_yard_types(type_str)
17+
end
18+
end

0 commit comments

Comments
 (0)