Skip to content

RDoc::Parser::C: Integrate do_classes and do_modules by one regexp match #731

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

Merged
merged 1 commit into from
Aug 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 95 additions & 103 deletions lib/rdoc/parser/c.rb
Original file line number Diff line number Diff line change
Expand Up @@ -324,12 +324,100 @@ def do_boot_defclass
# Scans #content for rb_define_class, boot_defclass, rb_define_class_under
# and rb_singleton_class

def do_classes
do_boot_defclass
do_define_class
do_define_class_under
do_singleton_class
do_struct_define_without_accessor
def do_classes_and_modules
do_boot_defclass if @file_name == "class.c"

@content.scan(
%r(
(?<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:]+)"\)
)
\s*\)
)
|
module(?: # rb_define_module(module_name_1)
\s*\(
\s*"(?<module_name_1>\w+)"\s*
\)
|
_under\s*\( # rb_define_module_under(module_under, module_name_1)
\s*(?<module_under>\w+),
\s*"(?<module_name_2>\w+)"
\s*\)
)
)
|
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
\)
|
singleton_class\s*\( # rb_singleton_class(target_class_name)
\s*(?<target_class_name>\w+)
\)
)
)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
end

handle_class_module($~[:var_name], type, class_name, parent_name, under)
end
end

##
Expand Down Expand Up @@ -378,65 +466,6 @@ def do_constants
end
end

##
# Scans #content for rb_define_class

def do_define_class
# The '.' lets us handle SWIG-generated files
@content.scan(/([\w\.]+)\s* = \s*rb_define_class\s*
\(
\s*"(\w+)",
\s*(\w+)\s*
\)/mx) do |var_name, class_name, parent|
handle_class_module(var_name, :class, class_name, parent, nil)
end
end

##
# Scans #content for rb_define_class_under

def do_define_class_under
@content.scan(/([\w\.]+)\s* = # var_name
\s*rb_define_class_under\s*
\(
\s* (\w+), # under
\s* "(\w+)", # class_name
\s*
(?:
([\w\*\s\(\)\.\->]+) | # parent_name
rb_path2class\("([\w:]+)"\) # path
)
\s*
\)
/mx) do |var_name, under, class_name, parent_name, path|
parent = path || parent_name

handle_class_module var_name, :class, class_name, parent, under
end
end

##
# Scans #content for rb_define_module

def do_define_module
@content.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do
|var_name, class_name|
handle_class_module(var_name, :module, class_name, nil, nil)
end
end

##
# Scans #content for rb_define_module_under

def do_define_module_under
@content.scan(/(\w+)\s* = \s*rb_define_module_under\s*
\(
\s*(\w+),
\s*"(\w+)"
\s*\)/mx) do |var_name, in_module, class_name|
handle_class_module(var_name, :module, class_name, nil, in_module)
end
end

##
# Scans #content for rb_include_module
Expand Down Expand Up @@ -518,42 +547,6 @@ def do_missing
end
end

##
# Scans #content for rb_define_module and rb_define_module_under

def do_modules
do_define_module
do_define_module_under
end

##
# Scans #content for rb_singleton_class

def do_singleton_class
@content.scan(/([\w\.]+)\s* = \s*rb_singleton_class\s*
\(
\s*(\w+)
\s*\)/mx) do |sclass_var, class_var|
handle_singleton sclass_var, class_var
end
end

##
# Scans #content for struct_define_without_accessor

def do_struct_define_without_accessor
@content.scan(/([\w\.]+)\s* = \s*rb_struct_define_without_accessor\s*
\(
\s*"(\w+)", # Class name
\s*(\w+), # Parent class
\s*\w+, # Allocation function
(\s*"\w+",)* # Attributes
\s*NULL
\)/mx) do |var_name, class_name, parent|
handle_class_module(var_name, :class, class_name, parent, nil)
end
end

##
# Finds the comment for an alias on +class_name+ from +new_name+ to
# +old_name+
Expand Down Expand Up @@ -1247,8 +1240,7 @@ def remove_commented_out_lines
def scan
remove_commented_out_lines

do_modules
do_classes
do_classes_and_modules
do_missing

do_constants
Expand Down
34 changes: 3 additions & 31 deletions test/rdoc/test_rdoc_parser_c.rb
Original file line number Diff line number Diff line change
Expand Up @@ -304,32 +304,6 @@ def test_do_aliases_singleton
assert_equal 'This should show up as an alias', methods.last.comment.text
end

def test_do_classes_boot_class
content = <<-EOF
/* Document-class: Foo
* this is the Foo boot class
*/
VALUE cFoo = boot_defclass("Foo", rb_cObject);
EOF

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

def test_do_classes_boot_class_nil
content = <<-EOF
/* Document-class: Foo
* this is the Foo boot class
*/
VALUE cFoo = boot_defclass("Foo", 0);
EOF

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

def test_do_aliases_missing_class
content = <<-EOF
void Init_Blah(void) {
Expand Down Expand Up @@ -511,7 +485,7 @@ def test_do_constants

@parser = util_parser content

@parser.do_classes
@parser.do_classes_and_modules
@parser.do_constants

klass = @parser.classes['cFoo']
Expand Down Expand Up @@ -581,8 +555,7 @@ def test_do_constants_curses

@parser = util_parser content

@parser.do_modules
@parser.do_classes
@parser.do_classes_and_modules
@parser.do_constants

klass = @parser.classes['mCurses']
Expand All @@ -608,8 +581,7 @@ def test_do_constants_file

@parser = util_parser content

@parser.do_modules
@parser.do_classes
@parser.do_classes_and_modules
@parser.do_constants

klass = @parser.classes['rb_mFConst']
Expand Down