lsegal / yard

YARD is a Ruby Documentation tool. The Y stands for "Yay!"
http://yardoc.org
MIT License
1.92k stars 394 forks source link

RangeError When using pattern matching in YARD documentation generation #1521

Open aristotelesbr opened 7 months ago

aristotelesbr commented 7 months ago

Description

Maybe i encountered an issue while generating documentation using the YARD gem with pattern matching syntax like "foo" => String. A RangeError is thrown regarding a 'beginless range'. This error specifically arises in the ast_node.rb:348 file as part of the documentation generation process.

Error Message: .asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/yard-0.9.34/lib/yard/parser/ruby/ast_node.rb:348:in `first': cannot get the first element of beginless range (RangeError)

Steps to reproduce

  1. Include pattern matching in the style of "foo" => String in a method documented with YARD.
  2. Run the command yard doc .
  3. Observe the above-mentioned RangeError.

Expected Result: Documentation is generated without any errors.

Actual Result: The documentation generation process fails with a RangeError when trying to interpret pattern matching with string literals.

Environment:

Code Example:

# @api private
#
# @param type [String] the response content type
# @param charset [Hash] the response charset
#
# @return [void]
def put_content_type(type, charset: nil)
  type => ::String

  case charset
  in ::String then header!('Content-Type', "#{type}; charset=#{charset}")
  else             header!('Content-Type', type)
  end
rescue ::NoMatchingPatternError
  raise ::ArgumentError, 'type must be a string'
end

Repository reference link

mike-burns commented 1 month ago

Possible workaround in #1536 .

akimd commented 4 weeks ago

I face the same issue (Yard 0.9.36) on this sample test case:

def foo(code)
  case code
  in Foo
  end
end

def bar(code)
  code.type => Bar
end
$ bundle exec yardoc --output-dir rdoc --debug foo.rb
[debug]: Parsing ["foo.rb"] with `ruby` parser
[debug]: Parsing foo.rb
vendor/ruby/3.3.0/gems/yard-0.9.36/lib/yard/parser/ruby/ruby_parser.rb:245:in `first': cannot get the first element of beginless range (RangeError)
        from vendor/ruby/3.3.0/gems/yard-0.9.36/lib/yard/parser/ruby/ruby_parser.rb:245:in `visit_event'
        from vendor/ruby/3.3.0/gems/yard-0.9.36/lib/yard/parser/ruby/ruby_parser.rb:171:in `on_def'
        from vendor/ruby/3.3.0/gems/yard-0.9.36/lib/yard/parser/ruby/ruby_parser.rb:56:in `parse'

Unfortunately #1536 does not fix my problem.

Weirdly enough, I need both functions for yard to crash. With only foo or only bar, it works.

There is good news: I can easily work-around by adding useless parens:

def bar(code)
  (code.type => Bar)
end