yard icon indicating copy to clipboard operation
yard copied to clipboard

Generated docs for class is empty when a sub-file defines a module with the same name

Open postmodern opened this issue 3 years ago • 2 comments

I stumbled across this strange edge-case while refactoring an old project. If you have a class called Foo::Bar defined in lib/foo/bar.rb, but also have an older file laying around which defines Foo::Bar as a module in lib/foo/bar/old_file.rb and you have another sub-module named Foo::Bar::OtherModule defined in lib/foo/bar/other_module.rb, it someshow shadows the Foo::Bar class and causes it's generated documentation to be completely empty.

Steps to reproduce

Gemfile:

source 'https://rubygems.org'

gem 'kramdown'
gem 'yard', '0.9.28'

lib/foo/bar.rb:

module Foo
  class Bar # Note: Bar is defined as a class

    def self.a_class_method
    end

    def an_instance_method
    end

  end
end

lib/foo/bar/old_file.rb:

module Foo
  module Bar # Wrong: this is the old Bar which is a module, not a class
    def self.some_old_method
    end
  end
end

lib/foo/bar/other_module.rb:

module Foo
  class Bar # Correct: Bar is correctly defined as a class
    module OtherModule
      def some_mixin_method
      end
    end
  end
end
  1. bundle install
  2. bundle exec yardoc
  3. Open doc/Foo/Bar.html in the browser.

Actual Output

[warn]: Could not load default RDoc formatter, ignoring any markup (install RDoc to get default formatting).
[debug]: Parsing ["{lib,app}/**/*.rb", "ext/**/*.{c,cc,cxx,cpp,rb}"] with `ruby` parser
[debug]: Parsing lib/foo/bar.rb
[debug]: Parsing lib/foo/bar/old_file.rb
[debug]: Parsing lib/foo/bar/other_module.rb
[debug]: Serializing to .yardoc/objects/root.dat
[debug]: Re-generating object ...
[debug]: Re-generating object Foo...
[debug]: Re-generating object Foo::Bar::OtherModule...
[debug]: Re-generating object Foo::Bar...
[debug]: Generating asset js/jquery.js
[debug]: Serializing to doc/js/jquery.js
[debug]: Generating asset js/app.js
[debug]: Serializing to doc/js/app.js
[debug]: Generating asset js/full_list.js
[debug]: Serializing to doc/js/full_list.js
[debug]: Generating asset css/style.css
[debug]: Serializing to doc/css/style.css
[debug]: Generating asset css/common.css
[debug]: Serializing to doc/css/common.css
[debug]: Generating asset css/full_list.css
[debug]: Serializing to doc/css/full_list.css
[debug]: Generating asset class_list.html
[debug]: Serializing to doc/class_list.html
[debug]: Generating asset method_list.html
[debug]: Serializing to doc/method_list.html
[debug]: Generating asset file_list.html
[debug]: Serializing to doc/file_list.html
[debug]: Generating asset frames.html
[debug]: Serializing to doc/frames.html
[debug]: Serializing to doc/index.html
[debug]: Serializing to doc/_index.html
[debug]: Serializing to doc/top-level-namespace.html
[debug]: Serializing to doc/Foo.html
[debug]: Serializing to doc/Foo/Bar/OtherModule.html
[debug]: Serializing to doc/Foo/Bar.html
Files:           3
Modules:         2 (    2 undocumented)
Classes:         1 (    1 undocumented)
Constants:       0 (    0 undocumented)
Attributes:      0 (    0 undocumented)
Methods:         4 (    4 undocumented)
 0.00% documented

Expected Output

A warning that Foo::Bar was defined as a class then re-defined as a module would be helpful.

Environment details:

  • OS: Fedora Linux
  • ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
  • yard 0.9.28
  • kramdown 2.4.0

yard_empty_docs

postmodern avatar Aug 24 '22 01:08 postmodern

If I rename lib/foo/bar/other_module.rb to lib/foo/bar/baz.rb, the documentation for Foo::Bar in lib/foo/bar/old_file.rb suddenly appears, which implies the order of the files within lib/foo/bar/ matter.

postmodern avatar Aug 24 '22 01:08 postmodern

The challenge here is that this Ruby code is fairly undefined in the larger context of the full codebase.

I'd say the only reasonable approach would be to have a warning for this type of use-case. YARD cannot really make a choice on your behalf, so it's pretty much for the end-user to resolve. A warning would at least surface the issue.

I will note, however, that given the extreme rarity of this case, this is likely not a high priority to resolve in the project. For that reason, this is likely going to be closed as a WontFix, with the following caveat/notice:

If you want to throw together a PR for this, I would gladly accept such a warning being surfaced. There are good APIs to perform such a check as well as precedent implementation for warnings, at least in the context of docstrings.

Hope that is helpful!

lsegal avatar Sep 03 '22 19:09 lsegal