Skip to content

Commit 5fb832a

Browse files
committed
Handle private_class_method and public_class_method correctly by copying methods from superclasses when visibility needs to be changed
1 parent 1877775 commit 5fb832a

File tree

12 files changed

+181
-16
lines changed

12 files changed

+181
-16
lines changed

History.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* Completing IO::o in `ri -i` now returns results. Ruby Bug #3167
1515
* RDoc::Parser::C ignores prototypes better. Pull Request #34 by Pete
1616
Higgins.
17+
* private_class_method and public_class_method are now parsed correctly for
18+
inherited methods. Issue #16 by gitsucks.
1719

1820
=== 3.5.3 / 2010-02-06
1921

lib/rdoc/class_module.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,22 @@ def complete min_visibility
137137
remove_invisible min_visibility
138138
end
139139

140+
##
141+
# Iterates the ancestors of this class or module for which an
142+
# RDoc::ClassModule exists.
143+
144+
def each_ancestor # :yields: module
145+
ancestors.each do |mod|
146+
next if String === mod
147+
yield mod
148+
end
149+
end
150+
140151
##
141152
# Looks for a symbol in the #ancestors. See Context#find_local_symbol.
142153

143154
def find_ancestor_local_symbol symbol
144-
ancestors.each do |m|
145-
next if m.is_a?(String)
155+
each_ancestor do |m|
146156
res = m.find_local_symbol(symbol)
147157
return res if res
148158
end

lib/rdoc/code_object.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,20 @@ def done_documenting=(value)
180180
@document_children = @document_self
181181
end
182182

183+
##
184+
# Yields each parent of this CodeObject. See also
185+
# RDoc::ClassModule#each_ancestor
186+
187+
def each_parent
188+
code_object = self
189+
190+
while code_object = code_object.parent do
191+
yield code_object
192+
end
193+
194+
self
195+
end
196+
183197
##
184198
# Force the documentation of this object unless documentation
185199
# has been turned off by :endoc:

lib/rdoc/context.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,10 +950,14 @@ def methods_by_type section = nil
950950
##
951951
# Yields AnyMethod and Attr entries matching the list of names in +methods+.
952952

953-
def methods_matching(methods, singleton = false)
953+
def methods_matching(methods, singleton = false, &block)
954954
(@method_list + @attributes).each do |m|
955955
yield m if methods.include?(m.name) and m.singleton == singleton
956956
end
957+
958+
each_ancestor do |parent|
959+
parent.methods_matching(methods, singleton, &block)
960+
end
957961
end
958962

959963
##

lib/rdoc/parser/ruby.rb

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,32 +1558,45 @@ def parse_visibility(container, single, tk)
15581558
when TkNL, TkUNLESS_MOD, TkIF_MOD, TkSEMICOLON then
15591559
container.ongoing_visibility = vis
15601560
else
1561-
if vis_type == 'module_function' then
1561+
new_methods = []
1562+
1563+
case vis_type
1564+
when 'module_function' then
15621565
args = parse_symbol_arg
15631566
container.set_visibility_for args, :private, false
15641567

1565-
module_functions = []
1566-
15671568
container.methods_matching args do |m|
15681569
s_m = m.dup
15691570
s_m.record_location @top_level
15701571
s_m.singleton = true
1571-
s_m.visibility = :public
1572-
module_functions << s_m
1572+
new_methods << s_m
15731573
end
1574+
when 'public_class_method', 'private_class_method' then
1575+
args = parse_symbol_arg
15741576

1575-
module_functions.each do |s_m|
1576-
case s_m
1577-
when RDoc::AnyMethod then
1578-
container.add_method s_m
1579-
when RDoc::Attr then
1580-
container.add_attribute s_m
1577+
container.methods_matching args, true do |m|
1578+
if m.parent != container then
1579+
m = m.dup
1580+
m.record_location @top_level
1581+
new_methods << m
15811582
end
1583+
1584+
m.visibility = vis
15821585
end
15831586
else
15841587
args = parse_symbol_arg
15851588
container.set_visibility_for args, vis, singleton
15861589
end
1590+
1591+
new_methods.each do |method|
1592+
case method
1593+
when RDoc::AnyMethod then
1594+
container.add_method method
1595+
when RDoc::Attr then
1596+
container.add_attribute method
1597+
end
1598+
method.visibility = vis
1599+
end
15871600
end
15881601
end
15891602

test/test_rdoc_class_module.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ def setup
88
@RM = RDoc::Markup
99
end
1010

11+
def test_ancestors
12+
assert_equal [@parent], @child.ancestors
13+
end
14+
1115
def test_comment_equals
1216
cm = RDoc::ClassModule.new 'Klass'
1317
cm.comment = '# comment 1'
@@ -23,6 +27,16 @@ def test_comment_equals
2327
assert_equal "comment 1\n---\ncomment 2\n---\n* comment 3", cm.comment
2428
end
2529

30+
def test_each_ancestor
31+
ancestors = []
32+
33+
@child.each_ancestor do |mod|
34+
ancestors << mod
35+
end
36+
37+
assert_equal [@parent], ancestors
38+
end
39+
2640
# handle making a short module alias of yourself
2741

2842
def test_find_class_named

test/test_rdoc_code_object.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ def test_done_documenting
119119
assert @co.document_children
120120
end
121121

122+
def test_each_parent
123+
parents = []
124+
125+
@parent_m.each_parent do |code_object|
126+
parents << code_object
127+
end
128+
129+
assert_equal [@parent, @xref_data], parents
130+
end
131+
122132
def test_full_name_equals
123133
@co.full_name = 'hi'
124134

test/test_rdoc_context.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,5 +448,35 @@ def test_methods_by_type_section
448448
assert_equal expected, @c1.methods_by_type(separate)
449449
end
450450

451+
def test_methods_matching
452+
methods = []
453+
454+
@parent.methods_matching 'm' do |m|
455+
methods << m
456+
end
457+
458+
assert_equal [@parent_m], methods
459+
end
460+
461+
def test_methods_matching_singleton
462+
methods = []
463+
464+
@parent.methods_matching 'm', true do |m|
465+
methods << m
466+
end
467+
468+
assert_equal [@parent__m], methods
469+
end
470+
471+
def test_methods_matching_inherit
472+
methods = []
473+
474+
@child.methods_matching 'm' do |m|
475+
methods << m
476+
end
477+
478+
assert_equal [@parent_m], methods
479+
end
480+
451481
end
452482

test/test_rdoc_parser_ruby.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,56 @@ def test_parse_statements_identifier_private
17991799
assert_equal :private, foo.visibility
18001800
end
18011801

1802+
def test_parse_statements_identifier_public_class_method
1803+
content = <<-CONTENT
1804+
class Date
1805+
def self.now; end
1806+
private_class_method :now
1807+
end
1808+
1809+
class DateTime < Date
1810+
public_class_method :now
1811+
end
1812+
CONTENT
1813+
1814+
util_parser content
1815+
1816+
@parser.parse_statements @top_level
1817+
1818+
date, date_time = @top_level.classes
1819+
1820+
date_now = date.method_list.first
1821+
date_time_now = date_time.method_list.first
1822+
1823+
assert_equal :private, date_now.visibility
1824+
assert_equal :public, date_time_now.visibility
1825+
end
1826+
1827+
def test_parse_statements_identifier_private_class_method
1828+
content = <<-CONTENT
1829+
class Date
1830+
def self.now; end
1831+
public_class_method :now
1832+
end
1833+
1834+
class DateTime < Date
1835+
private_class_method :now
1836+
end
1837+
CONTENT
1838+
1839+
util_parser content
1840+
1841+
@parser.parse_statements @top_level
1842+
1843+
date, date_time = @top_level.classes
1844+
1845+
date_now = date.method_list.first
1846+
date_time_now = date_time.method_list.first
1847+
1848+
assert_equal :public, date_now.visibility, date_now.full_name
1849+
assert_equal :private, date_time_now.visibility, date_time_now.full_name
1850+
end
1851+
18021852
def test_parse_statements_identifier_require
18031853
content = "require 'bar'"
18041854

test/test_rdoc_top_level.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ def setup
1212

1313
def test_class_all_classes_and_modules
1414
expected = %w[
15-
C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 M1 M1::M2
15+
C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1
16+
Child
17+
M1 M1::M2
18+
Parent
1619
]
1720

1821
assert_equal expected,
@@ -22,6 +25,7 @@ def test_class_all_classes_and_modules
2225
def test_class_classes
2326
expected = %w[
2427
C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1
28+
Child Parent
2529
]
2630

2731
assert_equal expected, RDoc::TopLevel.classes.map { |m| m.full_name }.sort

0 commit comments

Comments
 (0)