Skip to content

Commit d1eaa56

Browse files
committed
Change default ruby parser to RDoc::Parser::PrismRuby
1 parent 96f9312 commit d1eaa56

File tree

10 files changed

+170
-155
lines changed

10 files changed

+170
-155
lines changed

.github/workflows/ruby-core.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,13 @@ jobs:
7070
run: make html
7171
working-directory: ruby/ruby
7272
# We need to clear the generated documentation to generate them again
73-
# with the Prism parser.
73+
# with the Ripper parser.
7474
- name: Clear Generated Documentation
7575
run: rm -r .ext/html
7676
working-directory: ruby/ruby
77-
- name: Generate Documentation with RDoc (Prism parser)
77+
- name: Generate Documentation with RDoc (Ripper parser)
7878
run: make html
7979
working-directory: ruby/ruby
8080
env:
81-
RDOC_USE_PRISM_PARSER: true
81+
RDOC_USE_RIPPER_PARSER: true
8282

.github/workflows/test.yml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ jobs:
3939
runs-on: ${{ matrix.os }}
4040
steps:
4141
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
42-
# libyaml-dev is needed for psych, see https://github.com/ruby/setup-ruby/issues/409
43-
- if: ${{ matrix.os == 'ubuntu-latest' }}
44-
run: sudo apt install libyaml-dev
4542
- name: Set up Ruby
4643
uses: ruby/setup-ruby@8d27f39a5e7ad39aebbcbd1324f7af020229645c # v1.287.0
4744
with:
@@ -62,3 +59,23 @@ jobs:
6259
run: bundle exec rake rdoc
6360
- if: ${{ matrix.ruby == 'head' && startsWith(matrix.os, 'ubuntu') }}
6461
run: bundle exec rake install
62+
63+
prism-version-test:
64+
needs: ruby-versions
65+
strategy:
66+
fail-fast: false
67+
matrix:
68+
prism_version: ['1.0.0', '1.3.0', '1.7.0', 'head']
69+
runs-on: ubuntu-latest
70+
env:
71+
RUBYOPT: --enable-frozen_string_literal
72+
PRISM_VERSION: ${{matrix.prism_version}}
73+
steps:
74+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
75+
- name: Set up Ruby
76+
uses: ruby/setup-ruby@80740b3b13bf9857e28854481ca95a84e78a2bdf # v1.284.0
77+
with:
78+
ruby-version: ${{ fromJson(needs.ruby-versions.outputs.latest) }}
79+
bundler-cache: true
80+
- name: Run test
81+
run: bundle exec rake

Gemfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ gem 'test-unit'
99
gem 'test-unit-ruby-core'
1010
gem 'rubocop', '>= 1.31.0'
1111
gem 'gettext'
12-
gem 'prism', '>= 0.30.0'
1312
gem 'webrick'
1413

14+
if ENV['PRISM_VERSION'] == 'head'
15+
gem 'prism', github: 'ruby/prism'
16+
elsif ENV['PRISM_VERSION']
17+
gem 'prism', ENV['PRISM_VERSION']
18+
end
19+
1520
platforms :ruby do
1621
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2')
1722
gem 'mini_racer' # For testing the searcher.js file

doc/rdoc/example.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def instance_method_example(foo, bar)
5858
#
5959
# Here is the <tt>:call-seq:</tt> directive given for this method:
6060
#
61-
# :call-seq:
61+
# \:call-seq:
6262
# call_seq_example(foo, bar)
6363
# Can be anything -> bar
6464
# Also anything more -> baz or bat

lib/rdoc/parser.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,4 +294,15 @@ def handle_tab_width(body)
294294
require_relative 'parser/changelog'
295295
require_relative 'parser/markdown'
296296
require_relative 'parser/rd'
297-
require_relative 'parser/ruby'
297+
298+
if ENV['RDOC_USE_RIPPER_PARSER']
299+
puts "========================================================================="
300+
puts "RDoc is using the deprecated Ripper parser to generate the documentation."
301+
puts "This parser will be removed in a future version of RDoc."
302+
puts "========================================================================="
303+
require 'rdoc/parser/ripper_ruby'
304+
RDoc::Parser::Ruby = RDoc::Parser::RipperRuby
305+
else
306+
require 'rdoc/parser/prism_ruby'
307+
RDoc::Parser::Ruby = RDoc::Parser::PrismRuby
308+
end

lib/rdoc/parser/prism_ruby.rb

Lines changed: 121 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,135 @@
33
require 'prism'
44
require_relative 'ripper_state_lex'
55

6-
# Unlike lib/rdoc/parser/ruby.rb, this file is not based on rtags and does not contain code from
6+
# Unlike lib/rdoc/parser/ripper_ruby.rb, this file is not based on rtags and does not contain code from
77
# rtags.rb -
88
# ruby-lex.rb - ruby lexcal analyzer
99
# ruby-token.rb - ruby tokens
1010

1111
# Parse and collect document from Ruby source code.
12-
# RDoc::Parser::PrismRuby is compatible with RDoc::Parser::Ruby and aims to replace it.
12+
13+
##
14+
# Extracts code elements from a source file returning a TopLevel object
15+
# containing the constituent file elements.
16+
#
17+
# RubyParser understands how to document:
18+
# * classes
19+
# * modules
20+
# * methods
21+
# * constants
22+
# * aliases
23+
# * private, public, protected
24+
# * private_class_function, public_class_function
25+
# * private_constant, public_constant
26+
# * module_function
27+
# * attr, attr_reader, attr_writer, attr_accessor
28+
# * extra accessors given on the command line
29+
# * metaprogrammed methods
30+
# * require
31+
# * include
32+
#
33+
# == Method Arguments
34+
#
35+
# The parser extracts the arguments from the method definition. You can
36+
# override this with a custom argument definition using the :args: directive:
37+
#
38+
# ##
39+
# # This method tries over and over until it is tired
40+
#
41+
# def go_go_go(thing_to_try, tries = 10) # :args: thing_to_try
42+
# puts thing_to_try
43+
# go_go_go thing_to_try, tries - 1
44+
# end
45+
#
46+
# If you have a more-complex set of overrides you can use the :call-seq:
47+
# directive:
48+
#
49+
# ##
50+
# # This method can be called with a range or an offset and length
51+
# #
52+
# # :call-seq:
53+
# # my_method(Range)
54+
# # my_method(offset, length)
55+
#
56+
# def my_method(*args)
57+
# end
58+
#
59+
# The parser extracts +yield+ expressions from method bodies to gather the
60+
# yielded argument names. If your method manually calls a block instead of
61+
# yielding or you want to override the discovered argument names use
62+
# the :yields: directive:
63+
#
64+
# ##
65+
# # My method is awesome
66+
#
67+
# def my_method(&block) # :yields: happy, times
68+
# block.call 1, 2
69+
# end
70+
#
71+
# == Metaprogrammed Methods
72+
#
73+
# To pick up a metaprogrammed method, the parser looks for a comment starting
74+
# with '##' before a metaprogramming method call:
75+
#
76+
# ##
77+
# # This is a meta-programmed method!
78+
#
79+
# add_my_method :meta_method, :arg1, :arg2
80+
#
81+
# The parser looks at the first argument to determine the name, in
82+
# this example, :meta_method. If a name cannot be found, a warning is printed
83+
# and 'unknown' is used.
84+
#
85+
# You can force the name of a method using the :method: directive:
86+
#
87+
# ##
88+
# # :method: some_method!
89+
#
90+
# By default, meta-methods are instance methods. To indicate that a method is
91+
# a singleton method instead use the :singleton-method: directive:
92+
#
93+
# ##
94+
# # :singleton-method:
95+
#
96+
# You can also use the :singleton-method: directive with a name:
97+
#
98+
# ##
99+
# # :singleton-method: some_method!
100+
#
101+
# You can define arguments for metaprogrammed methods via either the
102+
# \:call-seq:, :arg: or :args: directives.
103+
#
104+
# Additionally you can mark a method as an attribute by
105+
# using :attr:, :attr_reader:, :attr_writer: or :attr_accessor:. Just like
106+
# for :method:, the name is optional.
107+
#
108+
# ##
109+
# # :attr_reader: my_attr_name
110+
#
111+
# == Hidden methods and attributes
112+
#
113+
# You can provide documentation for methods that don't appear using
114+
# the :method:, :singleton-method: and :attr: directives:
115+
#
116+
# ##
117+
# # :attr_writer: ghost_writer
118+
# # There is an attribute here, but you can't see it!
119+
#
120+
# ##
121+
# # :method: ghost_method
122+
# # There is a method here, but you can't see it!
123+
#
124+
# ##
125+
# # this is a comment for a regular method
126+
#
127+
# def regular_method() end
128+
#
129+
# Note that by default, the :method: directive will be ignored if there is a
130+
# standard rdocable item following it.
13131

14132
class RDoc::Parser::PrismRuby < RDoc::Parser
15133

16-
parse_files_matching(/\.rbw?$/) if ENV['RDOC_USE_PRISM_PARSER']
134+
parse_files_matching(/\.rbw?$/) unless ENV['RDOC_USE_RIPPER_PARSER']
17135

18136
attr_accessor :visibility
19137
attr_reader :container, :singleton
Lines changed: 3 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -8,151 +8,14 @@
88
# by Keiju ISHITSUKA (Nippon Rational Inc.)
99
#
1010

11-
if ENV['RDOC_USE_PRISM_PARSER']
12-
require 'rdoc/parser/prism_ruby'
13-
RDoc::Parser.const_set(:Ruby, RDoc::Parser::PrismRuby)
14-
puts "========================================================================="
15-
puts "RDoc is using the experimental Prism parser to generate the documentation"
16-
puts "========================================================================="
17-
return
18-
end
11+
# This file is based on rtags
1912

2013
require 'ripper'
2114
require_relative 'ripper_state_lex'
2215

23-
##
24-
# Extracts code elements from a source file returning a TopLevel object
25-
# containing the constituent file elements.
26-
#
27-
# This file is based on rtags
28-
#
29-
# RubyParser understands how to document:
30-
# * classes
31-
# * modules
32-
# * methods
33-
# * constants
34-
# * aliases
35-
# * private, public, protected
36-
# * private_class_function, public_class_function
37-
# * private_constant, public_constant
38-
# * module_function
39-
# * attr, attr_reader, attr_writer, attr_accessor
40-
# * extra accessors given on the command line
41-
# * metaprogrammed methods
42-
# * require
43-
# * include
44-
#
45-
# == Method Arguments
46-
#
47-
#--
48-
# NOTE: I don't think this works, needs tests, remove the paragraph following
49-
# this block when known to work
50-
#
51-
# The parser extracts the arguments from the method definition. You can
52-
# override this with a custom argument definition using the :args: directive:
53-
#
54-
# ##
55-
# # This method tries over and over until it is tired
56-
#
57-
# def go_go_go(thing_to_try, tries = 10) # :args: thing_to_try
58-
# puts thing_to_try
59-
# go_go_go thing_to_try, tries - 1
60-
# end
61-
#
62-
# If you have a more-complex set of overrides you can use the :call-seq:
63-
# directive:
64-
#++
65-
#
66-
# The parser extracts the arguments from the method definition. You can
67-
# override this with a custom argument definition using the :call-seq:
68-
# directive:
69-
#
70-
# ##
71-
# # This method can be called with a range or an offset and length
72-
# #
73-
# # :call-seq:
74-
# # my_method(Range)
75-
# # my_method(offset, length)
76-
#
77-
# def my_method(*args)
78-
# end
79-
#
80-
# The parser extracts +yield+ expressions from method bodies to gather the
81-
# yielded argument names. If your method manually calls a block instead of
82-
# yielding or you want to override the discovered argument names use
83-
# the :yields: directive:
84-
#
85-
# ##
86-
# # My method is awesome
87-
#
88-
# def my_method(&block) # :yields: happy, times
89-
# block.call 1, 2
90-
# end
91-
#
92-
# == Metaprogrammed Methods
93-
#
94-
# To pick up a metaprogrammed method, the parser looks for a comment starting
95-
# with '##' before an identifier:
96-
#
97-
# ##
98-
# # This is a meta-programmed method!
99-
#
100-
# add_my_method :meta_method, :arg1, :arg2
101-
#
102-
# The parser looks at the token after the identifier to determine the name, in
103-
# this example, :meta_method. If a name cannot be found, a warning is printed
104-
# and 'unknown' is used.
105-
#
106-
# You can force the name of a method using the :method: directive:
107-
#
108-
# ##
109-
# # :method: some_method!
110-
#
111-
# By default, meta-methods are instance methods. To indicate that a method is
112-
# a singleton method instead use the :singleton-method: directive:
113-
#
114-
# ##
115-
# # :singleton-method:
116-
#
117-
# You can also use the :singleton-method: directive with a name:
118-
#
119-
# ##
120-
# # :singleton-method: some_method!
121-
#
122-
# You can define arguments for metaprogrammed methods via either the
123-
# \:call-seq:, :arg: or :args: directives.
124-
#
125-
# Additionally you can mark a method as an attribute by
126-
# using :attr:, :attr_reader:, :attr_writer: or :attr_accessor:. Just like
127-
# for :method:, the name is optional.
128-
#
129-
# ##
130-
# # :attr_reader: my_attr_name
131-
#
132-
# == Hidden methods and attributes
133-
#
134-
# You can provide documentation for methods that don't appear using
135-
# the :method:, :singleton-method: and :attr: directives:
136-
#
137-
# ##
138-
# # :attr_writer: ghost_writer
139-
# # There is an attribute here, but you can't see it!
140-
#
141-
# ##
142-
# # :method: ghost_method
143-
# # There is a method here, but you can't see it!
144-
#
145-
# ##
146-
# # this is a comment for a regular method
147-
#
148-
# def regular_method() end
149-
#
150-
# Note that by default, the :method: directive will be ignored if there is a
151-
# standard rdocable item following it.
152-
153-
class RDoc::Parser::Ruby < RDoc::Parser
16+
class RDoc::Parser::RipperRuby < RDoc::Parser
15417

155-
parse_files_matching(/\.rbw?$/)
18+
parse_files_matching(/\.rbw?$/) if ENV['RDOC_USE_RIPPER_PARSER']
15619

15720
include RDoc::TokenStream
15821
include RDoc::Parser::RubyTools

rdoc.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,5 @@ RDoc includes the +rdoc+ and +ri+ tools for generating and displaying documentat
6969
s.add_dependency 'psych', '>= 4.0.0'
7070
s.add_dependency 'erb'
7171
s.add_dependency 'tsort'
72+
s.add_dependency 'prism', '>= 1.0.0'
7273
end

test/rdoc/parser/prism_ruby_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2216,4 +2216,4 @@ def util_parser(content)
22162216
@parser = RDoc::Parser::Ruby.new @top_level, content, @options, @stats
22172217
@parser.scan
22182218
end
2219-
end unless ENV['RDOC_USE_PRISM_PARSER']
2219+
end if ENV['RDOC_USE_RIPPER_PARSER']

0 commit comments

Comments
 (0)