diff --git a/lib/yard/parser/ruby/ruby_parser.rb b/lib/yard/parser/ruby/ruby_parser.rb index 57831b5fe..1caf77b34 100644 --- a/lib/yard/parser/ruby/ruby_parser.rb +++ b/lib/yard/parser/ruby/ruby_parser.rb @@ -658,6 +658,23 @@ def insert_comments end end unless @comments.empty? + # Attach comments that fall within an otherwise empty + # class or module body. Without this step, a comment used + # solely for directives (like @!method) would be treated as + # a top-level comment and its directives would not be scoped + # to the namespace. + unless @comments.empty? + root.traverse do |node| + next unless [:class, :module, :sclass].include?(node.type) + body = node.children.last + next unless body && body.type == :list && body.empty? + @comments.keys.each do |line| + next unless node.line_range.include?(line) + add_comment(line, nil, body, true) + end + end + end + # insert all remaining comments @comments.each do |line, _comment| add_comment(line, nil, root, true) diff --git a/spec/tags/directives_spec.rb b/spec/tags/directives_spec.rb index 147a8e53d..ca310e828 100644 --- a/spec/tags/directives_spec.rb +++ b/spec/tags/directives_spec.rb @@ -263,6 +263,16 @@ class Foo expect(Registry.at('#foo').parameters).to eq [['a', nil], ['b', nil], ['c', 'nil']] end + it "processes @!method inside an empty class" do + YARD.parse_string <<-eof + class Foo + # @!method bar + # Docstring + end + eof + expect(Registry.at('Foo#bar').docstring).to eq 'Docstring' + end + it "is able to define method with module scope (module function)" do YARD.parse_string <<-eof # @!method foo