Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How is !group directive working? #1534

Open
thomthom opened this issue Feb 22, 2024 · 6 comments
Open

How is !group directive working? #1534

thomthom opened this issue Feb 22, 2024 · 6 comments

Comments

@thomthom
Copy link
Contributor

I'm having problem seeing the !group directive doing anything. When adding it I don't see constants or methods grouped in any way in the generated docs.

Steps to reproduce

# Hello module.
module Example

  # Hi there.
  # @return [Integer]
  def self.hello
  end

  HELLO_CONSTANT = "hi!"

  #!group ExampleGroup

  # Tellus.
  # @return [Integer]
  def self.world
  end

  WORLD_CONSTANT = "hi!"
  UNIVERSE_CONSTANT = "hi!"

  #!endgroup ExampleGroup

end

Actual Output

image

Expected Output

I thought it would visually group methods and constants in the generated docs.

Environment details:

  • OS: macOS, Windows
  • Ruby version (ruby -v): ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [arm64-darwin20]
  • YARD version (yard -v): yard 0.9.34

I have read the Contributing Guide.

@MSP-Greg
Copy link
Contributor

MSP-Greg commented Feb 22, 2024

@thomthom

Try (note the '@'):

# @!group ExampleGroup
# @!endgroup ExampleGroup  

I don't recall groups ever affecting constants, just methods and attributes. Also, they are only grouped in the 'summary' section.

@thomthom
Copy link
Contributor Author

thomthom commented Feb 22, 2024

Try (note the '@'):

Duh! Thanks for catching that! (Though, this was a bug in my repro code, not my real scenario.)

I don't recall groups ever affecting constants, just methods and attributes. Also, they are only grouped in the 'summary' section.

This jogged my memory; constants can be grouped in Ruby code, but not via C Ruby code: #1237

Which, might be my original problem. I see it working with my pure Ruby example. But I was trying to add this via C Ruby code:

// @!group Example

/**
 * Hello World
 * @return [nil]
 */
static VALUE _wrap_example(VALUE self) {
  return Qnil;
}

It might be the same problem I had with constants apply to methods...

@thomthom
Copy link
Contributor Author

Ok, so this is an issue with the C parser.

This doesn't work:

// @!group Foos

/**
  * @!group Foos
  * Hello foo bar
  */
VALUE foobar(VALUE self, VALUE x) {
  int value = x;
}

/**
  * Hello foo biz
  */
VALUE foobiz(VALUE self, VALUE x) {
  int value = x;
}

// @!endgroup

/**
  * Hello world
  */
VALUE hello(VALUE self, VALUE x) {
  int value = x;
}

void Init_Mask(void)
{
    rb_cExample  = rb_define_class("Example", rb_cObject);
    rb_define_method(rb_cExample, "foobar", foobar, 1);
    rb_define_method(rb_cExample, "foobiz", foobiz, 1); 
    rb_define_method(rb_cExample, "hello", hello, 1);
}

But this works:

/**
  * @!group Foos
  * Hello foo bar
  */
VALUE foobar(VALUE self, VALUE x) {
  int value = x;
}

/**
  * Hello foo biz
  */
VALUE foobiz(VALUE self, VALUE x) {
  int value = x;
}

/**
  * @!endgroup
  * Hello world
  */
VALUE hello(VALUE self, VALUE x) {
  int value = x;
}

void Init_Mask(void)
{
    rb_cExample  = rb_define_class("Example", rb_cObject);
    rb_define_method(rb_cExample, "foobar", foobar, 1);
    rb_define_method(rb_cExample, "foobiz", foobiz, 1); 
    rb_define_method(rb_cExample, "hello", hello, 1);
}

@lsegal
Copy link
Owner

lsegal commented Feb 23, 2024

Based on my best recollection, the C parser doesn't parse loose comments because we don't have context on what those comments are "attached" to-- in other words, we can't really differentiate if the comment is part of a function, above a member declaration in a C++ class, etc. We have some sense of "toplevel", but things get hairy once you start using scopes / namespaces in C++, and thus we tend to ignore those. The one exception to this rule, ironically, is RDoc style directives, since they're fundamentally context-free.

It's worth noting that the C parser is significantly more rudimentary than the Ruby parser(s) and is mostly designed to pattern match for comments that sit above function declarations or very specific method calls (rb_*). Your best bet is probably to stick with your second syntax.

@thomthom
Copy link
Contributor Author

Noted. I'll go back and see if I the same thing let me pick up groups for constants as well.

Based on my best recollection, the C parser doesn't parse loose comments because we don't have context on what those comments are "attached" to-- in other words, we can't really differentiate if the comment is part of a function, above a member declaration in a C++ class, etc.

How does the Ruby parser handle this? Is it a difference in how the parsers keep state? I think I recalled when I looked at the issue with constant and groups that the state in the C parser ended up in the "wrong" place.

@MSP-Greg
Copy link
Contributor

@thomthom

I just did a quick check of things, and only used groups in the rb_* section of methods. The following patch seemed to correct things.

diff --git a/lib/yard/handlers/c/handler_methods.rb b/lib/yard/handlers/c/handler_methods.rb
index 9f1769b..bd3aee2 100644
--- a/lib/yard/handlers/c/handler_methods.rb
+++ b/lib/yard/handlers/c/handler_methods.rb
@@ -67,6 +67,11 @@ module YARD
           register MethodObject.new(namespace, name, scope) do |obj|
             register_visibility(obj, visibility)
             find_method_body(obj, func_name)
+
+            if statement&.comments&.source&.start_with? '@!endgroup'
+              extra_state.group = nil
+            end
+
             obj.explicit = true
             add_predicate_return_tag(obj) if name =~ /\?$/
           end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants