Skip to content

Commit a8b46ec

Browse files
authored
Fix Ruby parser to not create a class whose superclass references itself (#1784)
Fixes #1781 `Context#add_class` will create a class with nil superclass in some case: BasicObject, superclass referencing itself. Ruby parser should support handling class with nil superclass, and also superclass overwrite mechanism should also follow this rule.
1 parent 5bd8719 commit a8b46ec

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

‎lib/rdoc/parser/ruby.rb‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -906,10 +906,12 @@ def add_module_or_class(module_name, start_line, end_line, is_class: false, supe
906906
mod = owner.add_class(RDoc::NormalClass, name, superclass_name || superclass_expr || '::Object')
907907
mod.ignore if document_suppressed? && mod.in_files.empty?
908908
end
909-
if superclass_name
909+
910+
# Superclass with the same full path and superclass for BasicObject are not allowed
911+
if superclass_name && mod.full_name != superclass_full_path && mod.full_name != 'BasicObject'
910912
if superclass
911913
mod.superclass = superclass
912-
elsif (mod.superclass.is_a?(String) || mod.superclass.name == 'Object') && mod.superclass != superclass_full_path
914+
elsif mod.superclass.nil? || (mod.superclass.is_a?(String) || mod.superclass.name == 'Object') && mod.superclass != superclass_full_path
913915
mod.superclass = superclass_full_path
914916
end
915917
end

‎test/rdoc/parser/ruby_test.rb‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,6 +3023,29 @@ def bar(x); end
30233023
assert_match %r{:\d+: invalid RBS type signature: "\(String ->"}, err
30243024
end
30253025

3026+
def test_nil_superclass_case
3027+
# Context#add_class will create a class with nil superclass when
3028+
# the class is a BasicObject, or a superclass has the same full_name as the class itself.
3029+
# Superclass overwrite should follow this rule.
3030+
util_parser <<~RUBY
3031+
class BasicObject < Super; end
3032+
class BasicObject < Super; end
3033+
class Foo < Foo; end
3034+
class Bar < Bar; end
3035+
class Bar < Super; end
3036+
module M
3037+
class Baz < Super; end
3038+
class Baz < Baz; end
3039+
class Baz < M::Baz; end
3040+
end
3041+
RUBY
3042+
3043+
assert_nil @store.find_class_named('BasicObject').superclass
3044+
assert_nil @store.find_class_named('Foo').superclass
3045+
assert_equal 'Super', @store.find_class_named('Bar').superclass
3046+
assert_equal 'Super', @store.find_class_named('M::Baz').superclass
3047+
end
3048+
30263049
def util_parser(content)
30273050
@parser = RDoc::Parser::Ruby.new @top_level, content, @options, @stats
30283051
@parser.scan

0 commit comments

Comments
 (0)