rdoc 5.0.0 → 6.3.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rdoc might be problematic. Click here for more details.

Files changed (158) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTING.rdoc +4 -4
  3. data/Gemfile +9 -0
  4. data/History.rdoc +12 -2
  5. data/README.rdoc +5 -6
  6. data/Rakefile +35 -65
  7. data/lib/rdoc/alias.rb +1 -1
  8. data/lib/rdoc/anon_class.rb +1 -1
  9. data/lib/rdoc/any_method.rb +59 -15
  10. data/lib/rdoc/attr.rb +1 -1
  11. data/lib/rdoc/class_module.rb +5 -3
  12. data/lib/rdoc/code_object.rb +2 -9
  13. data/lib/rdoc/code_objects.rb +1 -1
  14. data/lib/rdoc/comment.rb +32 -11
  15. data/lib/rdoc/constant.rb +3 -3
  16. data/lib/rdoc/context/section.rb +1 -14
  17. data/lib/rdoc/context.rb +74 -21
  18. data/lib/rdoc/cross_reference.rb +33 -15
  19. data/lib/rdoc/encoding.rb +58 -30
  20. data/lib/rdoc/erb_partial.rb +2 -2
  21. data/lib/rdoc/erbio.rb +8 -4
  22. data/lib/rdoc/extend.rb +1 -1
  23. data/lib/rdoc/generator/darkfish.rb +60 -29
  24. data/lib/rdoc/generator/json_index.rb +7 -4
  25. data/lib/rdoc/generator/markup.rb +3 -13
  26. data/lib/rdoc/generator/pot/message_extractor.rb +1 -1
  27. data/lib/rdoc/generator/pot/po.rb +3 -3
  28. data/lib/rdoc/generator/pot/po_entry.rb +11 -11
  29. data/lib/rdoc/generator/pot.rb +4 -4
  30. data/lib/rdoc/generator/ri.rb +1 -1
  31. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +2 -2
  32. data/lib/rdoc/generator/template/darkfish/_head.rhtml +9 -7
  33. data/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +2 -2
  34. data/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +2 -2
  35. data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +7 -7
  36. data/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +2 -2
  37. data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +7 -7
  38. data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +6 -6
  39. data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +5 -5
  40. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +5 -5
  41. data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +5 -5
  42. data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +4 -4
  43. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +4 -4
  44. data/lib/rdoc/generator/template/darkfish/class.rhtml +45 -47
  45. data/lib/rdoc/generator/template/darkfish/css/rdoc.css +55 -6
  46. data/lib/rdoc/generator/template/darkfish/index.rhtml +3 -4
  47. data/lib/rdoc/generator/template/darkfish/js/darkfish.js +22 -99
  48. data/lib/rdoc/generator/template/darkfish/js/search.js +32 -31
  49. data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +15 -16
  50. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +16 -16
  51. data/lib/rdoc/generator/template/json_index/js/navigation.js +4 -41
  52. data/lib/rdoc/generator/template/json_index/js/searcher.js +6 -6
  53. data/lib/rdoc/generator.rb +1 -1
  54. data/lib/rdoc/ghost_method.rb +1 -1
  55. data/lib/rdoc/i18n/locale.rb +2 -2
  56. data/lib/rdoc/i18n/text.rb +5 -5
  57. data/lib/rdoc/i18n.rb +3 -3
  58. data/lib/rdoc/include.rb +1 -1
  59. data/lib/rdoc/known_classes.rb +1 -1
  60. data/lib/rdoc/markdown/entities.rb +1 -1
  61. data/lib/rdoc/markdown/literals.kpeg +1 -0
  62. data/lib/rdoc/markdown/literals.rb +19 -7
  63. data/lib/rdoc/markdown.kpeg +92 -44
  64. data/lib/rdoc/markdown.rb +1171 -610
  65. data/lib/rdoc/markup/attr_changer.rb +1 -1
  66. data/lib/rdoc/markup/attr_span.rb +9 -3
  67. data/lib/rdoc/markup/attribute_manager.rb +115 -50
  68. data/lib/rdoc/markup/attributes.rb +7 -7
  69. data/lib/rdoc/markup/blank_line.rb +1 -1
  70. data/lib/rdoc/markup/block_quote.rb +1 -1
  71. data/lib/rdoc/markup/document.rb +1 -1
  72. data/lib/rdoc/markup/formatter.rb +25 -24
  73. data/lib/rdoc/markup/hard_break.rb +1 -1
  74. data/lib/rdoc/markup/heading.rb +4 -4
  75. data/lib/rdoc/markup/include.rb +1 -1
  76. data/lib/rdoc/markup/indented_paragraph.rb +1 -1
  77. data/lib/rdoc/markup/list.rb +1 -1
  78. data/lib/rdoc/markup/list_item.rb +1 -1
  79. data/lib/rdoc/markup/paragraph.rb +1 -1
  80. data/lib/rdoc/markup/parser.rb +79 -47
  81. data/lib/rdoc/markup/pre_process.rb +11 -6
  82. data/lib/rdoc/markup/raw.rb +1 -1
  83. data/lib/rdoc/markup/regexp_handling.rb +41 -0
  84. data/lib/rdoc/markup/rule.rb +1 -1
  85. data/lib/rdoc/markup/to_ansi.rb +1 -1
  86. data/lib/rdoc/markup/to_bs.rb +4 -4
  87. data/lib/rdoc/markup/to_html.rb +71 -26
  88. data/lib/rdoc/markup/to_html_crossref.rb +41 -26
  89. data/lib/rdoc/markup/to_html_snippet.rb +10 -10
  90. data/lib/rdoc/markup/to_joined_paragraph.rb +7 -32
  91. data/lib/rdoc/markup/to_label.rb +10 -10
  92. data/lib/rdoc/markup/to_markdown.rb +9 -9
  93. data/lib/rdoc/markup/to_rdoc.rb +35 -7
  94. data/lib/rdoc/markup/to_table_of_contents.rb +2 -1
  95. data/lib/rdoc/markup/to_test.rb +1 -1
  96. data/lib/rdoc/markup/to_tt_only.rb +3 -3
  97. data/lib/rdoc/markup/verbatim.rb +1 -1
  98. data/lib/rdoc/markup.rb +14 -17
  99. data/lib/rdoc/meta_method.rb +1 -1
  100. data/lib/rdoc/method_attr.rb +2 -2
  101. data/lib/rdoc/mixin.rb +1 -1
  102. data/lib/rdoc/normal_class.rb +3 -3
  103. data/lib/rdoc/normal_module.rb +1 -1
  104. data/lib/rdoc/options.rb +79 -21
  105. data/lib/rdoc/parser/c.rb +147 -194
  106. data/lib/rdoc/parser/changelog.rb +150 -19
  107. data/lib/rdoc/parser/markdown.rb +1 -1
  108. data/lib/rdoc/parser/rd.rb +1 -1
  109. data/lib/rdoc/parser/ripper_state_lex.rb +590 -0
  110. data/lib/rdoc/parser/ruby.rb +634 -465
  111. data/lib/rdoc/parser/ruby_tools.rb +33 -34
  112. data/lib/rdoc/parser/simple.rb +3 -3
  113. data/lib/rdoc/parser/text.rb +1 -1
  114. data/lib/rdoc/parser.rb +12 -35
  115. data/lib/rdoc/rd/block_parser.rb +109 -108
  116. data/lib/rdoc/rd/block_parser.ry +3 -3
  117. data/lib/rdoc/rd/inline.rb +5 -5
  118. data/lib/rdoc/rd/inline_parser.rb +186 -185
  119. data/lib/rdoc/rd/inline_parser.ry +1 -1
  120. data/lib/rdoc/rd.rb +1 -1
  121. data/lib/rdoc/rdoc.rb +54 -41
  122. data/lib/rdoc/require.rb +1 -1
  123. data/lib/rdoc/ri/driver.rb +132 -42
  124. data/lib/rdoc/ri/formatter.rb +1 -1
  125. data/lib/rdoc/ri/paths.rb +4 -18
  126. data/lib/rdoc/ri/store.rb +1 -1
  127. data/lib/rdoc/ri/task.rb +2 -2
  128. data/lib/rdoc/ri.rb +1 -1
  129. data/lib/rdoc/rubygems_hook.rb +3 -3
  130. data/lib/rdoc/servlet.rb +21 -12
  131. data/lib/rdoc/single_class.rb +1 -1
  132. data/lib/rdoc/stats/normal.rb +24 -18
  133. data/lib/rdoc/stats/quiet.rb +1 -1
  134. data/lib/rdoc/stats/verbose.rb +1 -1
  135. data/lib/rdoc/stats.rb +1 -1
  136. data/lib/rdoc/store.rb +38 -27
  137. data/lib/rdoc/task.rb +2 -2
  138. data/lib/rdoc/text.rb +16 -21
  139. data/lib/rdoc/token_stream.rb +56 -33
  140. data/lib/rdoc/tom_doc.rb +17 -12
  141. data/lib/rdoc/top_level.rb +9 -3
  142. data/lib/rdoc/version.rb +8 -0
  143. data/lib/rdoc.rb +24 -10
  144. data/man/ri.1 +247 -0
  145. data/rdoc.gemspec +206 -15
  146. metadata +15 -64
  147. data/.document +0 -5
  148. data/.gitignore +0 -13
  149. data/.travis.yml +0 -23
  150. data/lib/gauntlet_rdoc.rb +0 -82
  151. data/lib/rdoc/generator/template/darkfish/js/jquery.js +0 -4
  152. data/lib/rdoc/markup/formatter_test_case.rb +0 -764
  153. data/lib/rdoc/markup/inline.rb +0 -2
  154. data/lib/rdoc/markup/special.rb +0 -41
  155. data/lib/rdoc/markup/text_formatter_test_case.rb +0 -115
  156. data/lib/rdoc/ruby_lex.rb +0 -1367
  157. data/lib/rdoc/ruby_token.rb +0 -461
  158. data/lib/rdoc/test_case.rb +0 -204
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  ##
3
3
  # This file contains stuff stolen outright from:
4
4
  #
@@ -8,8 +8,6 @@
8
8
  # by Keiju ISHITSUKA (Nippon Rational Inc.)
9
9
  #
10
10
 
11
- $TOKEN_DEBUG ||= nil
12
-
13
11
  ##
14
12
  # Extracts code elements from a source file returning a TopLevel object
15
13
  # containing the constituent file elements.
@@ -24,6 +22,7 @@ $TOKEN_DEBUG ||= nil
24
22
  # * aliases
25
23
  # * private, public, protected
26
24
  # * private_class_function, public_class_function
25
+ # * private_constant, public_constant
27
26
  # * module_function
28
27
  # * attr, attr_reader, attr_writer, attr_accessor
29
28
  # * extra accessors given on the command line
@@ -139,11 +138,13 @@ $TOKEN_DEBUG ||= nil
139
138
  # Note that by default, the :method: directive will be ignored if there is a
140
139
  # standard rdocable item following it.
141
140
 
141
+ require 'ripper'
142
+ require_relative 'ripper_state_lex'
143
+
142
144
  class RDoc::Parser::Ruby < RDoc::Parser
143
145
 
144
146
  parse_files_matching(/\.rbw?$/)
145
147
 
146
- include RDoc::RubyToken
147
148
  include RDoc::TokenStream
148
149
  include RDoc::Parser::RubyTools
149
150
 
@@ -163,10 +164,22 @@ class RDoc::Parser::Ruby < RDoc::Parser
163
164
  def initialize(top_level, file_name, content, options, stats)
164
165
  super
165
166
 
167
+ if /\t/ =~ content then
168
+ tab_width = @options.tab_width
169
+ content = content.split(/\n/).map do |line|
170
+ 1 while line.gsub!(/\t+/) {
171
+ ' ' * (tab_width*$&.length - $`.length % tab_width)
172
+ } && $~
173
+ line
174
+ end.join("\n")
175
+ end
176
+
166
177
  @size = 0
167
178
  @token_listeners = nil
168
- @scanner = RDoc::RubyLex.new content, @options
169
- @scanner.exception_on_syntax_error = false
179
+ content = RDoc::Encoding.remove_magic_comment content
180
+ @scanner = RDoc::Parser::RipperStateLex.parse(content)
181
+ @content = content
182
+ @scanner_point = 0
170
183
  @prev_seek = nil
171
184
  @markup = @options.markup
172
185
  @track_visibility = :nodoc != @options.visibility
@@ -175,6 +188,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
175
188
  reset
176
189
  end
177
190
 
191
+ def tk_nl?(tk)
192
+ :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]
193
+ end
194
+
178
195
  ##
179
196
  # Retrieves the read token stream and replaces +pattern+ with +replacement+
180
197
  # using gsub. If the result is only a ";" returns an empty string.
@@ -194,7 +211,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
194
211
  # methods.
195
212
 
196
213
  def get_visibility_information tk, single # :nodoc:
197
- vis_type = tk.name
214
+ vis_type = tk[:text]
198
215
  singleton = single == SINGLE
199
216
 
200
217
  vis =
@@ -223,31 +240,34 @@ class RDoc::Parser::Ruby < RDoc::Parser
223
240
 
224
241
  def collect_first_comment
225
242
  skip_tkspace
226
- comment = ''
227
- comment.force_encoding @encoding if @encoding
243
+ comment = ''.dup
244
+ comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
228
245
  first_line = true
229
- first_comment_tk_class = nil
246
+ first_comment_tk_kind = nil
247
+ line_no = nil
230
248
 
231
249
  tk = get_tk
232
250
 
233
- while TkCOMMENT === tk
234
- if first_line and tk.text =~ /\A#!/ then
251
+ while tk && (:on_comment == tk[:kind] or :on_embdoc == tk[:kind])
252
+ comment_body = retrieve_comment_body(tk)
253
+ if first_line and comment_body =~ /\A#!/ then
235
254
  skip_tkspace
236
255
  tk = get_tk
237
- elsif first_line and tk.text =~ /\A#\s*-\*-/ then
256
+ elsif first_line and comment_body =~ /\A#\s*-\*-/ then
238
257
  first_line = false
239
258
  skip_tkspace
240
259
  tk = get_tk
241
260
  else
242
- break if first_comment_tk_class and not first_comment_tk_class === tk
243
- first_comment_tk_class = tk.class
261
+ break if first_comment_tk_kind and not first_comment_tk_kind === tk[:kind]
262
+ first_comment_tk_kind = tk[:kind]
244
263
 
264
+ line_no = tk[:line_no] if first_line
245
265
  first_line = false
246
- comment << tk.text << "\n"
266
+ comment << comment_body
247
267
  tk = get_tk
248
268
 
249
- if TkNL === tk then
250
- skip_tkspace false
269
+ if :on_nl === tk then
270
+ skip_tkspace_without_nl
251
271
  tk = get_tk
252
272
  end
253
273
  end
@@ -255,15 +275,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
255
275
 
256
276
  unget_tk tk
257
277
 
258
- new_comment comment
278
+ new_comment comment, line_no
259
279
  end
260
280
 
261
281
  ##
262
282
  # Consumes trailing whitespace from the token stream
263
283
 
264
284
  def consume_trailing_spaces # :nodoc:
265
- get_tkread
266
- skip_tkspace false
285
+ skip_tkspace_without_nl
267
286
  end
268
287
 
269
288
  ##
@@ -290,7 +309,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
290
309
  container.find_module_named rhs_name
291
310
  end
292
311
 
293
- container.add_module_alias mod, constant.name, @top_level if mod
312
+ container.add_module_alias mod, rhs_name, constant, @top_level
294
313
  end
295
314
 
296
315
  ##
@@ -303,16 +322,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
303
322
  end
304
323
 
305
324
  ##
306
- # Looks for a true or false token. Returns false if TkFALSE or TkNIL are
307
- # found.
325
+ # Looks for a true or false token.
308
326
 
309
327
  def get_bool
310
328
  skip_tkspace
311
329
  tk = get_tk
312
- case tk
313
- when TkTRUE
330
+ if :on_kw == tk[:kind] && 'true' == tk[:text]
314
331
  true
315
- when TkFALSE, TkNIL
332
+ elsif :on_kw == tk[:kind] && ('false' == tk[:text] || 'nil' == tk[:text])
316
333
  false
317
334
  else
318
335
  unget_tk tk
@@ -328,27 +345,31 @@ class RDoc::Parser::Ruby < RDoc::Parser
328
345
  def get_class_or_module container, ignore_constants = false
329
346
  skip_tkspace
330
347
  name_t = get_tk
331
- given_name = ''
348
+ given_name = ''.dup
332
349
 
333
350
  # class ::A -> A is in the top level
334
- case name_t
335
- when TkCOLON2, TkCOLON3 then # bug
351
+ if :on_op == name_t[:kind] and '::' == name_t[:text] then # bug
336
352
  name_t = get_tk
337
353
  container = @top_level
338
354
  given_name << '::'
339
355
  end
340
356
 
341
- skip_tkspace false
342
- given_name << name_t.name
357
+ skip_tkspace_without_nl
358
+ given_name << name_t[:text]
343
359
 
344
- while TkCOLON2 === peek_tk do
360
+ is_self = name_t[:kind] == :on_op && name_t[:text] == '<<'
361
+ new_modules = []
362
+ while !is_self && (tk = peek_tk) and :on_op == tk[:kind] and '::' == tk[:text] do
345
363
  prev_container = container
346
- container = container.find_module_named name_t.name
364
+ container = container.find_module_named name_t[:text]
347
365
  container ||=
348
366
  if ignore_constants then
349
- RDoc::Context.new
367
+ c = RDoc::NormalModule.new name_t[:text]
368
+ c.store = @store
369
+ new_modules << [prev_container, c]
370
+ c
350
371
  else
351
- c = prev_container.add_module RDoc::NormalModule, name_t.name
372
+ c = prev_container.add_module RDoc::NormalModule, name_t[:text]
352
373
  c.ignore unless prev_container.document_children
353
374
  @top_level.add_to_classes_or_modules c
354
375
  c
@@ -357,35 +378,51 @@ class RDoc::Parser::Ruby < RDoc::Parser
357
378
  record_location container
358
379
 
359
380
  get_tk
360
- skip_tkspace false
381
+ skip_tkspace
382
+ if :on_lparen == peek_tk[:kind] # ProcObjectInConstant::()
383
+ parse_method_or_yield_parameters
384
+ break
385
+ end
361
386
  name_t = get_tk
362
- given_name << '::' << name_t.name
387
+ unless :on_const == name_t[:kind] || :on_ident == name_t[:kind]
388
+ raise RDoc::Error, "Invalid class or module definition: #{given_name}"
389
+ end
390
+ if prev_container == container and !ignore_constants
391
+ given_name = name_t[:text]
392
+ else
393
+ given_name << '::' + name_t[:text]
394
+ end
363
395
  end
364
396
 
365
- skip_tkspace false
397
+ skip_tkspace_without_nl
366
398
 
367
- return [container, name_t, given_name]
399
+ return [container, name_t, given_name, new_modules]
368
400
  end
369
401
 
370
402
  ##
371
403
  # Return a superclass, which can be either a constant of an expression
372
404
 
373
405
  def get_class_specification
374
- case peek_tk
375
- when TkSELF then return 'self'
376
- when TkGVAR then return ''
406
+ tk = peek_tk
407
+ if tk.nil?
408
+ return ''
409
+ elsif :on_kw == tk[:kind] && 'self' == tk[:text]
410
+ return 'self'
411
+ elsif :on_gvar == tk[:kind]
412
+ return ''
377
413
  end
378
414
 
379
415
  res = get_constant
380
416
 
381
- skip_tkspace false
417
+ skip_tkspace_without_nl
382
418
 
383
419
  get_tkread # empty out read buffer
384
420
 
385
421
  tk = get_tk
422
+ return res unless tk
386
423
 
387
- case tk
388
- when TkNL, TkCOMMENT, TkSEMICOLON then
424
+ case tk[:kind]
425
+ when :on_nl, :on_comment, :on_embdoc, :on_semicolon then
389
426
  unget_tk(tk)
390
427
  return res
391
428
  end
@@ -400,11 +437,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
400
437
 
401
438
  def get_constant
402
439
  res = ""
403
- skip_tkspace false
440
+ skip_tkspace_without_nl
404
441
  tk = get_tk
405
442
 
406
- while TkCOLON2 === tk or TkCOLON3 === tk or TkCONSTANT === tk do
407
- res += tk.name
443
+ while tk && ((:on_op == tk[:kind] && '::' == tk[:text]) || :on_const == tk[:kind]) do
444
+ res += tk[:text]
408
445
  tk = get_tk
409
446
  end
410
447
 
@@ -413,28 +450,83 @@ class RDoc::Parser::Ruby < RDoc::Parser
413
450
  end
414
451
 
415
452
  ##
416
- # Get a constant that may be surrounded by parens
453
+ # Get an included module that may be surrounded by parens
417
454
 
418
- def get_constant_with_optional_parens
419
- skip_tkspace false
455
+ def get_included_module_with_optional_parens
456
+ skip_tkspace_without_nl
457
+ get_tkread
458
+ tk = get_tk
459
+ end_token = get_end_token tk
460
+ return '' unless end_token
420
461
 
421
462
  nest = 0
463
+ continue = false
464
+ only_constant = true
422
465
 
423
- while TkLPAREN === (tk = peek_tk) or TkfLPAREN === tk do
424
- get_tk
425
- skip_tkspace
426
- nest += 1
427
- end
428
-
429
- name = get_constant
430
-
431
- while nest > 0
432
- skip_tkspace
466
+ while tk != nil do
467
+ is_element_of_constant = false
468
+ case tk[:kind]
469
+ when :on_semicolon then
470
+ break if nest == 0
471
+ when :on_lbracket then
472
+ nest += 1
473
+ when :on_rbracket then
474
+ nest -= 1
475
+ when :on_lbrace then
476
+ nest += 1
477
+ when :on_rbrace then
478
+ nest -= 1
479
+ if nest <= 0
480
+ # we might have a.each { |i| yield i }
481
+ unget_tk(tk) if nest < 0
482
+ break
483
+ end
484
+ when :on_lparen then
485
+ nest += 1
486
+ when end_token[:kind] then
487
+ if end_token[:kind] == :on_rparen
488
+ nest -= 1
489
+ break if nest <= 0
490
+ else
491
+ break if nest <= 0
492
+ end
493
+ when :on_rparen then
494
+ nest -= 1
495
+ when :on_comment, :on_embdoc then
496
+ @read.pop
497
+ if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and
498
+ (!continue or (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0) then
499
+ break if !continue and nest <= 0
500
+ end
501
+ when :on_comma then
502
+ continue = true
503
+ when :on_ident then
504
+ continue = false if continue
505
+ when :on_kw then
506
+ case tk[:text]
507
+ when 'def', 'do', 'case', 'for', 'begin', 'class', 'module'
508
+ nest += 1
509
+ when 'if', 'unless', 'while', 'until', 'rescue'
510
+ # postfix if/unless/while/until/rescue must be EXPR_LABEL
511
+ nest += 1 unless (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0
512
+ when 'end'
513
+ nest -= 1
514
+ break if nest == 0
515
+ end
516
+ when :on_const then
517
+ is_element_of_constant = true
518
+ when :on_op then
519
+ is_element_of_constant = true if '::' == tk[:text]
520
+ end
521
+ only_constant = false unless is_element_of_constant
433
522
  tk = get_tk
434
- nest -= 1 if TkRPAREN === tk
435
523
  end
436
524
 
437
- name
525
+ if only_constant
526
+ get_tkread_clean(/\s+/, ' ')
527
+ else
528
+ ''
529
+ end
438
530
  end
439
531
 
440
532
  ##
@@ -446,13 +538,19 @@ class RDoc::Parser::Ruby < RDoc::Parser
446
538
  # won't catch all cases (such as "a = yield + 1"
447
539
 
448
540
  def get_end_token tk # :nodoc:
449
- case tk
450
- when TkLPAREN, TkfLPAREN
451
- TkRPAREN
452
- when TkRPAREN
541
+ case tk[:kind]
542
+ when :on_lparen
543
+ token = RDoc::Parser::RipperStateLex::Token.new
544
+ token[:kind] = :on_rparen
545
+ token[:text] = ')'
546
+ token
547
+ when :on_rparen
453
548
  nil
454
549
  else
455
- TkNL
550
+ token = RDoc::Parser::RipperStateLex::Token.new
551
+ token[:kind] = :on_nl
552
+ token[:text] = "\n"
553
+ token
456
554
  end
457
555
  end
458
556
 
@@ -461,11 +559,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
461
559
 
462
560
  def get_method_container container, name_t # :nodoc:
463
561
  prev_container = container
464
- container = container.find_module_named(name_t.name)
562
+ container = container.find_module_named(name_t[:text])
465
563
 
466
564
  unless container then
467
565
  constant = prev_container.constants.find do |const|
468
- const.name == name_t.name
566
+ const.name == name_t[:text]
469
567
  end
470
568
 
471
569
  if constant then
@@ -476,21 +574,21 @@ class RDoc::Parser::Ruby < RDoc::Parser
476
574
 
477
575
  unless container then
478
576
  # TODO seems broken, should starting at Object in @store
479
- obj = name_t.name.split("::").inject(Object) do |state, item|
577
+ obj = name_t[:text].split("::").inject(Object) do |state, item|
480
578
  state.const_get(item)
481
579
  end rescue nil
482
580
 
483
581
  type = obj.class == Class ? RDoc::NormalClass : RDoc::NormalModule
484
582
 
485
583
  unless [Class, Module].include?(obj.class) then
486
- warn("Couldn't find #{name_t.name}. Assuming it's a module")
584
+ warn("Couldn't find #{name_t[:text]}. Assuming it's a module")
487
585
  end
488
586
 
489
587
  if type == RDoc::NormalClass then
490
588
  sclass = obj.superclass ? obj.superclass.name : nil
491
- container = prev_container.add_class type, name_t.name, sclass
589
+ container = prev_container.add_class type, name_t[:text], sclass
492
590
  else
493
- container = prev_container.add_module type, name_t.name
591
+ container = prev_container.add_module type, name_t[:text]
494
592
  end
495
593
 
496
594
  record_location container
@@ -504,32 +602,26 @@ class RDoc::Parser::Ruby < RDoc::Parser
504
602
 
505
603
  def get_symbol_or_name
506
604
  tk = get_tk
507
- case tk
508
- when TkSYMBOL then
509
- text = tk.text.sub(/^:/, '')
605
+ case tk[:kind]
606
+ when :on_symbol then
607
+ text = tk[:text].sub(/^:/, '')
510
608
 
511
- if TkASSIGN === peek_tk then
609
+ next_tk = peek_tk
610
+ if next_tk && :on_op == next_tk[:kind] && '=' == next_tk[:text] then
512
611
  get_tk
513
612
  text << '='
514
613
  end
515
614
 
516
615
  text
517
- when TkId, TkOp then
518
- tk.name
519
- when TkAMPER,
520
- TkDSTRING,
521
- TkSTAR,
522
- TkSTRING then
523
- tk.text
616
+ when :on_ident, :on_const, :on_gvar, :on_cvar, :on_ivar, :on_op, :on_kw then
617
+ tk[:text]
618
+ when :on_tstring, :on_dstring then
619
+ tk[:text][1..-2]
524
620
  else
525
621
  raise RDoc::Error, "Name or symbol expected (got #{tk})"
526
622
  end
527
623
  end
528
624
 
529
- def stop_at_EXPR_END # :nodoc:
530
- @scanner.lex_state == :EXPR_END || !@scanner.continue
531
- end
532
-
533
625
  ##
534
626
  # Marks containers between +container+ and +ancestor+ as ignored
535
627
 
@@ -548,29 +640,31 @@ class RDoc::Parser::Ruby < RDoc::Parser
548
640
  #
549
641
  # This routine modifies its +comment+ parameter.
550
642
 
551
- def look_for_directives_in context, comment
552
- @preprocess.handle comment, context do |directive, param|
643
+ def look_for_directives_in container, comment
644
+ @preprocess.handle comment, container do |directive, param|
553
645
  case directive
554
646
  when 'method', 'singleton-method',
555
647
  'attr', 'attr_accessor', 'attr_reader', 'attr_writer' then
556
648
  false # handled elsewhere
557
649
  when 'section' then
558
- context.set_current_section param, comment.dup
650
+ break unless container.kind_of?(RDoc::Context)
651
+ container.set_current_section param, comment.dup
559
652
  comment.text = ''
560
653
  break
561
654
  end
562
655
  end
563
656
 
564
- remove_private_comments comment
657
+ comment.remove_private
565
658
  end
566
659
 
567
660
  ##
568
661
  # Adds useful info about the parser to +message+
569
662
 
570
663
  def make_message message
571
- prefix = "#{@file_name}:"
664
+ prefix = "#{@file_name}:".dup
572
665
 
573
- prefix << "#{@scanner.line_no}:#{@scanner.char_no}:" if @scanner
666
+ tk = peek_tk
667
+ prefix << "#{tk[:line_no]}:#{tk[:char_no]}:" if tk
574
668
 
575
669
  "#{prefix} #{message}"
576
670
  end
@@ -578,8 +672,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
578
672
  ##
579
673
  # Creates a comment with the correct format
580
674
 
581
- def new_comment comment
582
- c = RDoc::Comment.new comment, @top_level
675
+ def new_comment comment, line_no = nil
676
+ c = RDoc::Comment.new comment, @top_level, :ruby
677
+ c.line = line_no
583
678
  c.format = @markup
584
679
  c
585
680
  end
@@ -589,24 +684,22 @@ class RDoc::Parser::Ruby < RDoc::Parser
589
684
  # +comment+.
590
685
 
591
686
  def parse_attr(context, single, tk, comment)
592
- offset = tk.seek
593
- line_no = tk.line_no
687
+ line_no = tk[:line_no]
594
688
 
595
689
  args = parse_symbol_arg 1
596
690
  if args.size > 0 then
597
691
  name = args[0]
598
692
  rw = "R"
599
- skip_tkspace false
693
+ skip_tkspace_without_nl
600
694
  tk = get_tk
601
695
 
602
- if TkCOMMA === tk then
696
+ if :on_comma == tk[:kind] then
603
697
  rw = "RW" if get_bool
604
698
  else
605
699
  unget_tk tk
606
700
  end
607
701
 
608
702
  att = create_attr context, single, name, rw, comment
609
- att.offset = offset
610
703
  att.line = line_no
611
704
 
612
705
  read_documentation_modifiers att, RDoc::ATTR_MODIFIERS
@@ -620,8 +713,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
620
713
  # comment for each to +comment+.
621
714
 
622
715
  def parse_attr_accessor(context, single, tk, comment)
623
- offset = tk.seek
624
- line_no = tk.line_no
716
+ line_no = tk[:line_no]
625
717
 
626
718
  args = parse_symbol_arg
627
719
  rw = "?"
@@ -632,7 +724,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
632
724
  # and add found items appropriately but here we do not. I'm not sure why.
633
725
  return if @track_visibility and not tmp.document_self
634
726
 
635
- case tk.name
727
+ case tk[:text]
636
728
  when "attr_reader" then rw = "R"
637
729
  when "attr_writer" then rw = "W"
638
730
  when "attr_accessor" then rw = "RW"
@@ -642,7 +734,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
642
734
 
643
735
  for name in args
644
736
  att = create_attr context, single, name, rw, comment
645
- att.offset = offset
646
737
  att.line = line_no
647
738
  end
648
739
  end
@@ -651,22 +742,19 @@ class RDoc::Parser::Ruby < RDoc::Parser
651
742
  # Parses an +alias+ in +context+ with +comment+
652
743
 
653
744
  def parse_alias(context, single, tk, comment)
654
- offset = tk.seek
655
- line_no = tk.line_no
745
+ line_no = tk[:line_no]
656
746
 
657
747
  skip_tkspace
658
748
 
659
- if TkLPAREN === peek_tk then
749
+ if :on_lparen === peek_tk[:kind] then
660
750
  get_tk
661
751
  skip_tkspace
662
752
  end
663
753
 
664
754
  new_name = get_symbol_or_name
665
755
 
666
- @scanner.lex_state = :EXPR_FNAME
667
-
668
756
  skip_tkspace
669
- if TkCOMMA === peek_tk then
757
+ if :on_comma === peek_tk[:kind] then
670
758
  get_tk
671
759
  skip_tkspace
672
760
  end
@@ -680,7 +768,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
680
768
  al = RDoc::Alias.new(get_tkread, old_name, new_name, comment,
681
769
  single == SINGLE)
682
770
  record_location al
683
- al.offset = offset
684
771
  al.line = line_no
685
772
 
686
773
  read_documentation_modifiers al, RDoc::ATTR_MODIFIERS
@@ -694,34 +781,38 @@ class RDoc::Parser::Ruby < RDoc::Parser
694
781
  # Extracts call parameters from the token stream.
695
782
 
696
783
  def parse_call_parameters(tk)
697
- end_token = case tk
698
- when TkLPAREN, TkfLPAREN
699
- TkRPAREN
700
- when TkRPAREN
784
+ end_token = case tk[:kind]
785
+ when :on_lparen
786
+ :on_rparen
787
+ when :on_rparen
701
788
  return ""
702
789
  else
703
- TkNL
790
+ :on_nl
704
791
  end
705
792
  nest = 0
706
793
 
707
794
  loop do
708
- case tk
709
- when TkSEMICOLON
795
+ break if tk.nil?
796
+ case tk[:kind]
797
+ when :on_semicolon
710
798
  break
711
- when TkLPAREN, TkfLPAREN
799
+ when :on_lparen
712
800
  nest += 1
713
801
  when end_token
714
- if end_token == TkRPAREN
802
+ if end_token == :on_rparen
715
803
  nest -= 1
716
- break if @scanner.lex_state == :EXPR_END and nest <= 0
804
+ break if RDoc::Parser::RipperStateLex.end?(tk) and nest <= 0
717
805
  else
718
- break unless @scanner.continue
806
+ break if RDoc::Parser::RipperStateLex.end?(tk)
719
807
  end
720
- when TkCOMMENT, TkASSIGN, TkOPASGN
808
+ when :on_comment, :on_embdoc
721
809
  unget_tk(tk)
722
810
  break
723
- when nil then
724
- break
811
+ when :on_op
812
+ if tk[:text] =~ /^(.{1,2})?=$/
813
+ unget_tk(tk)
814
+ break
815
+ end
725
816
  end
726
817
  tk = get_tk
727
818
  end
@@ -733,33 +824,33 @@ class RDoc::Parser::Ruby < RDoc::Parser
733
824
  # Parses a class in +context+ with +comment+
734
825
 
735
826
  def parse_class container, single, tk, comment
736
- offset = tk.seek
737
- line_no = tk.line_no
827
+ line_no = tk[:line_no]
738
828
 
739
829
  declaration_context = container
740
- container, name_t, given_name = get_class_or_module container
741
-
742
- cls =
743
- case name_t
744
- when TkCONSTANT
745
- parse_class_regular container, declaration_context, single,
746
- name_t, given_name, comment
747
- when TkLSHFT
748
- case name = get_class_specification
749
- when 'self', container.name
750
- parse_statements container, SINGLE
751
- return # don't update offset or line
752
- else
753
- parse_class_singleton container, name, comment
754
- end
830
+ container, name_t, given_name, = get_class_or_module container
831
+
832
+ if name_t[:kind] == :on_const
833
+ cls = parse_class_regular container, declaration_context, single,
834
+ name_t, given_name, comment
835
+ elsif name_t[:kind] == :on_op && name_t[:text] == '<<'
836
+ case name = get_class_specification
837
+ when 'self', container.name
838
+ read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
839
+ parse_statements container, SINGLE
840
+ return # don't update line
755
841
  else
756
- warn "Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}"
757
- return
842
+ cls = parse_class_singleton container, name, comment
758
843
  end
844
+ else
845
+ warn "Expected class name or '<<'. Got #{name_t[:kind]}: #{name_t[:text].inspect}"
846
+ return
847
+ end
759
848
 
760
- cls.offset = offset
761
849
  cls.line = line_no
762
850
 
851
+ # after end modifiers
852
+ read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
853
+
763
854
  cls
764
855
  end
765
856
 
@@ -775,7 +866,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
775
866
  given_name = $'
776
867
  end
777
868
 
778
- if TkLT === peek_tk then
869
+ tk = peek_tk
870
+ if tk[:kind] == :on_op && tk[:text] == '<' then
779
871
  get_tk
780
872
  skip_tkspace
781
873
  superclass = get_class_specification
@@ -845,102 +937,125 @@ class RDoc::Parser::Ruby < RDoc::Parser
845
937
  # true, no found constants will be added to RDoc.
846
938
 
847
939
  def parse_constant container, tk, comment, ignore_constants = false
848
- offset = tk.seek
849
- line_no = tk.line_no
940
+ line_no = tk[:line_no]
850
941
 
851
- name = tk.name
852
- skip_tkspace false
942
+ name = tk[:text]
943
+ skip_tkspace_without_nl
853
944
 
854
945
  return unless name =~ /^\w+$/
855
946
 
856
- eq_tk = get_tk
857
-
858
- if TkCOLON2 === eq_tk then
859
- unget_tk eq_tk
947
+ new_modules = []
948
+ if :on_op == peek_tk[:kind] && '::' == peek_tk[:text] then
860
949
  unget_tk tk
861
950
 
862
- container, name_t, = get_class_or_module container, ignore_constants
951
+ container, name_t, _, new_modules = get_class_or_module container, true
863
952
 
864
- name = name_t.name
953
+ name = name_t[:text]
954
+ end
865
955
 
866
- eq_tk = get_tk
956
+ is_array_or_hash = false
957
+ if peek_tk && :on_lbracket == peek_tk[:kind]
958
+ get_tk
959
+ nest = 1
960
+ while bracket_tk = get_tk
961
+ case bracket_tk[:kind]
962
+ when :on_lbracket
963
+ nest += 1
964
+ when :on_rbracket
965
+ nest -= 1
966
+ break if nest == 0
967
+ end
968
+ end
969
+ skip_tkspace_without_nl
970
+ is_array_or_hash = true
867
971
  end
868
972
 
869
- unless TkASSIGN === eq_tk then
870
- unget_tk eq_tk
973
+ unless peek_tk && :on_op == peek_tk[:kind] && '=' == peek_tk[:text] then
871
974
  return false
872
975
  end
976
+ get_tk
873
977
 
874
- if TkGT === peek_tk then
875
- unget_tk eq_tk
876
- return
978
+ unless ignore_constants
979
+ new_modules.each do |prev_c, new_module|
980
+ prev_c.add_module_by_normal_module new_module
981
+ new_module.ignore unless prev_c.document_children
982
+ @top_level.add_to_classes_or_modules new_module
983
+ end
877
984
  end
878
985
 
879
986
  value = ''
880
987
  con = RDoc::Constant.new name, value, comment
881
988
 
882
- body = parse_constant_body container, con
989
+ body = parse_constant_body container, con, is_array_or_hash
883
990
 
884
991
  return unless body
885
992
 
886
- value.replace body
993
+ con.value = body
887
994
  record_location con
888
- con.offset = offset
889
995
  con.line = line_no
890
996
  read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS
891
997
 
998
+ return if is_array_or_hash
999
+
892
1000
  @stats.add_constant con
893
1001
  container.add_constant con
894
1002
 
895
1003
  true
896
1004
  end
897
1005
 
898
- def parse_constant_body container, constant # :nodoc:
1006
+ def parse_constant_body container, constant, is_array_or_hash # :nodoc:
899
1007
  nest = 0
900
- rhs_name = ''
1008
+ rhs_name = ''.dup
901
1009
 
902
1010
  get_tkread
903
1011
 
904
1012
  tk = get_tk
905
1013
 
1014
+ body = nil
906
1015
  loop do
907
- case tk
908
- when TkSEMICOLON then
1016
+ break if tk.nil?
1017
+ if :on_semicolon == tk[:kind] then
909
1018
  break if nest <= 0
910
- when TkLPAREN, TkfLPAREN, TkLBRACE, TkfLBRACE, TkLBRACK, TkfLBRACK,
911
- TkDO, TkIF, TkUNLESS, TkCASE, TkDEF, TkBEGIN then
1019
+ elsif [:on_tlambeg, :on_lparen, :on_lbrace, :on_lbracket].include?(tk[:kind]) then
912
1020
  nest += 1
913
- when TkRPAREN, TkRBRACE, TkRBRACK, TkEND then
1021
+ elsif (:on_kw == tk[:kind] && 'def' == tk[:text]) then
1022
+ nest += 1
1023
+ elsif (:on_kw == tk[:kind] && %w{do if unless case begin}.include?(tk[:text])) then
1024
+ if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
1025
+ nest += 1
1026
+ end
1027
+ elsif [:on_rparen, :on_rbrace, :on_rbracket].include?(tk[:kind]) ||
1028
+ (:on_kw == tk[:kind] && 'end' == tk[:text]) then
914
1029
  nest -= 1
915
- when TkCOMMENT then
916
- if nest <= 0 and stop_at_EXPR_END then
917
- unget_tk tk
1030
+ elsif (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then
1031
+ unget_tk tk
1032
+ if nest <= 0 and RDoc::Parser::RipperStateLex.end?(tk) then
1033
+ body = get_tkread_clean(/^[ \t]+/, '')
1034
+ read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS
918
1035
  break
919
1036
  else
920
- unget_tk tk
921
1037
  read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS
922
1038
  end
923
- when TkCONSTANT then
924
- rhs_name << tk.name
1039
+ elsif :on_const == tk[:kind] then
1040
+ rhs_name << tk[:text]
925
1041
 
926
- if nest <= 0 and TkNL === peek_tk then
927
- create_module_alias container, constant, rhs_name
1042
+ next_tk = peek_tk
1043
+ if nest <= 0 and (next_tk.nil? || :on_nl == next_tk[:kind]) then
1044
+ create_module_alias container, constant, rhs_name unless is_array_or_hash
928
1045
  break
929
1046
  end
930
- when TkNL then
931
- if nest <= 0 and stop_at_EXPR_END then
1047
+ elsif :on_nl == tk[:kind] then
1048
+ if nest <= 0 and RDoc::Parser::RipperStateLex.end?(tk) then
932
1049
  unget_tk tk
933
1050
  break
934
1051
  end
935
- when TkCOLON2, TkCOLON3 then
1052
+ elsif :on_op == tk[:kind] && '::' == tk[:text]
936
1053
  rhs_name << '::'
937
- when nil then
938
- break
939
1054
  end
940
1055
  tk = get_tk
941
1056
  end
942
1057
 
943
- get_tkread_clean(/^[ \t]+/, '')
1058
+ body ? body : get_tkread_clean(/^[ \t]+/, '')
944
1059
  end
945
1060
 
946
1061
  ##
@@ -949,24 +1064,22 @@ class RDoc::Parser::Ruby < RDoc::Parser
949
1064
 
950
1065
  def parse_comment container, tk, comment
951
1066
  return parse_comment_tomdoc container, tk, comment if @markup == 'tomdoc'
952
- column = tk.char_no
953
- offset = tk.seek
954
- line_no = tk.line_no
955
-
956
- text = comment.text
1067
+ column = tk[:char_no]
1068
+ line_no = comment.line.nil? ? tk[:line_no] : comment.line
957
1069
 
958
- singleton = !!text.sub!(/(^# +:?)(singleton-)(method:)/, '\1\3')
1070
+ comment.text = comment.text.sub(/(^# +:?)(singleton-)(method:)/, '\1\3')
1071
+ singleton = !!$~
959
1072
 
960
1073
  co =
961
- if text.sub!(/^# +:?method: *(\S*).*?\n/i, '') then
962
- parse_comment_ghost container, text, $1, column, line_no, comment
963
- elsif text.sub!(/# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '') then
1074
+ if (comment.text = comment.text.sub(/^# +:?method: *(\S*).*?\n/i, '')) && !!$~ then
1075
+ line_no += $`.count("\n")
1076
+ parse_comment_ghost container, comment.text, $1, column, line_no, comment
1077
+ elsif (comment.text = comment.text.sub(/# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '')) && !!$~ then
964
1078
  parse_comment_attr container, $1, $3, comment
965
1079
  end
966
1080
 
967
1081
  if co then
968
1082
  co.singleton = singleton
969
- co.offset = offset
970
1083
  co.line = line_no
971
1084
  end
972
1085
 
@@ -997,12 +1110,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
997
1110
  record_location meth
998
1111
 
999
1112
  meth.start_collecting_tokens
1000
- indent = TkSPACE.new 0, 1, 1
1001
- indent.set_text " " * column
1002
-
1003
- position_comment = TkCOMMENT.new 0, line_no, 1
1004
- position_comment.set_text "# File #{@top_level.relative_name}, line #{line_no}"
1005
- meth.add_tokens [position_comment, NEWLINE_TOKEN, indent]
1113
+ indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
1114
+ position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
1115
+ position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
1116
+ newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
1117
+ meth.add_tokens [position_comment, newline, indent]
1006
1118
 
1007
1119
  meth.params =
1008
1120
  if text.sub!(/^#\s+:?args?:\s*(.*?)\s*$/i, '') then
@@ -1031,23 +1143,21 @@ class RDoc::Parser::Ruby < RDoc::Parser
1031
1143
 
1032
1144
  def parse_comment_tomdoc container, tk, comment
1033
1145
  return unless signature = RDoc::TomDoc.signature(comment)
1034
- offset = tk.seek
1035
- line_no = tk.line_no
1146
+ column = tk[:char_no]
1147
+ line_no = tk[:line_no]
1036
1148
 
1037
1149
  name, = signature.split %r%[ \(]%, 2
1038
1150
 
1039
1151
  meth = RDoc::GhostMethod.new get_tkread, name
1040
1152
  record_location meth
1041
- meth.offset = offset
1042
1153
  meth.line = line_no
1043
1154
 
1044
1155
  meth.start_collecting_tokens
1045
- indent = TkSPACE.new 0, 1, 1
1046
- indent.set_text " " * offset
1047
-
1048
- position_comment = TkCOMMENT.new 0, line_no, 1
1049
- position_comment.set_text "# File #{@top_level.relative_name}, line #{line_no}"
1050
- meth.add_tokens [position_comment, NEWLINE_TOKEN, indent]
1156
+ indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
1157
+ position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
1158
+ position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
1159
+ newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
1160
+ meth.add_tokens [position_comment, newline, indent]
1051
1161
 
1052
1162
  meth.call_seq = signature
1053
1163
 
@@ -1070,14 +1180,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
1070
1180
  loop do
1071
1181
  skip_tkspace_comment
1072
1182
 
1073
- name = get_constant_with_optional_parens
1183
+ name = get_included_module_with_optional_parens
1074
1184
 
1075
1185
  unless name.empty? then
1076
1186
  obj = container.add klass, name, comment
1077
1187
  record_location obj
1078
1188
  end
1079
1189
 
1080
- return unless TkCOMMA === peek_tk
1190
+ return if peek_tk.nil? || :on_comma != peek_tk[:kind]
1081
1191
 
1082
1192
  get_tk
1083
1193
  end
@@ -1089,11 +1199,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
1089
1199
  # Returns true if the comment was not consumed.
1090
1200
 
1091
1201
  def parse_identifier container, single, tk, comment # :nodoc:
1092
- case tk.name
1202
+ case tk[:text]
1093
1203
  when 'private', 'protected', 'public', 'private_class_method',
1094
1204
  'public_class_method', 'module_function' then
1095
1205
  parse_visibility container, single, tk
1096
1206
  return true
1207
+ when 'private_constant', 'public_constant'
1208
+ parse_constant_visibility container, single, tk
1209
+ return true
1097
1210
  when 'attr' then
1098
1211
  parse_attr container, single, tk, comment
1099
1212
  when /^attr_(reader|writer|accessor)$/ then
@@ -1158,7 +1271,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
1158
1271
  tmp = RDoc::CodeObject.new
1159
1272
  read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS
1160
1273
 
1161
- if comment.text.sub!(/^# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '') then
1274
+ regexp = /^# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i
1275
+ if regexp =~ comment.text then
1276
+ comment.text = comment.text.sub(regexp, '')
1162
1277
  rw = case $1
1163
1278
  when 'attr_reader' then 'R'
1164
1279
  when 'attr_writer' then 'W'
@@ -1182,17 +1297,17 @@ class RDoc::Parser::Ruby < RDoc::Parser
1182
1297
  # Parses a meta-programmed method
1183
1298
 
1184
1299
  def parse_meta_method(container, single, tk, comment)
1185
- column = tk.char_no
1186
- offset = tk.seek
1187
- line_no = tk.line_no
1300
+ column = tk[:char_no]
1301
+ line_no = tk[:line_no]
1188
1302
 
1189
1303
  start_collecting_tokens
1190
1304
  add_token tk
1191
1305
  add_token_listener self
1192
1306
 
1193
- skip_tkspace false
1307
+ skip_tkspace_without_nl
1194
1308
 
1195
- singleton = !!comment.text.sub!(/(^# +:?)(singleton-)(method:)/, '\1\3')
1309
+ comment.text = comment.text.sub(/(^# +:?)(singleton-)(method:)/, '\1\3')
1310
+ singleton = !!$~
1196
1311
 
1197
1312
  name = parse_meta_method_name comment, tk
1198
1313
 
@@ -1200,19 +1315,17 @@ class RDoc::Parser::Ruby < RDoc::Parser
1200
1315
 
1201
1316
  meth = RDoc::MetaMethod.new get_tkread, name
1202
1317
  record_location meth
1203
- meth.offset = offset
1204
1318
  meth.line = line_no
1205
1319
  meth.singleton = singleton
1206
1320
 
1207
1321
  remove_token_listener self
1208
1322
 
1209
1323
  meth.start_collecting_tokens
1210
- indent = TkSPACE.new 0, 1, 1
1211
- indent.set_text " " * column
1212
-
1213
- position_comment = TkCOMMENT.new 0, line_no, 1
1214
- position_comment.value = "# File #{@top_level.relative_name}, line #{line_no}"
1215
- meth.add_tokens [position_comment, NEWLINE_TOKEN, indent]
1324
+ indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
1325
+ position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
1326
+ position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
1327
+ newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
1328
+ meth.add_tokens [position_comment, newline, indent]
1216
1329
  meth.add_tokens @token_stream
1217
1330
 
1218
1331
  parse_meta_method_params container, single, meth, tk, comment
@@ -1236,17 +1349,16 @@ class RDoc::Parser::Ruby < RDoc::Parser
1236
1349
 
1237
1350
  name_t = get_tk
1238
1351
 
1239
- case name_t
1240
- when TkSYMBOL then
1241
- name_t.text[1..-1]
1242
- when TkSTRING then
1243
- name_t.value[1..-2]
1244
- when TkASSIGN then # ignore
1352
+ if :on_symbol == name_t[:kind] then
1353
+ name_t[:text][1..-1]
1354
+ elsif :on_tstring == name_t[:kind] then
1355
+ name_t[:text][1..-2]
1356
+ elsif :on_op == name_t[:kind] && '=' == name_t[:text] then # ignore
1245
1357
  remove_token_listener self
1246
1358
 
1247
1359
  nil
1248
1360
  else
1249
- warn "unknown name token #{name_t.inspect} for meta-method '#{tk.name}'"
1361
+ warn "unknown name token #{name_t.inspect} for meta-method '#{tk[:text]}'"
1250
1362
  'unknown'
1251
1363
  end
1252
1364
  end
@@ -1258,6 +1370,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1258
1370
  token_listener meth do
1259
1371
  meth.params = ''
1260
1372
 
1373
+ look_for_directives_in meth, comment
1261
1374
  comment.normalize
1262
1375
  comment.extract_call_seq meth
1263
1376
 
@@ -1266,14 +1379,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
1266
1379
  last_tk = tk
1267
1380
 
1268
1381
  while tk = get_tk do
1269
- case tk
1270
- when TkSEMICOLON then
1382
+ if :on_semicolon == tk[:kind] then
1271
1383
  break
1272
- when TkNL then
1273
- break unless last_tk and TkCOMMA === last_tk
1274
- when TkSPACE then
1384
+ elsif :on_nl == tk[:kind] then
1385
+ break unless last_tk and :on_comma == last_tk[:kind]
1386
+ elsif :on_sp == tk[:kind] then
1275
1387
  # expression continues
1276
- when TkDO then
1388
+ elsif :on_kw == tk[:kind] && 'do' == tk[:text] then
1277
1389
  parse_statements container, single, meth
1278
1390
  break
1279
1391
  else
@@ -1290,9 +1402,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
1290
1402
  singleton = nil
1291
1403
  added_container = false
1292
1404
  name = nil
1293
- column = tk.char_no
1294
- offset = tk.seek
1295
- line_no = tk.line_no
1405
+ column = tk[:char_no]
1406
+ line_no = tk[:line_no]
1296
1407
 
1297
1408
  start_collecting_tokens
1298
1409
  add_token tk
@@ -1306,19 +1417,18 @@ class RDoc::Parser::Ruby < RDoc::Parser
1306
1417
  return unless name
1307
1418
 
1308
1419
  meth = RDoc::AnyMethod.new get_tkread, name
1420
+ look_for_directives_in meth, comment
1309
1421
  meth.singleton = single == SINGLE ? true : singleton
1310
1422
 
1311
1423
  record_location meth
1312
- meth.offset = offset
1313
1424
  meth.line = line_no
1314
1425
 
1315
1426
  meth.start_collecting_tokens
1316
- indent = TkSPACE.new 0, 1, 1
1317
- indent.set_text " " * column
1318
-
1319
- token = TkCOMMENT.new 0, line_no, 1
1320
- token.set_text "# File #{@top_level.relative_name}, line #{line_no}"
1321
- meth.add_tokens [token, NEWLINE_TOKEN, indent]
1427
+ indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
1428
+ token = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
1429
+ token[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
1430
+ newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
1431
+ meth.add_tokens [token, newline, indent]
1322
1432
  meth.add_tokens @token_stream
1323
1433
 
1324
1434
  parse_method_params_and_body container, single, meth, added_container
@@ -1328,6 +1438,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
1328
1438
 
1329
1439
  meth.comment = comment
1330
1440
 
1441
+ # after end modifiers
1442
+ read_documentation_modifiers meth, RDoc::METHOD_MODIFIERS
1443
+
1331
1444
  @stats.add_method meth
1332
1445
  end
1333
1446
 
@@ -1336,7 +1449,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
1336
1449
 
1337
1450
  def parse_method_params_and_body container, single, meth, added_container
1338
1451
  token_listener meth do
1339
- @scanner.continue = false
1340
1452
  parse_method_parameters meth
1341
1453
 
1342
1454
  if meth.document_self or not @track_visibility then
@@ -1379,15 +1491,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
1379
1491
  # it is a singleton or regular method.
1380
1492
 
1381
1493
  def parse_method_name container # :nodoc:
1382
- @scanner.lex_state = :EXPR_FNAME
1383
-
1384
1494
  skip_tkspace
1385
1495
  name_t = get_tk
1386
- back_tk = skip_tkspace
1496
+ back_tk = skip_tkspace_without_nl
1387
1497
  singleton = false
1388
1498
 
1389
- case dot = get_tk
1390
- when TkDOT, TkCOLON2 then
1499
+ dot = get_tk
1500
+ if dot[:kind] == :on_period || (dot[:kind] == :on_op && dot[:text] == '::') then
1391
1501
  singleton = true
1392
1502
 
1393
1503
  name, container = parse_method_name_singleton container, name_t
@@ -1408,16 +1518,15 @@ class RDoc::Parser::Ruby < RDoc::Parser
1408
1518
  # is parsed from the token stream for a regular method.
1409
1519
 
1410
1520
  def parse_method_name_regular container, name_t # :nodoc:
1411
- case name_t
1412
- when TkSTAR, TkAMPER then
1413
- name_t.text
1521
+ if :on_op == name_t[:kind] && (%w{* & [] []= <<}.include?(name_t[:text])) then
1522
+ name_t[:text]
1414
1523
  else
1415
- unless name_t.respond_to? :name then
1524
+ unless [:on_kw, :on_const, :on_ident].include?(name_t[:kind]) then
1416
1525
  warn "expected method name token, . or ::, got #{name_t.inspect}"
1417
1526
  skip_method container
1418
1527
  return
1419
1528
  end
1420
- name_t.name
1529
+ name_t[:text]
1421
1530
  end
1422
1531
  end
1423
1532
 
@@ -1427,47 +1536,42 @@ class RDoc::Parser::Ruby < RDoc::Parser
1427
1536
  # for a singleton method.
1428
1537
 
1429
1538
  def parse_method_name_singleton container, name_t # :nodoc:
1430
- @scanner.lex_state = :EXPR_FNAME
1431
1539
  skip_tkspace
1432
1540
  name_t2 = get_tk
1433
1541
 
1434
- name =
1435
- case name_t
1436
- when TkSELF, TkMOD then
1437
- case name_t2
1438
- # NOTE: work around '[' being consumed early and not being re-tokenized
1439
- # as a TkAREF
1440
- when TkfLBRACK then
1441
- get_tk
1442
- '[]'
1443
- else
1444
- name_t2.name
1445
- end
1446
- when TkCONSTANT then
1447
- name = name_t2.name
1542
+ if (:on_kw == name_t[:kind] && 'self' == name_t[:text]) || (:on_op == name_t[:kind] && '%' == name_t[:text]) then
1543
+ # NOTE: work around '[' being consumed early
1544
+ if :on_lbracket == name_t2[:kind]
1545
+ get_tk
1546
+ name = '[]'
1547
+ else
1548
+ name = name_t2[:text]
1549
+ end
1550
+ elsif :on_const == name_t[:kind] then
1551
+ name = name_t2[:text]
1448
1552
 
1449
- container = get_method_container container, name_t
1553
+ container = get_method_container container, name_t
1450
1554
 
1451
- return unless container
1555
+ return unless container
1452
1556
 
1453
- name
1454
- when TkIDENTIFIER, TkIVAR, TkGVAR then
1455
- parse_method_dummy container
1557
+ name
1558
+ elsif :on_ident == name_t[:kind] || :on_ivar == name_t[:kind] || :on_gvar == name_t[:kind] then
1559
+ parse_method_dummy container
1456
1560
 
1457
- nil
1458
- when TkTRUE, TkFALSE, TkNIL then
1459
- klass_name = "#{name_t.name.capitalize}Class"
1460
- container = @store.find_class_named klass_name
1461
- container ||= @top_level.add_class RDoc::NormalClass, klass_name
1561
+ name = nil
1562
+ elsif (:on_kw == name_t[:kind]) && ('true' == name_t[:text] || 'false' == name_t[:text] || 'nil' == name_t[:text]) then
1563
+ klass_name = "#{name_t[:text].capitalize}Class"
1564
+ container = @store.find_class_named klass_name
1565
+ container ||= @top_level.add_class RDoc::NormalClass, klass_name
1462
1566
 
1463
- name_t2.name
1464
- else
1465
- warn "unexpected method name token #{name_t.inspect}"
1466
- # break
1467
- skip_method container
1567
+ name = name_t2[:text]
1568
+ else
1569
+ warn "unexpected method name token #{name_t.inspect}"
1570
+ # break
1571
+ skip_method container
1468
1572
 
1469
- nil
1470
- end
1573
+ name = nil
1574
+ end
1471
1575
 
1472
1576
  return name, container
1473
1577
  end
@@ -1477,45 +1581,56 @@ class RDoc::Parser::Ruby < RDoc::Parser
1477
1581
 
1478
1582
  def parse_method_or_yield_parameters(method = nil,
1479
1583
  modifiers = RDoc::METHOD_MODIFIERS)
1480
- skip_tkspace false
1584
+ skip_tkspace_without_nl
1481
1585
  tk = get_tk
1482
1586
  end_token = get_end_token tk
1483
1587
  return '' unless end_token
1484
1588
 
1485
1589
  nest = 0
1590
+ continue = false
1486
1591
 
1487
- loop do
1488
- case tk
1489
- when TkSEMICOLON then
1592
+ while tk != nil do
1593
+ case tk[:kind]
1594
+ when :on_semicolon then
1490
1595
  break if nest == 0
1491
- when TkLBRACE, TkfLBRACE then
1596
+ when :on_lbracket then
1597
+ nest += 1
1598
+ when :on_rbracket then
1599
+ nest -= 1
1600
+ when :on_lbrace then
1492
1601
  nest += 1
1493
- when TkRBRACE then
1602
+ when :on_rbrace then
1494
1603
  nest -= 1
1495
1604
  if nest <= 0
1496
1605
  # we might have a.each { |i| yield i }
1497
1606
  unget_tk(tk) if nest < 0
1498
1607
  break
1499
1608
  end
1500
- when TkLPAREN, TkfLPAREN then
1609
+ when :on_lparen then
1501
1610
  nest += 1
1502
- when end_token then
1503
- if end_token == TkRPAREN
1611
+ when end_token[:kind] then
1612
+ if end_token[:kind] == :on_rparen
1504
1613
  nest -= 1
1505
1614
  break if nest <= 0
1506
1615
  else
1507
- break unless @scanner.continue
1616
+ break
1508
1617
  end
1509
- when TkRPAREN then
1618
+ when :on_rparen then
1510
1619
  nest -= 1
1511
- when method && method.block_params.nil? && TkCOMMENT then
1512
- unget_tk tk
1513
- read_documentation_modifiers method, modifiers
1514
- @read.pop
1515
- when TkCOMMENT then
1620
+ when :on_comment, :on_embdoc then
1516
1621
  @read.pop
1517
- when nil then
1518
- break
1622
+ if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and
1623
+ (!continue or (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0) then
1624
+ if method && method.block_params.nil? then
1625
+ unget_tk tk
1626
+ read_documentation_modifiers method, modifiers
1627
+ end
1628
+ break if !continue and nest <= 0
1629
+ end
1630
+ when :on_comma then
1631
+ continue = true
1632
+ when :on_ident then
1633
+ continue = false if continue
1519
1634
  end
1520
1635
  tk = get_tk
1521
1636
  end
@@ -1539,7 +1654,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1539
1654
 
1540
1655
  return if method.block_params
1541
1656
 
1542
- skip_tkspace false
1657
+ skip_tkspace_without_nl
1543
1658
  read_documentation_modifiers method, RDoc::METHOD_MODIFIERS
1544
1659
  end
1545
1660
 
@@ -1549,7 +1664,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1549
1664
  def parse_module container, single, tk, comment
1550
1665
  container, name_t, = get_class_or_module container
1551
1666
 
1552
- name = name_t.name
1667
+ name = name_t[:text]
1553
1668
 
1554
1669
  mod = container.add_module RDoc::NormalModule, name
1555
1670
  mod.ignore unless container.document_children
@@ -1559,6 +1674,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
1559
1674
  mod.add_comment comment, @top_level
1560
1675
  parse_statements mod
1561
1676
 
1677
+ # after end modifiers
1678
+ read_documentation_modifiers mod, RDoc::CLASS_MODIFIERS
1679
+
1562
1680
  @stats.add_module mod
1563
1681
  end
1564
1682
 
@@ -1569,12 +1687,12 @@ class RDoc::Parser::Ruby < RDoc::Parser
1569
1687
  skip_tkspace_comment
1570
1688
  tk = get_tk
1571
1689
 
1572
- if TkLPAREN === tk then
1690
+ if :on_lparen == tk[:kind] then
1573
1691
  skip_tkspace_comment
1574
1692
  tk = get_tk
1575
1693
  end
1576
1694
 
1577
- name = tk.text if TkSTRING === tk
1695
+ name = tk[:text][1..-2] if :on_tstring == tk[:kind]
1578
1696
 
1579
1697
  if name then
1580
1698
  @top_level.add_require RDoc::Require.new(name, comment)
@@ -1587,19 +1705,30 @@ class RDoc::Parser::Ruby < RDoc::Parser
1587
1705
  # Parses a rescue
1588
1706
 
1589
1707
  def parse_rescue
1590
- skip_tkspace false
1708
+ skip_tkspace_without_nl
1591
1709
 
1592
1710
  while tk = get_tk
1593
- case tk
1594
- when TkNL, TkSEMICOLON then
1711
+ case tk[:kind]
1712
+ when :on_nl, :on_semicolon, :on_comment then
1595
1713
  break
1596
- when TkCOMMA then
1597
- skip_tkspace false
1714
+ when :on_comma then
1715
+ skip_tkspace_without_nl
1598
1716
 
1599
- get_tk if TkNL === peek_tk
1717
+ get_tk if :on_nl == peek_tk[:kind]
1600
1718
  end
1601
1719
 
1602
- skip_tkspace false
1720
+ skip_tkspace_without_nl
1721
+ end
1722
+ end
1723
+
1724
+ ##
1725
+ # Retrieve comment body without =begin/=end
1726
+
1727
+ def retrieve_comment_body(tk)
1728
+ if :on_embdoc == tk[:kind]
1729
+ tk[:text].gsub(/\A=begin.*\n/, '').gsub(/=end\n?\z/, '')
1730
+ else
1731
+ tk[:text]
1603
1732
  end
1604
1733
  end
1605
1734
 
@@ -1609,7 +1738,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1609
1738
  def parse_statements(container, single = NORMAL, current_method = nil,
1610
1739
  comment = new_comment(''))
1611
1740
  raise 'no' unless RDoc::Comment === comment
1612
- comment.force_encoding @encoding if @encoding
1741
+ comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
1613
1742
 
1614
1743
  nest = 1
1615
1744
  save_visibility = container.visibility
@@ -1620,35 +1749,55 @@ class RDoc::Parser::Ruby < RDoc::Parser
1620
1749
  keep_comment = false
1621
1750
  try_parse_comment = false
1622
1751
 
1623
- non_comment_seen = true unless TkCOMMENT === tk
1752
+ non_comment_seen = true unless (:on_comment == tk[:kind] or :on_embdoc == tk[:kind])
1624
1753
 
1625
- case tk
1626
- when TkNL then
1627
- skip_tkspace
1628
- tk = get_tk
1754
+ case tk[:kind]
1755
+ when :on_nl, :on_ignored_nl, :on_comment, :on_embdoc then
1756
+ if :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]
1757
+ skip_tkspace
1758
+ tk = get_tk
1759
+ else
1760
+ past_tokens = @read.size > 1 ? @read[0..-2] : []
1761
+ nl_position = 0
1762
+ past_tokens.reverse.each_with_index do |read_tk, i|
1763
+ if read_tk =~ /^\n$/ then
1764
+ nl_position = (past_tokens.size - 1) - i
1765
+ break
1766
+ elsif read_tk =~ /^#.*\n$/ then
1767
+ nl_position = ((past_tokens.size - 1) - i) + 1
1768
+ break
1769
+ end
1770
+ end
1771
+ comment_only_line = past_tokens[nl_position..-1].all?{ |c| c =~ /^\s+$/ }
1772
+ unless comment_only_line then
1773
+ tk = get_tk
1774
+ end
1775
+ end
1629
1776
 
1630
- if TkCOMMENT === tk then
1777
+ if tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then
1631
1778
  if non_comment_seen then
1632
1779
  # Look for RDoc in a comment about to be thrown away
1633
1780
  non_comment_seen = parse_comment container, tk, comment unless
1634
1781
  comment.empty?
1635
1782
 
1636
1783
  comment = ''
1637
- comment.force_encoding @encoding if @encoding
1784
+ comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
1638
1785
  end
1639
1786
 
1640
- while TkCOMMENT === tk do
1641
- comment << tk.text << "\n"
1642
-
1643
- tk = get_tk
1787
+ line_no = nil
1788
+ while tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) do
1789
+ comment_body = retrieve_comment_body(tk)
1790
+ line_no = tk[:line_no] if comment.empty?
1791
+ comment += comment_body
1792
+ comment << "\n" unless comment_body =~ /\n\z/
1644
1793
 
1645
- if TkNL === tk then
1646
- skip_tkspace false # leading spaces
1647
- tk = get_tk
1794
+ if comment_body.size > 1 && comment_body =~ /\n\z/ then
1795
+ skip_tkspace_without_nl # leading spaces
1648
1796
  end
1797
+ tk = get_tk
1649
1798
  end
1650
1799
 
1651
- comment = new_comment comment
1800
+ comment = new_comment comment, line_no
1652
1801
 
1653
1802
  unless comment.empty? then
1654
1803
  look_for_directives_in container, comment
@@ -1666,60 +1815,78 @@ class RDoc::Parser::Ruby < RDoc::Parser
1666
1815
 
1667
1816
  unget_tk tk
1668
1817
  keep_comment = true
1818
+ container.current_line_visibility = nil
1669
1819
 
1670
- when TkCLASS then
1671
- parse_class container, single, tk, comment
1820
+ when :on_kw then
1821
+ case tk[:text]
1822
+ when 'class' then
1823
+ parse_class container, single, tk, comment
1672
1824
 
1673
- when TkMODULE then
1674
- parse_module container, single, tk, comment
1825
+ when 'module' then
1826
+ parse_module container, single, tk, comment
1675
1827
 
1676
- when TkDEF then
1677
- parse_method container, single, tk, comment
1828
+ when 'def' then
1829
+ parse_method container, single, tk, comment
1678
1830
 
1679
- when TkCONSTANT then
1680
- unless parse_constant container, tk, comment, current_method then
1681
- try_parse_comment = true
1682
- end
1831
+ when 'alias' then
1832
+ parse_alias container, single, tk, comment unless current_method
1683
1833
 
1684
- when TkALIAS then
1685
- parse_alias container, single, tk, comment unless current_method
1834
+ when 'yield' then
1835
+ if current_method.nil? then
1836
+ warn "Warning: yield outside of method" if container.document_self
1837
+ else
1838
+ parse_yield container, single, tk, current_method
1839
+ end
1686
1840
 
1687
- when TkYIELD then
1688
- if current_method.nil? then
1689
- warn "Warning: yield outside of method" if container.document_self
1690
- else
1691
- parse_yield container, single, tk, current_method
1692
- end
1841
+ when 'until', 'while' then
1842
+ if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
1843
+ nest += 1
1844
+ skip_optional_do_after_expression
1845
+ end
1693
1846
 
1694
- # Until and While can have a 'do', which shouldn't increase the nesting.
1695
- # We can't solve the general case, but we can handle most occurrences by
1696
- # ignoring a do at the end of a line.
1847
+ # Until and While can have a 'do', which shouldn't increase the nesting.
1848
+ # We can't solve the general case, but we can handle most occurrences by
1849
+ # ignoring a do at the end of a line.
1697
1850
 
1698
- when TkUNTIL, TkWHILE then
1699
- nest += 1
1700
- skip_optional_do_after_expression
1851
+ # 'for' is trickier
1852
+ when 'for' then
1853
+ nest += 1
1854
+ skip_for_variable
1855
+ skip_optional_do_after_expression
1701
1856
 
1702
- # 'for' is trickier
1703
- when TkFOR then
1704
- nest += 1
1705
- skip_for_variable
1706
- skip_optional_do_after_expression
1857
+ when 'case', 'do', 'if', 'unless', 'begin' then
1858
+ if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
1859
+ nest += 1
1860
+ end
1707
1861
 
1708
- when TkCASE, TkDO, TkIF, TkUNLESS, TkBEGIN then
1709
- nest += 1
1862
+ when 'super' then
1863
+ current_method.calls_super = true if current_method
1864
+
1865
+ when 'rescue' then
1866
+ parse_rescue
1710
1867
 
1711
- when TkSUPER then
1712
- current_method.calls_super = true if current_method
1868
+ when 'end' then
1869
+ nest -= 1
1870
+ if nest == 0 then
1871
+ container.ongoing_visibility = save_visibility
1872
+
1873
+ parse_comment container, tk, comment unless comment.empty?
1874
+
1875
+ return
1876
+ end
1877
+ end
1713
1878
 
1714
- when TkRESCUE then
1715
- parse_rescue
1879
+ when :on_const then
1880
+ unless parse_constant container, tk, comment, current_method then
1881
+ try_parse_comment = true
1882
+ end
1716
1883
 
1717
- when TkIDENTIFIER then
1884
+ when :on_ident then
1718
1885
  if nest == 1 and current_method.nil? then
1719
1886
  keep_comment = parse_identifier container, single, tk, comment
1720
1887
  end
1721
1888
 
1722
- case tk.name
1889
+ case tk[:text]
1723
1890
  when "require" then
1724
1891
  parse_require container, comment
1725
1892
  when "include" then
@@ -1728,16 +1895,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
1728
1895
  parse_extend_or_include RDoc::Extend, container, comment
1729
1896
  end
1730
1897
 
1731
- when TkEND then
1732
- nest -= 1
1733
- if nest == 0 then
1734
- read_documentation_modifiers container, RDoc::CLASS_MODIFIERS
1735
- container.ongoing_visibility = save_visibility
1736
-
1737
- parse_comment container, tk, comment unless comment.empty?
1738
-
1739
- return
1740
- end
1741
1898
  else
1742
1899
  try_parse_comment = nest == 1
1743
1900
  end
@@ -1751,7 +1908,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1751
1908
 
1752
1909
  unless keep_comment then
1753
1910
  comment = new_comment ''
1754
- comment.force_encoding @encoding if @encoding
1911
+ comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
1755
1912
  container.params = nil
1756
1913
  container.block_params = nil
1757
1914
  end
@@ -1769,8 +1926,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
1769
1926
  def parse_symbol_arg(no = nil)
1770
1927
  skip_tkspace_comment
1771
1928
 
1772
- case tk = get_tk
1773
- when TkLPAREN
1929
+ tk = get_tk
1930
+ if tk[:kind] == :on_lparen
1774
1931
  parse_symbol_arg_paren no
1775
1932
  else
1776
1933
  parse_symbol_arg_space no, tk
@@ -1792,10 +1949,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
1792
1949
  end
1793
1950
 
1794
1951
  skip_tkspace_comment
1795
- case tk2 = get_tk
1796
- when TkRPAREN
1952
+ case (tk2 = get_tk)[:kind]
1953
+ when :on_rparen
1797
1954
  break
1798
- when TkCOMMA
1955
+ when :on_comma
1799
1956
  else
1800
1957
  warn("unexpected token: '#{tk2.inspect}'") if $DEBUG_RDOC
1801
1958
  break
@@ -1819,10 +1976,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
1819
1976
  end
1820
1977
 
1821
1978
  loop do
1822
- skip_tkspace false
1979
+ skip_tkspace_without_nl
1823
1980
 
1824
1981
  tk1 = get_tk
1825
- unless TkCOMMA === tk1 then
1982
+ if tk1.nil? || :on_comma != tk1[:kind] then
1826
1983
  unget_tk tk1
1827
1984
  break
1828
1985
  end
@@ -1841,12 +1998,12 @@ class RDoc::Parser::Ruby < RDoc::Parser
1841
1998
  # Returns symbol text from the next token
1842
1999
 
1843
2000
  def parse_symbol_in_arg
1844
- case tk = get_tk
1845
- when TkSYMBOL
1846
- tk.text.sub(/^:/, '')
1847
- when TkSTRING
1848
- eval @read[-1]
1849
- when TkDSTRING, TkIDENTIFIER then
2001
+ tk = get_tk
2002
+ if :on_symbol == tk[:kind] then
2003
+ tk[:text].sub(/^:/, '')
2004
+ elsif :on_tstring == tk[:kind] then
2005
+ tk[:text][1..-2]
2006
+ elsif :on_dstring == tk[:kind] or :on_ident == tk[:kind] then
1850
2007
  nil # ignore
1851
2008
  else
1852
2009
  warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG_RDOC
@@ -1880,19 +2037,37 @@ class RDoc::Parser::Ruby < RDoc::Parser
1880
2037
 
1881
2038
  skip_tkspace_comment false
1882
2039
 
1883
- case peek_tk
1884
- # Ryan Davis suggested the extension to ignore modifiers, because he
1885
- # often writes
1886
- #
1887
- # protected unless $TESTING
1888
- #
1889
- when TkNL, TkUNLESS_MOD, TkIF_MOD, TkSEMICOLON then
2040
+ ptk = peek_tk
2041
+ # Ryan Davis suggested the extension to ignore modifiers, because he
2042
+ # often writes
2043
+ #
2044
+ # protected unless $TESTING
2045
+ #
2046
+ if [:on_nl, :on_semicolon].include?(ptk[:kind]) || (:on_kw == ptk[:kind] && (['if', 'unless'].include?(ptk[:text]))) then
1890
2047
  container.ongoing_visibility = vis
2048
+ elsif :on_kw == ptk[:kind] && 'def' == ptk[:text]
2049
+ container.current_line_visibility = vis
1891
2050
  else
1892
2051
  update_visibility container, vis_type, vis, singleton
1893
2052
  end
1894
2053
  end
1895
2054
 
2055
+ ##
2056
+ # Parses a Module#private_constant or Module#public_constant call from +tk+.
2057
+
2058
+ def parse_constant_visibility(container, single, tk)
2059
+ args = parse_symbol_arg
2060
+ case tk[:text]
2061
+ when 'private_constant'
2062
+ vis = :private
2063
+ when 'public_constant'
2064
+ vis = :public
2065
+ else
2066
+ raise RDoc::Error, 'Unreachable'
2067
+ end
2068
+ container.set_constant_visibility_for args, vis
2069
+ end
2070
+
1896
2071
  ##
1897
2072
  # Determines the block parameter for +context+
1898
2073
 
@@ -1900,7 +2075,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
1900
2075
  return if method.block_params
1901
2076
 
1902
2077
  get_tkread
1903
- @scanner.continue = false
1904
2078
  method.block_params = parse_method_or_yield_parameters
1905
2079
  end
1906
2080
 
@@ -1924,11 +2098,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
1924
2098
  while tk = get_tk do
1925
2099
  tokens << tk
1926
2100
 
1927
- case tk
1928
- when TkNL, TkDEF then
2101
+ if :on_nl == tk[:kind] or (:on_kw == tk[:kind] && 'def' == tk[:text]) then
1929
2102
  return
1930
- when TkCOMMENT then
1931
- return unless tk.text =~ /\s*:?([\w-]+):\s*(.*)/
2103
+ elsif :on_comment == tk[:kind] or :on_embdoc == tk[:kind] then
2104
+ return unless tk[:text] =~ /\s*:?([\w-]+):\s*(.*)/
1932
2105
 
1933
2106
  directive = $1.downcase
1934
2107
 
@@ -1938,7 +2111,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1938
2111
  end
1939
2112
  end
1940
2113
  ensure
1941
- unless tokens.length == 1 and TkCOMMENT === tokens.first then
2114
+ unless tokens.length == 1 and (:on_comment == tokens.first[:kind] or :on_embdoc == tokens.first[:kind]) then
1942
2115
  tokens.reverse_each do |token|
1943
2116
  unget_tk token
1944
2117
  end
@@ -1952,6 +2125,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1952
2125
  # See also RDoc::Markup::PreProcess#handle_directive
1953
2126
 
1954
2127
  def read_documentation_modifiers context, allowed
2128
+ skip_tkspace_without_nl
1955
2129
  directive, value = read_directive allowed
1956
2130
 
1957
2131
  return unless directive
@@ -1978,15 +2152,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
1978
2152
  container.record_location @top_level
1979
2153
  end
1980
2154
 
1981
- ##
1982
- # Removes private comments from +comment+
1983
- #--
1984
- # TODO remove
1985
-
1986
- def remove_private_comments comment
1987
- comment.remove_private
1988
- end
1989
-
1990
2155
  ##
1991
2156
  # Scans this Ruby file for Ruby constructs
1992
2157
 
@@ -1998,29 +2163,33 @@ class RDoc::Parser::Ruby < RDoc::Parser
1998
2163
  parse_top_level_statements @top_level
1999
2164
 
2000
2165
  rescue StandardError => e
2001
- bytes = ''
2002
-
2003
- 20.times do @scanner.ungetc end
2004
- count = 0
2005
- 60.times do |i|
2006
- count = i
2007
- byte = @scanner.getc
2008
- break unless byte
2009
- bytes << byte
2166
+ if @content.include?('<%') and @content.include?('%>') then
2167
+ # Maybe, this is ERB.
2168
+ $stderr.puts "\033[2KRDoc detects ERB file. Skips it for compatibility:"
2169
+ $stderr.puts @file_name
2170
+ return
2171
+ end
2172
+
2173
+ if @scanner_point >= @scanner.size
2174
+ now_line_no = @scanner[@scanner.size - 1][:line_no]
2175
+ else
2176
+ now_line_no = peek_tk[:line_no]
2010
2177
  end
2011
- count -= 20
2012
- count.times do @scanner.ungetc end
2178
+ first_tk_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no }
2179
+ last_tk_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no + 1 }
2180
+ last_tk_index = last_tk_index ? last_tk_index - 1 : @scanner.size - 1
2181
+ code = @scanner[first_tk_index..last_tk_index].map{ |t| t[:text] }.join
2013
2182
 
2014
2183
  $stderr.puts <<-EOF
2015
2184
 
2016
- #{self.class} failure around line #{@scanner.line_no} of
2185
+ #{self.class} failure around line #{now_line_no} of
2017
2186
  #{@file_name}
2018
2187
 
2019
2188
  EOF
2020
2189
 
2021
- unless bytes.empty? then
2190
+ unless code.empty? then
2191
+ $stderr.puts code
2022
2192
  $stderr.puts
2023
- $stderr.puts bytes.inspect
2024
2193
  end
2025
2194
 
2026
2195
  raise e
@@ -2034,53 +2203,52 @@ class RDoc::Parser::Ruby < RDoc::Parser
2034
2203
  # while, until, and for have an optional do
2035
2204
 
2036
2205
  def skip_optional_do_after_expression
2037
- skip_tkspace false
2206
+ skip_tkspace_without_nl
2038
2207
  tk = get_tk
2039
- end_token = get_end_token tk
2040
2208
 
2041
2209
  b_nest = 0
2042
2210
  nest = 0
2043
- @scanner.continue = false
2044
2211
 
2045
2212
  loop do
2046
- case tk
2047
- when TkSEMICOLON then
2213
+ break unless tk
2214
+ case tk[:kind]
2215
+ when :on_semicolon, :on_nl, :on_ignored_nl then
2048
2216
  break if b_nest.zero?
2049
- when TkLPAREN, TkfLPAREN then
2217
+ when :on_lparen then
2050
2218
  nest += 1
2051
- when TkBEGIN then
2052
- b_nest += 1
2053
- when TkEND then
2054
- b_nest -= 1
2055
- when TkDO
2056
- break if nest.zero?
2057
- when end_token then
2058
- if end_token == TkRPAREN
2059
- nest -= 1
2060
- break if @scanner.lex_state == :EXPR_END and nest.zero?
2061
- else
2062
- break unless @scanner.continue
2219
+ when :on_rparen then
2220
+ nest -= 1
2221
+ when :on_kw then
2222
+ case tk[:text]
2223
+ when 'begin'
2224
+ b_nest += 1
2225
+ when 'end'
2226
+ b_nest -= 1
2227
+ when 'do'
2228
+ break if nest.zero?
2229
+ end
2230
+ when :on_comment, :on_embdoc then
2231
+ if b_nest.zero? and "\n" == tk[:text][-1] then
2232
+ break
2063
2233
  end
2064
- when nil then
2065
- break
2066
2234
  end
2067
2235
  tk = get_tk
2068
2236
  end
2069
2237
 
2070
- skip_tkspace false
2238
+ skip_tkspace_without_nl
2071
2239
 
2072
- get_tk if TkDO === peek_tk
2240
+ get_tk if peek_tk && :on_kw == peek_tk[:kind] && 'do' == peek_tk[:text]
2073
2241
  end
2074
2242
 
2075
2243
  ##
2076
2244
  # skip the var [in] part of a 'for' statement
2077
2245
 
2078
2246
  def skip_for_variable
2079
- skip_tkspace false
2247
+ skip_tkspace_without_nl
2080
2248
  get_tk
2081
- skip_tkspace false
2249
+ skip_tkspace_without_nl
2082
2250
  tk = get_tk
2083
- unget_tk(tk) unless TkIN === tk
2251
+ unget_tk(tk) unless :on_kw == tk[:kind] and 'in' == tk[:text]
2084
2252
  end
2085
2253
 
2086
2254
  ##
@@ -2097,8 +2265,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
2097
2265
 
2098
2266
  def skip_tkspace_comment(skip_nl = true)
2099
2267
  loop do
2100
- skip_tkspace skip_nl
2101
- return unless TkCOMMENT === peek_tk
2268
+ skip_nl ? skip_tkspace : skip_tkspace_without_nl
2269
+ next_tk = peek_tk
2270
+ return if next_tk.nil? || (:on_comment != next_tk[:kind] and :on_embdoc != next_tk[:kind])
2102
2271
  get_tk
2103
2272
  end
2104
2273
  end