[ruby/rdoc] ClassModule#superclass= accepts a ClassModule as an
argument (https://github.com/ruby/rdoc/pull/1222) It is necessary for ClassModule's instance variable @superclass to always be a String (or nil) so that the class can be saved with `#marshal_dump` and loaded with `#marshal_load`. However, there's no type checking being done, which allows a bug like the one reported in #1221 (which was introduced in #1217) that sets superclass to a ClassModule. That bug requires: - setting a superclass to a NormalClass - marshal_save - marshal_load (which raises an exception) With this change, passing a ClassModule to ClassModule#superclass= is explicitly allowed by saving the full name of the ClassModule in the @superclass instance variable. https://github.com/ruby/rdoc/commit/9ced6d534c
This commit is contained in:
parent
d588a1c880
commit
4cce246d86
@ -705,10 +705,23 @@ class RDoc::ClassModule < RDoc::Context
|
|||||||
|
|
||||||
##
|
##
|
||||||
# Set the superclass of this class to +superclass+
|
# Set the superclass of this class to +superclass+
|
||||||
|
#
|
||||||
|
# where +superclass+ is one of:
|
||||||
|
#
|
||||||
|
# - +nil+
|
||||||
|
# - a String containing the full name of the superclass
|
||||||
|
# - the RDoc::ClassModule representing the superclass
|
||||||
|
|
||||||
def superclass=(superclass)
|
def superclass=(superclass)
|
||||||
raise NoMethodError, "#{full_name} is a module" if module?
|
raise NoMethodError, "#{full_name} is a module" if module?
|
||||||
@superclass = superclass
|
case superclass
|
||||||
|
when RDoc::ClassModule
|
||||||
|
@superclass = superclass.full_name
|
||||||
|
when nil, String
|
||||||
|
@superclass = superclass
|
||||||
|
else
|
||||||
|
raise TypeError, "superclass must be a String or RDoc::ClassModule, not #{superclass.class}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -1279,6 +1279,26 @@ class TestRDocClassModule < XrefTestCase
|
|||||||
assert_equal @c3_h1, @c3_h2.superclass
|
assert_equal @c3_h1, @c3_h2.superclass
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_setting_superclass
|
||||||
|
@c1.superclass = nil
|
||||||
|
assert_nil(@c1.superclass)
|
||||||
|
assert_nil(@c1.instance_variable_get("@superclass")) # proxy to test marshalling
|
||||||
|
|
||||||
|
@c1.superclass = @c4_c4.full_name
|
||||||
|
assert_equal(@c1.superclass, @c4_c4)
|
||||||
|
assert_equal(@c4_c4.full_name, @c1.instance_variable_get("@superclass"))
|
||||||
|
|
||||||
|
@c1.superclass = @c4_c4
|
||||||
|
assert_equal(@c1.superclass, @c4_c4)
|
||||||
|
assert_equal(@c4_c4.full_name, @c1.instance_variable_get("@superclass"))
|
||||||
|
|
||||||
|
# we could support this if we find we need to in the future.
|
||||||
|
assert_raise(TypeError) { @c1.superclass = Object }
|
||||||
|
|
||||||
|
# but this doesn't make sense.
|
||||||
|
assert_raise(TypeError) { @c1.superclass = Object.new }
|
||||||
|
end
|
||||||
|
|
||||||
def test_super_classes
|
def test_super_classes
|
||||||
rdoc_c3_h1 = @xref_data.find_module_named('C3::H1')
|
rdoc_c3_h1 = @xref_data.find_module_named('C3::H1')
|
||||||
rdoc_object = @xref_data.find_module_named('Object')
|
rdoc_object = @xref_data.find_module_named('Object')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user