Skip to content

Commit 2bce391

Browse files
committed
Fix :stopdoc: directive being undone for C-defined classes
After parsing, `parse_file` resets `done_documenting = false` on all classes in `top_level.classes_or_modules`. The `done_documenting=` setter unconditionally sets `document_self = !value`, which overrides the `document_self = false` state set by `:stopdoc:`. This became visible after `add_to_classes_or_modules` was added to the C parser's `handle_class_module`, causing C-defined classes to appear in `top_level.classes_or_modules` for the first time. Fix by tracking when `:stopdoc:` is explicitly used via a `@stopped_doc` flag. The `done_documenting=` setter skips the `document_self` override when this flag is set. The flag is: - Set only when the `:stopdoc:` directive is processed - Cleared by `:startdoc:` - NOT set by `suppress` (which calls `stop_doc` internally but should remain reversible via `done_documenting = false`)
1 parent 911b122 commit 2bce391

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

lib/rdoc/code_object.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ def initialize_visibility # :nodoc:
125125
@received_nodoc = false
126126
@ignored = false
127127
@suppressed = false
128+
@stopped_doc = false
128129
@track_visibility = true
129130
end
130131

@@ -205,8 +206,10 @@ def documented?
205206
def done_documenting=(value)
206207
return unless @track_visibility
207208
@done_documenting = value
208-
@document_self = !value
209-
@document_children = @document_self
209+
unless @stopped_doc
210+
@document_self = !value
211+
@document_children = @document_self
212+
end
210213
end
211214

212215
##
@@ -343,16 +346,18 @@ def start_doc
343346
@document_children = true
344347
@ignored = false
345348
@suppressed = false
349+
@stopped_doc = false
346350
end
347351

348352
##
349353
# Disable capture of documentation
350354

351-
def stop_doc
355+
def stop_doc(from_directive: false)
352356
return unless @track_visibility
353357

354358
@document_self = false
355359
@document_children = false
360+
@stopped_doc = true if from_directive
356361
end
357362

358363
##

lib/rdoc/markup/pre_process.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def handle_directive(prefix, directive, param, code_object = nil,
231231
when 'stopdoc' then
232232
return blankline unless code_object
233233

234-
code_object.stop_doc
234+
code_object.stop_doc(from_directive: true)
235235

236236
blankline
237237
when 'yield', 'yields' then

test/rdoc/parser/c_test.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,6 +2328,32 @@ def test_handle_method_source_file_with_non_ascii
23282328
File.delete source_path if source_path && File.exist?(source_path)
23292329
end
23302330

2331+
def test_stopdoc_class_display
2332+
content = <<~C
2333+
/* Document-class: Parent
2334+
* This is the Parent class
2335+
*/
2336+
VALUE rb_cParent = rb_define_class("Parent", rb_cObject);
2337+
2338+
/* :stopdoc: */
2339+
VALUE cInternal = rb_define_class_under(rb_cParent, "Internal", rb_cObject);
2340+
/* :startdoc: */
2341+
C
2342+
2343+
util_get_class content, 'cInternal'
2344+
2345+
# Simulate parse_file's done_documenting reset
2346+
@top_level.classes_or_modules.each do |cm|
2347+
cm.done_documenting = false
2348+
end
2349+
2350+
parent = @store.find_class_named 'Parent'
2351+
internal = @store.find_class_named 'Parent::Internal'
2352+
2353+
assert parent.display?, 'Parent should be displayed'
2354+
refute internal.display?, 'stopdoc class should not be displayed'
2355+
end
2356+
23312357
def util_get_class(content, name = nil)
23322358
@parser = util_parser content
23332359
@parser.scan

0 commit comments

Comments
 (0)