Don't create tokens by hand#1696
Conversation
|
|
||
| def test_markup_code | ||
| tokens = [ | ||
| { :line_no => 0, :char_no => 0, :kind => :on_const, :text => 'CONSTANT' }, |
There was a problem hiding this comment.
This testcase didn't make much sense since only methods have their source code shown. I simply removed it.
|
🚀 Preview deployment available at: https://0206fae0.rdoc-6cd.pages.dev (commit: 01677d0) |
There was a problem hiding this comment.
Pull request overview
This PR removes “synthetic” tokens (file/line comment, newline, indent) from Ruby parser token streams and moves location/line-number decoration into RDoc::MethodAttr#markup_code, with tests updated to build token streams via RipperStateLex instead of hand-crafted hashes.
Changes:
- Stop prepending non-source tokens in
RDoc::Parser::Ruby#visible_tokens_from_locationand related paths. - Rework
RDoc::MethodAttr#markup_codeto dedent, optionally add line numbers, and prepend a generated location comment. - Update
any_method_testto useRipperStateLex.parseand assert the new HTML output format.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
test/rdoc/code_object/any_method_test.rb |
Updates expectations and replaces hand-built token hashes with RipperStateLex.parse output. |
lib/rdoc/parser/ruby.rb |
Removes construction of extra non-source tokens from token streams; returns only sliced source tokens. |
lib/rdoc/generator/markup.rb |
Moves location comment and line-number generation into markup_code, and adjusts dedent logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| meth.start_collecting_tokens(:ruby) | ||
| node = @line_nodes[line_no] | ||
| tokens = node ? visible_tokens_from_location(node.location) : [file_line_comment_token(start_line)] | ||
| tokens = node ? visible_tokens_from_location(node.location) : [] | ||
| tokens.each { |token| meth.token_stream << token } | ||
|
|
There was a problem hiding this comment.
Seems correct. Previously they were not empty because it contained the comment
| line_no = node.location.start_line | ||
| else | ||
| tokens = [file_line_comment_token(line_no)] | ||
| tokens = [] |
45fa797 to
187755a
Compare
| meth.start_collecting_tokens(:ruby) | ||
| node = @line_nodes[line_no] | ||
| tokens = node ? visible_tokens_from_location(node.location) : [file_line_comment_token(start_line)] | ||
| tokens = node ? visible_tokens_from_location(node.location) : [] |
There was a problem hiding this comment.
If a method doesn't have tokens, it used to have a line number information but it's gone.
##
# :method: ghost_method
##
# :method:
# :call-seq: ghost_method2() -> Integer
I think the line number is important to know why and where the ghost-method is defined.
How about adding a new attribute that represents source location and use it instead of token_stream.first[:line_no]
There was a problem hiding this comment.
Makes sense, I'll try to fix that. It already exists as line on CodeObject and the parser sets it as far as I can tell so it shouldn't be too involved.
There was a problem hiding this comment.
Should be done. I moved the tests to the ruby parser, since that is where the line number is actually being set. That said, I only ran rdoc against ruby/prism to check for differences (there are none).
Is there an easy way to run it on ruby/ruby with a local checkout? I couldn't figure it out.
There was a problem hiding this comment.
I usually use bundle exec rdoc path/to/ruby/ruby --op ruby_doc for quick check (though it may not be as same as document deployed to https://docs.ruby-lang.org/en/master/)
Comparison without --line-numbers option
Only Delegator.html and Singleton.html had a small diff that we can ignore 👍
# Before
<pre class="ruby"><span class="ruby-comment"># File lib/delegate.rb, line 67</span></pre>
# After
<pre class="ruby"><span class="ruby-comment"># File lib/delegate.rb, line 67</span>
</pre>Comparison with --line-numbers option
Removing spaces before # File file.rb seems a great improvement 👍
Most files doesn't have a diff after normalizing: compare after removing that space with gsub
Delegator.html and Singleton.html had a diff #1696 (comment)
# Before
<pre class="ruby"> <span class="ruby-comment"># File ../ruby/lib/delegate.rb</span></pre>
# After
<pre class="ruby"><span class="ruby-comment"># File ../ruby/lib/delegate.rb</span>
<span class="line-num">67</span> </pre>187755a to
7e0269b
Compare
| def add_location_comment(src) | ||
| path = CGI.escapeHTML(file.relative_name) | ||
| if options.line_numbers | ||
| src.prepend("<span class=\"ruby-comment\"># File #{path}</span>\n") | ||
| else | ||
| src.prepend("<span class=\"ruby-comment\"># File #{path}, line #{line}</span>\n") | ||
| end |
There was a problem hiding this comment.
Is this necessary?
There was a problem hiding this comment.
No I think it's not. Feel free to ignore it
There is some awkward code that dances around the fact that the tokens for a method actually contain a 3 extra tokens that don't exist in the source code. Now `RipperStateLex` is only referenced to actually parse, rest is kept internal
7e0269b to
01677d0
Compare
| first = $3.to_i - 1 | ||
| last = first + src.count("\n") | ||
| size = last.to_s.length | ||
| start_line = line or return |
There was a problem hiding this comment.
I think we can add one more early return when src is empty.
bundle exec rdoc path/to/ruby/ruby/lib/delegate.rb --line-numbers --op outputdirIf src is empty, line number wasn't and won't be displayed. So perhaps we can change def add_location_comment such as:
if options.line_numbers && !src.empty? # Add empty check here
src.prepend("<span class=\"ruby-comment\"># File #{path}</span>\n")
else
src.prepend("<span class=\"ruby-comment\"># File #{path}, line #{line}</span>\n")
end

There is some awkward code that dances around the fact that the tokens for a method actually contain a 3 extra tokens that don't exist in the source code.
Now
RipperStateLexis only referenced to actually parse, rest is kept internal