diff --git a/lib/rdoc/parser/ruby.rb b/lib/rdoc/parser/ruby.rb index 909b02d2af..76d6061e5f 100644 --- a/lib/rdoc/parser/ruby.rb +++ b/lib/rdoc/parser/ruby.rb @@ -1804,65 +1804,58 @@ def parse_statements(container, single = NORMAL, current_method = nil, non_comment_seen = true unless (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) case tk[:kind] - when :on_nl, :on_ignored_nl, :on_comment, :on_embdoc then - if :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind] - skip_tkspace - tk = get_tk - else - past_tokens = @read.size > 1 ? @read[0..-2] : [] - nl_position = 0 - past_tokens.reverse.each_with_index do |read_tk, i| - if read_tk =~ /^\n$/ then - nl_position = (past_tokens.size - 1) - i - break - elsif read_tk =~ /^#.*\n$/ then - nl_position = ((past_tokens.size - 1) - i) + 1 - break - end - end - comment_only_line = past_tokens[nl_position..-1].all?{ |c| c =~ /^\s+$/ } - unless comment_only_line then - tk = get_tk + when :on_nl, :on_ignored_nl then + skip_tkspace + non_comment_seen = parse_comment container, tk, comment unless + comment.empty? + + keep_comment = true + container.current_line_visibility = nil + + when :on_comment, :on_embdoc then + past_tokens = @read.size > 1 ? @read[0..-2] : [] + nl_position = 0 + past_tokens.reverse.each_with_index do |read_tk, i| + if read_tk =~ /^\n$/ then + nl_position = (past_tokens.size - 1) - i + break + elsif read_tk =~ /^#.*\n$/ then + nl_position = ((past_tokens.size - 1) - i) + 1 + break end end + comment_only_line = past_tokens[nl_position..-1].all?{ |c| c =~ /^\s+$/ } + unless comment_only_line then + tk = get_tk + end - if tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then - if non_comment_seen then - # Look for RDoc in a comment about to be thrown away - non_comment_seen = parse_comment container, tk, comment unless - comment.empty? + if non_comment_seen then + comment = '' + comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding + end - comment = '' - comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding - end + line_no = nil + while tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) do + comment_body = retrieve_comment_body(tk) + line_no = tk[:line_no] if comment.empty? + comment += comment_body + comment << "\n" unless comment_body =~ /\n\z/ - line_no = nil - while tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) do - comment_body = retrieve_comment_body(tk) - line_no = tk[:line_no] if comment.empty? - comment += comment_body - comment << "\n" unless comment_body =~ /\n\z/ - - if comment_body.size > 1 && comment_body =~ /\n\z/ then - skip_tkspace_without_nl # leading spaces - end - tk = get_tk + if comment_body.size > 1 && comment_body =~ /\n\z/ then + skip_tkspace_without_nl # leading spaces end + tk = get_tk + end - comment = new_comment comment, line_no + comment = new_comment comment, line_no - unless comment.empty? then - look_for_directives_in container, comment + unless comment.empty? then + look_for_directives_in container, comment - if container.done_documenting then - throw :eof if RDoc::TopLevel === container - container.ongoing_visibility = save_visibility - end + if container.done_documenting then + throw :eof if RDoc::TopLevel === container + container.ongoing_visibility = save_visibility end - - keep_comment = true - else - non_comment_seen = true end unget_tk tk diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb index cf02a035a6..169db3ead9 100644 --- a/test/rdoc/test_rdoc_parser_ruby.rb +++ b/test/rdoc/test_rdoc_parser_ruby.rb @@ -872,6 +872,80 @@ class Foo assert_equal 2, foo.method_list.length end + def test_parse_comments_followed_by_linebreaks + util_parser <<-CLASS +class Foo + # Ignored comment + + ## + # :method: ghost + # This is a ghost method + + # Comment followed by a method + def regular + end + + ## + # :method: another_ghost + # This is another ghost method + + # Comment followed by a linebreak + + def regular2 + end +end + CLASS + + tk = @parser.get_tk + + @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment + + foo = @top_level.classes.first + assert_equal 'Foo', foo.full_name + + ghost = foo.method_list.first + assert_equal 'Foo#ghost', ghost.full_name + assert_equal 'This is a ghost method', ghost.comment.to_s + + regular = foo.method_list[1] + assert_equal 'Foo#regular', regular.full_name + assert_equal 'Comment followed by a method', regular.comment.to_s + + another_ghost = foo.method_list[2] + assert_equal 'Foo#another_ghost', another_ghost.full_name + assert_equal 'This is another ghost method', another_ghost.comment.to_s + + regular2 = foo.method_list[3] + assert_equal 'Foo#regular2', regular2.full_name + assert_equal 'Comment followed by a linebreak', regular2.comment.to_s + end + + def test_parse_ghost_method_followed_by_undocumented_method + util_parser <<-'CLASS' +class Foo + ## + # :method: ghost + # This is a ghost method + + def baz() end +end + CLASS + + tk = @parser.get_tk + + @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment + + foo = @top_level.classes.first + assert_equal 'Foo', foo.full_name + + ghost = foo.method_list.first + assert_equal 'Foo#ghost', ghost.full_name + assert_equal 'This is a ghost method', ghost.comment.to_s + + baz = foo.method_list[1] + assert_equal 'Foo#baz', baz.full_name + end + def test_parse_class_nodoc comment = RDoc::Comment.new "##\n# my class\n", @top_level