@!endgroup requires two blank lines between it and `class << self`
This is probably a bit obscure, but I’m running into a situation where @!endgroup has to be followed by two blank lines (rather than one or none) in order to take effect. Specifically, it’s when the directive is followed by a class << self block (but not sure if other method calls with blocks, internal classes, or other things might also cause this).
For example, I have some code like the following:
module A
class B
# @!group Foo
def foo; end
def self.bar; end
# @!endgroup
class << self
def class_method; end
end
def instance_method; end
end
end
In this setup, class_method and instance_method wind up in the Foo group, when they should not. If I add a second blank line after # @!endgroup, they are correctly removed from the group.
Steps to reproduce
For an exact reproduction, run the following Ruby:
require 'yard'
YARD::Registry.clear
parsed = YARD.parse_string <<-'eof'
module A
class B
# @!group Foo
def foo; end
def self.bar; end
# @!endgroup
class << self
def class_method; end
end
def instance_method; end
end
end
eof
YARD::Registry.at('A::B').meths.each {|m| puts "#{m}: group '#{m.group}'"}
…which outputs:
A::B#foo: group 'Foo'
A::B.bar: group 'Foo'
A::B.class_method: group 'Foo'
A::B#instance_method: group 'Foo'
Expected Output
Instead, I’m pretty sure I should have seen:
A::B#foo: group 'Foo'
A::B.bar: group 'Foo'
A::B.class_method: group ''
A::B#instance_method: group ''
Environment details:
- OS: MacOS 10.14.6
- Ruby version (
ruby -v): ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-darwin18] - YARD version (
yard -v): yard 0.9.25 - Relevant software dependency/versions: None
I have read the Contributing Guide.
Looks like this is probably happening because:
-
The source parser attaches the
# @!endgroupcomment to theclass << selfAST node if it’s less than two lines above (which seems OK, the same thing happens if the next thing is a method instead ofclass << self): https://github.com/lsegal/yard/blob/2b16190ced212bdb948fb47568645b29590bdbcd/lib/yard/parser/ruby/ruby_parser.rb#L623-L630 -
The handler for
sclassnodes parses inside the block, but never registers/parses the docstring: https://github.com/lsegal/yard/blob/2b16190ced212bdb948fb47568645b29590bdbcd/lib/yard/handlers/ruby/class_handler.rb#L32-L35
I’m not really familiar with Yard’s internals at all, but it doesn’t seem like creating a ClassObject and calling register with it makes sense there. Two approaches jump out to me given my limited knowledge:
- Maybe the
sclasshandler should be callingregister_docstring(nil)like the comment handler does? - Maybe the parser should special case this situation and not attach the comment to the
sclassAST node in the first place?
Anyway, I’m happy to work on a PR for this if someone here has a preference for one of the two solutions above.