Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion lib/rdoc/code_object/class_module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ def add_things(my_things, other_things) # :nodoc:
# in the ancestors. The superclass, if any, comes last.

def ancestors
included_ancestors
end

def included_ancestors # :nodoc:
includes.map { |i| i.module }.reverse
end

Expand Down Expand Up @@ -807,10 +811,17 @@ def superclass=(superclass)

def super_classes
result = []
# Degenerate input can produce a cyclic superclass chain
visited = [full_name]
parent = self
while parent = parent.superclass
if parent.is_a?(String)
result << parent
break
end
break if visited.include?(parent.full_name)
visited << parent.full_name
result << parent
return result if parent.is_a?(String)
end
result
end
Expand Down
13 changes: 5 additions & 8 deletions lib/rdoc/code_object/normal_class.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,12 @@ class RDoc::NormalClass < RDoc::ClassModule
# RDoc::ClassModules and Strings.

def ancestors
if String === superclass then
super << superclass
elsif superclass then
ancestors = super
ancestors << superclass
ancestors.concat superclass.ancestors
else
super
ancestors = included_ancestors
super_classes.each do |sclass|
ancestors << sclass
ancestors.concat sclass.included_ancestors unless String === sclass
end
ancestors
end

def aref_prefix # :nodoc:
Expand Down
17 changes: 17 additions & 0 deletions test/rdoc/code_object/class_module_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,23 @@ def test_super_classes
assert_equal [rdoc_c3_h1, rdoc_object, "BasicObject"], @c3_h2.super_classes
end

def test_super_classes_superclass_cycle
c1 = @top_level.add_class RDoc::NormalClass, 'Cycle1'
c2 = @top_level.add_class RDoc::NormalClass, 'Cycle2'
c1.superclass = c2
c2.superclass = c1

assert_equal [c2], c1.super_classes
assert_equal [c1], c2.super_classes
end

def test_super_classes_superclass_referencing_itself
klass = @top_level.add_class RDoc::NormalClass, 'Klass'
klass.superclass = klass

assert_empty klass.super_classes
end

def test_update_aliases_class
n1 = @xref_data.add_module RDoc::NormalClass, 'N1'
n1_k2 = n1.add_module RDoc::NormalClass, 'N2'
Expand Down
37 changes: 37 additions & 0 deletions test/rdoc/code_object/normal_class_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,43 @@ def test_ancestors_multilevel
assert_equal [c2, c1, @object, 'BasicObject'], c3.ancestors
end

def test_ancestors_superclass_cycle
c1 = @top_level.add_class RDoc::NormalClass, 'Cycle1'
c2 = @top_level.add_class RDoc::NormalClass, 'Cycle2'
c1.superclass = c2
c2.superclass = c1

assert_equal [c2], c1.ancestors
assert_equal [c1], c2.ancestors
end

def test_ancestors_superclass_referencing_itself
klass = @top_level.add_class RDoc::NormalClass, 'Klass'
incl = RDoc::Include.new 'Incl', ''
klass.add_include incl
klass.superclass = klass

assert_equal [incl.name], klass.ancestors
end

def test_ancestors_chain_ending_with_nil_superclass
base = @top_level.add_class RDoc::NormalClass, 'Base'
base.superclass = nil
sub = @top_level.add_class RDoc::NormalClass, 'Sub', 'Base'

assert_equal [base], sub.ancestors
end

def test_ancestors_superclass_is_module
klass = @top_level.add_class RDoc::NormalClass, 'Klass'
mod = @top_level.add_module RDoc::NormalModule, 'Mod'
klass.superclass = mod

# A module is not registered as a class, so the superclass stays a String
assert_equal 'Mod', klass.superclass
assert_equal ['Mod'], klass.ancestors
end

def test_aref
assert_equal 'class-c1', @c1.aref
assert_equal 'class-c2-c3', @c2_c3.aref
Expand Down