Skip to content

Commit

Permalink
[ruby/rdoc] Fix prism_ruby superclass resolve order
Browse files Browse the repository at this point in the history
(ruby/rdoc#1267)

RDoc::Parser::PrismRuby wrongly resolves superclass of `class Cipher < Cipher; end` that exist in openssl.
Superclass resolve should be done before adding class.

ruby/rdoc@57a4615a92
  • Loading branch information
tompng authored and matzbot committed Jan 3, 2025
1 parent fb73be1 commit 23018c2
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
6 changes: 4 additions & 2 deletions lib/rdoc/parser/prism_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -642,14 +642,16 @@ def add_module_or_class(module_name, start_line, end_line, is_class: false, supe

owner, name = find_or_create_constant_owner_name(module_name)
if is_class
mod = owner.classes_hash[name] || owner.add_class(RDoc::NormalClass, name, superclass_name || '::Object')

# RDoc::NormalClass resolves superclass name despite of the lack of module nesting information.
# We need to fix it when RDoc::NormalClass resolved to a wrong constant name
if superclass_name
superclass_full_path = resolve_constant_path(superclass_name)
superclass = @store.find_class_or_module(superclass_full_path) if superclass_full_path
superclass_full_path ||= superclass_name
end
# add_class should be done after resolving superclass
mod = owner.classes_hash[name] || owner.add_class(RDoc::NormalClass, name, superclass_name || '::Object')
if superclass_name
if superclass
mod.superclass = superclass
elsif mod.superclass.is_a?(String) && mod.superclass != superclass_full_path
Expand Down
19 changes: 19 additions & 0 deletions test/rdoc/test_rdoc_parser_prism_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,25 @@ class A::C4 < A::B; end
assert_equal ['A::B', 'A::B', 'A::A::B', 'A::B'], classes.drop(1).map(&:superclass).map(&:full_name)
end

def test_pseudo_recursive_superclass
util_parser <<~RUBY
module Foo
class Bar
class Foo < Bar; end
# This class definition is used in OpenSSL::Cipher::Cipher
class Bar < Bar; end
class Baz < Bar; end
end
end
RUBY
foo_klass = @store.find_class_named 'Foo::Bar::Foo'
bar_klass = @store.find_class_named 'Foo::Bar::Bar'
baz_klass = @store.find_class_named 'Foo::Bar::Baz'
assert_equal 'Foo::Bar', foo_klass.superclass.full_name
assert_equal 'Foo::Bar', bar_klass.superclass.full_name
assert_equal 'Foo::Bar::Bar', baz_klass.superclass.full_name
end

def test_class_module_nodoc
util_parser <<~RUBY
class Foo # :nodoc:
Expand Down

0 comments on commit 23018c2

Please sign in to comment.