rdoc 6.0.0.beta1 → 6.0.0.beta2

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.

@@ -24,6 +24,7 @@ $TOKEN_DEBUG ||= nil
24
24
  # * aliases
25
25
  # * private, public, protected
26
26
  # * private_class_function, public_class_function
27
+ # * private_constant, public_constant
27
28
  # * module_function
28
29
  # * attr, attr_reader, attr_writer, attr_accessor
29
30
  # * extra accessors given on the command line
@@ -139,11 +140,12 @@ $TOKEN_DEBUG ||= nil
139
140
  # Note that by default, the :method: directive will be ignored if there is a
140
141
  # standard rdocable item following it.
141
142
 
143
+ require 'ripper'
144
+
142
145
  class RDoc::Parser::Ruby < RDoc::Parser
143
146
 
144
147
  parse_files_matching(/\.rbw?$/)
145
148
 
146
- include RDoc::RubyToken
147
149
  include RDoc::TokenStream
148
150
  include RDoc::Parser::RubyTools
149
151
 
@@ -163,10 +165,20 @@ class RDoc::Parser::Ruby < RDoc::Parser
163
165
  def initialize(top_level, file_name, content, options, stats)
164
166
  super
165
167
 
168
+ if /\t/ =~ content then
169
+ tab_width = @options.tab_width
170
+ content = content.split(/\n/).map do |line|
171
+ 1 while line.gsub!(/\t+/) {
172
+ ' ' * (tab_width*$&.length - $`.length % tab_width)
173
+ } && $~
174
+ line
175
+ end.join("\n")
176
+ end
177
+
166
178
  @size = 0
167
179
  @token_listeners = nil
168
- @scanner = RDoc::RubyLex.new content, @options
169
- @scanner.exception_on_syntax_error = false
180
+ @scanner = RDoc::RipperStateLex.parse(content)
181
+ @scanner_point = 0
170
182
  @prev_seek = nil
171
183
  @markup = @options.markup
172
184
  @track_visibility = :nodoc != @options.visibility
@@ -175,6 +187,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
175
187
  reset
176
188
  end
177
189
 
190
+ def tk_nl?(tk)
191
+ :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]
192
+ end
193
+
178
194
  ##
179
195
  # Retrieves the read token stream and replaces +pattern+ with +replacement+
180
196
  # using gsub. If the result is only a ";" returns an empty string.
@@ -194,7 +210,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
194
210
  # methods.
195
211
 
196
212
  def get_visibility_information tk, single # :nodoc:
197
- vis_type = tk.name
213
+ vis_type = tk[:text]
198
214
  singleton = single == SINGLE
199
215
 
200
216
  vis =
@@ -226,27 +242,27 @@ class RDoc::Parser::Ruby < RDoc::Parser
226
242
  comment = ''
227
243
  comment.force_encoding @encoding if @encoding
228
244
  first_line = true
229
- first_comment_tk_class = nil
245
+ first_comment_tk_kind = nil
230
246
 
231
247
  tk = get_tk
232
248
 
233
- while TkCOMMENT === tk
234
- if first_line and tk.text =~ /\A#!/ then
249
+ while tk && (:on_comment == tk[:kind] or :on_embdoc == tk[:kind])
250
+ if first_line and tk[:text] =~ /\A#!/ then
235
251
  skip_tkspace
236
252
  tk = get_tk
237
- elsif first_line and tk.text =~ /\A#\s*-\*-/ then
253
+ elsif first_line and tk[:text] =~ /\A#\s*-\*-/ then
238
254
  first_line = false
239
255
  skip_tkspace
240
256
  tk = get_tk
241
257
  else
242
- break if first_comment_tk_class and not first_comment_tk_class === tk
243
- first_comment_tk_class = tk.class
258
+ break if first_comment_tk_kind and not first_comment_tk_kind === tk[:kind]
259
+ first_comment_tk_kind = tk[:kind]
244
260
 
245
261
  first_line = false
246
- comment << tk.text << "\n"
262
+ comment << tk[:text]
247
263
  tk = get_tk
248
264
 
249
- if TkNL === tk then
265
+ if :on_nl === tk then
250
266
  skip_tkspace false
251
267
  tk = get_tk
252
268
  end
@@ -262,7 +278,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
262
278
  # Consumes trailing whitespace from the token stream
263
279
 
264
280
  def consume_trailing_spaces # :nodoc:
265
- get_tkread
266
281
  skip_tkspace false
267
282
  end
268
283
 
@@ -309,10 +324,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
309
324
  def get_bool
310
325
  skip_tkspace
311
326
  tk = get_tk
312
- case tk
313
- when TkTRUE
327
+ if :on_kw == tk[:kind] && 'true' == tk[:text]
314
328
  true
315
- when TkFALSE, TkNIL
329
+ elsif :on_kw == tk[:kind] && ('false' == tk[:text] || 'nil' == tk[:text])
316
330
  false
317
331
  else
318
332
  unget_tk tk
@@ -331,24 +345,24 @@ class RDoc::Parser::Ruby < RDoc::Parser
331
345
  given_name = ''
332
346
 
333
347
  # class ::A -> A is in the top level
334
- case name_t
335
- when TkCOLON2, TkCOLON3 then # bug
348
+ if :on_op == name_t[:kind] and '::' == name_t[:text] then # bug
336
349
  name_t = get_tk
337
350
  container = @top_level
338
351
  given_name << '::'
339
352
  end
340
353
 
341
354
  skip_tkspace false
342
- given_name << name_t.name
355
+ given_name << name_t[:text]
343
356
 
344
- while TkCOLON2 === peek_tk do
357
+ is_self = name_t[:kind] == :on_op && name_t[:text] == '<<'
358
+ while !is_self && (tk = peek_tk) and :on_op == tk[:kind] and '::' == tk[:text] do
345
359
  prev_container = container
346
- container = container.find_module_named name_t.name
360
+ container = container.find_module_named name_t[:text]
347
361
  container ||=
348
362
  if ignore_constants then
349
363
  RDoc::Context.new
350
364
  else
351
- c = prev_container.add_module RDoc::NormalModule, name_t.name
365
+ c = prev_container.add_module RDoc::NormalModule, name_t[:text]
352
366
  c.ignore unless prev_container.document_children
353
367
  @top_level.add_to_classes_or_modules c
354
368
  c
@@ -359,7 +373,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
359
373
  get_tk
360
374
  skip_tkspace false
361
375
  name_t = get_tk
362
- given_name << '::' << name_t.name
376
+ unless :on_const == name_t[:kind] || :on_ident == name_t[:kind]
377
+ raise RDoc::Error, "Invalid class or module definition: #{given_name}"
378
+ end
379
+ given_name << '::' << name_t[:text]
363
380
  end
364
381
 
365
382
  skip_tkspace false
@@ -371,9 +388,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
371
388
  # Return a superclass, which can be either a constant of an expression
372
389
 
373
390
  def get_class_specification
374
- case peek_tk
375
- when TkSELF then return 'self'
376
- when TkGVAR then return ''
391
+ tk = peek_tk
392
+ if tk.nil?
393
+ return ''
394
+ elsif :on_kw == tk[:kind] && 'self' == tk[:text]
395
+ return 'self'
396
+ elsif :on_gvar == tk[:kind]
397
+ return ''
377
398
  end
378
399
 
379
400
  res = get_constant
@@ -383,9 +404,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
383
404
  get_tkread # empty out read buffer
384
405
 
385
406
  tk = get_tk
407
+ return res unless tk
386
408
 
387
- case tk
388
- when TkNL, TkCOMMENT, TkSEMICOLON then
409
+ case tk[:kind]
410
+ when :on_nl, :on_comment, :on_embdoc, :on_semicolon then
389
411
  unget_tk(tk)
390
412
  return res
391
413
  end
@@ -403,8 +425,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
403
425
  skip_tkspace false
404
426
  tk = get_tk
405
427
 
406
- while TkCOLON2 === tk or TkCOLON3 === tk or TkCONSTANT === tk do
407
- res += tk.name
428
+ while tk && ((:on_op == tk[:kind] && '::' == tk[:text]) || :on_const == tk[:kind]) do
429
+ res += tk[:text]
408
430
  tk = get_tk
409
431
  end
410
432
 
@@ -420,7 +442,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
420
442
 
421
443
  nest = 0
422
444
 
423
- while TkLPAREN === (tk = peek_tk) or TkfLPAREN === tk do
445
+ while :on_lparen == (tk = peek_tk)[:kind] do
424
446
  get_tk
425
447
  skip_tkspace
426
448
  nest += 1
@@ -431,7 +453,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
431
453
  while nest > 0
432
454
  skip_tkspace
433
455
  tk = get_tk
434
- nest -= 1 if TkRPAREN === tk
456
+ nest -= 1 if :on_rparen == tk[:kind]
435
457
  end
436
458
 
437
459
  name
@@ -446,13 +468,19 @@ class RDoc::Parser::Ruby < RDoc::Parser
446
468
  # won't catch all cases (such as "a = yield + 1"
447
469
 
448
470
  def get_end_token tk # :nodoc:
449
- case tk
450
- when TkLPAREN, TkfLPAREN
451
- TkRPAREN
452
- when TkRPAREN
471
+ case tk[:kind]
472
+ when :on_lparen
473
+ {
474
+ :kind => :on_rparen,
475
+ :text => ')'
476
+ }
477
+ when :on_rparen
453
478
  nil
454
479
  else
455
- TkNL
480
+ {
481
+ :kind => :on_nl,
482
+ :text => "\n"
483
+ }
456
484
  end
457
485
  end
458
486
 
@@ -461,11 +489,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
461
489
 
462
490
  def get_method_container container, name_t # :nodoc:
463
491
  prev_container = container
464
- container = container.find_module_named(name_t.name)
492
+ container = container.find_module_named(name_t[:text])
465
493
 
466
494
  unless container then
467
495
  constant = prev_container.constants.find do |const|
468
- const.name == name_t.name
496
+ const.name == name_t[:text]
469
497
  end
470
498
 
471
499
  if constant then
@@ -476,21 +504,21 @@ class RDoc::Parser::Ruby < RDoc::Parser
476
504
 
477
505
  unless container then
478
506
  # TODO seems broken, should starting at Object in @store
479
- obj = name_t.name.split("::").inject(Object) do |state, item|
507
+ obj = name_t[:text].split("::").inject(Object) do |state, item|
480
508
  state.const_get(item)
481
509
  end rescue nil
482
510
 
483
511
  type = obj.class == Class ? RDoc::NormalClass : RDoc::NormalModule
484
512
 
485
513
  unless [Class, Module].include?(obj.class) then
486
- warn("Couldn't find #{name_t.name}. Assuming it's a module")
514
+ warn("Couldn't find #{name_t[:text]}. Assuming it's a module")
487
515
  end
488
516
 
489
517
  if type == RDoc::NormalClass then
490
518
  sclass = obj.superclass ? obj.superclass.name : nil
491
- container = prev_container.add_class type, name_t.name, sclass
519
+ container = prev_container.add_class type, name_t[:text], sclass
492
520
  else
493
- container = prev_container.add_module type, name_t.name
521
+ container = prev_container.add_module type, name_t[:text]
494
522
  end
495
523
 
496
524
  record_location container
@@ -504,32 +532,26 @@ class RDoc::Parser::Ruby < RDoc::Parser
504
532
 
505
533
  def get_symbol_or_name
506
534
  tk = get_tk
507
- case tk
508
- when TkSYMBOL then
509
- text = tk.text.sub(/^:/, '')
535
+ case tk[:kind]
536
+ when :on_symbol then
537
+ text = tk[:text].sub(/^:/, '')
510
538
 
511
- if TkASSIGN === peek_tk then
539
+ next_tk = peek_tk
540
+ if next_tk && :on_op == next_tk[:kind] && '=' == next_tk[:text] then
512
541
  get_tk
513
542
  text << '='
514
543
  end
515
544
 
516
545
  text
517
- when TkId, TkOp then
518
- tk.name
519
- when TkAMPER,
520
- TkDSTRING,
521
- TkSTAR,
522
- TkSTRING then
523
- tk.text
546
+ when :on_ident, :on_const, :on_gvar, :on_cvar, :on_ivar, :on_op, :on_kw then
547
+ tk[:text]
548
+ when :on_tstring, :on_dstring then
549
+ tk[:text][1..-2]
524
550
  else
525
551
  raise RDoc::Error, "Name or symbol expected (got #{tk})"
526
552
  end
527
553
  end
528
554
 
529
- def stop_at_EXPR_END # :nodoc:
530
- @scanner.lex_state == :EXPR_END || !@scanner.continue
531
- end
532
-
533
555
  ##
534
556
  # Marks containers between +container+ and +ancestor+ as ignored
535
557
 
@@ -570,7 +592,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
570
592
  def make_message message
571
593
  prefix = "#{@file_name}:"
572
594
 
573
- prefix << "#{@scanner.line_no}:#{@scanner.char_no}:" if @scanner
595
+ tk = peek_tk
596
+ prefix << "#{tk[:line_no]}:#{tk[:char_no]}:" if tk
574
597
 
575
598
  "#{prefix} #{message}"
576
599
  end
@@ -589,7 +612,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
589
612
  # +comment+.
590
613
 
591
614
  def parse_attr(context, single, tk, comment)
592
- line_no = tk.line_no
615
+ line_no = tk[:line_no]
593
616
 
594
617
  args = parse_symbol_arg 1
595
618
  if args.size > 0 then
@@ -598,7 +621,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
598
621
  skip_tkspace false
599
622
  tk = get_tk
600
623
 
601
- if TkCOMMA === tk then
624
+ if :on_comma == tk[:kind] then
602
625
  rw = "RW" if get_bool
603
626
  else
604
627
  unget_tk tk
@@ -618,7 +641,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
618
641
  # comment for each to +comment+.
619
642
 
620
643
  def parse_attr_accessor(context, single, tk, comment)
621
- line_no = tk.line_no
644
+ line_no = tk[:line_no]
622
645
 
623
646
  args = parse_symbol_arg
624
647
  rw = "?"
@@ -629,7 +652,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
629
652
  # and add found items appropriately but here we do not. I'm not sure why.
630
653
  return if @track_visibility and not tmp.document_self
631
654
 
632
- case tk.name
655
+ case tk[:text]
633
656
  when "attr_reader" then rw = "R"
634
657
  when "attr_writer" then rw = "W"
635
658
  when "attr_accessor" then rw = "RW"
@@ -647,21 +670,19 @@ class RDoc::Parser::Ruby < RDoc::Parser
647
670
  # Parses an +alias+ in +context+ with +comment+
648
671
 
649
672
  def parse_alias(context, single, tk, comment)
650
- line_no = tk.line_no
673
+ line_no = tk[:line_no]
651
674
 
652
675
  skip_tkspace
653
676
 
654
- if TkLPAREN === peek_tk then
677
+ if :on_lparen === peek_tk[:kind] then
655
678
  get_tk
656
679
  skip_tkspace
657
680
  end
658
681
 
659
682
  new_name = get_symbol_or_name
660
683
 
661
- @scanner.lex_state = :EXPR_FNAME
662
-
663
684
  skip_tkspace
664
- if TkCOMMA === peek_tk then
685
+ if :on_comma === peek_tk[:kind] then
665
686
  get_tk
666
687
  skip_tkspace
667
688
  end
@@ -688,34 +709,38 @@ class RDoc::Parser::Ruby < RDoc::Parser
688
709
  # Extracts call parameters from the token stream.
689
710
 
690
711
  def parse_call_parameters(tk)
691
- end_token = case tk
692
- when TkLPAREN, TkfLPAREN
693
- TkRPAREN
694
- when TkRPAREN
712
+ end_token = case tk[:kind]
713
+ when :on_lparen
714
+ :on_rparen
715
+ when :on_rparen
695
716
  return ""
696
717
  else
697
- TkNL
718
+ :on_nl
698
719
  end
699
720
  nest = 0
700
721
 
701
722
  loop do
702
- case tk
703
- when TkSEMICOLON
723
+ break if tk.nil?
724
+ case tk[:kind]
725
+ when :on_semicolon
704
726
  break
705
- when TkLPAREN, TkfLPAREN
727
+ when :on_lparen
706
728
  nest += 1
707
729
  when end_token
708
- if end_token == TkRPAREN
730
+ if end_token == :on_rparen
709
731
  nest -= 1
710
- break if @scanner.lex_state == :EXPR_END and nest <= 0
732
+ break if RDoc::RipperStateLex.end?(tk) and nest <= 0
711
733
  else
712
- break unless @scanner.continue
734
+ break if RDoc::RipperStateLex.end?(tk)
713
735
  end
714
- when TkCOMMENT, TkASSIGN, TkOPASGN
736
+ when :on_comment, :on_embdoc
715
737
  unget_tk(tk)
716
738
  break
717
- when nil then
718
- break
739
+ when :on_op
740
+ if tk[:text] =~ /^(.{1,2})?=$/
741
+ unget_tk(tk)
742
+ break
743
+ end
719
744
  end
720
745
  tk = get_tk
721
746
  end
@@ -727,28 +752,27 @@ class RDoc::Parser::Ruby < RDoc::Parser
727
752
  # Parses a class in +context+ with +comment+
728
753
 
729
754
  def parse_class container, single, tk, comment
730
- line_no = tk.line_no
755
+ line_no = tk[:line_no]
731
756
 
732
757
  declaration_context = container
733
758
  container, name_t, given_name = get_class_or_module container
734
759
 
735
- cls =
736
- case name_t
737
- when TkCONSTANT
738
- parse_class_regular container, declaration_context, single,
739
- name_t, given_name, comment
740
- when TkLSHFT
741
- case name = get_class_specification
742
- when 'self', container.name
743
- parse_statements container, SINGLE
744
- return # don't update line
745
- else
746
- parse_class_singleton container, name, comment
747
- end
760
+ if name_t[:kind] == :on_const
761
+ cls = parse_class_regular container, declaration_context, single,
762
+ name_t, given_name, comment
763
+ elsif name_t[:kind] == :on_op && name_t[:text] == '<<'
764
+ case name = get_class_specification
765
+ when 'self', container.name
766
+ read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
767
+ parse_statements container, SINGLE
768
+ return # don't update line
748
769
  else
749
- warn "Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}"
750
- return
770
+ cls = parse_class_singleton container, name, comment
751
771
  end
772
+ else
773
+ warn "Expected class name or '<<'. Got #{name_t[:kind]}: #{name_t[:text].inspect}"
774
+ return
775
+ end
752
776
 
753
777
  cls.line = line_no
754
778
 
@@ -770,7 +794,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
770
794
  given_name = $'
771
795
  end
772
796
 
773
- if TkLT === peek_tk then
797
+ tk = peek_tk
798
+ if tk[:kind] == :on_op && tk[:text] == '<' then
774
799
  get_tk
775
800
  skip_tkspace
776
801
  superclass = get_class_specification
@@ -840,40 +865,52 @@ class RDoc::Parser::Ruby < RDoc::Parser
840
865
  # true, no found constants will be added to RDoc.
841
866
 
842
867
  def parse_constant container, tk, comment, ignore_constants = false
843
- line_no = tk.line_no
868
+ line_no = tk[:line_no]
844
869
 
845
- name = tk.name
870
+ name = tk[:text]
846
871
  skip_tkspace false
847
872
 
848
873
  return unless name =~ /^\w+$/
849
874
 
850
875
  eq_tk = get_tk
851
876
 
852
- if TkCOLON2 === eq_tk then
877
+ if :on_op == eq_tk[:kind] && '::' == eq_tk[:text] then
853
878
  unget_tk eq_tk
854
879
  unget_tk tk
855
880
 
856
881
  container, name_t, = get_class_or_module container, ignore_constants
857
882
 
858
- name = name_t.name
883
+ name = name_t[:text]
859
884
 
860
885
  eq_tk = get_tk
861
886
  end
862
887
 
863
- unless TkASSIGN === eq_tk then
864
- unget_tk eq_tk
865
- return false
888
+ is_array_or_hash = false
889
+ if eq_tk && :on_lbracket == eq_tk[:kind]
890
+ nest = 1
891
+ while bracket_tk = get_tk
892
+ case bracket_tk[:kind]
893
+ when :on_lbracket
894
+ nest += 1
895
+ when :on_rbracket
896
+ nest -= 1
897
+ break if nest == 0
898
+ end
899
+ end
900
+ skip_tkspace false
901
+ eq_tk = get_tk
902
+ is_array_or_hash = true
866
903
  end
867
904
 
868
- if TkGT === peek_tk then
905
+ unless eq_tk && :on_op == eq_tk[:kind] && '=' == eq_tk[:text] then
869
906
  unget_tk eq_tk
870
- return
907
+ return false
871
908
  end
872
909
 
873
910
  value = ''
874
911
  con = RDoc::Constant.new name, value, comment
875
912
 
876
- body = parse_constant_body container, con
913
+ body = parse_constant_body container, con, is_array_or_hash
877
914
 
878
915
  return unless body
879
916
 
@@ -882,13 +919,15 @@ class RDoc::Parser::Ruby < RDoc::Parser
882
919
  con.line = line_no
883
920
  read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS
884
921
 
922
+ return if is_array_or_hash
923
+
885
924
  @stats.add_constant con
886
925
  container.add_constant con
887
926
 
888
927
  true
889
928
  end
890
929
 
891
- def parse_constant_body container, constant # :nodoc:
930
+ def parse_constant_body container, constant, is_array_or_hash # :nodoc:
892
931
  nest = 0
893
932
  rhs_name = ''
894
933
 
@@ -896,44 +935,51 @@ class RDoc::Parser::Ruby < RDoc::Parser
896
935
 
897
936
  tk = get_tk
898
937
 
938
+ body = nil
899
939
  loop do
900
- case tk
901
- when TkSEMICOLON then
940
+ break if tk.nil?
941
+ if :on_semicolon == tk[:kind] then
902
942
  break if nest <= 0
903
- when TkLPAREN, TkfLPAREN, TkLBRACE, TkfLBRACE, TkLBRACK, TkfLBRACK,
904
- TkDO, TkIF, TkUNLESS, TkCASE, TkDEF, TkBEGIN then
943
+ elsif [:on_tlambeg, :on_lparen, :on_lbrace, :on_lbracket].include?(tk[:kind]) then
944
+ nest += 1
945
+ elsif (:on_kw == tk[:kind] && 'def' == tk[:text]) then
905
946
  nest += 1
906
- when TkRPAREN, TkRBRACE, TkRBRACK, TkEND then
947
+ elsif (:on_kw == tk[:kind] && %w{do if unless case begin}.include?(tk[:text])) then
948
+ if (RDoc::RipperStateLex::EXPR_LABEL & tk[:state]) == 0
949
+ nest += 1
950
+ end
951
+ elsif [:on_rparen, :on_rbrace, :on_rbracket].include?(tk[:kind]) ||
952
+ (:on_kw == tk[:kind] && 'end' == tk[:text]) then
907
953
  nest -= 1
908
- when TkCOMMENT then
909
- if nest <= 0 and stop_at_EXPR_END then
910
- unget_tk tk
954
+ elsif (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then
955
+ unget_tk tk
956
+ if nest <= 0 and RDoc::RipperStateLex.end?(tk) then
957
+ body = get_tkread_clean(/^[ \t]+/, '')
958
+ read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS
911
959
  break
912
960
  else
913
- unget_tk tk
914
961
  read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS
915
962
  end
916
- when TkCONSTANT then
917
- rhs_name << tk.name
963
+ elsif :on_const == tk[:kind] then
964
+ rhs_name << tk[:text]
918
965
 
919
- if nest <= 0 and TkNL === peek_tk then
920
- create_module_alias container, constant, rhs_name
966
+ next_tk = peek_tk
967
+ if nest <= 0 and (next_tk.nil? || :on_nl == next_tk[:kind]) then
968
+ create_module_alias container, constant, rhs_name unless is_array_or_hash
921
969
  break
922
970
  end
923
- when TkNL then
924
- if nest <= 0 and stop_at_EXPR_END then
971
+ elsif :on_nl == tk[:kind] then
972
+ if nest <= 0 and RDoc::RipperStateLex.end?(tk) then
925
973
  unget_tk tk
926
974
  break
927
975
  end
928
- when TkCOLON2, TkCOLON3 then
976
+ elsif :on_op == tk[:kind] && '::' == tk[:text]
929
977
  rhs_name << '::'
930
- when nil then
931
- break
932
978
  end
933
979
  tk = get_tk
934
980
  end
935
981
 
936
- get_tkread_clean(/^[ \t]+/, '')
982
+ body ? body : get_tkread_clean(/^[ \t]+/, '')
937
983
  end
938
984
 
939
985
  ##
@@ -942,8 +988,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
942
988
 
943
989
  def parse_comment container, tk, comment
944
990
  return parse_comment_tomdoc container, tk, comment if @markup == 'tomdoc'
945
- column = tk.char_no
946
- line_no = tk.line_no
991
+ column = tk[:char_no]
992
+ line_no = tk[:line_no]
947
993
 
948
994
  text = comment.text
949
995
 
@@ -988,12 +1034,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
988
1034
  record_location meth
989
1035
 
990
1036
  meth.start_collecting_tokens
991
- indent = TkSPACE.new 0, 1, 1
992
- indent.set_text " " * column
993
-
994
- position_comment = TkCOMMENT.new 0, line_no, 1
995
- position_comment.set_text "# File #{@top_level.relative_name}, line #{line_no}"
996
- meth.add_tokens [position_comment, NEWLINE_TOKEN, indent]
1037
+ indent = { :line_no => 1, :char_no => 1, :kind => :on_sp, :text => ' ' * column }
1038
+ position_comment = { :line_no => line_no, :char_no => 1, :kind => :on_comment }
1039
+ position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
1040
+ newline = { :line_no => 0, :char_no => 0, :kind => :on_nl, :text => "\n" }
1041
+ meth.add_tokens [position_comment, newline, indent]
997
1042
 
998
1043
  meth.params =
999
1044
  if text.sub!(/^#\s+:?args?:\s*(.*?)\s*$/i, '') then
@@ -1022,8 +1067,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
1022
1067
 
1023
1068
  def parse_comment_tomdoc container, tk, comment
1024
1069
  return unless signature = RDoc::TomDoc.signature(comment)
1025
- column = tk.char_no
1026
- line_no = tk.line_no
1070
+ column = tk[:char_no]
1071
+ line_no = tk[:line_no]
1027
1072
 
1028
1073
  name, = signature.split %r%[ \(]%, 2
1029
1074
 
@@ -1032,12 +1077,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
1032
1077
  meth.line = line_no
1033
1078
 
1034
1079
  meth.start_collecting_tokens
1035
- indent = TkSPACE.new 0, 1, 1
1036
- indent.set_text " " * column
1037
-
1038
- position_comment = TkCOMMENT.new 0, line_no, 1
1039
- position_comment.set_text "# File #{@top_level.relative_name}, line #{line_no}"
1040
- meth.add_tokens [position_comment, NEWLINE_TOKEN, indent]
1080
+ indent = { :line_no => 1, :char_no => 1, :kind => :on_sp, :text => ' ' * column }
1081
+ position_comment = { :line_no => line_no, :char_no => 1, :kind => :on_comment }
1082
+ position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
1083
+ newline = { :line_no => 0, :char_no => 0, :kind => :on_nl, :text => "\n" }
1084
+ meth.add_tokens [position_comment, newline, indent]
1041
1085
 
1042
1086
  meth.call_seq = signature
1043
1087
 
@@ -1067,7 +1111,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1067
1111
  record_location obj
1068
1112
  end
1069
1113
 
1070
- return unless TkCOMMA === peek_tk
1114
+ return if peek_tk.nil? || :on_comma != peek_tk[:kind]
1071
1115
 
1072
1116
  get_tk
1073
1117
  end
@@ -1079,11 +1123,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
1079
1123
  # Returns true if the comment was not consumed.
1080
1124
 
1081
1125
  def parse_identifier container, single, tk, comment # :nodoc:
1082
- case tk.name
1126
+ case tk[:text]
1083
1127
  when 'private', 'protected', 'public', 'private_class_method',
1084
1128
  'public_class_method', 'module_function' then
1085
1129
  parse_visibility container, single, tk
1086
1130
  return true
1131
+ when 'private_constant', 'public_constant'
1132
+ parse_constant_visibility container, single, tk
1133
+ return true
1087
1134
  when 'attr' then
1088
1135
  parse_attr container, single, tk, comment
1089
1136
  when /^attr_(reader|writer|accessor)$/ then
@@ -1172,8 +1219,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
1172
1219
  # Parses a meta-programmed method
1173
1220
 
1174
1221
  def parse_meta_method(container, single, tk, comment)
1175
- column = tk.char_no
1176
- line_no = tk.line_no
1222
+ column = tk[:char_no]
1223
+ line_no = tk[:line_no]
1177
1224
 
1178
1225
  start_collecting_tokens
1179
1226
  add_token tk
@@ -1195,12 +1242,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
1195
1242
  remove_token_listener self
1196
1243
 
1197
1244
  meth.start_collecting_tokens
1198
- indent = TkSPACE.new 0, 1, 1
1199
- indent.set_text " " * column
1200
-
1201
- position_comment = TkCOMMENT.new 0, line_no, 1
1202
- position_comment.value = "# File #{@top_level.relative_name}, line #{line_no}"
1203
- meth.add_tokens [position_comment, NEWLINE_TOKEN, indent]
1245
+ indent = { :line_no => 1, :char_no => 1, :kind => :on_sp, :text => ' ' * column }
1246
+ position_comment = { :line_no => line_no, :char_no => 1, :kind => :on_comment }
1247
+ position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
1248
+ newline = { :line_no => 0, :char_no => 0, :kind => :on_nl, :text => "\n" }
1249
+ meth.add_tokens [position_comment, newline, indent]
1204
1250
  meth.add_tokens @token_stream
1205
1251
 
1206
1252
  parse_meta_method_params container, single, meth, tk, comment
@@ -1224,17 +1270,16 @@ class RDoc::Parser::Ruby < RDoc::Parser
1224
1270
 
1225
1271
  name_t = get_tk
1226
1272
 
1227
- case name_t
1228
- when TkSYMBOL then
1229
- name_t.text[1..-1]
1230
- when TkSTRING then
1231
- name_t.value[1..-2]
1232
- when TkASSIGN then # ignore
1273
+ if :on_symbol == name_t[:kind] then
1274
+ name_t[:text][1..-1]
1275
+ elsif :on_tstring == name_t[:kind] then
1276
+ name_t[:text][1..-2]
1277
+ elsif :on_op == name_t[:kind] && '=' == name_t[:text] then # ignore
1233
1278
  remove_token_listener self
1234
1279
 
1235
1280
  nil
1236
1281
  else
1237
- warn "unknown name token #{name_t.inspect} for meta-method '#{tk.name}'"
1282
+ warn "unknown name token #{name_t.inspect} for meta-method '#{tk[:text]}'"
1238
1283
  'unknown'
1239
1284
  end
1240
1285
  end
@@ -1254,14 +1299,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
1254
1299
  last_tk = tk
1255
1300
 
1256
1301
  while tk = get_tk do
1257
- case tk
1258
- when TkSEMICOLON then
1302
+ if :on_semicolon == tk[:kind] then
1259
1303
  break
1260
- when TkNL then
1261
- break unless last_tk and TkCOMMA === last_tk
1262
- when TkSPACE then
1304
+ elsif :on_nl == tk[:kind] then
1305
+ break unless last_tk and :on_comma == last_tk[:kind]
1306
+ elsif :on_sp == tk[:kind] then
1263
1307
  # expression continues
1264
- when TkDO then
1308
+ elsif :on_kw == tk[:kind] && 'do' == tk[:text] then
1265
1309
  parse_statements container, single, meth
1266
1310
  break
1267
1311
  else
@@ -1278,8 +1322,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
1278
1322
  singleton = nil
1279
1323
  added_container = false
1280
1324
  name = nil
1281
- column = tk.char_no
1282
- line_no = tk.line_no
1325
+ column = tk[:char_no]
1326
+ line_no = tk[:line_no]
1283
1327
 
1284
1328
  start_collecting_tokens
1285
1329
  add_token tk
@@ -1299,12 +1343,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
1299
1343
  meth.line = line_no
1300
1344
 
1301
1345
  meth.start_collecting_tokens
1302
- indent = TkSPACE.new 0, 1, 1
1303
- indent.set_text " " * column
1304
-
1305
- token = TkCOMMENT.new 0, line_no, 1
1306
- token.set_text "# File #{@top_level.relative_name}, line #{line_no}"
1307
- meth.add_tokens [token, NEWLINE_TOKEN, indent]
1346
+ indent = { :line_no => 1, :char_no => 1, :kind => :on_sp, :text => ' ' * column }
1347
+ token = { :line_no => line_no, :char_no => 1, :kind => :on_comment }
1348
+ token[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
1349
+ newline = { :line_no => 0, :char_no => 0, :kind => :on_nl, :text => "\n" }
1350
+ meth.add_tokens [token, newline, indent]
1308
1351
  meth.add_tokens @token_stream
1309
1352
 
1310
1353
  parse_method_params_and_body container, single, meth, added_container
@@ -1325,7 +1368,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
1325
1368
 
1326
1369
  def parse_method_params_and_body container, single, meth, added_container
1327
1370
  token_listener meth do
1328
- @scanner.continue = false
1329
1371
  parse_method_parameters meth
1330
1372
 
1331
1373
  if meth.document_self or not @track_visibility then
@@ -1368,15 +1410,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
1368
1410
  # it is a singleton or regular method.
1369
1411
 
1370
1412
  def parse_method_name container # :nodoc:
1371
- @scanner.lex_state = :EXPR_FNAME
1372
-
1373
1413
  skip_tkspace
1374
1414
  name_t = get_tk
1375
- back_tk = skip_tkspace
1415
+ back_tk = skip_tkspace(false)
1376
1416
  singleton = false
1377
1417
 
1378
- case dot = get_tk
1379
- when TkDOT, TkCOLON2 then
1418
+ dot = get_tk
1419
+ if dot[:kind] == :on_period || (dot[:kind] == :on_op && dot[:text] == '::') then
1380
1420
  singleton = true
1381
1421
 
1382
1422
  name, container = parse_method_name_singleton container, name_t
@@ -1397,16 +1437,15 @@ class RDoc::Parser::Ruby < RDoc::Parser
1397
1437
  # is parsed from the token stream for a regular method.
1398
1438
 
1399
1439
  def parse_method_name_regular container, name_t # :nodoc:
1400
- case name_t
1401
- when TkSTAR, TkAMPER then
1402
- name_t.text
1440
+ if :on_op == name_t[:kind] && (%w{* & [] []= <<}.include?(name_t[:text])) then
1441
+ name_t[:text]
1403
1442
  else
1404
- unless name_t.respond_to? :name then
1443
+ unless [:on_kw, :on_const, :on_ident].include?(name_t[:kind]) then
1405
1444
  warn "expected method name token, . or ::, got #{name_t.inspect}"
1406
1445
  skip_method container
1407
1446
  return
1408
1447
  end
1409
- name_t.name
1448
+ name_t[:text]
1410
1449
  end
1411
1450
  end
1412
1451
 
@@ -1416,47 +1455,43 @@ class RDoc::Parser::Ruby < RDoc::Parser
1416
1455
  # for a singleton method.
1417
1456
 
1418
1457
  def parse_method_name_singleton container, name_t # :nodoc:
1419
- @scanner.lex_state = :EXPR_FNAME
1420
1458
  skip_tkspace
1421
1459
  name_t2 = get_tk
1422
1460
 
1423
- name =
1424
- case name_t
1425
- when TkSELF, TkMOD then
1426
- case name_t2
1427
- # NOTE: work around '[' being consumed early and not being re-tokenized
1428
- # as a TkAREF
1429
- when TkfLBRACK then
1430
- get_tk
1431
- '[]'
1432
- else
1433
- name_t2.name
1434
- end
1435
- when TkCONSTANT then
1436
- name = name_t2.name
1461
+ if (:on_kw == name_t[:kind] && 'self' == name_t[:text]) || (:on_op == name_t[:kind] && '%' == name_t[:text]) then
1462
+ # NOTE: work around '[' being consumed early and not being re-tokenized
1463
+ # as a TkAREF
1464
+ if :on_lbracket == name_t2[:kind]
1465
+ get_tk
1466
+ name = '[]'
1467
+ else
1468
+ name = name_t2[:text]
1469
+ end
1470
+ elsif :on_const == name_t[:kind] then
1471
+ name = name_t2[:text]
1437
1472
 
1438
- container = get_method_container container, name_t
1473
+ container = get_method_container container, name_t
1439
1474
 
1440
- return unless container
1475
+ return unless container
1441
1476
 
1442
- name
1443
- when TkIDENTIFIER, TkIVAR, TkGVAR then
1444
- parse_method_dummy container
1477
+ name
1478
+ elsif :on_ident == name_t[:kind] || :on_ivar == name_t[:kind] || :on_gvar == name_t[:kind] then
1479
+ parse_method_dummy container
1445
1480
 
1446
- nil
1447
- when TkTRUE, TkFALSE, TkNIL then
1448
- klass_name = "#{name_t.name.capitalize}Class"
1449
- container = @store.find_class_named klass_name
1450
- container ||= @top_level.add_class RDoc::NormalClass, klass_name
1481
+ name = nil
1482
+ elsif (:on_kw == name_t[:kind]) && ('true' == name_t[:text] || 'false' == name_t[:text] || 'nil' == name_t[:text]) then
1483
+ klass_name = "#{name_t[:text].capitalize}Class"
1484
+ container = @store.find_class_named klass_name
1485
+ container ||= @top_level.add_class RDoc::NormalClass, klass_name
1451
1486
 
1452
- name_t2.name
1453
- else
1454
- warn "unexpected method name token #{name_t.inspect}"
1455
- # break
1456
- skip_method container
1487
+ name = name_t2[:text]
1488
+ else
1489
+ warn "unexpected method name token #{name_t.inspect}"
1490
+ # break
1491
+ skip_method container
1457
1492
 
1458
- nil
1459
- end
1493
+ name = nil
1494
+ end
1460
1495
 
1461
1496
  return name, container
1462
1497
  end
@@ -1472,43 +1507,49 @@ class RDoc::Parser::Ruby < RDoc::Parser
1472
1507
  return '' unless end_token
1473
1508
 
1474
1509
  nest = 0
1510
+ continue = false
1475
1511
 
1476
- loop do
1477
- case tk
1478
- when TkSEMICOLON then
1512
+ while tk != nil do
1513
+ case tk[:kind]
1514
+ when :on_semicolon then
1479
1515
  break if nest == 0
1480
- when TkLBRACE, TkfLBRACE then
1516
+ when :on_lbrace then
1481
1517
  nest += 1
1482
- when TkRBRACE then
1518
+ when :on_rbrace then
1483
1519
  nest -= 1
1484
1520
  if nest <= 0
1485
1521
  # we might have a.each { |i| yield i }
1486
1522
  unget_tk(tk) if nest < 0
1487
1523
  break
1488
1524
  end
1489
- when TkLPAREN, TkfLPAREN then
1525
+ when :on_lparen then
1490
1526
  nest += 1
1491
- when end_token then
1492
- if end_token == TkRPAREN
1527
+ when end_token[:kind] then
1528
+ if end_token[:kind] == :on_rparen
1493
1529
  nest -= 1
1494
1530
  break if nest <= 0
1495
1531
  else
1496
- break unless @scanner.continue
1532
+ break
1497
1533
  end
1498
- when TkRPAREN then
1534
+ when :on_rparen then
1499
1535
  nest -= 1
1500
- when method && method.block_params.nil? && TkCOMMENT then
1501
- unget_tk tk
1502
- read_documentation_modifiers method, modifiers
1503
- @read.pop
1504
- when TkCOMMENT then
1536
+ when :on_comment, :on_embdoc then
1505
1537
  @read.pop
1506
- when nil then
1507
- break
1538
+ if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and
1539
+ (!continue or (RDoc::RipperStateLex::EXPR_LABEL & tk[:state]) != 0) then
1540
+ if method && method.block_params.nil? then
1541
+ unget_tk tk
1542
+ read_documentation_modifiers method, modifiers
1543
+ end
1544
+ break if !continue and nest <= 0
1545
+ end
1546
+ when :on_comma then
1547
+ continue = true
1548
+ when :on_ident then
1549
+ continue = false if continue
1508
1550
  end
1509
1551
  tk = get_tk
1510
1552
  end
1511
- @scanner.first_in_method_statement = true
1512
1553
 
1513
1554
  get_tkread_clean(/\s+/, ' ')
1514
1555
  end
@@ -1539,7 +1580,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1539
1580
  def parse_module container, single, tk, comment
1540
1581
  container, name_t, = get_class_or_module container
1541
1582
 
1542
- name = name_t.name
1583
+ name = name_t[:text]
1543
1584
 
1544
1585
  mod = container.add_module RDoc::NormalModule, name
1545
1586
  mod.ignore unless container.document_children
@@ -1562,12 +1603,12 @@ class RDoc::Parser::Ruby < RDoc::Parser
1562
1603
  skip_tkspace_comment
1563
1604
  tk = get_tk
1564
1605
 
1565
- if TkLPAREN === tk then
1606
+ if :on_lparen == tk[:kind] then
1566
1607
  skip_tkspace_comment
1567
1608
  tk = get_tk
1568
1609
  end
1569
1610
 
1570
- name = tk.text if TkSTRING === tk
1611
+ name = tk[:text][1..-2] if :on_tstring == tk[:kind]
1571
1612
 
1572
1613
  if name then
1573
1614
  @top_level.add_require RDoc::Require.new(name, comment)
@@ -1582,14 +1623,15 @@ class RDoc::Parser::Ruby < RDoc::Parser
1582
1623
  def parse_rescue
1583
1624
  skip_tkspace false
1584
1625
 
1626
+ nest = 0
1585
1627
  while tk = get_tk
1586
- case tk
1587
- when TkNL, TkSEMICOLON then
1628
+ case tk[:kind]
1629
+ when :on_nl, :on_semicolon, :on_comment then
1588
1630
  break
1589
- when TkCOMMA then
1631
+ when :on_comma then
1590
1632
  skip_tkspace false
1591
1633
 
1592
- get_tk if TkNL === peek_tk
1634
+ get_tk if :on_nl == peek_tk[:kind]
1593
1635
  end
1594
1636
 
1595
1637
  skip_tkspace false
@@ -1613,14 +1655,32 @@ class RDoc::Parser::Ruby < RDoc::Parser
1613
1655
  keep_comment = false
1614
1656
  try_parse_comment = false
1615
1657
 
1616
- non_comment_seen = true unless TkCOMMENT === tk
1658
+ non_comment_seen = true unless (:on_comment == tk[:kind] or :on_embdoc == tk[:kind])
1617
1659
 
1618
- case tk
1619
- when TkNL then
1620
- skip_tkspace
1621
- tk = get_tk
1660
+ case tk[:kind]
1661
+ when :on_nl, :on_ignored_nl, :on_comment, :on_embdoc then
1662
+ if :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]
1663
+ skip_tkspace
1664
+ tk = get_tk
1665
+ else
1666
+ past_tokens = @read.size > 1 ? @read[0..-2] : []
1667
+ nl_position = 0
1668
+ past_tokens.reverse.each_with_index do |read_tk, i|
1669
+ if read_tk =~ /^\n$/ then
1670
+ nl_position = (past_tokens.size - 1) - i
1671
+ break
1672
+ elsif read_tk =~ /^#.*\n$/ then
1673
+ nl_position = ((past_tokens.size - 1) - i) + 1
1674
+ break
1675
+ end
1676
+ end
1677
+ comment_only_line = past_tokens[nl_position..-1].all?{ |c| c =~ /^\s+$/ }
1678
+ unless comment_only_line then
1679
+ tk = get_tk
1680
+ end
1681
+ end
1622
1682
 
1623
- if TkCOMMENT === tk then
1683
+ if tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then
1624
1684
  if non_comment_seen then
1625
1685
  # Look for RDoc in a comment about to be thrown away
1626
1686
  non_comment_seen = parse_comment container, tk, comment unless
@@ -1630,15 +1690,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
1630
1690
  comment.force_encoding @encoding if @encoding
1631
1691
  end
1632
1692
 
1633
- while TkCOMMENT === tk do
1634
- comment << tk.text << "\n"
1635
-
1636
- tk = get_tk
1693
+ while tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) do
1694
+ comment << tk[:text]
1695
+ comment << "\n" unless "\n" == tk[:text].chars.to_a.last
1637
1696
 
1638
- if TkNL === tk then
1697
+ if tk[:text].size > 1 && "\n" == tk[:text].chars.to_a.last then
1639
1698
  skip_tkspace false # leading spaces
1640
- tk = get_tk
1641
1699
  end
1700
+ tk = get_tk
1642
1701
  end
1643
1702
 
1644
1703
  comment = new_comment comment
@@ -1661,59 +1720,76 @@ class RDoc::Parser::Ruby < RDoc::Parser
1661
1720
  keep_comment = true
1662
1721
  container.current_line_visibility = nil
1663
1722
 
1664
- when TkCLASS then
1665
- parse_class container, single, tk, comment
1723
+ when :on_kw then
1724
+ case tk[:text]
1725
+ when 'class' then
1726
+ parse_class container, single, tk, comment
1666
1727
 
1667
- when TkMODULE then
1668
- parse_module container, single, tk, comment
1728
+ when 'module' then
1729
+ parse_module container, single, tk, comment
1669
1730
 
1670
- when TkDEF then
1671
- parse_method container, single, tk, comment
1731
+ when 'def' then
1732
+ parse_method container, single, tk, comment
1672
1733
 
1673
- when TkCONSTANT then
1674
- unless parse_constant container, tk, comment, current_method then
1675
- try_parse_comment = true
1676
- end
1734
+ when 'alias' then
1735
+ parse_alias container, single, tk, comment unless current_method
1677
1736
 
1678
- when TkALIAS then
1679
- parse_alias container, single, tk, comment unless current_method
1737
+ when 'yield' then
1738
+ if current_method.nil? then
1739
+ warn "Warning: yield outside of method" if container.document_self
1740
+ else
1741
+ parse_yield container, single, tk, current_method
1742
+ end
1680
1743
 
1681
- when TkYIELD then
1682
- if current_method.nil? then
1683
- warn "Warning: yield outside of method" if container.document_self
1684
- else
1685
- parse_yield container, single, tk, current_method
1686
- end
1744
+ when 'until', 'while' then
1745
+ if (RDoc::RipperStateLex::EXPR_LABEL & tk[:state]) == 0
1746
+ nest += 1
1747
+ skip_optional_do_after_expression
1748
+ end
1687
1749
 
1688
- # Until and While can have a 'do', which shouldn't increase the nesting.
1689
- # We can't solve the general case, but we can handle most occurrences by
1690
- # ignoring a do at the end of a line.
1750
+ # Until and While can have a 'do', which shouldn't increase the nesting.
1751
+ # We can't solve the general case, but we can handle most occurrences by
1752
+ # ignoring a do at the end of a line.
1691
1753
 
1692
- when TkUNTIL, TkWHILE then
1693
- nest += 1
1694
- skip_optional_do_after_expression
1754
+ # 'for' is trickier
1755
+ when 'for' then
1756
+ nest += 1
1757
+ skip_for_variable
1758
+ skip_optional_do_after_expression
1695
1759
 
1696
- # 'for' is trickier
1697
- when TkFOR then
1698
- nest += 1
1699
- skip_for_variable
1700
- skip_optional_do_after_expression
1760
+ when 'case', 'do', 'if', 'unless', 'begin' then
1761
+ if (RDoc::RipperStateLex::EXPR_LABEL & tk[:state]) == 0
1762
+ nest += 1
1763
+ end
1701
1764
 
1702
- when TkCASE, TkDO, TkIF, TkUNLESS, TkBEGIN then
1703
- nest += 1
1765
+ when 'super' then
1766
+ current_method.calls_super = true if current_method
1704
1767
 
1705
- when TkSUPER then
1706
- current_method.calls_super = true if current_method
1768
+ when 'rescue' then
1769
+ parse_rescue
1707
1770
 
1708
- when TkRESCUE then
1709
- parse_rescue
1771
+ when 'end' then
1772
+ nest -= 1
1773
+ if nest == 0 then
1774
+ container.ongoing_visibility = save_visibility
1775
+
1776
+ parse_comment container, tk, comment unless comment.empty?
1777
+
1778
+ return
1779
+ end
1780
+ end
1781
+
1782
+ when :on_const then
1783
+ unless parse_constant container, tk, comment, current_method then
1784
+ try_parse_comment = true
1785
+ end
1710
1786
 
1711
- when TkIDENTIFIER then
1787
+ when :on_ident then
1712
1788
  if nest == 1 and current_method.nil? then
1713
1789
  keep_comment = parse_identifier container, single, tk, comment
1714
1790
  end
1715
1791
 
1716
- case tk.name
1792
+ case tk[:text]
1717
1793
  when "require" then
1718
1794
  parse_require container, comment
1719
1795
  when "include" then
@@ -1722,15 +1798,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
1722
1798
  parse_extend_or_include RDoc::Extend, container, comment
1723
1799
  end
1724
1800
 
1725
- when TkEND then
1726
- nest -= 1
1727
- if nest == 0 then
1728
- container.ongoing_visibility = save_visibility
1729
-
1730
- parse_comment container, tk, comment unless comment.empty?
1731
-
1732
- return
1733
- end
1734
1801
  else
1735
1802
  try_parse_comment = nest == 1
1736
1803
  end
@@ -1762,8 +1829,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
1762
1829
  def parse_symbol_arg(no = nil)
1763
1830
  skip_tkspace_comment
1764
1831
 
1765
- case tk = get_tk
1766
- when TkLPAREN
1832
+ tk = get_tk
1833
+ if tk[:kind] == :on_lparen
1767
1834
  parse_symbol_arg_paren no
1768
1835
  else
1769
1836
  parse_symbol_arg_space no, tk
@@ -1785,10 +1852,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
1785
1852
  end
1786
1853
 
1787
1854
  skip_tkspace_comment
1788
- case tk2 = get_tk
1789
- when TkRPAREN
1855
+ case (tk2 = get_tk)[:kind]
1856
+ when :on_rparen
1790
1857
  break
1791
- when TkCOMMA
1858
+ when :on_comma
1792
1859
  else
1793
1860
  warn("unexpected token: '#{tk2.inspect}'") if $DEBUG_RDOC
1794
1861
  break
@@ -1815,7 +1882,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1815
1882
  skip_tkspace false
1816
1883
 
1817
1884
  tk1 = get_tk
1818
- unless TkCOMMA === tk1 then
1885
+ if tk1.nil? || :on_comma != tk1[:kind] then
1819
1886
  unget_tk tk1
1820
1887
  break
1821
1888
  end
@@ -1834,12 +1901,12 @@ class RDoc::Parser::Ruby < RDoc::Parser
1834
1901
  # Returns symbol text from the next token
1835
1902
 
1836
1903
  def parse_symbol_in_arg
1837
- case tk = get_tk
1838
- when TkSYMBOL
1839
- tk.text.sub(/^:/, '')
1840
- when TkSTRING
1841
- eval @read[-1]
1842
- when TkDSTRING, TkIDENTIFIER then
1904
+ tk = get_tk
1905
+ if :on_symbol == tk[:kind] then
1906
+ tk[:text].sub(/^:/, '')
1907
+ elsif :on_tstring == tk[:kind] then
1908
+ tk[:text][1..-2]
1909
+ elsif :on_dstring == tk[:kind] or :on_ident == tk[:kind] then
1843
1910
  nil # ignore
1844
1911
  else
1845
1912
  warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG_RDOC
@@ -1873,21 +1940,37 @@ class RDoc::Parser::Ruby < RDoc::Parser
1873
1940
 
1874
1941
  skip_tkspace_comment false
1875
1942
 
1876
- case peek_tk
1877
- # Ryan Davis suggested the extension to ignore modifiers, because he
1878
- # often writes
1879
- #
1880
- # protected unless $TESTING
1881
- #
1882
- when TkNL, TkUNLESS_MOD, TkIF_MOD, TkSEMICOLON then
1943
+ ptk = peek_tk
1944
+ # Ryan Davis suggested the extension to ignore modifiers, because he
1945
+ # often writes
1946
+ #
1947
+ # protected unless $TESTING
1948
+ #
1949
+ if [:on_nl, :on_semicolon].include?(ptk[:kind]) || (:on_kw == ptk[:kind] && (['if', 'unless'].include?(ptk[:text]))) then
1883
1950
  container.ongoing_visibility = vis
1884
- when TkDEF
1951
+ elsif :on_kw == ptk[:kind] && 'def' == ptk[:text]
1885
1952
  container.current_line_visibility = vis
1886
1953
  else
1887
1954
  update_visibility container, vis_type, vis, singleton
1888
1955
  end
1889
1956
  end
1890
1957
 
1958
+ ##
1959
+ # Parses a Module#private_constant or Module#public_constant call from +tk+.
1960
+
1961
+ def parse_constant_visibility(container, single, tk)
1962
+ args = parse_symbol_arg
1963
+ case tk[:text]
1964
+ when 'private_constant'
1965
+ vis = :private
1966
+ when 'public_constant'
1967
+ vis = :public
1968
+ else
1969
+ raise RDoc::Error, 'Unreachable'
1970
+ end
1971
+ container.set_constant_visibility_for args, vis
1972
+ end
1973
+
1891
1974
  ##
1892
1975
  # Determines the block parameter for +context+
1893
1976
 
@@ -1895,7 +1978,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
1895
1978
  return if method.block_params
1896
1979
 
1897
1980
  get_tkread
1898
- @scanner.continue = false
1899
1981
  method.block_params = parse_method_or_yield_parameters
1900
1982
  end
1901
1983
 
@@ -1919,11 +2001,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
1919
2001
  while tk = get_tk do
1920
2002
  tokens << tk
1921
2003
 
1922
- case tk
1923
- when TkNL, TkDEF then
2004
+ if :on_nl == tk[:kind] or (:on_kw == tk[:kind] && 'def' == tk[:text]) then
1924
2005
  return
1925
- when TkCOMMENT then
1926
- return unless tk.text =~ /\s*:?([\w-]+):\s*(.*)/
2006
+ elsif :on_comment == tk[:kind] or :on_embdoc == tk[:kind] then
2007
+ return unless tk[:text] =~ /\s*:?([\w-]+):\s*(.*)/
1927
2008
 
1928
2009
  directive = $1.downcase
1929
2010
 
@@ -1933,7 +2014,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1933
2014
  end
1934
2015
  end
1935
2016
  ensure
1936
- unless tokens.length == 1 and TkCOMMENT === tokens.first then
2017
+ unless tokens.length == 1 and (:on_comment == tokens.first[:kind] or :on_embdoc == tokens.first[:kind]) then
1937
2018
  tokens.reverse_each do |token|
1938
2019
  unget_tk token
1939
2020
  end
@@ -1947,6 +2028,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
1947
2028
  # See also RDoc::Markup::PreProcess#handle_directive
1948
2029
 
1949
2030
  def read_documentation_modifiers context, allowed
2031
+ skip_tkspace(false)
1950
2032
  directive, value = read_directive allowed
1951
2033
 
1952
2034
  return unless directive
@@ -1995,27 +2077,25 @@ class RDoc::Parser::Ruby < RDoc::Parser
1995
2077
  rescue StandardError => e
1996
2078
  bytes = ''
1997
2079
 
1998
- 20.times do @scanner.ungetc end
1999
- count = 0
2000
- 60.times do |i|
2001
- count = i
2002
- byte = @scanner.getc
2003
- break unless byte
2004
- bytes << byte
2080
+ if @scanner_point >= @scanner.size
2081
+ now_line_no = @scanner[@scanner.size - 1][:line_no]
2082
+ else
2083
+ now_line_no = peek_tk[:line_no]
2005
2084
  end
2006
- count -= 20
2007
- count.times do @scanner.ungetc end
2008
2085
 
2009
2086
  $stderr.puts <<-EOF
2010
2087
 
2011
- #{self.class} failure around line #{@scanner.line_no} of
2088
+ #{self.class} failure around line #{now_line_no} of
2012
2089
  #{@file_name}
2013
2090
 
2014
2091
  EOF
2015
2092
 
2016
2093
  unless bytes.empty? then
2017
2094
  $stderr.puts
2018
- $stderr.puts bytes.inspect
2095
+ now_line_no = peek_tk[:line_no]
2096
+ start_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no }
2097
+ end_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no + 1 } - 1
2098
+ $stderr.puts @scanner[start_index..end_index].join
2019
2099
  end
2020
2100
 
2021
2101
  raise e
@@ -2034,31 +2114,36 @@ class RDoc::Parser::Ruby < RDoc::Parser
2034
2114
 
2035
2115
  b_nest = 0
2036
2116
  nest = 0
2037
- @scanner.continue = false
2038
2117
 
2039
2118
  loop do
2040
- case tk
2041
- when TkSEMICOLON, TkNL then
2119
+ break unless tk
2120
+ case tk[:kind]
2121
+ when :on_semicolon, :on_nl, :on_ignored_nl then
2042
2122
  break if b_nest.zero?
2043
- when TkLPAREN, TkfLPAREN then
2123
+ when :on_lparen then
2044
2124
  nest += 1
2045
- when TkRPAREN then
2125
+ when :on_rparen then
2046
2126
  nest -= 1
2047
- when TkBEGIN then
2048
- b_nest += 1
2049
- when TkEND then
2050
- b_nest -= 1
2051
- when TkDO
2052
- break if nest.zero?
2053
- when nil then
2054
- break
2127
+ when :on_kw then
2128
+ case tk[:text]
2129
+ when 'begin'
2130
+ b_nest += 1
2131
+ when 'end'
2132
+ b_nest -= 1
2133
+ when 'do'
2134
+ break if nest.zero?
2135
+ end
2136
+ when :on_comment, :on_embdoc then
2137
+ if b_nest.zero? and "\n" == tk[:text][-1] then
2138
+ break
2139
+ end
2055
2140
  end
2056
2141
  tk = get_tk
2057
2142
  end
2058
2143
 
2059
2144
  skip_tkspace false
2060
2145
 
2061
- get_tk if TkDO === peek_tk
2146
+ get_tk if peek_tk && :on_kw == peek_tk[:kind] && 'do' == peek_tk[:text]
2062
2147
  end
2063
2148
 
2064
2149
  ##
@@ -2069,7 +2154,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
2069
2154
  get_tk
2070
2155
  skip_tkspace false
2071
2156
  tk = get_tk
2072
- unget_tk(tk) unless TkIN === tk
2157
+ unget_tk(tk) unless :on_kw == tk[:kind] and 'in' == tk[:text]
2073
2158
  end
2074
2159
 
2075
2160
  ##
@@ -2087,7 +2172,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
2087
2172
  def skip_tkspace_comment(skip_nl = true)
2088
2173
  loop do
2089
2174
  skip_tkspace skip_nl
2090
- return unless TkCOMMENT === peek_tk
2175
+ next_tk = peek_tk
2176
+ return if next_tk.nil? || (:on_comment != next_tk[:kind] and :on_embdoc != next_tk[:kind])
2091
2177
  get_tk
2092
2178
  end
2093
2179
  end