Skip to content

Commit ef958c2

Browse files
committed
Delay registration constants discovered in passing
RDoc::Parser::Ruby#parse_constant registers nested constants automatically. For example, it registers module 'A' and 'B' with A::B::C. Second, constant 'C' is registered if assign token '=' comes. This logic automatically registers 'A' and 'B' if assign token doesn't come. This commit fixes it.
1 parent cb375a3 commit ef958c2

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

lib/rdoc/context.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ def add_class_or_module mod, self_hash, all_hash
407407
mod.section = current_section # TODO declaring context? something is
408408
# wrong here...
409409
mod.parent = self
410+
mod.full_name = nil
410411
mod.store = @store
411412

412413
unless @done_documenting then
@@ -510,6 +511,13 @@ def add_module(class_type, name)
510511
add_class_or_module mod, @modules, @store.modules_hash
511512
end
512513

514+
##
515+
# Adds a module by +RDoc::NormalModule+ instance. See also #add_module.
516+
517+
def add_module_by_normal_module(mod)
518+
add_class_or_module mod, @modules, @store.modules_hash
519+
end
520+
513521
##
514522
# Adds an alias from +from+ (a class or module) to +name+ which was defined
515523
# in +file+.

lib/rdoc/parser/ruby.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,15 @@ def get_class_or_module container, ignore_constants = false
356356
given_name << name_t[:text]
357357

358358
is_self = name_t[:kind] == :on_op && name_t[:text] == '<<'
359+
new_modules = []
359360
while !is_self && (tk = peek_tk) and :on_op == tk[:kind] and '::' == tk[:text] do
360361
prev_container = container
361362
container = container.find_module_named name_t[:text]
362363
container ||=
363364
if ignore_constants then
364-
RDoc::Context.new
365+
c = RDoc::NormalModule.new name_t[:text]
366+
new_modules << [prev_container, c]
367+
c
365368
else
366369
c = prev_container.add_module RDoc::NormalModule, name_t[:text]
367370
c.ignore unless prev_container.document_children
@@ -386,7 +389,7 @@ def get_class_or_module container, ignore_constants = false
386389

387390
skip_tkspace false
388391

389-
return [container, name_t, given_name]
392+
return [container, name_t, given_name, new_modules]
390393
end
391394

392395
##
@@ -761,7 +764,7 @@ def parse_class container, single, tk, comment
761764
line_no = tk[:line_no]
762765

763766
declaration_context = container
764-
container, name_t, given_name = get_class_or_module container
767+
container, name_t, given_name, = get_class_or_module container
765768

766769
if name_t[:kind] == :on_const
767770
cls = parse_class_regular container, declaration_context, single,
@@ -878,10 +881,11 @@ def parse_constant container, tk, comment, ignore_constants = false
878881

879882
return unless name =~ /^\w+$/
880883

884+
new_modules = []
881885
if :on_op == peek_tk[:kind] && '::' == peek_tk[:text] then
882886
unget_tk tk
883887

884-
container, name_t, = get_class_or_module container, ignore_constants
888+
container, name_t, _, new_modules = get_class_or_module container, true
885889

886890
name = name_t[:text]
887891
end
@@ -908,6 +912,14 @@ def parse_constant container, tk, comment, ignore_constants = false
908912
end
909913
get_tk
910914

915+
unless ignore_constants
916+
new_modules.each do |prev_c, new_module|
917+
prev_c.add_module_by_normal_module new_module
918+
new_module.ignore unless prev_c.document_children
919+
@top_level.add_to_classes_or_modules new_module
920+
end
921+
end
922+
911923
value = ''
912924
con = RDoc::Constant.new name, value, comment
913925

test/test_rdoc_parser_ruby.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3928,4 +3928,29 @@ def util_two_parsers(first_file_content, second_file_content)
39283928
second_file_content, @options, @stats
39293929
end
39303930

3931+
def test_parse_const_third_party
3932+
util_parser <<-CLASS
3933+
class A
3934+
true if B
3935+
true if B::C
3936+
true if B::C::D
3937+
3938+
module B
3939+
end
3940+
end
3941+
CLASS
3942+
3943+
tk = @parser.get_tk
3944+
3945+
@parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
3946+
3947+
a = @top_level.classes.first
3948+
assert_equal 'A', a.full_name
3949+
3950+
visible = @store.all_modules.reject { |mod| mod.suppressed? }
3951+
visible = visible.map { |mod| mod.full_name }
3952+
3953+
assert_equal ['A::B'], visible
3954+
end
3955+
39313956
end

0 commit comments

Comments
 (0)