Conversation
|
🚀 Preview deployment available at: https://b146eebc.rdoc-6cd.pages.dev (commit: fd4b149) |
251f5db to
be86678
Compare
a469122 to
bfcd437
Compare
be86678 to
4b26c40
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support for RBS type signatures in RDoc by extracting inline #: annotations during parsing, optionally loading signatures from .rbs files, and rendering those signatures in both HTML (Aliki theme) and ri terminal output.
Changes:
- Extract
#:type signatures from comment blocks in the Prism parser and attach them toRDoc::MethodAttrobjects. - Load/merge signatures from RBS sources into the store (without overwriting inline annotations) and add type-name linking in HTML output.
- Render signatures in Aliki HTML +
ri, update marshal formats, and bump runtime requirements (Ruby >= 3.2, addrbsdependency).
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
lib/rdoc/parser/prism_ruby.rb |
Extracts/validates inline #: signatures and attaches them to methods/attrs. |
lib/rdoc/rbs_support.rb |
New RBS integration: validation, signature loading, and HTML linking. |
lib/rdoc/store.rb |
Adds signature merge logic and cached type-name lookup for linking. |
lib/rdoc/generator/aliki.rb |
Exposes type_signature_html helper for templates (linked type names). |
lib/rdoc/generator/template/aliki/class.rhtml |
Renders type signatures for methods and attributes in HTML output. |
lib/rdoc/generator/template/aliki/css/rdoc.css |
Styles signature blocks and linked type names. |
lib/rdoc/generator/template/aliki/js/aliki.js |
Avoids wrapping signature <pre> blocks with “copy” UI. |
lib/rdoc/ri/driver.rb |
Prints method type signatures in ri output. |
lib/rdoc/code_object/method_attr.rb |
Adds type_signature storage + line splitting helper. |
lib/rdoc/code_object/any_method.rb |
Bumps marshal version and persists type_signature. |
lib/rdoc/code_object/attr.rb |
Bumps marshal version and persists type_signature. |
lib/rdoc/rdoc.rb |
Loads RBS signatures after store completion and merges into objects. |
rdoc.gemspec |
Bumps Ruby minimum to 3.2, adds rbs dependency, bumps prism minimum. |
Gemfile |
Always includes mini_racer on MRI (Ruby >= 3.2 now required). |
.github/workflows/test.yml |
Aligns CI with Ruby >= 3.2 and updated Prism versions. |
test/rdoc/parser/prism_ruby_test.rb |
Adds Prism-only tests for inline signature extraction. |
test/rdoc/rbs_support_test.rb |
New tests for validation, loading, and HTML linking. |
test/rdoc/rdoc_store_test.rb |
Tests signature merging + type_name_lookup behavior/caching. |
test/rdoc/ri/driver_test.rb |
Tests ri output includes a type signature. |
test/rdoc/code_object/any_method_test.rb |
Tests marshal persistence for method type signatures. |
test/rdoc/code_object/attr_test.rb |
Tests marshal persistence for attribute type signatures. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
599eacc to
1034e9b
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 24 out of 24 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def validate_type_signature(sig, line_no) | ||
| sig.split("\n").each_with_index do |line, i| | ||
| method_error = RDoc::RbsHelper.validate_method_type(line) | ||
| next unless method_error | ||
| type_error = RDoc::RbsHelper.validate_type(line) | ||
| next unless type_error | ||
| @options.warn "#{@top_level.relative_name}:#{line_no + i}: invalid RBS type signature: #{line.inspect}" | ||
| end |
| result[start_in_escaped...end_in_escaped] = | ||
| "<a href=\"#{href}\" class=\"rbs-type\">#{escaped_name}</a>" |
RBS 4.0 requires Ruby >= 3.2. Bump RDoc's own minimum to match and add `rbs >= 4.0.0` as a gemspec dependency. Bump prism minimum to `>= 1.6.0` (required by rbs). Drop JRuby and TruffleRuby from CI matrix (rbs has a C extension that cannot build on them).
Add support for displaying RBS type signatures in both HTML and RI output. Type information is sourced from inline `#:` annotations (parsed by the Prism parser) and from `.rbs` files in the project's `sig/` directory plus RBS stdlib declarations. Implementation: - `RDoc::RbsHelper` module: loads RBS signatures, validates types, renders type signatures as HTML with linked type names - Parser extracts `#:` annotation lines via `RBS_SIG_LINE` constant, validates them, and attaches to `MethodAttr#type_signature` - `Store#merge_rbs_signatures` fills in signatures from `.rbs` files where inline annotations are absent - `Store#type_name_lookup` maps qualified and unambiguous unqualified names to documentation paths for type linking - Aliki theme: type signatures render as styled `<pre>` blocks under method headings, with linked type names using `a.rbs-type` class - RI driver: type signatures display as verbatim blocks - `MARSHAL_VERSION` bumped to 4 for `AnyMethod` and `Attr`
|
Do I understand correctly that the sorbet type signature will not work with this implementation? |
|
Yes, because it's not a official signature syntax for Ruby. |
Does this mean that JRuby can't use RDoc with this? |
|
@kou Unfortunately, yes. It's essentially a decision between:
Given that I want to make RBS support a key feature of future RDoc and directly encourage gems to write more RBS signatures, I think 1 is a more reasonable decision. |
|
@headius I assumed JRuby doesn't support |
Add `rbs` and its dependency `logger` to the bundled gem load paths in `tool/rdoc-srcdir`, and add the compiled extension path from `.bundle/extensions/` so the `rbs_extension` C extension can be found. This is needed because `make html` runs with `--disable-gems`, so RubyGems cannot resolve the extension path automatically. The extension is already compiled by `make build-ext` (which `make html` depends on via `main`), it just wasn't discoverable. Required for ruby/rdoc#1665 to work with `make html` in ruby/ruby.
|
@soutaro Can RBS add support for JRuby? |
|
@kou I'm not sure. I remember @headius was working on FFI with RBS (ruby/rbs#2572). I thought it was something related to JRuby, but I don't have exact context about this. |
|
Thanks. Let's wait for a response from @headius . |
|
@kou At the same time, I'd appreciate review on the rest of implementation too 🙏 |
| return nil if sig_lines.empty? | ||
|
|
||
| text.replace(doc_lines.join) | ||
| type_sig = sig_lines.map { |l| l.sub(RBS_SIG_LINE, '').chomp }.join("\n") |
There was a problem hiding this comment.
It seems that we can simplify this:
| type_sig = sig_lines.map { |l| l.sub(RBS_SIG_LINE, '').chomp }.join("\n") | |
| type_sig = sig_lines.map { |l| l.sub(RBS_SIG_LINE, '') }.join |
| end | ||
|
|
||
| def validate_type_signature(sig, line_no) | ||
| sig.split("\n").each_with_index do |line, i| |
There was a problem hiding this comment.
| sig.split("\n").each_with_index do |line, i| | |
| sig.each_line(chomp: true).with_index do |line, i| |
| method_error = RDoc::RbsHelper.validate_method_type(line) | ||
| next unless method_error | ||
| type_error = RDoc::RbsHelper.validate_type(line) | ||
| next unless type_error |
There was a problem hiding this comment.
If we don't use error messages in warning messages, valid_XXX? instead of validate_XXX may be better.
| decl.members.each do |member| | ||
| case member | ||
| when RBS::AST::Members::MethodDefinition | ||
| key = member.singleton? ? "#{class_name}::#{member.name}" : "#{class_name}##{member.name}" |
There was a problem hiding this comment.
#{class_name}.#{member.name} is better for singleton method.
| key = member.singleton? ? "#{class_name}::#{member.name}" : "#{class_name}##{member.name}" | |
| key = member.singleton? ? "#{class_name}.#{member.name}" : "#{class_name}##{member.name}" |
| sigs = member.overloads.map { |o| o.method_type.to_s } | ||
| signatures[key] = sigs.join("\n") | ||
| when RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter, RBS::AST::Members::AttrAccessor | ||
| key = "#{class_name}.#{member.name}" |
There was a problem hiding this comment.
Hmm. Can we use # instead of . as the separator because attribute accessors just methods?
| top_level = @store.add_file 'file.rb' | ||
|
|
||
| m = RDoc::AnyMethod.new nil, 'method' | ||
| m.block_params = 'some_block' |
There was a problem hiding this comment.
| m.block_params = 'some_block' | |
| m.block_params = 'some_block' |
|
|
||
| klass = @store.find_class_named 'Foo' | ||
| bar = klass.method_list.first | ||
| assert_equal '(Integer) -> void', bar.type_signature |
There was a problem hiding this comment.
Should we assert bar.comment.text here? (nil? An empty string?)
| klass = @store.find_class_named 'Foo' | ||
| bar = klass.method_list.first | ||
| assert_equal '(String) -> void', bar.type_signature | ||
| assert_includes bar.comment.text, 'Documentation here' |
There was a problem hiding this comment.
Can we use assert_equal not assert_includes to check type signature doesn't exist in bar.comment?
| assert_includes bar.comment.text, 'Documentation here' | |
| assert_equal "Documentation here\n", bar.comment.text |
| end | ||
|
|
||
| def validate_type_signature(sig, line_no) | ||
| sig.split("\n").each_with_index do |line, i| |
There was a problem hiding this comment.
I'm not familiar with RBS syntax but RBS doesn't support splitting one signature to multiple lines, right?
Summary
#:annotations and.rbsfiles (including RBS stdlib)Details
New module:
RDoc::RbsHelpersig/directories and stdlib declarations viaRBS::EnvironmentLoader#:annotations usingRBS::Parser, warns with file:line on invalid signaturesa.rbs-typeParser integration (
PrismRuby)#:annotation lines from comments viaRBS_SIG_LINEconstantMethodAttr#type_signature.rbsfile signaturesStore
merge_rbs_signaturesfills in type signatures from loaded.rbsfiles where no inline annotation existstype_name_lookupbuilds a cached name-to-path map for type linking; ambiguous unqualified names are excluded to avoid wrong linksDisplay
<pre>blocks with dotted separator; attribute signatures render inline after the[RW]badgeSerialization
MARSHAL_VERSIONbumped to 4 for bothAnyMethodandAttr(additive — appendstype_signatureto marshal array)CI/Dependencies
rbs4.0)rbs >= 4.0.0andprism >= 1.6.0dependenciesrbshas a C extension)