Skip to content

Commit 57a4615

Browse files
authored
Fix prism_ruby superclass resolve order (#1267)
RDoc::Parser::PrismRuby wrongly resolves superclass of `class Cipher < Cipher; end` that exist in openssl. Superclass resolve should be done before adding class.
1 parent fb7041e commit 57a4615

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

lib/rdoc/parser/prism_ruby.rb

+4-2
Original file line numberDiff line numberDiff line change
@@ -642,14 +642,16 @@ def add_module_or_class(module_name, start_line, end_line, is_class: false, supe
642642

643643
owner, name = find_or_create_constant_owner_name(module_name)
644644
if is_class
645-
mod = owner.classes_hash[name] || owner.add_class(RDoc::NormalClass, name, superclass_name || '::Object')
646-
647645
# RDoc::NormalClass resolves superclass name despite of the lack of module nesting information.
648646
# We need to fix it when RDoc::NormalClass resolved to a wrong constant name
649647
if superclass_name
650648
superclass_full_path = resolve_constant_path(superclass_name)
651649
superclass = @store.find_class_or_module(superclass_full_path) if superclass_full_path
652650
superclass_full_path ||= superclass_name
651+
end
652+
# add_class should be done after resolving superclass
653+
mod = owner.classes_hash[name] || owner.add_class(RDoc::NormalClass, name, superclass_name || '::Object')
654+
if superclass_name
653655
if superclass
654656
mod.superclass = superclass
655657
elsif mod.superclass.is_a?(String) && mod.superclass != superclass_full_path

test/rdoc/test_rdoc_parser_prism_ruby.rb

+19
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,25 @@ class A::C4 < A::B; end
201201
assert_equal ['A::B', 'A::B', 'A::A::B', 'A::B'], classes.drop(1).map(&:superclass).map(&:full_name)
202202
end
203203

204+
def test_pseudo_recursive_superclass
205+
util_parser <<~RUBY
206+
module Foo
207+
class Bar
208+
class Foo < Bar; end
209+
# This class definition is used in OpenSSL::Cipher::Cipher
210+
class Bar < Bar; end
211+
class Baz < Bar; end
212+
end
213+
end
214+
RUBY
215+
foo_klass = @store.find_class_named 'Foo::Bar::Foo'
216+
bar_klass = @store.find_class_named 'Foo::Bar::Bar'
217+
baz_klass = @store.find_class_named 'Foo::Bar::Baz'
218+
assert_equal 'Foo::Bar', foo_klass.superclass.full_name
219+
assert_equal 'Foo::Bar', bar_klass.superclass.full_name
220+
assert_equal 'Foo::Bar::Bar', baz_klass.superclass.full_name
221+
end
222+
204223
def test_class_module_nodoc
205224
util_parser <<~RUBY
206225
class Foo # :nodoc:

0 commit comments

Comments
 (0)