Skip to content

Commit 941b441

Browse files
committed
Merge branch 'master' into fix-escape-in-string
2 parents f17a85f + daf4867 commit 941b441

File tree

4 files changed

+213
-37
lines changed

4 files changed

+213
-37
lines changed

lib/rdoc/ruby_lex.rb

Lines changed: 107 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,9 @@ def token
396396
"r" => "/",
397397
"w" => "]",
398398
"W" => "]",
399-
"s" => ":"
399+
"s" => ":",
400+
"i" => "]",
401+
"I" => "]"
400402
}
401403

402404
PERCENT_PAREN = {
@@ -479,25 +481,44 @@ def lex_init()
479481
Token(TkNL)
480482
end
481483

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+
482495
@OP.def_rules("*", "**",
483-
"=", "==", "===",
496+
"==", "===",
484497
"=~", "<=>",
485498
"<", "<=",
486499
">", ">=", ">>", "=>") do
487500
|op, io|
488501
case @lex_state
489502
when :EXPR_FNAME, :EXPR_DOT
503+
tk = Token(TkId, op)
490504
@lex_state = :EXPR_ARG
491505
else
506+
tk = Token(op)
492507
@lex_state = :EXPR_BEG
493508
end
494-
Token(op)
509+
tk
495510
end
496511

497512
@OP.def_rules("!", "!=", "!~") do
498513
|op, io|
499-
@lex_state = :EXPR_BEG
500-
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
501522
end
502523

503524
@OP.def_rules("<<") do
@@ -511,11 +532,12 @@ def lex_init()
511532
end
512533
end
513534
unless tk
514-
tk = Token(op)
515535
case @lex_state
516536
when :EXPR_FNAME, :EXPR_DOT
537+
tk = Token(TkId, op)
517538
@lex_state = :EXPR_ARG
518539
else
540+
tk = Token(op)
519541
@lex_state = :EXPR_BEG
520542
end
521543
end
@@ -529,9 +551,9 @@ def lex_init()
529551

530552
@OP.def_rules("`") do
531553
|op, io|
532-
if @lex_state == :EXPR_FNAME
533-
@lex_state = :EXPR_END
534-
Token(op)
554+
if :EXPR_FNAME == @lex_state or :EXPR_DOT == @lex_state
555+
@lex_state = :EXPR_ARG
556+
Token(TkId, op)
535557
else
536558
identify_string(op)
537559
end
@@ -555,12 +577,25 @@ def lex_init()
555577
end
556578
end
557579

558-
@OP.def_rules("&", "&&", "|", "||") do
580+
@OP.def_rules("&&", "||") do
559581
|op, io|
560582
@lex_state = :EXPR_BEG
561583
Token(op)
562584
end
563585

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+
564599
@OP.def_rules("+=", "-=", "*=", "**=",
565600
"&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
566601
|op, io|
@@ -572,19 +607,22 @@ def lex_init()
572607
@OP.def_rule("+@", proc{|op, io| @lex_state == :EXPR_FNAME}) do
573608
|op, io|
574609
@lex_state = :EXPR_ARG
575-
Token(op)
610+
Token(TkId, op)
576611
end
577612

578613
@OP.def_rule("-@", proc{|op, io| @lex_state == :EXPR_FNAME}) do
579614
|op, io|
580615
@lex_state = :EXPR_ARG
581-
Token(op)
616+
Token(TkId, op)
582617
end
583618

584619
@OP.def_rules("+", "-") do
585620
|op, io|
586621
catch(:RET) do
587-
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
588626
if @space_seen and peek(0) =~ /[0-9]/
589627
throw :RET, identify_number(op)
590628
else
@@ -595,7 +633,8 @@ def lex_init()
595633
else
596634
@lex_state = :EXPR_BEG
597635
end
598-
Token(op)
636+
tk = Token(op) unless tk
637+
tk
599638
end
600639
end
601640

@@ -655,7 +694,10 @@ def lex_int2
655694

656695
@OP.def_rule("/") do
657696
|op, io|
658-
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
659701
identify_string(op)
660702
elsif peek(0) == '='
661703
getc
@@ -671,8 +713,15 @@ def lex_int2
671713

672714
@OP.def_rules("^") do
673715
|op, io|
674-
@lex_state = :EXPR_BEG
675-
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
676725
end
677726

678727
# @OP.def_rules("^=") do
@@ -699,8 +748,14 @@ def lex_int2
699748

700749
@OP.def_rule("~") do
701750
|op, io|
702-
@lex_state = :EXPR_BEG
703-
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
704759
end
705760

706761
@OP.def_rule("~@", proc{|op, io| @lex_state == :EXPR_FNAME}) do
@@ -726,17 +781,18 @@ def lex_int2
726781
@OP.def_rule("[]", proc{|op, io| @lex_state == :EXPR_FNAME}) do
727782
|op, io|
728783
@lex_state = :EXPR_ARG
729-
Token("[]")
784+
Token(TkId, op)
730785
end
731786

732787
@OP.def_rule("[]=", proc{|op, io| @lex_state == :EXPR_FNAME}) do
733788
|op, io|
734789
@lex_state = :EXPR_ARG
735-
Token("[]=")
790+
Token(TkId, op)
736791
end
737792

738793
@OP.def_rule("[") do
739794
|op, io|
795+
text = nil
740796
@indent += 1
741797
if @lex_state == :EXPR_FNAME
742798
tk_c = TkfLBRACK
@@ -745,13 +801,25 @@ def lex_int2
745801
tk_c = TkLBRACK
746802
elsif @lex_state == :EXPR_ARG && @space_seen
747803
tk_c = TkLBRACK
804+
elsif @lex_state == :EXPR_DOT
805+
if peek(0) == "]"
806+
tk_c = TkIDENTIFIER
807+
getc
808+
if peek(0) == "="
809+
text = "[]="
810+
else
811+
text = "[]"
812+
end
813+
else
814+
tk_c = TkOp
815+
end
748816
else
749817
tk_c = TkfLBRACK
750818
end
751819
@lex_state = :EXPR_BEG
752820
end
753821
@indent_stack.push tk_c
754-
Token(tk_c)
822+
Token(tk_c, text)
755823
end
756824

757825
@OP.def_rule("{") do
@@ -781,7 +849,10 @@ def lex_int2
781849

782850
@OP.def_rule('%') do
783851
|op, io|
784-
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
785856
identify_quotation
786857
elsif peek(0) == '='
787858
getc
@@ -948,7 +1019,12 @@ def identify_identifier
9481019
@indent_stack.push token_c
9491020
end
9501021
else
951-
token_c = TkIDENTIFIER
1022+
if peek(0) == ':' and !peek_match?(/^::/)
1023+
token.concat getc
1024+
token_c = TkSYMBOL
1025+
else
1026+
token_c = TkIDENTIFIER
1027+
end
9521028
end
9531029

9541030
elsif DEINDENT_CLAUSE.include?(token)
@@ -981,7 +1057,12 @@ def identify_identifier
9811057
elsif token[token.size - 1, 1] =~ /[!?]/
9821058
return Token(TkFID, token)
9831059
else
984-
return Token(TkIDENTIFIER, token)
1060+
if peek(0) == ':' and !peek_match?(/^::/)
1061+
token.concat getc
1062+
return Token(TkSYMBOL, token)
1063+
else
1064+
return Token(TkIDENTIFIER, token)
1065+
end
9851066
end
9861067
end
9871068

@@ -1225,8 +1306,8 @@ def identify_string(ltype, quoted = ltype, type = nil)
12251306
break
12261307
elsif @ltype != "'" && @ltype != "]" && @ltype != ":" and ch == "#"
12271308
ch = getc
1228-
subtype = true
12291309
if ch == "{" then
1310+
subtype = true
12301311
str << ch << skip_inner_expression
12311312
next
12321313
else

test/test_rdoc_markup_to_html.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,36 @@ def test_accept_verbatim_ruby
545545
assert_equal expected, @to.res.join
546546
end
547547

548+
def test_accept_verbatim_redefinable_operators
549+
functions = %w[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ` ! != !~].map { |redefinable_op|
550+
["def #{redefinable_op}\n", "end\n"]
551+
}.flatten
552+
553+
verb = @RM::Verbatim.new(*functions)
554+
555+
@to.start_accepting
556+
@to.accept_verbatim verb
557+
558+
expected = <<-EXPECTED
559+
560+
<pre class="ruby">
561+
EXPECTED
562+
expected = expected.rstrip
563+
564+
%w[| ^ &amp; &lt;=&gt; == === =~ &gt; &gt;= &lt; &lt;= &lt;&lt; &gt;&gt; + - * / % ** ~ +@ -@ [] []= ` ! != !~].each do |html_escaped_op|
565+
expected += <<-EXPECTED
566+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">#{html_escaped_op}</span>
567+
<span class="ruby-keyword">end</span>
568+
EXPECTED
569+
end
570+
571+
expected += <<-EXPECTED
572+
</pre>
573+
EXPECTED
574+
575+
assert_equal expected, @to.res.join
576+
end
577+
548578
def test_convert_string
549579
assert_equal '&lt;&gt;', @to.convert_string('<>')
550580
end

test/test_rdoc_parser_ruby.rb

Lines changed: 24 additions & 3 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
@@ -2063,7 +2082,7 @@ def test_parse_statements_class_nested
20632082
end
20642083

20652084
def test_parse_statements_def_percent_string_pound
2066-
util_parser "class C\ndef a\n%r{#}\nend\ndef b() end\nend"
2085+
util_parser "class C\ndef a\n%r{#}\n%r{\#{}}\nend\ndef b() end\nend"
20672086

20682087
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL
20692088

@@ -2080,9 +2099,11 @@ def test_parse_statements_def_percent_string_pound
20802099
tk(:SPACE, 11, 2, 3, nil, ' '),
20812100
tk(:IDENTIFIER, 12, 2, 4, 'a', 'a'),
20822101
tk(:NL, 13, 2, 5, nil, "\n"),
2083-
tk(:DREGEXP, 14, 3, 0, nil, '%r{#}'),
2102+
tk(:REGEXP, 14, 3, 0, nil, '%r{#}'),
20842103
tk(:NL, 19, 3, 5, nil, "\n"),
2085-
tk(:END, 20, 4, 0, 'end', 'end'),
2104+
tk(:DREGEXP, 20, 4, 0, nil, '%r{#{}}'),
2105+
tk(:NL, 27, 4, 7, nil, "\n"),
2106+
tk(:END, 28, 5, 0, 'end', 'end'),
20862107
]
20872108

20882109
assert_equal expected, a.token_stream

0 commit comments

Comments
 (0)