Skip to content

Commit 2c33648

Browse files
committed
Fix rb_define_method(singleton_class_of_module, ...) not to change nested module name
Always track class and singleton class stored to a variable to `@classes`. Otherwise, `find_class var_name, class_name` called from `handle_method` will add a new class to `@toplevel`.
1 parent b0e21ef commit 2c33648

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

lib/rdoc/parser/c.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,10 +1052,13 @@ def handle_method(type, var_name, meth_name, function, param_count,
10521052
# Registers a singleton class +sclass_var+ as a singleton of +class_var+
10531053

10541054
def handle_singleton(sclass_var, class_var)
1055-
class_name = @known_classes[class_var]
1056-
1057-
@known_classes[sclass_var] = class_name
1058-
@singleton_classes[sclass_var] = class_name
1055+
if (klass = @classes[class_var])
1056+
@classes[sclass_var] = klass
1057+
end
1058+
if (class_name = @known_classes[class_var])
1059+
@known_classes[sclass_var] = class_name
1060+
@singleton_classes[sclass_var] = class_name
1061+
end
10591062
end
10601063

10611064
##

test/rdoc/parser/c_test.rb

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,41 @@ def test_do_methods_singleton_class
781781
assert methods.first.singleton
782782
end
783783

784+
785+
def test_do_methods_nested_module_singleton_class
786+
parser = util_parser <<~EOF
787+
VALUE baz(VALUE klass, VALUE year) {
788+
}
789+
void Init_Foo(void) {
790+
VALUE mFoo = rb_define_module("Foo");
791+
VALUE mBar = rb_define_module_under(mFoo, "Bar");
792+
VALUE mBarS = rb_singleton_class(mBar);
793+
rb_define_method(mBarS, "baz", baz, 0);
794+
}
795+
EOF
796+
parser.scan
797+
798+
klass = parser.classes['mBarS']
799+
assert_equal 'Foo::Bar', klass.full_name
800+
assert_equal 'Foo::Bar', parser.singleton_classes['mBarS']
801+
methods = klass.method_list
802+
assert_equal 1, methods.length
803+
assert_equal 'baz', methods.first.name
804+
assert methods.first.singleton
805+
end
806+
807+
def test_do_methods_undocumentable
808+
parser = util_parser <<~EOF
809+
void Func(VALUE v) {
810+
VALUE k = rb_singleton_class(v);
811+
rb_define_method(k, "baz", baz, 0);
812+
}
813+
EOF
814+
parser.scan
815+
assert_empty parser.classes
816+
assert_empty parser.singleton_classes
817+
end
818+
784819
def test_do_missing
785820
parser = util_parser
786821

@@ -1973,7 +2008,8 @@ def test_scan
19732008
expected = {
19742009
@fn => {
19752010
'mM' => 'M',
1976-
'cC' => 'C', }}
2011+
'cC' => 'C',
2012+
'sC' => 'C' }}
19772013
assert_equal expected, @store.c_class_variables
19782014

19792015
expected = {

0 commit comments

Comments
 (0)