Skip to content

Commit 369f964

Browse files
Prevent RDoc from polluting in_files
There is currently a bug in RDoc v6.5.0 that causes the value of `RDoc::ClassModule#in_files` to become polluted when referring to a constant nested in a module where the module has been previously seen but the constant has not. For example, if RDoc sees a core extension like: ```ruby class Float def as_json(*) # ... end end ``` and later sees a reference to `Float::INFINITY` in a file `foo.rb`, then it will add `foo.rb` to `in_files` for `Float`. That will cause `foo.rb` to appear in `public/classes/Float.html` and `Float` to appear in `public/files/foo.rb`. This commit monkey patches RDoc to prevent such pollution. The monkey patch has been tested with the test suites of RDoc v6.5.0 and RDoc `master` as of ruby/rdoc@9e75bf6, and all tests pass.
1 parent d0e2ead commit 369f964

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

lib/sdoc/rdoc_monkey_patches.rb

+16
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,19 @@ def cross_reference(name, text = nil, code = true)
2222
super
2323
end
2424
end)
25+
26+
27+
RDoc::Parser::Ruby.prepend(Module.new do
28+
def get_class_or_module(container, ignore_constants = false)
29+
@ignoring_constants ||= nil
30+
original_ignoring_constants, @ignoring_constants = @ignoring_constants, ignore_constants
31+
super
32+
ensure
33+
@ignoring_constants = original_ignoring_constants
34+
end
35+
36+
def record_location(*)
37+
@ignoring_constants ||= nil
38+
super unless @ignoring_constants
39+
end
40+
end)

spec/rdoc_monkey_patches_spec.rb

+28
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,32 @@ def qux; end
4747
_(description).must_match %r"and <a href=.+?>qux \(also\) cannot</a>"
4848
end
4949
end
50+
51+
describe RDoc::Parser::Ruby do
52+
it "does not pollute RDoc::ClassModule#in_files when parsing constants" do
53+
Dir.mktmpdir do |dir|
54+
Dir.chdir(dir) do
55+
File.write("float_ext.rb", <<~RUBY)
56+
class Float
57+
def ext; end
58+
end
59+
RUBY
60+
61+
File.write("foo.rb", <<~RUBY)
62+
class Foo
63+
def foo; Float::INFINITY; end
64+
end
65+
RUBY
66+
67+
rdoc_store = rdoc_dry_run("--files", "float_ext.rb", "foo.rb").store
68+
69+
_(rdoc_store.find_class_or_module("Float").in_files).
70+
must_equal [rdoc_store.find_file_named("float_ext.rb")]
71+
72+
_(rdoc_store.find_file_named("foo.rb").classes_and_modules).
73+
must_equal [rdoc_store.find_class_or_module("Foo")]
74+
end
75+
end
76+
end
77+
end
5078
end

0 commit comments

Comments
 (0)