Skip to content

Commit daf4867

Browse files
authored
Merge pull request #470 from aycabta/handle-redefinable-operators
Handle redefinable operators as identifier
2 parents 2772846 + 59f8d55 commit daf4867

File tree

3 files changed

+126
-21
lines changed

3 files changed

+126
-21
lines changed

lib/rdoc/ruby_lex.rb

Lines changed: 77 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -481,25 +481,44 @@ def lex_init()
481481
Token(TkNL)
482482
end
483483

484+
@OP.def_rules("=") do
485+
|op, io|
486+
case @lex_state
487+
when :EXPR_FNAME, :EXPR_DOT
488+
@lex_state = :EXPR_ARG
489+
else
490+
@lex_state = :EXPR_BEG
491+
end
492+
Token(op)
493+
end
494+
484495
@OP.def_rules("*", "**",
485-
"=", "==", "===",
496+
"==", "===",
486497
"=~", "<=>",
487498
"<", "<=",
488499
">", ">=", ">>", "=>") do
489500
|op, io|
490501
case @lex_state
491502
when :EXPR_FNAME, :EXPR_DOT
503+
tk = Token(TkId, op)
492504
@lex_state = :EXPR_ARG
493505
else
506+
tk = Token(op)
494507
@lex_state = :EXPR_BEG
495508
end
496-
Token(op)
509+
tk
497510
end
498511

499512
@OP.def_rules("!", "!=", "!~") do
500513
|op, io|
501-
@lex_state = :EXPR_BEG
502-
Token(op)
514+
case @lex_state
515+
when :EXPR_FNAME, :EXPR_DOT
516+
@lex_state = :EXPR_ARG
517+
Token(TkId, op)
518+
else
519+
@lex_state = :EXPR_BEG
520+
Token(op)
521+
end
503522
end
504523

505524
@OP.def_rules("<<") do
@@ -513,11 +532,12 @@ def lex_init()
513532
end
514533
end
515534
unless tk
516-
tk = Token(op)
517535
case @lex_state
518536
when :EXPR_FNAME, :EXPR_DOT
537+
tk = Token(TkId, op)
519538
@lex_state = :EXPR_ARG
520539
else
540+
tk = Token(op)
521541
@lex_state = :EXPR_BEG
522542
end
523543
end
@@ -531,9 +551,9 @@ def lex_init()
531551

532552
@OP.def_rules("`") do
533553
|op, io|
534-
if @lex_state == :EXPR_FNAME
535-
@lex_state = :EXPR_END
536-
Token(op)
554+
if :EXPR_FNAME == @lex_state or :EXPR_DOT == @lex_state
555+
@lex_state = :EXPR_ARG
556+
Token(TkId, op)
537557
else
538558
identify_string(op)
539559
end
@@ -557,12 +577,25 @@ def lex_init()
557577
end
558578
end
559579

560-
@OP.def_rules("&", "&&", "|", "||") do
580+
@OP.def_rules("&&", "||") do
561581
|op, io|
562582
@lex_state = :EXPR_BEG
563583
Token(op)
564584
end
565585

586+
@OP.def_rules("&", "|") do
587+
|op, io|
588+
case @lex_state
589+
when :EXPR_FNAME, :EXPR_DOT
590+
tk = Token(TkId, op)
591+
@lex_state = :EXPR_ARG
592+
else
593+
tk = Token(op)
594+
@lex_state = :EXPR_BEG
595+
end
596+
tk
597+
end
598+
566599
@OP.def_rules("+=", "-=", "*=", "**=",
567600
"&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
568601
|op, io|
@@ -574,19 +607,22 @@ def lex_init()
574607
@OP.def_rule("+@", proc{|op, io| @lex_state == :EXPR_FNAME}) do
575608
|op, io|
576609
@lex_state = :EXPR_ARG
577-
Token(op)
610+
Token(TkId, op)
578611
end
579612

580613
@OP.def_rule("-@", proc{|op, io| @lex_state == :EXPR_FNAME}) do
581614
|op, io|
582615
@lex_state = :EXPR_ARG
583-
Token(op)
616+
Token(TkId, op)
584617
end
585618

586619
@OP.def_rules("+", "-") do
587620
|op, io|
588621
catch(:RET) do
589-
if @lex_state == :EXPR_ARG
622+
if :EXPR_FNAME == @lex_state or :EXPR_DOT == @lex_state
623+
tk = Token(TkId, op)
624+
@lex_state = :EXPR_ARG
625+
elsif @lex_state == :EXPR_ARG
590626
if @space_seen and peek(0) =~ /[0-9]/
591627
throw :RET, identify_number(op)
592628
else
@@ -597,7 +633,8 @@ def lex_init()
597633
else
598634
@lex_state = :EXPR_BEG
599635
end
600-
Token(op)
636+
tk = Token(op) unless tk
637+
tk
601638
end
602639
end
603640

@@ -657,7 +694,10 @@ def lex_int2
657694

658695
@OP.def_rule("/") do
659696
|op, io|
660-
if @lex_state == :EXPR_BEG || @lex_state == :EXPR_MID
697+
if :EXPR_FNAME == @lex_state or :EXPR_DOT == @lex_state
698+
@lex_state = :EXPR_ARG
699+
Token(TkId, op)
700+
elsif @lex_state == :EXPR_BEG || @lex_state == :EXPR_MID
661701
identify_string(op)
662702
elsif peek(0) == '='
663703
getc
@@ -673,8 +713,15 @@ def lex_int2
673713

674714
@OP.def_rules("^") do
675715
|op, io|
676-
@lex_state = :EXPR_BEG
677-
Token("^")
716+
case @lex_state
717+
when :EXPR_FNAME, :EXPR_DOT
718+
tk = Token(TkId, op)
719+
@lex_state = :EXPR_ARG
720+
else
721+
tk = Token(op)
722+
@lex_state = :EXPR_BEG
723+
end
724+
tk
678725
end
679726

680727
# @OP.def_rules("^=") do
@@ -701,8 +748,14 @@ def lex_int2
701748

702749
@OP.def_rule("~") do
703750
|op, io|
704-
@lex_state = :EXPR_BEG
705-
Token("~")
751+
case @lex_state
752+
when :EXPR_FNAME, :EXPR_DOT
753+
@lex_state = :EXPR_ARG
754+
Token(TkId, op)
755+
else
756+
@lex_state = :EXPR_BEG
757+
Token(op)
758+
end
706759
end
707760

708761
@OP.def_rule("~@", proc{|op, io| @lex_state == :EXPR_FNAME}) do
@@ -728,13 +781,13 @@ def lex_int2
728781
@OP.def_rule("[]", proc{|op, io| @lex_state == :EXPR_FNAME}) do
729782
|op, io|
730783
@lex_state = :EXPR_ARG
731-
Token("[]")
784+
Token(TkId, op)
732785
end
733786

734787
@OP.def_rule("[]=", proc{|op, io| @lex_state == :EXPR_FNAME}) do
735788
|op, io|
736789
@lex_state = :EXPR_ARG
737-
Token("[]=")
790+
Token(TkId, op)
738791
end
739792

740793
@OP.def_rule("[") do
@@ -796,7 +849,10 @@ def lex_int2
796849

797850
@OP.def_rule('%') do
798851
|op, io|
799-
if @lex_state == :EXPR_BEG || @lex_state == :EXPR_MID
852+
if :EXPR_FNAME == @lex_state or :EXPR_DOT == @lex_state
853+
@lex_state = :EXPR_ARG
854+
Token(TkId, op)
855+
elsif @lex_state == :EXPR_BEG || @lex_state == :EXPR_MID
800856
identify_quotation
801857
elsif peek(0) == '='
802858
getc

test/test_rdoc_markup_to_html.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,36 @@ def test_accept_verbatim_ruby
485485
assert_equal expected, @to.res.join
486486
end
487487

488+
def test_accept_verbatim_redefinable_operators
489+
functions = %w[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ` ! != !~].map { |redefinable_op|
490+
["def #{redefinable_op}\n", "end\n"]
491+
}.flatten
492+
493+
verb = @RM::Verbatim.new(*functions)
494+
495+
@to.start_accepting
496+
@to.accept_verbatim verb
497+
498+
expected = <<-EXPECTED
499+
500+
<pre class="ruby">
501+
EXPECTED
502+
expected = expected.rstrip
503+
504+
%w[| ^ &amp; &lt;=&gt; == === =~ &gt; &gt;= &lt; &lt;= &lt;&lt; &gt;&gt; + - * / % ** ~ +@ -@ [] []= ` ! != !~].each do |html_escaped_op|
505+
expected += <<-EXPECTED
506+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">#{html_escaped_op}</span>
507+
<span class="ruby-keyword">end</span>
508+
EXPECTED
509+
end
510+
511+
expected += <<-EXPECTED
512+
</pre>
513+
EXPECTED
514+
515+
assert_equal expected, @to.res.join
516+
end
517+
488518
def test_convert_string
489519
assert_equal '&lt;&gt;', @to.convert_string('<>')
490520
end

test/test_rdoc_parser_ruby.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,25 @@ def test_parse_method
16501650
assert_equal stream, foo.token_stream
16511651
end
16521652

1653+
def test_parse_redefinable_methods
1654+
klass = RDoc::NormalClass.new 'Foo'
1655+
klass.parent = @top_level
1656+
1657+
comment = RDoc::Comment.new "", @top_level
1658+
1659+
redefinable_ops = %w[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ` ! != !~]
1660+
redefinable_ops.each do |redefinable_op|
1661+
util_parser "def #{redefinable_op}\nend\n"
1662+
tk = @parser.get_tk
1663+
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
1664+
end
1665+
1666+
klass.method_list.each do |method|
1667+
assert_kind_of RDoc::RubyToken::TkId, method.token_stream[5]
1668+
assert_includes redefinable_ops, method.token_stream[5].text
1669+
end
1670+
end
1671+
16531672
def test_parse_method_bracket
16541673
util_parser <<-RUBY
16551674
class C

0 commit comments

Comments
 (0)