Skip to content

Commit 58e0fd8

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 58e0fd8

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-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: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,40 @@ def test_do_methods_singleton_class
781781
assert methods.first.singleton
782782
end
783783

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

@@ -1973,7 +2007,8 @@ def test_scan
19732007
expected = {
19742008
@fn => {
19752009
'mM' => 'M',
1976-
'cC' => 'C', }}
2010+
'cC' => 'C',
2011+
'sC' => 'C' }}
19772012
assert_equal expected, @store.c_class_variables
19782013

19792014
expected = {

0 commit comments

Comments
 (0)