Skip to content

Commit

Permalink
[ruby/rdoc] Support all struct definition functions
Browse files Browse the repository at this point in the history
Currently only `rb_struct_define_without_accessor` is supported by
ruby/rdoc#73.  We should support other
three functions too.

ruby/rdoc@d42288f06c
  • Loading branch information
nobu authored and matzbot committed Feb 9, 2022
1 parent 7604933 commit dec96dd
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 71 deletions.
132 changes: 61 additions & 71 deletions lib/rdoc/parser/c.rb
Expand Up @@ -295,93 +295,83 @@ def do_classes_and_modules

@content.scan(
%r(
(?<open>\s*\(\s*) {0}
(?<close>\s*\)\s*) {0}
(?<name>\s*"(?<class_name>\w+)") {0}
(?<parent>\s*(?:
(?<parent_name>[\w\*\s\(\)\.\->]+) |
rb_path2class\s*\(\s*"(?<path>[\w:]+)"\s*\)
)) {0}
(?<under>\w+) {0}
(?<var_name>[\w\.]+)\s* =
\s*rb_(?:
define_(?:
class(?: # rb_define_class(class_name_1, parent_name_1)
\s*\(
\s*"(?<class_name_1>\w+)",
\s*(?<parent_name_1>\w+)\s*
\)
|
_under\s*\( # rb_define_class_under(class_under, class_name2, parent_name2...)
\s* (?<class_under>\w+),
\s* "(?<class_name_2>\w+)",
\s*
(?:
(?<parent_name_2>[\w\*\s\(\)\.\->]+) |
rb_path2class\("(?<path>[\w:]+)"\)
)
class(?: # rb_define_class(name, parent_name)
\(\s*
\g<name>,
\g<parent>
\s*\)
|
_under\g<open> # rb_define_class_under(under, name, parent_name...)
\g<under>,
\g<name>,
\g<parent>
\g<close>
)
|
module(?: # rb_define_module(module_name_1)
\s*\(
\s*"(?<module_name_1>\w+)"\s*
\)
(?<module>)
module(?: # rb_define_module(name)
\g<open>
\g<name>
\g<close>
|
_under\s*\( # rb_define_module_under(module_under, module_name_2)
\s*(?<module_under>\w+),
\s*"(?<module_name_2>\w+)"
\s*\)
_under\g<open> # rb_define_module_under(under, name)
\g<under>,
\g<name>
\g<close>
)
)
|
struct_define_without_accessor\s*\( # rb_struct_define_without_accessor(class_name_3, parent_name_3, ...)
\s*"(?<class_name_3>\w+)",
\s*(?<parent_name_3>\w+),
\s*\w+, # Allocation function
(?:\s*"\w+",)* # Attributes
\s*NULL
\)
(?<attributes>(?:\s*"\w+",)*\s*NULL\s*) {0}
struct_define(?:
\g<open> # rb_struct_define(name, ...)
\g<name>,
|
_under\g<open> # rb_struct_define_under(under, name, ...)
\g<under>,
\g<name>,
|
_without_accessor(?:
\g<open> # rb_struct_define_without_accessor(name, parent_name, ...)
|
_under\g<open> # rb_struct_define_without_accessor_under(under, name, parent_name, ...)
\g<under>,
)
\g<name>,
\g<parent>,
\s*\w+, # Allocation function
)
\g<attributes>
\g<close>
|
singleton_class\s*\( # rb_singleton_class(target_class_name)
\s*(?<target_class_name>\w+)
\)
singleton_class\g<open> # rb_singleton_class(target_class_name)
(?<target_class_name>\w+)
\g<close>
)
)mx
) do
class_name = $~[:class_name_1]
type = :class
if class_name
# rb_define_class(class_name_1, parent_name_1)
parent_name = $~[:parent_name_1]
#under = nil
else
class_name = $~[:class_name_2]
if class_name
# rb_define_class_under(class_under, class_name2, parent_name2...)
parent_name = $~[:parent_name_2] || $~[:path]
under = $~[:class_under]
else
class_name = $~[:class_name_3]
if class_name
# rb_struct_define_without_accessor(class_name_3, parent_name_3, ...)
parent_name = $~[:parent_name_3]
#under = nil
else
type = :module
class_name = $~[:module_name_1]
#parent_name = nil
if class_name
# rb_define_module(module_name_1)
#under = nil
else
class_name = $~[:module_name_2]
if class_name
# rb_define_module_under(module_under, module_name_1)
under = $~[:module_under]
else
# rb_singleton_class(target_class_name)
target_class_name = $~[:target_class_name]
handle_singleton $~[:var_name], target_class_name
next
end
end
end
end
if target_class_name = $~[:target_class_name]
# rb_singleton_class(target_class_name)
handle_singleton $~[:var_name], target_class_name
next
end

type = $~[:module] ? :module : :class
class_name = $~[:class_name]
parent_name = $~[:parent_name] || $~[:path]
under = $~[:under]

handle_class_module($~[:var_name], type, class_name, parent_name, under)
end
end
Expand Down
44 changes: 44 additions & 0 deletions test/rdoc/test_rdoc_parser_c.rb
Expand Up @@ -355,6 +355,35 @@ def test_do_classes_struct
/* Document-class: Foo
* this is the Foo class
*/
VALUE cFoo = rb_struct_define(
"Foo",
"some", "various", "fields", NULL);
EOF

klass = util_get_class content, 'cFoo'
assert_equal "this is the Foo class", klass.comment.text
end

def test_do_classes_struct_under
content = <<-EOF
/* Document-class: Kernel::Foo
* this is the Foo class under Kernel
*/
VALUE cFoo = rb_struct_define_under(
rb_mKernel, "Foo",
"some", "various", "fields", NULL);
EOF

klass = util_get_class content, 'cFoo'
assert_equal 'Kernel::Foo', klass.full_name
assert_equal "this is the Foo class under Kernel", klass.comment.text
end

def test_do_classes_struct_without_accessor
content = <<-EOF
/* Document-class: Foo
* this is the Foo class
*/
VALUE cFoo = rb_struct_define_without_accessor(
"Foo", rb_cObject, foo_alloc,
"some", "various", "fields", NULL);
Expand All @@ -364,6 +393,21 @@ def test_do_classes_struct
assert_equal "this is the Foo class", klass.comment.text
end

def test_do_classes_struct_without_accessor_under
content = <<-EOF
/* Document-class: Kernel::Foo
* this is the Foo class under Kernel
*/
VALUE cFoo = rb_struct_define_without_accessor_under(
rb_mKernel, "Foo", rb_cObject, foo_alloc,
"some", "various", "fields", NULL);
EOF

klass = util_get_class content, 'cFoo'
assert_equal 'Kernel::Foo', klass.full_name
assert_equal "this is the Foo class under Kernel", klass.comment.text
end

def test_do_classes_class_under
content = <<-EOF
/* Document-class: Kernel::Foo
Expand Down

0 comments on commit dec96dd

Please sign in to comment.