rdoc 6.15.1 → 7.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +196 -0
  3. data/History.rdoc +1 -1
  4. data/LEGAL.rdoc +6 -0
  5. data/README.md +20 -3
  6. data/lib/rdoc/code_object/any_method.rb +15 -7
  7. data/lib/rdoc/code_object/class_module.rb +38 -8
  8. data/lib/rdoc/code_object/constant.rb +9 -0
  9. data/lib/rdoc/code_object/method_attr.rb +13 -1
  10. data/lib/rdoc/code_object/top_level.rb +31 -18
  11. data/lib/rdoc/comment.rb +190 -8
  12. data/lib/rdoc/generator/aliki.rb +183 -0
  13. data/lib/rdoc/generator/darkfish.rb +8 -2
  14. data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +8 -0
  15. data/lib/rdoc/generator/template/aliki/_footer.rhtml +23 -0
  16. data/lib/rdoc/generator/template/aliki/_head.rhtml +158 -0
  17. data/lib/rdoc/generator/template/aliki/_header.rhtml +56 -0
  18. data/lib/rdoc/generator/template/aliki/_icons.rhtml +208 -0
  19. data/lib/rdoc/generator/template/aliki/_sidebar_ancestors.rhtml +16 -0
  20. data/lib/rdoc/generator/template/aliki/_sidebar_classes.rhtml +15 -0
  21. data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +25 -0
  22. data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +25 -0
  23. data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +16 -0
  24. data/lib/rdoc/generator/template/aliki/_sidebar_methods.rhtml +41 -0
  25. data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +67 -0
  26. data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +15 -0
  27. data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +21 -0
  28. data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +3 -0
  29. data/lib/rdoc/generator/template/aliki/class.rhtml +218 -0
  30. data/lib/rdoc/generator/template/aliki/css/rdoc.css +1943 -0
  31. data/lib/rdoc/generator/template/aliki/index.rhtml +22 -0
  32. data/lib/rdoc/generator/template/aliki/js/aliki.js +505 -0
  33. data/lib/rdoc/generator/template/aliki/js/c_highlighter.js +299 -0
  34. data/lib/rdoc/generator/template/aliki/js/search_controller.js +129 -0
  35. data/lib/rdoc/generator/template/aliki/js/search_navigation.js +105 -0
  36. data/lib/rdoc/generator/template/aliki/js/search_ranker.js +239 -0
  37. data/lib/rdoc/generator/template/aliki/js/theme-toggle.js +112 -0
  38. data/lib/rdoc/generator/template/aliki/page.rhtml +18 -0
  39. data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +14 -0
  40. data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +65 -0
  41. data/lib/rdoc/generator/template/darkfish/_head.rhtml +2 -7
  42. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +1 -1
  43. data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +1 -0
  44. data/lib/rdoc/generator/template/darkfish/class.rhtml +9 -11
  45. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +1 -1
  46. data/lib/rdoc/generator/template/json_index/js/searcher.js +5 -1
  47. data/lib/rdoc/generator.rb +1 -0
  48. data/lib/rdoc/markup/blank_line.rb +25 -23
  49. data/lib/rdoc/markup/element.rb +21 -0
  50. data/lib/rdoc/markup/hard_break.rb +30 -27
  51. data/lib/rdoc/markup/heading.rb +96 -79
  52. data/lib/rdoc/markup/pre_process.rb +34 -10
  53. data/lib/rdoc/markup/raw.rb +52 -55
  54. data/lib/rdoc/markup/table.rb +48 -40
  55. data/lib/rdoc/markup/to_ansi.rb +4 -0
  56. data/lib/rdoc/markup/to_bs.rb +4 -0
  57. data/lib/rdoc/markup/to_html.rb +6 -4
  58. data/lib/rdoc/markup/to_rdoc.rb +11 -3
  59. data/lib/rdoc/markup.rb +1 -0
  60. data/lib/rdoc/options.rb +21 -10
  61. data/lib/rdoc/parser/c.rb +15 -46
  62. data/lib/rdoc/parser/prism_ruby.rb +121 -113
  63. data/lib/rdoc/parser/ruby.rb +8 -8
  64. data/lib/rdoc/parser/ruby_tools.rb +5 -7
  65. data/lib/rdoc/parser/simple.rb +4 -21
  66. data/lib/rdoc/rdoc.rb +1 -0
  67. data/lib/rdoc/rubygems_hook.rb +3 -3
  68. data/lib/rdoc/text.rb +1 -1
  69. data/lib/rdoc/token_stream.rb +13 -1
  70. data/lib/rdoc/tom_doc.rb +1 -1
  71. data/lib/rdoc/version.rb +1 -1
  72. data/rdoc.gemspec +1 -1
  73. metadata +34 -5
  74. data/CONTRIBUTING.rdoc +0 -219
data/lib/rdoc/options.rb CHANGED
@@ -378,6 +378,21 @@ class RDoc::Options
378
378
 
379
379
  attr_accessor :canonical_root
380
380
 
381
+ ##
382
+ # Custom footer content configuration for themes that support it.
383
+ # Currently only supported by the Aliki theme.
384
+ #
385
+ # A hash where keys are column titles and values are hashes of link text => URL pairs.
386
+ # Each column will be displayed in the upper footer section.
387
+ #
388
+ # Example:
389
+ # {
390
+ # "DOCUMENTATION" => {"Home" => "/index.html", "Guide" => "/guide.html"},
391
+ # "RESOURCES" => {"RDoc" => "https://ruby.github.io/rdoc/", "GitHub" => "https://github.com/ruby/rdoc"}
392
+ # }
393
+
394
+ attr_accessor :footer_content
395
+
381
396
  def initialize(loaded_options = nil) # :nodoc:
382
397
  init_ivars
383
398
  override loaded_options if loaded_options
@@ -396,10 +411,9 @@ class RDoc::Options
396
411
  @files = nil
397
412
  @force_output = false
398
413
  @force_update = true
399
- @generator = nil
400
- @generator_name = nil
401
- @generator_options = []
414
+ @generator_name = "aliki"
402
415
  @generators = RDoc::RDoc::GENERATORS
416
+ @generator_options = []
403
417
  @hyperlink_all = false
404
418
  @line_numbers = false
405
419
  @locale = nil
@@ -435,6 +449,7 @@ class RDoc::Options
435
449
  @class_module_path_prefix = nil
436
450
  @file_path_prefix = nil
437
451
  @canonical_root = nil
452
+ @footer_content = nil
438
453
  end
439
454
 
440
455
  def init_with(map) # :nodoc:
@@ -463,6 +478,7 @@ class RDoc::Options
463
478
 
464
479
  @apply_default_exclude = map['apply_default_exclude']
465
480
  @autolink_excluded_words = map['autolink_excluded_words']
481
+ @footer_content = map['footer_content']
466
482
 
467
483
  @rdoc_include = sanitize_path map['rdoc_include']
468
484
  @static_path = sanitize_path map['static_path']
@@ -499,6 +515,7 @@ class RDoc::Options
499
515
  @autolink_excluded_words = map['autolink_excluded_words'] if map.has_key?('autolink_excluded_words')
500
516
  @apply_default_exclude = map['apply_default_exclude'] if map.has_key?('apply_default_exclude')
501
517
  @canonical_root = map['canonical_root'] if map.has_key?('canonical_root')
518
+ @footer_content = map['footer_content'] if map.has_key?('footer_content')
502
519
 
503
520
  @warn_missing_rdoc_ref = map['warn_missing_rdoc_ref'] if map.has_key?('warn_missing_rdoc_ref')
504
521
 
@@ -1213,9 +1230,6 @@ Usage: #{opt.program_name} [options] [names...]
1213
1230
  opt.separator nil
1214
1231
  end
1215
1232
 
1216
- setup_generator 'darkfish' if
1217
- argv.grep(/\A(-f|--fmt|--format|-r|-R|--ri|--ri-site)\b/).empty?
1218
-
1219
1233
  deprecated = []
1220
1234
  invalid = []
1221
1235
 
@@ -1233,10 +1247,7 @@ Usage: #{opt.program_name} [options] [names...]
1233
1247
  retry
1234
1248
  end
1235
1249
 
1236
- unless @generator then
1237
- @generator = RDoc::Generator::Darkfish
1238
- @generator_name = 'darkfish'
1239
- end
1250
+ setup_generator unless @generator
1240
1251
 
1241
1252
  if @pipe and not argv.empty? then
1242
1253
  @pipe = false
data/lib/rdoc/parser/c.rb CHANGED
@@ -607,8 +607,6 @@ class RDoc::Parser::C < RDoc::Parser
607
607
  body = args[1]
608
608
  offset, = args[2]
609
609
 
610
- comment.remove_private if comment
611
-
612
610
  # try to find the whole body
613
611
  body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content
614
612
 
@@ -621,11 +619,10 @@ class RDoc::Parser::C < RDoc::Parser
621
619
  override_comment = find_override_comment class_name, meth_obj
622
620
  comment = override_comment if override_comment
623
621
 
624
- comment.normalize
625
622
  find_modifiers comment, meth_obj if comment
626
623
 
627
624
  #meth_obj.params = params
628
- meth_obj.start_collecting_tokens
625
+ meth_obj.start_collecting_tokens(:c)
629
626
  tk = { :line_no => 1, :char_no => 1, :text => body }
630
627
  meth_obj.add_token tk
631
628
  meth_obj.comment = comment
@@ -639,10 +636,9 @@ class RDoc::Parser::C < RDoc::Parser
639
636
 
640
637
  find_body class_name, args[3], meth_obj, file_content, true
641
638
 
642
- comment.normalize
643
639
  find_modifiers comment, meth_obj
644
640
 
645
- meth_obj.start_collecting_tokens
641
+ meth_obj.start_collecting_tokens(:c)
646
642
  tk = { :line_no => 1, :char_no => 1, :text => body }
647
643
  meth_obj.add_token tk
648
644
  meth_obj.comment = comment
@@ -663,7 +659,6 @@ class RDoc::Parser::C < RDoc::Parser
663
659
  comment = find_override_comment class_name, meth_obj
664
660
 
665
661
  if comment then
666
- comment.normalize
667
662
  find_modifiers comment, meth_obj
668
663
  meth_obj.comment = comment
669
664
 
@@ -742,7 +737,6 @@ class RDoc::Parser::C < RDoc::Parser
742
737
  end
743
738
 
744
739
  comment = new_comment comment, @top_level, :c
745
- comment.normalize
746
740
 
747
741
  look_for_directives_in class_mod, comment
748
742
 
@@ -807,9 +801,6 @@ class RDoc::Parser::C < RDoc::Parser
807
801
  # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
808
802
 
809
803
  def find_modifiers(comment, meth_obj)
810
- comment.normalize
811
- meth_obj.call_seq = comment.extract_call_seq
812
-
813
804
  look_for_directives_in meth_obj, comment
814
805
  end
815
806
 
@@ -823,10 +814,10 @@ class RDoc::Parser::C < RDoc::Parser
823
814
  comment = if @content =~ %r%Document-method:
824
815
  \s+#{class_name}#{prefix}#{name}
825
816
  \s*?\n((?>.*?\*/))%xm then
826
- "/*#{$1}"
817
+ "/*\n#{$1}"
827
818
  elsif @content =~ %r%Document-method:
828
819
  \s#{name}\s*?\n((?>.*?\*/))%xm then
829
- "/*#{$1}"
820
+ "/*\n#{$1}"
830
821
  end
831
822
 
832
823
  return unless comment
@@ -1061,10 +1052,13 @@ class RDoc::Parser::C < RDoc::Parser
1061
1052
  # Registers a singleton class +sclass_var+ as a singleton of +class_var+
1062
1053
 
1063
1054
  def handle_singleton(sclass_var, class_var)
1064
- class_name = @known_classes[class_var]
1065
-
1066
- @known_classes[sclass_var] = class_name
1067
- @singleton_classes[sclass_var] = class_name
1055
+ if (klass = @classes[class_var])
1056
+ @classes[sclass_var] = klass
1057
+ end
1058
+ if (class_name = @known_classes[class_var])
1059
+ @known_classes[sclass_var] = class_name
1060
+ @singleton_classes[sclass_var] = class_name
1061
+ end
1068
1062
  end
1069
1063
 
1070
1064
  ##
@@ -1102,35 +1096,10 @@ class RDoc::Parser::C < RDoc::Parser
1102
1096
  # Both :main: and :title: directives are deprecated and will be removed in RDoc 7.
1103
1097
 
1104
1098
  def look_for_directives_in(context, comment)
1105
- @preprocess.handle comment, context do |directive, param|
1106
- case directive
1107
- when 'main' then
1108
- @options.main_page = param
1109
-
1110
- warn <<~MSG
1111
- The :main: directive is deprecated and will be removed in RDoc 7.
1112
-
1113
- You can use these options to specify the initial page displayed instead:
1114
- - `--main=#{param}` via the command line
1115
- - `rdoc.main = "#{param}"` if you use `RDoc::Task`
1116
- - `main_page: #{param}` in your `.rdoc_options` file
1117
- MSG
1118
- ''
1119
- when 'title' then
1120
- @options.default_title = param if @options.respond_to? :default_title=
1121
-
1122
- warn <<~MSG
1123
- The :title: directive is deprecated and will be removed in RDoc 7.
1124
-
1125
- You can use these options to specify the title displayed instead:
1126
- - `--title=#{param}` via the command line
1127
- - `rdoc.title = "#{param}"` if you use `RDoc::Task`
1128
- - `title: #{param}` in your `.rdoc_options` file
1129
- MSG
1130
- ''
1131
- end
1132
- end
1133
-
1099
+ comment.text, format = @preprocess.run_pre_processes(comment.text, context, comment.line || 1, :c)
1100
+ comment.format = format if format
1101
+ @preprocess.run_post_processes(comment, context)
1102
+ comment.normalized = true
1134
1103
  comment
1135
1104
  end
1136
1105
 
@@ -98,9 +98,9 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
98
98
  prepare_comments(result.comments)
99
99
  return if @top_level.done_documenting
100
100
 
101
- @first_non_meta_comment = nil
102
- if (_line_no, start_line, rdoc_comment = @unprocessed_comments.first)
103
- @first_non_meta_comment = rdoc_comment if start_line < @program_node.location.start_line
101
+ @first_non_meta_comment_start_line = nil
102
+ if (_line_no, start_line = @unprocessed_comments.first)
103
+ @first_non_meta_comment_start_line = start_line if start_line < @program_node.location.start_line
104
104
  end
105
105
 
106
106
  @program_node.accept(RDocVisitor.new(self, @top_level, @store))
@@ -150,7 +150,9 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
150
150
  if comment.is_a? Prism::EmbDocComment
151
151
  consecutive_comments << [comment] << (current = [])
152
152
  elsif comment.location.start_line_slice.match?(/\S/)
153
- @modifier_comments[comment.location.start_line] = RDoc::Comment.new(comment.slice, @top_level, :ruby)
153
+ text = comment.slice
154
+ text = RDoc::Encoding.change_encoding(text, @encoding) if @encoding
155
+ @modifier_comments[comment.location.start_line] = text
154
156
  elsif current.empty? || current.last.location.end_line + 1 == comment.location.start_line
155
157
  current << comment
156
158
  else
@@ -172,22 +174,18 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
172
174
  texts = comments.map do |c|
173
175
  c.is_a?(Prism::EmbDocComment) ? c.slice.lines[1...-1].join : c.slice
174
176
  end
175
- text = RDoc::Encoding.change_encoding(texts.join("\n"), @encoding) if @encoding
177
+ text = texts.join("\n")
178
+ text = RDoc::Encoding.change_encoding(text, @encoding) if @encoding
176
179
  line_no += 1 while @lines[line_no - 1]&.match?(/\A\s*$/)
177
- comment = RDoc::Comment.new(text, @top_level, :ruby)
178
- comment.line = start_line
179
- [line_no, start_line, comment]
180
+ [line_no, start_line, text]
180
181
  end
181
182
 
182
183
  # The first comment is special. It defines markup for the rest of the comments.
183
184
  _, first_comment_start_line, first_comment_text = @unprocessed_comments.first
184
185
  if first_comment_text && @lines[0...first_comment_start_line - 1].all? { |l| l.match?(/\A\s*$/) }
185
- comment = RDoc::Comment.new(first_comment_text.text, @top_level, :ruby)
186
- handle_consecutive_comment_directive(@container, comment)
187
- @markup = comment.format
188
- end
189
- @unprocessed_comments.each do |_, _, comment|
190
- comment.format = @markup
186
+ _text, directives = @preprocess.parse_comment(first_comment_text, first_comment_start_line, :ruby)
187
+ markup, = directives['markup']
188
+ @markup = markup.downcase if markup
191
189
  end
192
190
  end
193
191
 
@@ -205,42 +203,25 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
205
203
  meth.call_seq = signature
206
204
  return unless meth.name
207
205
 
208
- meth.start_collecting_tokens
206
+ meth.start_collecting_tokens(:ruby)
209
207
  node = @line_nodes[line_no]
210
208
  tokens = node ? visible_tokens_from_location(node.location) : [file_line_comment_token(start_line)]
211
209
  tokens.each { |token| meth.token_stream << token }
212
210
 
213
211
  container.add_method meth
214
- comment.remove_private
215
- comment.normalize
216
212
  meth.comment = comment
217
213
  @stats.add_method meth
218
214
  end
219
215
 
220
216
  def has_modifier_nodoc?(line_no) # :nodoc:
221
- @modifier_comments[line_no]&.text&.match?(/\A#\s*:nodoc:/)
217
+ @modifier_comments[line_no]&.match?(/\A#\s*:nodoc:/)
222
218
  end
223
219
 
224
220
  def handle_modifier_directive(code_object, line_no) # :nodoc:
225
- comment = @modifier_comments[line_no]
226
- @preprocess.handle(comment.text, code_object) if comment
227
- end
228
-
229
- def handle_consecutive_comment_directive(code_object, comment) # :nodoc:
230
- return unless comment
231
- @preprocess.handle(comment, code_object) do |directive, param|
232
- case directive
233
- when 'method', 'singleton-method',
234
- 'attr', 'attr_accessor', 'attr_reader', 'attr_writer' then
235
- # handled elsewhere
236
- ''
237
- when 'section' then
238
- @container.set_current_section(param, comment.dup)
239
- comment.text = ''
240
- break
241
- end
221
+ if (comment_text = @modifier_comments[line_no])
222
+ _text, directives = @preprocess.parse_comment(comment_text, line_no, :ruby)
223
+ handle_code_object_directives(code_object, directives)
242
224
  end
243
- comment.remove_private
244
225
  end
245
226
 
246
227
  def call_node_name_arguments(call_node) # :nodoc:
@@ -257,39 +238,32 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
257
238
 
258
239
  # Handles meta method comments
259
240
 
260
- def handle_meta_method_comment(comment, node)
241
+ def handle_meta_method_comment(comment, directives, node)
242
+ handle_code_object_directives(@container, directives)
261
243
  is_call_node = node.is_a?(Prism::CallNode)
262
244
  singleton_method = false
263
245
  visibility = @visibility
264
246
  attributes = rw = line_no = method_name = nil
265
-
266
- processed_comment = comment.dup
267
- @preprocess.handle(processed_comment, @container) do |directive, param, line|
247
+ directives.each do |directive, (param, line)|
268
248
  case directive
269
249
  when 'attr', 'attr_reader', 'attr_writer', 'attr_accessor'
270
250
  attributes = [param] if param
271
251
  attributes ||= call_node_name_arguments(node) if is_call_node
272
252
  rw = directive == 'attr_writer' ? 'W' : directive == 'attr_accessor' ? 'RW' : 'R'
273
- ''
274
253
  when 'method'
275
- method_name = param
254
+ method_name = param if param
276
255
  line_no = line
277
- ''
278
256
  when 'singleton-method'
279
- method_name = param
257
+ method_name = param if param
280
258
  line_no = line
281
259
  singleton_method = true
282
260
  visibility = :public
283
- ''
284
- when 'section' then
285
- @container.set_current_section(param, comment.dup)
286
- return # If the comment contains :section:, it is not a meta method comment
287
261
  end
288
262
  end
289
263
 
290
264
  if attributes
291
265
  attributes.each do |attr|
292
- a = RDoc::Attr.new(@container, attr, rw, processed_comment, singleton: @singleton)
266
+ a = RDoc::Attr.new(@container, attr, rw, comment, singleton: @singleton)
293
267
  a.store = @store
294
268
  a.line = line_no
295
269
  record_location(a)
@@ -298,11 +272,6 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
298
272
  end
299
273
  elsif line_no || node
300
274
  method_name ||= call_node_name_arguments(node).first if is_call_node
301
- meth = RDoc::AnyMethod.new(@container, method_name, singleton: @singleton || singleton_method)
302
- handle_consecutive_comment_directive(meth, comment)
303
- comment.normalize
304
- meth.call_seq = comment.extract_call_seq
305
- meth.comment = comment
306
275
  if node
307
276
  tokens = visible_tokens_from_location(node.location)
308
277
  line_no = node.location.start_line
@@ -310,37 +279,41 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
310
279
  tokens = [file_line_comment_token(line_no)]
311
280
  end
312
281
  internal_add_method(
282
+ method_name,
313
283
  @container,
314
- meth,
284
+ comment: comment,
285
+ directives: directives,
286
+ dont_rename_initialize: false,
315
287
  line_no: line_no,
316
288
  visibility: visibility,
317
- params: '()',
289
+ singleton: @singleton || singleton_method,
290
+ params: nil,
318
291
  calls_super: false,
319
292
  block_params: nil,
320
- tokens: tokens
293
+ tokens: tokens,
321
294
  )
322
295
  end
323
296
  end
324
297
 
325
- def normal_comment_treat_as_ghost_method_for_now?(comment_text, line_no) # :nodoc:
298
+ INVALID_GHOST_METHOD_ACCEPT_DIRECTIVE_LIST = %w[
299
+ method singleton-method attr attr_reader attr_writer attr_accessor
300
+ ].freeze
301
+ private_constant :INVALID_GHOST_METHOD_ACCEPT_DIRECTIVE_LIST
302
+
303
+ def normal_comment_treat_as_ghost_method_for_now?(directives, line_no) # :nodoc:
326
304
  # Meta method comment should start with `##` but some comments does not follow this rule.
327
305
  # For now, RDoc accepts them as a meta method comment if there is no node linked to it.
328
- !@line_nodes[line_no] && comment_text.match?(/^#\s+:(method|singleton-method|attr|attr_reader|attr_writer|attr_accessor):/)
306
+ !@line_nodes[line_no] && INVALID_GHOST_METHOD_ACCEPT_DIRECTIVE_LIST.any? { |directive| directives.has_key?(directive) }
329
307
  end
330
308
 
331
- def handle_standalone_consecutive_comment_directive(comment, line_no, start_line) # :nodoc:
332
- if @markup == 'tomdoc'
333
- parse_comment_tomdoc(@container, comment, line_no, start_line)
334
- return
335
- end
336
-
337
- if comment.text =~ /\A#\#$/ && comment != @first_non_meta_comment
309
+ def handle_standalone_consecutive_comment_directive(comment, directives, start_with_sharp_sharp, line_no, start_line) # :nodoc:
310
+ if start_with_sharp_sharp && start_line != @first_non_meta_comment_start_line
338
311
  node = @line_nodes[line_no]
339
- handle_meta_method_comment(comment, node)
340
- elsif normal_comment_treat_as_ghost_method_for_now?(comment.text, line_no) && comment != @first_non_meta_comment
341
- handle_meta_method_comment(comment, nil)
312
+ handle_meta_method_comment(comment, directives, node)
313
+ elsif normal_comment_treat_as_ghost_method_for_now?(directives, line_no) && start_line != @first_non_meta_comment_start_line
314
+ handle_meta_method_comment(comment, directives, nil)
342
315
  else
343
- handle_consecutive_comment_directive(@container, comment)
316
+ handle_code_object_directives(@container, directives)
344
317
  end
345
318
  end
346
319
 
@@ -348,8 +321,15 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
348
321
 
349
322
  def process_comments_until(line_no_until)
350
323
  while !@unprocessed_comments.empty? && @unprocessed_comments.first[0] <= line_no_until
351
- line_no, start_line, rdoc_comment = @unprocessed_comments.shift
352
- handle_standalone_consecutive_comment_directive(rdoc_comment, line_no, start_line)
324
+ line_no, start_line, text = @unprocessed_comments.shift
325
+ if @markup == 'tomdoc'
326
+ comment = RDoc::Comment.new(text, @top_level, :ruby)
327
+ comment.format = 'tomdoc'
328
+ parse_comment_tomdoc(@container, comment, line_no, start_line)
329
+ @preprocess.run_post_processes(comment, @container)
330
+ elsif (comment_text, directives = parse_comment_text_to_directives(text, start_line))
331
+ handle_standalone_consecutive_comment_directive(comment_text, directives, text.start_with?(/#\#$/), line_no, start_line)
332
+ end
353
333
  end
354
334
  end
355
335
 
@@ -365,9 +345,27 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
365
345
  # Returns consecutive comment linked to the given line number
366
346
 
367
347
  def consecutive_comment(line_no)
368
- if @unprocessed_comments.first&.first == line_no
369
- @unprocessed_comments.shift.last
348
+ return unless @unprocessed_comments.first&.first == line_no
349
+ _line_no, start_line, text = @unprocessed_comments.shift
350
+ parse_comment_text_to_directives(text, start_line)
351
+ end
352
+
353
+ # Parses comment text and retuns a pair of RDoc::Comment and directives
354
+
355
+ def parse_comment_text_to_directives(comment_text, start_line) # :nodoc:
356
+ comment_text, directives = @preprocess.parse_comment(comment_text, start_line, :ruby)
357
+ comment = RDoc::Comment.new(comment_text, @top_level, :ruby)
358
+ comment.normalized = true
359
+ comment.line = start_line
360
+ markup, = directives['markup']
361
+ comment.format = markup&.downcase || @markup
362
+ if (section, = directives['section'])
363
+ # If comment has :section:, it is not a documentable comment for a code object
364
+ @container.set_current_section(section, comment.dup)
365
+ return
370
366
  end
367
+ @preprocess.run_post_processes(comment, @container)
368
+ [comment, directives]
371
369
  end
372
370
 
373
371
  def slice_tokens(start_pos, end_pos) # :nodoc:
@@ -443,11 +441,17 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
443
441
  end
444
442
  end
445
443
 
444
+ def handle_code_object_directives(code_object, directives) # :nodoc:
445
+ directives.each do |directive, (param)|
446
+ @preprocess.handle_directive('', directive, param, code_object)
447
+ end
448
+ end
449
+
446
450
  # Handles `alias foo bar` and `alias_method :foo, :bar`
447
451
 
448
452
  def add_alias_method(old_name, new_name, line_no)
449
- comment = consecutive_comment(line_no)
450
- handle_consecutive_comment_directive(@container, comment)
453
+ comment, directives = consecutive_comment(line_no)
454
+ handle_code_object_directives(@container, directives) if directives
451
455
  visibility = @container.find_method(old_name, @singleton)&.visibility || :public
452
456
  a = RDoc::Alias.new(nil, old_name, new_name, comment, singleton: @singleton)
453
457
  handle_modifier_directive(a, line_no)
@@ -463,8 +467,8 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
463
467
  # Handles `attr :a, :b`, `attr_reader :a, :b`, `attr_writer :a, :b` and `attr_accessor :a, :b`
464
468
 
465
469
  def add_attributes(names, rw, line_no)
466
- comment = consecutive_comment(line_no)
467
- handle_consecutive_comment_directive(@container, comment)
470
+ comment, directives = consecutive_comment(line_no)
471
+ handle_code_object_directives(@container, directives) if directives
468
472
  return unless @container.document_children
469
473
 
470
474
  names.each do |symbol|
@@ -480,8 +484,8 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
480
484
 
481
485
  def add_includes_extends(names, rdoc_class, line_no) # :nodoc:
482
486
  return if @in_proc_block
483
- comment = consecutive_comment(line_no)
484
- handle_consecutive_comment_directive(@container, comment)
487
+ comment, directives = consecutive_comment(line_no)
488
+ handle_code_object_directives(@container, directives) if directives
485
489
  names.each do |name|
486
490
  ie = @container.add(rdoc_class, name, '')
487
491
  ie.store = @store
@@ -505,63 +509,67 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
505
509
 
506
510
  # Adds a method defined by `def` syntax
507
511
 
508
- def add_method(name, receiver_name:, receiver_fallback_type:, visibility:, singleton:, params:, calls_super:, block_params:, tokens:, start_line:, args_end_line:, end_line:)
512
+ def add_method(method_name, receiver_name:, receiver_fallback_type:, visibility:, singleton:, params:, calls_super:, block_params:, tokens:, start_line:, args_end_line:, end_line:)
509
513
  return if @in_proc_block
510
514
 
511
515
  receiver = receiver_name ? find_or_create_module_path(receiver_name, receiver_fallback_type) : @container
512
- meth = RDoc::AnyMethod.new(nil, name, singleton: singleton)
513
- if (comment = consecutive_comment(start_line))
514
- handle_consecutive_comment_directive(@container, comment)
515
- handle_consecutive_comment_directive(meth, comment)
516
-
517
- comment.normalize
518
- meth.call_seq = comment.extract_call_seq
519
- meth.comment = comment
520
- end
521
- handle_modifier_directive(meth, start_line)
522
- handle_modifier_directive(meth, args_end_line)
523
- handle_modifier_directive(meth, end_line)
524
- return unless should_document?(meth)
516
+ comment, directives = consecutive_comment(start_line)
517
+ handle_code_object_directives(@container, directives) if directives
525
518
 
526
519
  internal_add_method(
520
+ method_name,
527
521
  receiver,
528
- meth,
522
+ comment: comment,
523
+ directives: directives,
524
+ modifier_comment_lines: [start_line, args_end_line, end_line].uniq,
529
525
  line_no: start_line,
530
526
  visibility: visibility,
527
+ singleton: singleton,
531
528
  params: params,
532
529
  calls_super: calls_super,
533
530
  block_params: block_params,
534
531
  tokens: tokens
535
532
  )
533
+ end
536
534
 
537
- # Rename after add_method to register duplicated 'new' and 'initialize'
538
- # defined in c and ruby just like the old parser did.
539
- if meth.name == 'initialize' && !singleton
540
- if meth.dont_rename_initialize
541
- meth.visibility = :protected
542
- else
543
- meth.name = 'new'
544
- meth.singleton = true
545
- meth.visibility = :public
546
- end
535
+ private def internal_add_method(method_name, container, comment:, dont_rename_initialize: false, directives:, modifier_comment_lines: nil, line_no:, visibility:, singleton:, params:, calls_super:, block_params:, tokens:) # :nodoc:
536
+ meth = RDoc::AnyMethod.new(nil, method_name, singleton: singleton)
537
+ meth.comment = comment
538
+ handle_code_object_directives(meth, directives) if directives
539
+ modifier_comment_lines&.each do |line|
540
+ handle_modifier_directive(meth, line)
547
541
  end
548
- end
542
+ return unless should_document?(meth)
549
543
 
550
- private def internal_add_method(container, meth, line_no:, visibility:, params:, calls_super:, block_params:, tokens:) # :nodoc:
544
+ if directives && (call_seq, = directives['call-seq'])
545
+ meth.call_seq = call_seq.lines.map(&:chomp).reject(&:empty?).join("\n") if call_seq
546
+ end
551
547
  meth.name ||= meth.call_seq[/\A[^()\s]+/] if meth.call_seq
552
548
  meth.name ||= 'unknown'
553
549
  meth.store = @store
554
550
  meth.line = line_no
555
551
  container.add_method(meth) # should add after setting singleton and before setting visibility
556
552
  meth.visibility = visibility
557
- meth.params ||= params
553
+ meth.params ||= params || '()'
558
554
  meth.calls_super = calls_super
559
555
  meth.block_params ||= block_params if block_params
560
556
  record_location(meth)
561
- meth.start_collecting_tokens
557
+ meth.start_collecting_tokens(:ruby)
562
558
  tokens.each do |token|
563
559
  meth.token_stream << token
564
560
  end
561
+
562
+ # Rename after add_method to register duplicated 'new' and 'initialize'
563
+ # defined in c and ruby just like the old parser did.
564
+ if !dont_rename_initialize && method_name == 'initialize' && !singleton
565
+ if meth.dont_rename_initialize
566
+ meth.visibility = :protected
567
+ else
568
+ meth.name = 'new'
569
+ meth.singleton = true
570
+ meth.visibility = :public
571
+ end
572
+ end
565
573
  end
566
574
 
567
575
  # Find or create module or class from a given module name.
@@ -633,8 +641,8 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
633
641
  # Adds a constant
634
642
 
635
643
  def add_constant(constant_name, rhs_name, start_line, end_line)
636
- comment = consecutive_comment(start_line)
637
- handle_consecutive_comment_directive(@container, comment)
644
+ comment, directives = consecutive_comment(start_line)
645
+ handle_code_object_directives(@container, directives) if directives
638
646
  owner, name = find_or_create_constant_owner_name(constant_name)
639
647
  return unless owner
640
648
 
@@ -662,8 +670,8 @@ class RDoc::Parser::PrismRuby < RDoc::Parser
662
670
  # Adds module or class
663
671
 
664
672
  def add_module_or_class(module_name, start_line, end_line, is_class: false, superclass_name: nil, superclass_expr: nil)
665
- comment = consecutive_comment(start_line)
666
- handle_consecutive_comment_directive(@container, comment)
673
+ comment, directives = consecutive_comment(start_line)
674
+ handle_code_object_directives(@container, directives) if directives
667
675
  return unless @container.document_children
668
676
 
669
677
  owner, name = find_or_create_constant_owner_name(module_name)